Parcourir la source

Merge pull request #51 from Hex-Dragon/main

sync
薄奚梦灵 il y a 1 an
Parent
commit
d2e210320b
100 fichiers modifiés avec 1693 ajouts et 1460 suppressions
  1. 1 7
      Plain Craft Launcher 2/Application.xaml
  2. 7 17
      Plain Craft Launcher 2/Application.xaml.vb
  3. 3 3
      Plain Craft Launcher 2/Controls/MyButton.xaml.vb
  4. 63 44
      Plain Craft Launcher 2/Controls/MyCard.vb
  5. 6 6
      Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb
  6. 2 2
      Plain Craft Launcher 2/Controls/MyComboBox.vb
  7. 1 1
      Plain Craft Launcher 2/Controls/MyComboBoxItem.vb
  8. 66 41
      Plain Craft Launcher 2/Controls/MyDropShadow.vb
  9. 5 5
      Plain Craft Launcher 2/Controls/MyExtraButton.xaml.vb
  10. 2 2
      Plain Craft Launcher 2/Controls/MyExtraTextButton.xaml.vb
  11. 4 12
      Plain Craft Launcher 2/Controls/MyHint.xaml
  12. 73 38
      Plain Craft Launcher 2/Controls/MyHint.xaml.vb
  13. 1 1
      Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb
  14. 1 1
      Plain Craft Launcher 2/Controls/MyIconTextButton.xaml.vb
  15. 9 9
      Plain Craft Launcher 2/Controls/MyImage.vb
  16. 12 12
      Plain Craft Launcher 2/Controls/MyListItem.xaml.vb
  17. 6 6
      Plain Craft Launcher 2/Controls/MyLoading.xaml.vb
  18. 1 1
      Plain Craft Launcher 2/Controls/MyMenuItem.vb
  19. 2 2
      Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml.vb
  20. 2 2
      Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml.vb
  21. 3 3
      Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml.vb
  22. 12 11
      Plain Craft Launcher 2/Controls/MyPageLeft.vb
  23. 11 11
      Plain Craft Launcher 2/Controls/MyPageRight.vb
  24. 5 5
      Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb
  25. 6 6
      Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb
  26. 2 2
      Plain Craft Launcher 2/Controls/MyScrollViewer.vb
  27. 7 7
      Plain Craft Launcher 2/Controls/MySlider.xaml.vb
  28. 5 5
      Plain Craft Launcher 2/Controls/MyTextBox.vb
  29. 1 1
      Plain Craft Launcher 2/Controls/MyTextButton.vb
  30. 8 10
      Plain Craft Launcher 2/FormMain.xaml
  31. 91 60
      Plain Craft Launcher 2/FormMain.xaml.vb
  32. 21 1
      Plain Craft Launcher 2/Modules/Base/ModAnimation.vb
  33. 35 37
      Plain Craft Launcher 2/Modules/Base/ModBase.vb
  34. 48 52
      Plain Craft Launcher 2/Modules/Base/ModLoader.vb
  35. 19 19
      Plain Craft Launcher 2/Modules/Base/ModNet.vb
  36. 57 42
      Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb
  37. 82 77
      Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb
  38. 3 3
      Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb
  39. 5 2
      Plain Craft Launcher 2/Modules/Minecraft/ModJava.vb
  40. 19 27
      Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb
  41. 37 29
      Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb
  42. 16 16
      Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb
  43. 9 2
      Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
  44. 15 14
      Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb
  45. 5 5
      Plain Craft Launcher 2/Modules/ModEvent.vb
  46. 19 18
      Plain Craft Launcher 2/Modules/ModMain.vb
  47. 44 25
      Plain Craft Launcher 2/Modules/ModSecret.vb
  48. 2 2
      Plain Craft Launcher 2/My Project/AssemblyInfo.vb
  49. 6 6
      Plain Craft Launcher 2/Pages/PageDownload/Comp/MyCompItem.xaml.vb
  50. 1 1
      Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml
  51. 1 10
      Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml.vb
  52. 53 46
      Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.vb
  53. 1 1
      Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadResourcePack.xaml
  54. 5 2
      Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadShader.xaml
  55. 30 30
      Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb
  56. 1 1
      Plain Craft Launcher 2/Pages/PageDownload/PageDownloadForge.xaml.vb
  57. 4 4
      Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml
  58. 70 70
      Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml.vb
  59. 4 4
      Plain Craft Launcher 2/Pages/PageDownload/PageDownloadLeft.xaml.vb
  60. 2 2
      Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb
  61. 9 8
      Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb
  62. 14 14
      Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb
  63. 9 5
      Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb
  64. 1 2
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginAuthSkin.xaml.vb
  65. 1 1
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml
  66. 1 1
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb
  67. 6 6
      Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb
  68. 0 1
      Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml
  69. 10 10
      Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml.vb
  70. 1 1
      Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml
  71. 3 3
      Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb
  72. 286 188
      Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml
  73. 1 1
      Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml.vb
  74. 9 9
      Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb
  75. 20 20
      Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb
  76. 1 1
      Plain Craft Launcher 2/Pages/PageSelectRight.xaml.vb
  77. 8 10
      Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb
  78. 13 13
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml
  79. 19 19
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb
  80. 3 3
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupLeft.xaml.vb
  81. 1 1
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb
  82. 6 6
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb
  83. 5 5
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml
  84. 18 16
      Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb
  85. 8 7
      Plain Craft Launcher 2/Pages/PageSpeedLeft.xaml.vb
  86. 25 17
      Plain Craft Launcher 2/Pages/PageVersion/MyLocalModItem.xaml.vb
  87. 5 5
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
  88. 7 4
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
  89. 1 1
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb
  90. 1 1
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml
  91. 6 6
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb
  92. 13 13
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb
  93. 2 2
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml
  94. 14 14
      Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb
  95. 1 9
      Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj
  96. 4 7
      Plain Craft Launcher 2/Resources/Custom.xaml
  97. BIN
      Plain Craft Launcher 2/Resources/Help.zip
  98. 0 10
      Plain Craft Launcher 2/Resources/Language/en_US.xaml
  99. 0 10
      Plain Craft Launcher 2/Resources/Language/zh_CN.xaml
  100. 129 129
      Plain Craft Launcher 2/Resources/ModData.txt

+ 1 - 7
Plain Craft Launcher 2/Application.xaml

@@ -8,12 +8,6 @@
     <Application.Resources>
     <Application.Resources>
         <ResourceDictionary>
         <ResourceDictionary>
             
             
-            <!-- 本地化 -->
-            <ResourceDictionary.MergedDictionaries>
-                <ResourceDictionary Source="pack://application:,,,/Resources/Language/zh_CN.xaml" />
-                <ResourceDictionary Source="pack://application:,,,/Resources/Language/zh_CN.xaml" />
-            </ResourceDictionary.MergedDictionaries>
-            
             <!-- Converter -->
             <!-- Converter -->
             <local:AdditionConverter x:Key="AdditionConverter"/>
             <local:AdditionConverter x:Key="AdditionConverter"/>
             <local:MultiplicationConverter x:Key="MultiplicationConverter"/>
             <local:MultiplicationConverter x:Key="MultiplicationConverter"/>
@@ -66,7 +60,7 @@
             <SolidColorBrush x:Key="ColorBrushWhite" Color="#ffffff" />
             <SolidColorBrush x:Key="ColorBrushWhite" Color="#ffffff" />
             <SolidColorBrush x:Key="ColorBrushTransparent" Color="Transparent" />
             <SolidColorBrush x:Key="ColorBrushTransparent" Color="Transparent" />
             <SolidColorBrush x:Key="ColorBrushSemiTransparent">#01eaf2fe</SolidColorBrush>
             <SolidColorBrush x:Key="ColorBrushSemiTransparent">#01eaf2fe</SolidColorBrush>
-            <SolidColorBrush x:Key="ColorBrushBackgroundTransparentSidebar" Color="#D2FFFFFF" />
+            <SolidColorBrush x:Key="ColorBrushBackgroundTransparentSidebar" Color="#F1FFFFFF" />
 
 
             <!-- Window -->
             <!-- Window -->
             <Style TargetType="{x:Type Window}" x:Key="MyWindow">
             <Style TargetType="{x:Type Window}" x:Key="MyWindow">

+ 7 - 17
Plain Craft Launcher 2/Application.xaml.vb

@@ -165,28 +165,18 @@ WaitRetry:
     End Sub
     End Sub
 
 
     '异常
     '异常
-    Private IsCritErrored As Boolean = False
     Private Sub Application_DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
     Private Sub Application_DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
         On Error Resume Next
         On Error Resume Next
         e.Handled = True
         e.Handled = True
-        If IsProgramEnded Then Exit Sub
-        If IsCritErrored Then
-            '在汇报错误后继续引发错误,知道这次压不住了
-            FormMain.EndProgramForce(ProcessReturnValues.Exception)
-            Exit Sub
-        End If
-        IsCritErrored = True
-        Dim ExceptionString As String = GetExceptionDetail(e.Exception, True)
-        If ExceptionString.Contains("System.Windows.Threading.Dispatcher.Invoke") OrElse
-           ExceptionString.Contains("MS.Internal.AppModel.ITaskbarList.HrInit") OrElse
-           ExceptionString.Contains(".NET Framework") OrElse ' “自动错误判断” 的结果分析
-           ExceptionString.Contains("未能加载文件或程序集") Then
+        If IsProgramEnded Then Return
+        FeedbackInfo()
+        Dim Detail As String = GetExceptionDetail(e.Exception, True)
+        If Detail.Contains("System.Windows.Threading.Dispatcher.Invoke") OrElse Detail.Contains("MS.Internal.AppModel.ITaskbarList.HrInit") OrElse Detail.Contains("未能加载文件或程序集") OrElse
+           Detail.Contains(".NET Framework") Then ' “自动错误判断” 的结果分析
             OpenWebsite("https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-offline-installer")
             OpenWebsite("https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-offline-installer")
-            MsgBox("你的 .NET Framework 版本过低或损坏,请下载并重新安装 .NET Framework 4.6.2!", MsgBoxStyle.Information, "运行环境错误")
-            FormMain.EndProgramForce(ProcessReturnValues.Cancel)
+            Log(e.Exception, "你的 .NET Framework 版本过低或损坏,请下载并重新安装 .NET Framework 4.6.2!" & vbCrLf & "若无法安装,可在卸载高版本的 .NET Framework 后再试。", LogLevel.Critical, "运行环境错误")
         Else
         Else
-            FeedbackInfo()
-            Log(e.Exception, "程序出现未知错误", LogLevel.Assert, "锟斤拷烫烫烫")
+            Log(e.Exception, "程序出现未知错误", LogLevel.Critical, "锟斤拷烫烫烫")
         End If
         End If
     End Sub
     End Sub
 
 

+ 3 - 3
Plain Craft Launcher 2/Controls/MyButton.xaml.vb

@@ -142,7 +142,7 @@ Public Class MyButton
 
 
     '实现自定义事件
     '实现自定义事件
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
-        If Not IsMouseDown Then Exit Sub
+        If Not IsMouseDown Then Return
         Log("[Control] 按下按钮:" & Text)
         Log("[Control] 按下按钮:" & Text)
         RaiseEvent Click(sender, e)
         RaiseEvent Click(sender, e)
         If Not String.IsNullOrEmpty(Tag) Then
         If Not String.IsNullOrEmpty(Tag) Then
@@ -185,7 +185,7 @@ Public Class MyButton
         AniStart(AaColor(PanFore, BackgroundProperty, If(_ColorType = ColorState.Red, "ColorBrushRedBack", "ColorBrush7"), AnimationColorIn), "MyButton Background " & Uuid)
         AniStart(AaColor(PanFore, BackgroundProperty, If(_ColorType = ColorState.Red, "ColorBrushRedBack", "ColorBrush7"), AnimationColorIn), "MyButton Background " & Uuid)
     End Sub
     End Sub
     Private Sub Button_MouseUp() Handles Me.MouseLeftButtonUp
     Private Sub Button_MouseUp() Handles Me.MouseLeftButtonUp
-        If Not IsMouseDown Then Exit Sub
+        If Not IsMouseDown Then Return
         IsMouseDown = False
         IsMouseDown = False
         AniStart({
         AniStart({
                AaScaleTransform(PanFore, 1 - CType(PanFore.RenderTransform, ScaleTransform).ScaleX, 300, 10, New AniEaseOutFluent(AniEasePower.Middle))
                AaScaleTransform(PanFore, 1 - CType(PanFore.RenderTransform, ScaleTransform).ScaleX, 300, 10, New AniEaseOutFluent(AniEasePower.Middle))
@@ -193,7 +193,7 @@ Public Class MyButton
     End Sub
     End Sub
     Private Sub Button_MouseLeave() Handles Me.MouseLeave
     Private Sub Button_MouseLeave() Handles Me.MouseLeave
         AniStart(AaColor(PanFore, BackgroundProperty, "ColorBrushHalfWhite", AnimationColorOut), "MyButton Background " & Uuid)
         AniStart(AaColor(PanFore, BackgroundProperty, "ColorBrushHalfWhite", AnimationColorOut), "MyButton Background " & Uuid)
-        If Not IsMouseDown Then Exit Sub
+        If Not IsMouseDown Then Return
         IsMouseDown = False
         IsMouseDown = False
         AniStart(AaScaleTransform(PanFore, 1 - CType(PanFore.RenderTransform, ScaleTransform).ScaleX, 800,, New AniEaseOutFluent(AniEasePower.Strong)), "MyButton Scale " & Uuid)
         AniStart(AaScaleTransform(PanFore, 1 - CType(PanFore.RenderTransform, ScaleTransform).ScaleX, 800,, New AniEaseOutFluent(AniEasePower.Strong)), "MyButton Scale " & Uuid)
     End Sub
     End Sub

+ 63 - 44
Plain Craft Launcher 2/Controls/MyCard.vb

@@ -3,7 +3,7 @@
     '控件
     '控件
     Inherits Grid
     Inherits Grid
     Private ReadOnly MainGrid As Grid
     Private ReadOnly MainGrid As Grid
-    Public ReadOnly Property MainChrome As SystemDropShadowChrome
+    Public ReadOnly Property MainChrome As MyDropShadow
     Private ReadOnly MainBorder As Border
     Private ReadOnly MainBorder As Border
     Public Property BorderChild As UIElement
     Public Property BorderChild As UIElement
         Get
         Get
@@ -63,17 +63,18 @@
 
 
     'UI 建立
     'UI 建立
     Public Sub New()
     Public Sub New()
-        MainChrome = New SystemDropShadowChrome With {.Margin = New Thickness(-9.5, -9, 0.5, -0.5), .Opacity = 0.1, .CornerRadius = New CornerRadius(6)}
-        MainChrome.SetResourceReference(SystemDropShadowChrome.ColorProperty, "ColorObject1")
+        MainChrome = New MyDropShadow With {
+            .Margin = New Thickness(-3, -3, -3, -3 - GetWPFSize(1)), .ShadowRadius = 3, .Opacity = DropShadowIdleOpacity, .CornerRadius = New CornerRadius(5)}
+        MainChrome.SetResourceReference(MyDropShadow.ColorProperty, "ColorObject1")
         Children.Insert(0, MainChrome)
         Children.Insert(0, MainChrome)
-        MainBorder = New Border With {.Background = New SolidColorBrush(Color.FromArgb(205, 255, 255, 255)), .CornerRadius = New CornerRadius(6), .IsHitTestVisible = False}
+        MainBorder = New Border With {.Background = New SolidColorBrush(Color.FromArgb(245, 255, 255, 255)), .CornerRadius = New CornerRadius(5), .IsHitTestVisible = False}
         Children.Insert(1, MainBorder)
         Children.Insert(1, MainBorder)
         MainGrid = New Grid
         MainGrid = New Grid
         Children.Add(MainGrid)
         Children.Add(MainGrid)
     End Sub
     End Sub
     Private IsLoad As Boolean = False
     Private IsLoad As Boolean = False
     Private Sub Init() Handles Me.Loaded
     Private Sub Init() Handles Me.Loaded
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
         '初次加载限定
         '初次加载限定
         If MainTextBlock Is Nothing Then
         If MainTextBlock Is Nothing Then
@@ -108,7 +109,7 @@
         '这一部分的代码是好几年前留下的究极屎坑,当时还不知道该咋正确调用这种方法,就写了这么一坨屎
         '这一部分的代码是好几年前留下的究极屎坑,当时还不知道该咋正确调用这种方法,就写了这么一坨屎
         '但是现在……反正勉强能用……懒得改了就这样吧.jpg
         '但是现在……反正勉强能用……懒得改了就这样吧.jpg
         '别骂了别骂了.jpg
         '别骂了别骂了.jpg
-        If IsNothing(Stack.Tag) Then Exit Sub
+        If IsNothing(Stack.Tag) Then Return
         '排序
         '排序
         Select Case Type
         Select Case Type
             Case 3
             Case 3
@@ -186,29 +187,29 @@
         Stack.Tag = Nothing
         Stack.Tag = Nothing
     End Sub
     End Sub
 
 
-    '事件
+    '动画
+    Private Const DropShadowIdleOpacity As Double = 0.07
+    Private Const DropShadowHoverOpacity As Double = 0.4
     Public Property HasMouseAnimation As Boolean = True
     Public Property HasMouseAnimation As Boolean = True
     Private Sub MyCard_MouseEnter(sender As Object, e As MouseEventArgs) Handles Me.MouseEnter
     Private Sub MyCard_MouseEnter(sender As Object, e As MouseEventArgs) Handles Me.MouseEnter
-        If Not HasMouseAnimation Then Exit Sub
+        If Not HasMouseAnimation Then Return
         Dim AniList As New List(Of AniData)
         Dim AniList As New List(Of AniData)
-        If Not IsNothing(MainTextBlock) Then AniList.Add(AaColor(MainTextBlock, TextBlock.ForegroundProperty, "ColorBrush2", 150))
-        If Not IsNothing(MainSwap) Then AniList.Add(AaColor(MainSwap, Shapes.Path.FillProperty, "ColorBrush2", 150))
+        If Not IsNothing(MainTextBlock) Then AniList.Add(AaColor(MainTextBlock, TextBlock.ForegroundProperty, "ColorBrush2", 90))
+        If Not IsNothing(MainSwap) Then AniList.Add(AaColor(MainSwap, Shapes.Path.FillProperty, "ColorBrush2", 90))
         AniList.AddRange({
         AniList.AddRange({
-            AaColor(MainChrome, SystemDropShadowChrome.ColorProperty, "ColorObject2", 180),
-            AaColor(MainBorder, Border.BackgroundProperty, New MyColor(230, 255, 255, 255) - MainBorder.Background, 180),
-            AaOpacity(MainChrome, 0.3 - MainChrome.Opacity, 180)
+            AaColor(MainChrome, MyDropShadow.ColorProperty, "ColorObject4", 90),
+            AaOpacity(MainChrome, DropShadowHoverOpacity - MainChrome.Opacity, 90)
         })
         })
         AniStart(AniList, "MyCard Mouse " & Uuid)
         AniStart(AniList, "MyCard Mouse " & Uuid)
     End Sub
     End Sub
     Private Sub MyCard_MouseLeave(sender As Object, e As MouseEventArgs) Handles Me.MouseLeave
     Private Sub MyCard_MouseLeave(sender As Object, e As MouseEventArgs) Handles Me.MouseLeave
-        If Not HasMouseAnimation Then Exit Sub
+        If Not HasMouseAnimation Then Return
         Dim AniList As New List(Of AniData)
         Dim AniList As New List(Of AniData)
-        If Not IsNothing(MainTextBlock) Then AniList.Add(AaColor(MainTextBlock, TextBlock.ForegroundProperty, "ColorBrush1", 250))
-        If Not IsNothing(MainSwap) Then AniList.Add(AaColor(MainSwap, Shapes.Path.FillProperty, "ColorBrush1", 250))
+        If Not IsNothing(MainTextBlock) Then AniList.Add(AaColor(MainTextBlock, TextBlock.ForegroundProperty, "ColorBrush1", 90))
+        If Not IsNothing(MainSwap) Then AniList.Add(AaColor(MainSwap, Shapes.Path.FillProperty, "ColorBrush1", 90))
         AniList.AddRange({
         AniList.AddRange({
-            AaColor(MainChrome, SystemDropShadowChrome.ColorProperty, "ColorObject1", 300),
-            AaColor(MainBorder, Border.BackgroundProperty, New MyColor(205, 255, 255, 255) - MainBorder.Background, 300),
-            AaOpacity(MainChrome, 0.1 - MainChrome.Opacity, 300)
+            AaColor(MainChrome, MyDropShadow.ColorProperty, "ColorObject1", 90),
+            AaOpacity(MainChrome, DropShadowIdleOpacity - MainChrome.Opacity, 90)
         })
         })
         AniStart(AniList, "MyCard Mouse " & Uuid)
         AniStart(AniList, "MyCard Mouse " & Uuid)
     End Sub
     End Sub
@@ -222,37 +223,55 @@
     Private IsHeightAnimating As Boolean = False
     Private IsHeightAnimating As Boolean = False
     Private ActualUsedHeight As Double '回滚实际高度(例如 NaN)
     Private ActualUsedHeight As Double '回滚实际高度(例如 NaN)
     Private Sub MySizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
     Private Sub MySizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
-        If Not UseAnimation Then Exit Sub
+        If Not UseAnimation Then Return
         Dim DeltaHeight As Double = If(IsSwaped, SwapedHeight, e.NewSize.Height) - e.PreviousSize.Height
         Dim DeltaHeight As Double = If(IsSwaped, SwapedHeight, e.NewSize.Height) - e.PreviousSize.Height
         '卡片的进入时动画已被页面通用切换动画替代
         '卡片的进入时动画已被页面通用切换动画替代
-        If e.PreviousSize.Height = 0 OrElse IsHeightAnimating OrElse Math.Abs(DeltaHeight) < 1 OrElse ActualHeight = 0 Then Exit Sub
+        If e.PreviousSize.Height = 0 OrElse IsHeightAnimating OrElse Math.Abs(DeltaHeight) < 1 OrElse ActualHeight = 0 Then Return
         StartHeightAnimation(DeltaHeight, e.PreviousSize.Height, False)
         StartHeightAnimation(DeltaHeight, e.PreviousSize.Height, False)
     End Sub
     End Sub
-    Private Sub StartHeightAnimation(DeltaHeight As Double, PreviousHeight As Double, IsLoadAnimation As Boolean)
-        If IsHeightAnimating OrElse FrmMain Is Nothing Then Exit Sub '避免 XAML 设计器出错
+    Private Sub StartHeightAnimation(Delta As Double, PreviousHeight As Double, IsLoadAnimation As Boolean)
+        If IsHeightAnimating OrElse FrmMain Is Nothing Then Return '避免 XAML 设计器出错
 
 
         Dim AnimList As New List(Of AniData)
         Dim AnimList As New List(Of AniData)
-        If DeltaHeight > 10 OrElse (DeltaHeight < -10 AndAlso Not IsNothing(SwapControl)) Then '如果不是需要折叠的卡片,高度减小时的弹跳会吞掉按钮下边框
-            '高度增加较大,使用弹起动画
-            Dim Delta As Double = MathClamp(Math.Abs(DeltaHeight) * 0.05, 3, 10) * Math.Sign(DeltaHeight)
-            AnimList.AddRange({
-                AaHeight(Me, DeltaHeight + Delta, 300, If(IsLoadAnimation, 30, 0), If(DeltaHeight > FrmMain.Height, New AniEaseInFluent(AniEasePower.ExtraStrong), New AniEaseOutFluent(AniEasePower.ExtraStrong))),
-                AaHeight(Me, -Delta, 150, 260, Ease:=New AniEaseOutFluent(AniEasePower.Strong))
-            })
+        Dim AbsDelta = Math.Abs(Delta)
+
+        If AbsDelta <= 800 Then
+            '短距离,直接使用 150ms 的缓动动画
+            AnimList.Add(AaHeight(Me, Delta, 150,, New AniEaseOutFluent(AniEasePower.ExtraStrong)))
         Else
         Else
-            '普通的改变就行啦
-            AnimList.AddRange({
-                AaHeight(Me, DeltaHeight, MathClamp(Math.Abs(DeltaHeight) * 4, 150, 250),, New AniEaseOutFluent)
-            })
+            Dim EaseLength As Integer, EaseTime As Integer
+            Dim InitSpeed As Integer '到达缓动区前的初速度
+            If Delta < 0 AndAlso AbsDelta - EaseLength > 5000 * 0.1 Then
+                '收回距离过长 (>0.1s),强制以 100ms 完成匀速段,然后让减速段更长
+                EaseLength = 200
+                EaseTime = 150
+                InitSpeed = (AbsDelta - EaseLength) / 0.1
+            ElseIf Delta > 0 AndAlso AbsDelta - EaseLength > 5000 * 0.6 Then
+                '展开距离过长 (>0.6s),以 5000 速度展示 300ms 匀速段,剩下的距离全部归入减速段
+                InitSpeed = 5000
+                EaseLength = AbsDelta - InitSpeed * 0.3
+                EaseTime = 400
+            Else
+                '中程,匀速地快速展开(或收回)
+                EaseLength = 150
+                EaseTime = 200
+                InitSpeed = 4000
+            End If
+            '匀速段
+            AnimList.Add(AaHeight(Me, (AbsDelta - EaseLength) * Math.Sign(Delta),
+                (AbsDelta - EaseLength) / InitSpeed * 1000))
+            '减速段
+            AnimList.Add(AaHeight(Me, EaseLength * Math.Sign(Delta),
+                EaseTime,, New AniEaseOutFluentWithInitial(InitSpeed, EaseTime / 1000, EaseLength), True))
         End If
         End If
+
         AnimList.Add(AaCode(
         AnimList.Add(AaCode(
         Sub()
         Sub()
             IsHeightAnimating = False
             IsHeightAnimating = False
             Height = ActualUsedHeight
             Height = ActualUsedHeight
-            If IsSwaped Then SwapControl.Visibility = Visibility.Collapsed
+            If IsSwaped AndAlso SwapControl IsNot Nothing Then SwapControl.Visibility = Visibility.Collapsed
         End Sub,, True))
         End Sub,, True))
         AniStart(AnimList, "MyCard Height " & Uuid)
         AniStart(AnimList, "MyCard Height " & Uuid)
-
         IsHeightAnimating = True
         IsHeightAnimating = True
         ActualUsedHeight = If(IsSwaped, SwapedHeight, Height)
         ActualUsedHeight = If(IsSwaped, SwapedHeight, Height)
         Height = PreviousHeight
         Height = PreviousHeight
@@ -286,18 +305,18 @@
             Return _IsSwaped
             Return _IsSwaped
         End Get
         End Get
         Set(value As Boolean)
         Set(value As Boolean)
-            If _IsSwaped = value Then Exit Property
+            If _IsSwaped = value Then Return
             _IsSwaped = value
             _IsSwaped = value
-            If SwapControl Is Nothing Then Exit Property
+            If SwapControl Is Nothing Then Return
             '展开
             '展开
             If Not IsSwaped AndAlso TypeOf SwapControl Is StackPanel Then StackInstall(SwapControl, SwapType, Title)
             If Not IsSwaped AndAlso TypeOf SwapControl Is StackPanel Then StackInstall(SwapControl, SwapType, Title)
             '若尚未加载,会在 Loaded 事件中触发无动画的折叠,不需要在这里进行
             '若尚未加载,会在 Loaded 事件中触发无动画的折叠,不需要在这里进行
-            If Not IsLoaded Then Exit Property
+            If Not IsLoaded Then Return
             '更新高度
             '更新高度
             SwapControl.Visibility = Visibility.Visible
             SwapControl.Visibility = Visibility.Visible
             TriggerForceResize()
             TriggerForceResize()
             '改变箭头
             '改变箭头
-            AniStart(AaRotateTransform(MainSwap, If(_IsSwaped, If(SwapLogoRight, 270, 0), 180) - CType(MainSwap.RenderTransform, RotateTransform).Angle, 400,, New AniEaseOutBack(AniEasePower.Weak)), "MyCard Swap " & Uuid, True)
+            AniStart(AaRotateTransform(MainSwap, If(_IsSwaped, If(SwapLogoRight, 270, 0), 180) - CType(MainSwap.RenderTransform, RotateTransform).Angle, 250,, New AniEaseOutFluent(AniEasePower.ExtraStrong)), "MyCard Swap " & Uuid, True)
         End Set
         End Set
     End Property
     End Property
     Private _IsSwaped As Boolean = False
     Private _IsSwaped As Boolean = False
@@ -310,7 +329,7 @@
     Private Sub MyCard_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
     Private Sub MyCard_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
         Dim Pos As Double = Mouse.GetPosition(Me).Y
         Dim Pos As Double = Mouse.GetPosition(Me).Y
         If Not IsSwaped AndAlso
         If Not IsSwaped AndAlso
-            (SwapControl Is Nothing OrElse Pos > If(IsSwaped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Exit Sub '检测点击位置;或已经不在可视树上的误判
+            (SwapControl Is Nothing OrElse Pos > If(IsSwaped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Return '检测点击位置;或已经不在可视树上的误判
         IsMouseDown = True
         IsMouseDown = True
     End Sub
     End Sub
     Private Sub MyCard_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
     Private Sub MyCard_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
@@ -319,7 +338,7 @@
 
 
         Dim Pos As Double = Mouse.GetPosition(Me).Y
         Dim Pos As Double = Mouse.GetPosition(Me).Y
         If Not IsSwaped AndAlso
         If Not IsSwaped AndAlso
-            (SwapControl Is Nothing OrElse Pos > If(IsSwaped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Exit Sub '检测点击位置;或已经不在可视树上的误判
+            (SwapControl Is Nothing OrElse Pos > If(IsSwaped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Return '检测点击位置;或已经不在可视树上的误判
 
 
         Dim ee = New RouteEventArgs(True)
         Dim ee = New RouteEventArgs(True)
         RaiseEvent PreviewSwap(Me, ee)
         RaiseEvent PreviewSwap(Me, ee)
@@ -350,7 +369,7 @@ Partial Public Module ModAnimation
                 AaCode(
                 AaCode(
                 Sub()
                 Sub()
                     If RemoveFromChildren Then
                     If RemoveFromChildren Then
-                        If Control.Parent Is Nothing Then Exit Sub
+                        If Control.Parent Is Nothing Then Return
                         CType(Control.Parent, Object).Children.Remove(Control)
                         CType(Control.Parent, Object).Children.Remove(Control)
                     Else
                     Else
                         Control.Visibility = Visibility.Collapsed
                         Control.Visibility = Visibility.Collapsed
@@ -360,7 +379,7 @@ Partial Public Module ModAnimation
             }, "MyCard Dispose " & Control.Uuid)
             }, "MyCard Dispose " & Control.Uuid)
         Else
         Else
             If RemoveFromChildren Then
             If RemoveFromChildren Then
-                If Control.Parent Is Nothing Then Exit Sub
+                If Control.Parent Is Nothing Then Return
                 CType(Control.Parent, Object).Children.Remove(Control)
                 CType(Control.Parent, Object).Children.Remove(Control)
             Else
             Else
                 Control.Visibility = Visibility.Collapsed
                 Control.Visibility = Visibility.Collapsed

+ 6 - 6
Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb

@@ -40,7 +40,7 @@ Public Class MyCheckBox
     ''' <param name="user">是否由用户引发。</param>
     ''' <param name="user">是否由用户引发。</param>
     Public Sub SetChecked(value As Boolean, user As Boolean)
     Public Sub SetChecked(value As Boolean, user As Boolean)
         Try
         Try
-            If value = Checked Then Exit Sub
+            If value = Checked Then Return
 
 
             'Preview 事件
             'Preview 事件
             If value AndAlso user Then
             If value AndAlso user Then
@@ -50,7 +50,7 @@ Public Class MyCheckBox
                     MouseDowned = True
                     MouseDowned = True
                     Checkbox_MouseLeave()
                     Checkbox_MouseLeave()
                     MouseDowned = False
                     MouseDowned = False
-                    Exit Sub
+                    Return
                 End If
                 End If
             End If
             End If
 
 
@@ -133,14 +133,14 @@ Public Class MyCheckBox
     Private MouseDowned As Boolean = False
     Private MouseDowned As Boolean = False
     Private AllowMouseDown As Boolean = True
     Private AllowMouseDown As Boolean = True
     Private Sub Checkbox_MouseUp() Handles Me.MouseLeftButtonUp
     Private Sub Checkbox_MouseUp() Handles Me.MouseLeftButtonUp
-        If Not MouseDowned Then Exit Sub
+        If Not MouseDowned Then Return
         Log("[Control] 按下复选框(" & (Not Checked).ToString & "):" & Text)
         Log("[Control] 按下复选框(" & (Not Checked).ToString & "):" & Text)
         MouseDowned = False
         MouseDowned = False
         SetChecked(Not Checked, True)
         SetChecked(Not Checked, True)
         AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
         AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
     End Sub
     End Sub
     Private Sub Checkbox_MouseDown() Handles Me.MouseLeftButtonDown
     Private Sub Checkbox_MouseDown() Handles Me.MouseLeftButtonDown
-        If Not AllowMouseDown Then Exit Sub
+        If Not AllowMouseDown Then Return
         MouseDowned = True
         MouseDowned = True
         Focus()
         Focus()
         AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushBg1", 100), "MyCheckBox Background " & Uuid)
         AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushBg1", 100), "MyCheckBox Background " & Uuid)
@@ -154,7 +154,7 @@ Public Class MyCheckBox
         End If
         End If
     End Sub
     End Sub
     Private Sub Checkbox_MouseLeave() Handles Me.MouseLeave
     Private Sub Checkbox_MouseLeave() Handles Me.MouseLeave
-        If Not MouseDowned Then Exit Sub
+        If Not MouseDowned Then Return
         MouseDowned = False
         MouseDowned = False
         AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
         AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
         If Checked Then
         If Checked Then
@@ -203,7 +203,7 @@ Public Class MyCheckBox
          }, "MyCheckBox BorderColor " & Uuid)
          }, "MyCheckBox BorderColor " & Uuid)
     End Sub
     End Sub
     Private Sub Checkbox_MouseLeaveAnimation() Handles Me.MouseLeave
     Private Sub Checkbox_MouseLeaveAnimation() Handles Me.MouseLeave
-        If Not IsEnabled Then Exit Sub 'MouseLeave 比 IsEnabledChanged 后执行,所以如果自定义事件修改了 IsEnabled,将导致显示错误
+        If Not IsEnabled Then Return 'MouseLeave 比 IsEnabledChanged 后执行,所以如果自定义事件修改了 IsEnabled,将导致显示错误
         AniStart({
         AniStart({
                  AaColor(LabText, TextBlock.ForegroundProperty, If(Me.IsEnabled, "ColorBrush1", "ColorBrushGray4"), AnimationTimeOfMouseOut)
                  AaColor(LabText, TextBlock.ForegroundProperty, If(Me.IsEnabled, "ColorBrush1", "ColorBrushGray4"), AnimationTimeOfMouseOut)
          }, "MyCheckBox TextColor " & Uuid)
          }, "MyCheckBox TextColor " & Uuid)

+ 2 - 2
Plain Craft Launcher 2/Controls/MyComboBox.vb

@@ -8,7 +8,7 @@
     Public Property HintText As String = ""
     Public Property HintText As String = ""
     Public Overrides Sub OnApplyTemplate()
     Public Overrides Sub OnApplyTemplate()
         MyBase.OnApplyTemplate()
         MyBase.OnApplyTemplate()
-        If Not IsEditable Then Exit Sub
+        If Not IsEditable Then Return
         Try
         Try
             TextBox = Template.FindName("PART_EditableTextBox", Me)
             TextBox = Template.FindName("PART_EditableTextBox", Me)
             TextBox.AddHandler(LostFocusEvent, New RoutedEventHandler(AddressOf RefreshColor))
             TextBox.AddHandler(LostFocusEvent, New RoutedEventHandler(AddressOf RefreshColor))
@@ -116,7 +116,7 @@
     '修复 WPF Bug:下拉框文本修改后,依然误认为还选择着此前的选项,导致再次点击该选项时内容不变
     '修复 WPF Bug:下拉框文本修改后,依然误认为还选择着此前的选项,导致再次点击该选项时内容不变
     Private IsTextChanging As Boolean = False
     Private IsTextChanging As Boolean = False
     Private Sub MyComboBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
     Private Sub MyComboBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
-        If IsTextChanging OrElse Not IsEditable Then Exit Sub
+        If IsTextChanging OrElse Not IsEditable Then Return
         If SelectedItem IsNot Nothing AndAlso Text <> SelectedItem.ToString Then
         If SelectedItem IsNot Nothing AndAlso Text <> SelectedItem.ToString Then
             Dim RawText As String = Text
             Dim RawText As String = Text
             Dim RawSelectionStart As Integer = TextBox.SelectionStart
             Dim RawSelectionStart As Integer = TextBox.SelectionStart

+ 1 - 1
Plain Craft Launcher 2/Controls/MyComboBoxItem.vb

@@ -35,7 +35,7 @@
             NewFontOpacity = 0.4
             NewFontOpacity = 0.4
             Time = AnimationTimeOut
             Time = AnimationTimeOut
         End If
         End If
-        If BackColorName = NewBackColorName AndAlso FontOpacity = NewFontOpacity Then Exit Sub
+        If BackColorName = NewBackColorName AndAlso FontOpacity = NewFontOpacity Then Return
         BackColorName = NewBackColorName
         BackColorName = NewBackColorName
         FontOpacity = NewFontOpacity
         FontOpacity = NewFontOpacity
         '触发颜色动画
         '触发颜色动画

+ 66 - 41
Plain Craft Launcher 2/Modules/Reference/SystemDropShadowChrome.vb → Plain Craft Launcher 2/Controls/MyDropShadow.vb

@@ -1,65 +1,89 @@
-Public NotInheritable Class SystemDropShadowChrome
+Public Class MyDropShadow
     Inherits Decorator
     Inherits Decorator
 
 
-    '源码来源于:https://referencesource.microsoft.com/#PresentationFramework.Aero/parent/Shared/Microsoft/Windows/Themes/SystemDropShadowChrome.cs,6d9c27d92a8128c1
-
-    Public Shared ReadOnly ColorProperty As DependencyProperty = DependencyProperty.Register("Color", GetType(Color), GetType(SystemDropShadowChrome), New FrameworkPropertyMetadata(Color.FromArgb(&H71, &H0, &H0, &H0), FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf ClearBrushes)))
+    ''' <summary>
+    ''' 阴影颜色。
+    ''' </summary>
     Public Property Color As Color
     Public Property Color As Color
         Get
         Get
-            Return CType(GetValue(ColorProperty), Color)
+            Return GetValue(ColorProperty)
         End Get
         End Get
         Set(value As Color)
         Set(value As Color)
             SetValue(ColorProperty, value)
             SetValue(ColorProperty, value)
         End Set
         End Set
     End Property
     End Property
+    Public Shared ReadOnly ColorProperty As DependencyProperty = DependencyProperty.Register("Color", GetType(Color), GetType(MyDropShadow),
+        New FrameworkPropertyMetadata(Color.FromArgb(&H71, &H0, &H0, &H0), FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf ClearBrushes)))
+
+    ''' <summary>
+    ''' 阴影模糊半径。
+    ''' </summary>
+    Public Property ShadowRadius As Double
+        Get
+            Return GetValue(ShadowRadiusProperty)
+        End Get
+        Set(value As Double)
+            SetValue(ShadowRadiusProperty, value)
+        End Set
+    End Property
+    Public Shared ReadOnly ShadowRadiusProperty As DependencyProperty = DependencyProperty.Register("ShadowRadius", GetType(Double), GetType(MyDropShadow),
+        New FrameworkPropertyMetadata(CDbl(5), FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf ClearBrushes)))
 
 
-    Public Shared ReadOnly CornerRadiusProperty As DependencyProperty = DependencyProperty.Register("CornerRadius", GetType(CornerRadius), GetType(SystemDropShadowChrome), New FrameworkPropertyMetadata(New CornerRadius(), FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf ClearBrushes)), New ValidateValueCallback(AddressOf IsCornerRadiusValid))
+    ''' <summary>
+    ''' 圆角大小。
+    ''' </summary>
     Public Property CornerRadius As CornerRadius
     Public Property CornerRadius As CornerRadius
         Get
         Get
-            Return CType(GetValue(CornerRadiusProperty), CornerRadius)
+            Return GetValue(CornerRadiusProperty)
         End Get
         End Get
         Set(value As CornerRadius)
         Set(value As CornerRadius)
             SetValue(CornerRadiusProperty, value)
             SetValue(CornerRadiusProperty, value)
         End Set
         End Set
     End Property
     End Property
     Private Shared Function IsCornerRadiusValid(value As Object) As Boolean
     Private Shared Function IsCornerRadiusValid(value As Object) As Boolean
-        Dim cr As CornerRadius = CType(value, CornerRadius)
+        Dim cr As CornerRadius = value
         Return Not (cr.TopLeft < 0.0 OrElse cr.TopRight < 0.0 OrElse cr.BottomLeft < 0.0 OrElse cr.BottomRight < 0.0 OrElse Double.IsNaN(cr.TopLeft) OrElse Double.IsNaN(cr.TopRight) OrElse Double.IsNaN(cr.BottomLeft) OrElse Double.IsNaN(cr.BottomRight) OrElse Double.IsInfinity(cr.TopLeft) OrElse Double.IsInfinity(cr.TopRight) OrElse Double.IsInfinity(cr.BottomLeft) OrElse Double.IsInfinity(cr.BottomRight))
         Return Not (cr.TopLeft < 0.0 OrElse cr.TopRight < 0.0 OrElse cr.BottomLeft < 0.0 OrElse cr.BottomRight < 0.0 OrElse Double.IsNaN(cr.TopLeft) OrElse Double.IsNaN(cr.TopRight) OrElse Double.IsNaN(cr.BottomLeft) OrElse Double.IsNaN(cr.BottomRight) OrElse Double.IsInfinity(cr.TopLeft) OrElse Double.IsInfinity(cr.TopRight) OrElse Double.IsInfinity(cr.BottomLeft) OrElse Double.IsInfinity(cr.BottomRight))
     End Function
     End Function
+    Public Shared ReadOnly CornerRadiusProperty As DependencyProperty = DependencyProperty.Register("CornerRadius", GetType(CornerRadius), GetType(MyDropShadow),
+        New FrameworkPropertyMetadata(New CornerRadius(), FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf ClearBrushes)), New ValidateValueCallback(AddressOf IsCornerRadiusValid))
+
+
+    ' =======================================
+    '  渲染
+    ' =======================================
 
 
-    Private Const ShadowDepth As Double = 5
 
 
     Protected Overrides Sub OnRender(drawingContext As DrawingContext)
     Protected Overrides Sub OnRender(drawingContext As DrawingContext)
         Dim cornerRadius As CornerRadius = Me.CornerRadius
         Dim cornerRadius As CornerRadius = Me.CornerRadius
-        Dim shadowBounds As New Rect(New Point(ShadowDepth, ShadowDepth), New Size(RenderSize.Width, RenderSize.Height))
+        Dim shadowBounds As New Rect(0, 0, RenderSize.Width, RenderSize.Height)
         Dim color As Color = Me.Color
         Dim color As Color = Me.Color
 
 
         If shadowBounds.Width > 0 AndAlso shadowBounds.Height > 0 AndAlso color.A > 0 Then
         If shadowBounds.Width > 0 AndAlso shadowBounds.Height > 0 AndAlso color.A > 0 Then
-            Dim centerWidth As Double = shadowBounds.Right - shadowBounds.Left - 2 * ShadowDepth
-            Dim centerHeight As Double = shadowBounds.Bottom - shadowBounds.Top - 2 * ShadowDepth
+            Dim centerWidth As Double = shadowBounds.Right - shadowBounds.Left - 2 * ShadowRadius
+            Dim centerHeight As Double = shadowBounds.Bottom - shadowBounds.Top - 2 * ShadowRadius
             Dim maxRadius As Double = Math.Min(centerWidth * 0.5, centerHeight * 0.5)
             Dim maxRadius As Double = Math.Min(centerWidth * 0.5, centerHeight * 0.5)
             cornerRadius.TopLeft = Math.Min(cornerRadius.TopLeft, maxRadius)
             cornerRadius.TopLeft = Math.Min(cornerRadius.TopLeft, maxRadius)
             cornerRadius.TopRight = Math.Min(cornerRadius.TopRight, maxRadius)
             cornerRadius.TopRight = Math.Min(cornerRadius.TopRight, maxRadius)
             cornerRadius.BottomLeft = Math.Min(cornerRadius.BottomLeft, maxRadius)
             cornerRadius.BottomLeft = Math.Min(cornerRadius.BottomLeft, maxRadius)
             cornerRadius.BottomRight = Math.Min(cornerRadius.BottomRight, maxRadius)
             cornerRadius.BottomRight = Math.Min(cornerRadius.BottomRight, maxRadius)
             Dim brushes As Brush() = GetBrushes(color, cornerRadius)
             Dim brushes As Brush() = GetBrushes(color, cornerRadius)
-            Dim centerTop As Double = shadowBounds.Top + ShadowDepth
-            Dim centerLeft As Double = shadowBounds.Left + ShadowDepth
-            Dim centerRight As Double = shadowBounds.Right - ShadowDepth
-            Dim centerBottom As Double = shadowBounds.Bottom - ShadowDepth
+            Dim centerTop As Double = shadowBounds.Top + ShadowRadius
+            Dim centerLeft As Double = shadowBounds.Left + ShadowRadius
+            Dim centerRight As Double = shadowBounds.Right - ShadowRadius
+            Dim centerBottom As Double = shadowBounds.Bottom - ShadowRadius
             Dim guidelineSetX As Double() = New Double() {centerLeft, centerLeft + cornerRadius.TopLeft, centerRight - cornerRadius.TopRight, centerLeft + cornerRadius.BottomLeft, centerRight - cornerRadius.BottomRight, centerRight}
             Dim guidelineSetX As Double() = New Double() {centerLeft, centerLeft + cornerRadius.TopLeft, centerRight - cornerRadius.TopRight, centerLeft + cornerRadius.BottomLeft, centerRight - cornerRadius.BottomRight, centerRight}
             Dim guidelineSetY As Double() = New Double() {centerTop, centerTop + cornerRadius.TopLeft, centerTop + cornerRadius.TopRight, centerBottom - cornerRadius.BottomLeft, centerBottom - cornerRadius.BottomRight, centerBottom}
             Dim guidelineSetY As Double() = New Double() {centerTop, centerTop + cornerRadius.TopLeft, centerTop + cornerRadius.TopRight, centerBottom - cornerRadius.BottomLeft, centerBottom - cornerRadius.BottomRight, centerBottom}
             drawingContext.PushGuidelineSet(New GuidelineSet(guidelineSetX, guidelineSetY))
             drawingContext.PushGuidelineSet(New GuidelineSet(guidelineSetX, guidelineSetY))
-            cornerRadius.TopLeft += ShadowDepth
-            cornerRadius.TopRight += ShadowDepth
-            cornerRadius.BottomLeft += ShadowDepth
-            cornerRadius.BottomRight += ShadowDepth
+            cornerRadius.TopLeft += ShadowRadius
+            cornerRadius.TopRight += ShadowRadius
+            cornerRadius.BottomLeft += ShadowRadius
+            cornerRadius.BottomRight += ShadowRadius
             Dim topLeft As New Rect(shadowBounds.Left, shadowBounds.Top, cornerRadius.TopLeft, cornerRadius.TopLeft)
             Dim topLeft As New Rect(shadowBounds.Left, shadowBounds.Top, cornerRadius.TopLeft, cornerRadius.TopLeft)
             drawingContext.DrawRectangle(brushes(Placement.TopLeft), Nothing, topLeft)
             drawingContext.DrawRectangle(brushes(Placement.TopLeft), Nothing, topLeft)
             Dim topWidth As Double = guidelineSetX(2) - guidelineSetX(1)
             Dim topWidth As Double = guidelineSetX(2) - guidelineSetX(1)
 
 
             If topWidth > 0 Then
             If topWidth > 0 Then
-                Dim top As New Rect(guidelineSetX(1), shadowBounds.Top, topWidth, ShadowDepth)
+                Dim top As New Rect(guidelineSetX(1), shadowBounds.Top, topWidth, ShadowRadius)
                 drawingContext.DrawRectangle(brushes(Placement.Top), Nothing, top)
                 drawingContext.DrawRectangle(brushes(Placement.Top), Nothing, top)
             End If
             End If
 
 
@@ -68,14 +92,14 @@
             Dim leftHeight As Double = guidelineSetY(3) - guidelineSetY(1)
             Dim leftHeight As Double = guidelineSetY(3) - guidelineSetY(1)
 
 
             If leftHeight > 0 Then
             If leftHeight > 0 Then
-                Dim left As New Rect(shadowBounds.Left, guidelineSetY(1), ShadowDepth, leftHeight)
+                Dim left As New Rect(shadowBounds.Left, guidelineSetY(1), ShadowRadius, leftHeight)
                 drawingContext.DrawRectangle(brushes(Placement.Left), Nothing, left)
                 drawingContext.DrawRectangle(brushes(Placement.Left), Nothing, left)
             End If
             End If
 
 
             Dim rightHeight As Double = guidelineSetY(4) - guidelineSetY(2)
             Dim rightHeight As Double = guidelineSetY(4) - guidelineSetY(2)
 
 
             If rightHeight > 0 Then
             If rightHeight > 0 Then
-                Dim right As New Rect(guidelineSetX(5), guidelineSetY(2), ShadowDepth, rightHeight)
+                Dim right As New Rect(guidelineSetX(5), guidelineSetY(2), ShadowRadius, rightHeight)
                 drawingContext.DrawRectangle(brushes(Placement.Right), Nothing, right)
                 drawingContext.DrawRectangle(brushes(Placement.Right), Nothing, right)
             End If
             End If
 
 
@@ -84,20 +108,20 @@
             Dim bottomWidth As Double = guidelineSetX(4) - guidelineSetX(3)
             Dim bottomWidth As Double = guidelineSetX(4) - guidelineSetX(3)
 
 
             If bottomWidth > 0 Then
             If bottomWidth > 0 Then
-                Dim bottom As New Rect(guidelineSetX(3), guidelineSetY(5), bottomWidth, ShadowDepth)
+                Dim bottom As New Rect(guidelineSetX(3), guidelineSetY(5), bottomWidth, ShadowRadius)
                 drawingContext.DrawRectangle(brushes(Placement.Bottom), Nothing, bottom)
                 drawingContext.DrawRectangle(brushes(Placement.Bottom), Nothing, bottom)
             End If
             End If
 
 
             Dim bottomRight As New Rect(guidelineSetX(4), guidelineSetY(4), cornerRadius.BottomRight, cornerRadius.BottomRight)
             Dim bottomRight As New Rect(guidelineSetX(4), guidelineSetY(4), cornerRadius.BottomRight, cornerRadius.BottomRight)
             drawingContext.DrawRectangle(brushes(Placement.BottomRight), Nothing, bottomRight)
             drawingContext.DrawRectangle(brushes(Placement.BottomRight), Nothing, bottomRight)
 
 
-            If cornerRadius.TopLeft = ShadowDepth AndAlso cornerRadius.TopLeft = cornerRadius.TopRight AndAlso cornerRadius.TopLeft = cornerRadius.BottomLeft AndAlso cornerRadius.TopLeft = cornerRadius.BottomRight Then
+            If cornerRadius.TopLeft = ShadowRadius AndAlso cornerRadius.TopLeft = cornerRadius.TopRight AndAlso cornerRadius.TopLeft = cornerRadius.BottomLeft AndAlso cornerRadius.TopLeft = cornerRadius.BottomRight Then
                 Dim center As New Rect(guidelineSetX(0), guidelineSetY(0), centerWidth, centerHeight)
                 Dim center As New Rect(guidelineSetX(0), guidelineSetY(0), centerWidth, centerHeight)
                 drawingContext.DrawRectangle(brushes(Placement.Center), Nothing, center)
                 drawingContext.DrawRectangle(brushes(Placement.Center), Nothing, center)
             Else
             Else
                 Dim figure As New PathFigure()
                 Dim figure As New PathFigure()
 
 
-                If cornerRadius.TopLeft > ShadowDepth Then
+                If cornerRadius.TopLeft > ShadowRadius Then
                     figure.StartPoint = New Point(guidelineSetX(1), guidelineSetY(0))
                     figure.StartPoint = New Point(guidelineSetX(1), guidelineSetY(0))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(1), guidelineSetY(1)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(1), guidelineSetY(1)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(0), guidelineSetY(1)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(0), guidelineSetY(1)), True))
@@ -105,7 +129,7 @@
                     figure.StartPoint = New Point(guidelineSetX(0), guidelineSetY(0))
                     figure.StartPoint = New Point(guidelineSetX(0), guidelineSetY(0))
                 End If
                 End If
 
 
-                If cornerRadius.BottomLeft > ShadowDepth Then
+                If cornerRadius.BottomLeft > ShadowRadius Then
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(0), guidelineSetY(3)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(0), guidelineSetY(3)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(3), guidelineSetY(3)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(3), guidelineSetY(3)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(3), guidelineSetY(5)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(3), guidelineSetY(5)), True))
@@ -113,7 +137,7 @@
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(0), guidelineSetY(5)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(0), guidelineSetY(5)), True))
                 End If
                 End If
 
 
-                If cornerRadius.BottomRight > ShadowDepth Then
+                If cornerRadius.BottomRight > ShadowRadius Then
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(4), guidelineSetY(5)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(4), guidelineSetY(5)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(4), guidelineSetY(4)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(4), guidelineSetY(4)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(5), guidelineSetY(4)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(5), guidelineSetY(4)), True))
@@ -121,7 +145,7 @@
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(5), guidelineSetY(5)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(5), guidelineSetY(5)), True))
                 End If
                 End If
 
 
-                If cornerRadius.TopRight > ShadowDepth Then
+                If cornerRadius.TopRight > ShadowRadius Then
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(5), guidelineSetY(2)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(5), guidelineSetY(2)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(2), guidelineSetY(2)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(2), guidelineSetY(2)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(2), guidelineSetY(0)), True))
                     figure.Segments.Add(New LineSegment(New Point(guidelineSetX(2), guidelineSetY(0)), True))
@@ -158,28 +182,27 @@
     Private _brushes As Brush()
     Private _brushes As Brush()
 
 
     Private Shared Sub ClearBrushes(o As DependencyObject, e As DependencyPropertyChangedEventArgs)
     Private Shared Sub ClearBrushes(o As DependencyObject, e As DependencyPropertyChangedEventArgs)
-        CType(o, SystemDropShadowChrome)._brushes = Nothing
+        CType(o, MyDropShadow)._brushes = Nothing
     End Sub
     End Sub
-    Private Shared Function CreateStops(c As Color, cornerRadius As Double) As GradientStopCollection
-        Dim gradientScale As Double = 1 / (cornerRadius + ShadowDepth)
-        Dim gsc As New GradientStopCollection From {
-            New GradientStop(c, (0.5 + cornerRadius) * gradientScale)
-        }
+    Private Function CreateStops(c As Color, cornerRadius As Double) As GradientStopCollection
+        Dim gradientScale As Double = 1 / (ShadowRadius + cornerRadius)
+        Dim gsc As New GradientStopCollection
         Dim stopColor As Color = c
         Dim stopColor As Color = c
+        gsc.Add(New GradientStop(stopColor, (ShadowRadius * 0.1 + cornerRadius) * gradientScale))
         stopColor.A = CByte(0.74336 * c.A)
         stopColor.A = CByte(0.74336 * c.A)
-        gsc.Add(New GradientStop(stopColor, (1.5 + cornerRadius) * gradientScale))
+        gsc.Add(New GradientStop(stopColor, (ShadowRadius * 0.3 + cornerRadius) * gradientScale))
         stopColor.A = CByte(0.38053 * c.A)
         stopColor.A = CByte(0.38053 * c.A)
-        gsc.Add(New GradientStop(stopColor, (2.5 + cornerRadius) * gradientScale))
+        gsc.Add(New GradientStop(stopColor, (ShadowRadius * 0.5 + cornerRadius) * gradientScale))
         stopColor.A = CByte(0.12389 * c.A)
         stopColor.A = CByte(0.12389 * c.A)
-        gsc.Add(New GradientStop(stopColor, (3.5 + cornerRadius) * gradientScale))
+        gsc.Add(New GradientStop(stopColor, (ShadowRadius * 0.7 + cornerRadius) * gradientScale))
         stopColor.A = CByte(0.02654 * c.A)
         stopColor.A = CByte(0.02654 * c.A)
-        gsc.Add(New GradientStop(stopColor, (4.5 + cornerRadius) * gradientScale))
+        gsc.Add(New GradientStop(stopColor, (ShadowRadius * 0.9 + cornerRadius) * gradientScale))
         stopColor.A = 0
         stopColor.A = 0
-        gsc.Add(New GradientStop(stopColor, (5 + cornerRadius) * gradientScale))
+        gsc.Add(New GradientStop(stopColor, (ShadowRadius + cornerRadius) * gradientScale))
         gsc.Freeze()
         gsc.Freeze()
         Return gsc
         Return gsc
     End Function
     End Function
-    Private Shared Function CreateBrushes(c As Color, cornerRadius As CornerRadius) As Brush()
+    Private Function CreateBrushes(c As Color, cornerRadius As CornerRadius) As Brush()
         Dim brushes As Brush() = New Brush(8) {}
         Dim brushes As Brush() = New Brush(8) {}
         brushes(Placement.Center) = New SolidColorBrush(c)
         brushes(Placement.Center) = New SolidColorBrush(c)
         brushes(Placement.Center).Freeze()
         brushes(Placement.Center).Freeze()
@@ -297,3 +320,5 @@
     End Function
     End Function
 
 
 End Class
 End Class
+
+'参考自:https://referencesource.microsoft.com/#PresentationFramework.Aero/parent/Shared/Microsoft/Windows/Themes/SystemDropShadowChrome.cs,6d9c27d92a8128c1

+ 5 - 5
Plain Craft Launcher 2/Controls/MyExtraButton.xaml.vb

@@ -11,7 +11,7 @@
             Return _Progress
             Return _Progress
         End Get
         End Get
         Set(value As Double)
         Set(value As Double)
-            If _Progress = value Then Exit Property
+            If _Progress = value Then Return
             _Progress = value
             _Progress = value
             If value < 0.0001 Then
             If value < 0.0001 Then
                 PanProgress.Visibility = Visibility.Collapsed
                 PanProgress.Visibility = Visibility.Collapsed
@@ -30,7 +30,7 @@
             Return _Logo
             Return _Logo
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If value = _Logo Then Exit Property
+            If value = _Logo Then Return
             _Logo = value
             _Logo = value
             Path.Data = (New GeometryConverter).ConvertFromString(value)
             Path.Data = (New GeometryConverter).ConvertFromString(value)
         End Set
         End Set
@@ -51,7 +51,7 @@
             Return _Show
             Return _Show
         End Get
         End Get
         Set(value As Boolean)
         Set(value As Boolean)
-            If _Show = value Then Exit Property
+            If _Show = value Then Return
             _Show = value
             _Show = value
             RunInUi(Sub()
             RunInUi(Sub()
                         If value Then
                         If value Then
@@ -121,7 +121,7 @@
         Focus()
         Focus()
     End Sub
     End Sub
     Private Sub Button_RightMouseDown(sender As Object, e As MouseButtonEventArgs) Handles PanClick.MouseRightButtonDown
     Private Sub Button_RightMouseDown(sender As Object, e As MouseButtonEventArgs) Handles PanClick.MouseRightButtonDown
-        If Not CanRightClick Then Exit Sub
+        If Not CanRightClick Then Return
         If Not IsLeftMouseHeld AndAlso Not IsRightMouseHeld Then
         If Not IsLeftMouseHeld AndAlso Not IsRightMouseHeld Then
             AniStart({
             AniStart({
                 AaScaleTransform(PanScale, 0.85 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
                 AaScaleTransform(PanScale, 0.85 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
@@ -141,7 +141,7 @@
         RefreshColor() '直接刷新颜色以判断是否已触发 MouseLeave
         RefreshColor() '直接刷新颜色以判断是否已触发 MouseLeave
     End Sub
     End Sub
     Private Sub Button_RightMouseUp() Handles PanClick.MouseRightButtonUp
     Private Sub Button_RightMouseUp() Handles PanClick.MouseRightButtonUp
-        If Not CanRightClick Then Exit Sub
+        If Not CanRightClick Then Return
         If Not IsLeftMouseHeld Then
         If Not IsLeftMouseHeld Then
             AniStart({
             AniStart({
                 AaScaleTransform(PanScale, 1 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 300,, New AniEaseOutBack)
                 AaScaleTransform(PanScale, 1 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 300,, New AniEaseOutBack)

+ 2 - 2
Plain Craft Launcher 2/Controls/MyExtraTextButton.xaml.vb

@@ -14,7 +14,7 @@ Public Class MyExtraTextButton
             Return _Logo
             Return _Logo
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If value = _Logo Then Exit Property
+            If value = _Logo Then Return
             _Logo = value
             _Logo = value
             Path.Data = (New GeometryConverter).ConvertFromString(value)
             Path.Data = (New GeometryConverter).ConvertFromString(value)
         End Set
         End Set
@@ -55,7 +55,7 @@ Public Class MyExtraTextButton
             Return _Show
             Return _Show
         End Get
         End Get
         Set(value As Boolean)
         Set(value As Boolean)
-            If _Show = value Then Exit Property
+            If _Show = value Then Return
             _Show = value
             _Show = value
             RunInUi(
             RunInUi(
             Sub()
             Sub()

+ 4 - 12
Plain Craft Launcher 2/Controls/MyHint.xaml

@@ -3,22 +3,14 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:local="clr-namespace:PCL"
              xmlns:local="clr-namespace:PCL"
              FocusVisualStyle="{x:Null}"
              FocusVisualStyle="{x:Null}"
-             UseLayoutRounding="True" SnapsToDevicePixels="True" HorizontalAlignment="Stretch" BorderThickness="1" BorderBrush="#99FF4444" CornerRadius="3">
-    <Border.Background>
-        <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
-            <GradientStop x:Name="Gradient1" Color="#88FFBBBB" Offset="0.3"/>
-            <GradientStop x:Name="Gradient2" Color="#88FF8888" Offset="0.9"/>
-        </LinearGradientBrush>
-    </Border.Background>
+             UseLayoutRounding="True" SnapsToDevicePixels="True" HorizontalAlignment="Stretch" BorderThickness="3,0,0,0" BorderBrush="#99FF4444" CornerRadius="2">
     <Grid UseLayoutRounding="False" SnapsToDevicePixels="False">
     <Grid UseLayoutRounding="False" SnapsToDevicePixels="False">
         <Grid.ColumnDefinitions>
         <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="Auto" />
             <ColumnDefinition Width="1*" />
             <ColumnDefinition Width="1*" />
             <ColumnDefinition Width="Auto" />
             <ColumnDefinition Width="Auto" />
         </Grid.ColumnDefinitions>
         </Grid.ColumnDefinitions>
-        <Path IsHitTestVisible="False" Grid.Column="0" x:Name="Path" VerticalAlignment="Center" Fill="#BF0000" Width="14" Stretch="Uniform" Margin="10,0,2,0" Data="F1 M 58.5832,55.4172L 17.4169,55.4171C 15.5619,53.5621 15.5619,50.5546 17.4168,48.6996L 35.201,15.8402C 37.056,13.9852 40.0635,13.9852 41.9185,15.8402L 58.5832,48.6997C 60.4382,50.5546 60.4382,53.5622 58.5832,55.4172 Z M 34.0417,25.7292L 36.0208,41.9584L 39.9791,41.9583L 41.9583,25.7292L 34.0417,25.7292 Z M 38,44.3333C 36.2511,44.3333 34.8333,45.7511 34.8333,47.5C 34.8333,49.2489 36.2511,50.6667 38,50.6667C 39.7489,50.6667 41.1666,49.2489 41.1666,47.5C 41.1666,45.7511 39.7489,44.3333 38,44.3333 Z " />
-        <TextBlock IsHitTestVisible="False" Grid.Column="1" x:Name="LabText" Margin="0,0.5,0,0" Padding="6,6,8,6" VerticalAlignment="Center" Foreground="#BF0000" TextWrapping="Wrap" />
-        <local:MyIconButton x:Name="BtnClose" SnapsToDevicePixels="True" Visibility="Collapsed" Foreground="#BF0000" Theme="Custom" Margin="0,0,6,0" Grid.Column="2" Height="20" Width="20" VerticalAlignment="Center" Logo="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z"
-                           ToolTip="不再显示" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="29" ToolTipService.HorizontalOffset="2" />
+        <TextBlock IsHitTestVisible="False" x:Name="LabText" LineHeight="16" Margin="0,0,0,-1" Padding="12,9" VerticalAlignment="Center" TextWrapping="Wrap" />
+        <local:MyIconButton x:Name="BtnClose" Visibility="Collapsed" Theme="Custom" Margin="0,0,8,0" Grid.Column="1" Height="20" Width="20" VerticalAlignment="Center" Logo="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z"
+                           ToolTip="不再提示" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="29" ToolTipService.HorizontalOffset="2" />
     </Grid>
     </Grid>
 </Border>
 </Border>

+ 73 - 38
Plain Craft Launcher 2/Controls/MyHint.xaml.vb

@@ -2,37 +2,73 @@
 
 
 <ContentProperty("Inlines")>
 <ContentProperty("Inlines")>
 Public Class MyHint
 Public Class MyHint
-
     Public Uuid As Integer = GetUuid()
     Public Uuid As Integer = GetUuid()
 
 
-    Private _IsWarn As Boolean = True
-    Public Property IsWarn As Boolean
+    '边框
+    Public Property HasBorder As Boolean
         Get
         Get
-            Return _IsWarn
+            Return BorderThickness.Top > 0
         End Get
         End Get
         Set(value As Boolean)
         Set(value As Boolean)
-            If _IsWarn = value Then Exit Property
-            _IsWarn = value
-            If _IsWarn Then
-                BorderBrush = New MyColor("#CCFF4444")
-                Gradient1.Color = New MyColor("#BBFFBBBB")
-                Gradient2.Color = New MyColor("#BBFF8888")
-                Path.Fill = New MyColor("#BF0000")
-                LabText.Foreground = New MyColor("#BF0000")
-                BtnClose.Foreground = New MyColor("#BF0000")
-                Path.Data = (New GeometryConverter).ConvertFromString("F1 M 58.5832,55.4172L 17.4169,55.4171C 15.5619,53.5621 15.5619,50.5546 17.4168,48.6996L 35.201,15.8402C 37.056,13.9852 40.0635,13.9852 41.9185,15.8402L 58.5832,48.6997C 60.4382,50.5546 60.4382,53.5622 58.5832,55.4172 Z M 34.0417,25.7292L 36.0208,41.9584L 39.9791,41.9583L 41.9583,25.7292L 34.0417,25.7292 Z M 38,44.3333C 36.2511,44.3333 34.8333,45.7511 34.8333,47.5C 34.8333,49.2489 36.2511,50.6667 38,50.6667C 39.7489,50.6667 41.1666,49.2489 41.1666,47.5C 41.1666,45.7511 39.7489,44.3333 38,44.3333 Z ")
+            If value Then
+                BorderThickness = New Thickness(3, GetWPFSize(1), GetWPFSize(1), GetWPFSize(1))
             Else
             Else
-                BorderBrush = New MyColor("#CC4D76FF")
-                Gradient1.Color = New MyColor("#BBB0D0FF")
-                Gradient2.Color = New MyColor("#BB9EBAFF")
-                Path.Fill = New MyColor("#0062BF")
-                LabText.Foreground = New MyColor("#0062BF")
-                BtnClose.Foreground = New MyColor("#0062BF")
-                Path.Data = (New GeometryConverter).ConvertFromString("F1M38,19C48.4934,19 57,27.5066 57,38 57,48.4934 48.4934,57 38,57 27.5066,57 19,48.4934 19,38 19,27.5066 27.5066,19 38,19z M33.25,33.25L33.25,36.4167 36.4166,36.4167 36.4166,47.5 33.25,47.5 33.25,50.6667 44.3333,50.6667 44.3333,47.5 41.1666,47.5 41.1666,36.4167 41.1666,33.25 33.25,33.25z M38.7917,25.3333C37.48,25.3333 36.4167,26.3967 36.4167,27.7083 36.4167,29.02 37.48,30.0833 38.7917,30.0833 40.1033,30.0833 41.1667,29.02 41.1667,27.7083 41.1667,26.3967 40.1033,25.3333 38.7917,25.3333z")
+                BorderThickness = New Thickness(3, 0, 0, 0)
             End If
             End If
         End Set
         End Set
     End Property
     End Property
 
 
+    '配色
+    Public Enum Themes
+        Blue = 0
+        Red = 1
+        Yellow = 2
+    End Enum
+    Public Property Theme As Themes
+        Get
+            Return _ColorType
+        End Get
+        Set(value As Themes)
+            _ColorType = value
+            UpdateUI()
+        End Set
+    End Property
+    Private _ColorType As Themes = Themes.Red
+    Private Sub UpdateUI() Handles Me.Loaded
+        Select Case Theme
+            Case Themes.Blue
+                Background = New MyColor("#d9ecff")
+                BorderBrush = New MyColor("#1172D4")
+                LabText.Foreground = New MyColor("#0F64B8")
+                BtnClose.Foreground = New MyColor("#0F64B8")
+            Case Themes.Red
+                Background = New MyColor("#ffdddf")
+                BorderBrush = New MyColor("#d82929")
+                LabText.Foreground = New MyColor("#bf0b0b")
+                BtnClose.Foreground = New MyColor("#bf0b0b")
+            Case Themes.Yellow
+                Background = New MyColor("#ffebd7")
+                BorderBrush = New MyColor("#f57a00")
+                LabText.Foreground = New MyColor("#d86c00")
+                BtnClose.Foreground = New MyColor("#d86c00")
+        End Select
+    End Sub
+    <Obsolete("IsWarn 已过时。请换用 Theme 属性。")>
+    Public Property IsWarn As Boolean
+        Get
+            Return Theme = Themes.Red
+        End Get
+        Set(value As Boolean)
+            Theme = If(value, Themes.Red, Themes.Blue)
+        End Set
+    End Property
+    Public Shared ReadOnly IsWarnProperty As DependencyProperty =
+        DependencyProperty.Register("IsWarn", GetType(Boolean), GetType(MyHint), New PropertyMetadata(True,
+        Sub(d As MyHint, e As DependencyPropertyChangedEventArgs)
+            d.Theme = If(e.NewValue, Themes.Red, Themes.Blue)
+        End Sub))
+
+    '文本
     Public ReadOnly Property Inlines As InlineCollection
     Public ReadOnly Property Inlines As InlineCollection
         Get
         Get
             Return LabText.Inlines
             Return LabText.Inlines
@@ -52,6 +88,7 @@ Public Class MyHint
             d.LabText.Text = e.NewValue
             d.LabText.Text = e.NewValue
         End Sub))
         End Sub))
 
 
+    '关闭按钮
     Public Property CanClose As Boolean
     Public Property CanClose As Boolean
         Get
         Get
             Return BtnClose.Visibility = Visibility.Visible
             Return BtnClose.Visibility = Visibility.Visible
@@ -60,12 +97,9 @@ Public Class MyHint
             BtnClose.Visibility = If(value, Visibility.Visible, Visibility.Collapsed)
             BtnClose.Visibility = If(value, Visibility.Visible, Visibility.Collapsed)
         End Set
         End Set
     End Property
     End Property
-
     Public Property RelativeSetup As String = ""
     Public Property RelativeSetup As String = ""
     Private Sub MyHint_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
     Private Sub MyHint_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
-        If CanClose AndAlso Setup.Get(RelativeSetup) Then
-            Visibility = Visibility.Collapsed
-        End If
+        If CanClose AndAlso Setup.Get(RelativeSetup) Then Visibility = Visibility.Collapsed
     End Sub
     End Sub
     Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
     Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
         Setup.Set(RelativeSetup, True)
         Setup.Set(RelativeSetup, True)
@@ -109,20 +143,21 @@ Public Class MyHint
 End Class
 End Class
 Partial Public Module ModAnimation
 Partial Public Module ModAnimation
     Public Sub AniDispose(Control As MyHint, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
     Public Sub AniDispose(Control As MyHint, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
-        If Not Control.IsHitTestVisible Then Exit Sub
+        If Not Control.IsHitTestVisible Then Return
         Control.IsHitTestVisible = False
         Control.IsHitTestVisible = False
         AniStart({
         AniStart({
-                     AaScaleTransform(Control, -0.08, 200,, New AniEaseInFluent),
-                     AaOpacity(Control, -1, 200,, New AniEaseOutFluent),
-                     AaHeight(Control, -Control.ActualHeight, 150, 100, New AniEaseOutFluent),
-                     AaCode(Sub()
-                                If RemoveFromChildren Then
-                                    CType(Control.Parent, Object).Children.Remove(Control)
-                                Else
-                                    Control.Visibility = Visibility.Collapsed
-                                End If
-                                If CallBack IsNot Nothing Then CallBack(Control)
-                            End Sub,, True)
-            }, "MyCard Dispose " & Control.Uuid)
+            AaScaleTransform(Control, -0.08, 200,, New AniEaseInFluent),
+            AaOpacity(Control, -1, 200,, New AniEaseOutFluent),
+            AaHeight(Control, -Control.ActualHeight, 150, 100, New AniEaseOutFluent),
+            AaCode(
+            Sub()
+                If RemoveFromChildren Then
+                    CType(Control.Parent, Object).Children.Remove(Control)
+                Else
+                    Control.Visibility = Visibility.Collapsed
+                End If
+                If CallBack IsNot Nothing Then CallBack(Control)
+            End Sub,, True)
+        }, "MyCard Dispose " & Control.Uuid)
     End Sub
     End Sub
 End Module
 End Module

+ 1 - 1
Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb

@@ -186,7 +186,7 @@
 End Class
 End Class
 Partial Public Module ModAnimation
 Partial Public Module ModAnimation
     Public Sub AniDispose(Control As MyIconButton, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
     Public Sub AniDispose(Control As MyIconButton, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
-        If Not Control.IsHitTestVisible Then Exit Sub
+        If Not Control.IsHitTestVisible Then Return
         Control.IsHitTestVisible = False
         Control.IsHitTestVisible = False
         AniStart({
         AniStart({
                  AaScaleTransform(Control, -1.5, 200,, New AniEaseInFluent),
                  AaScaleTransform(Control, -1.5, 200,, New AniEaseInFluent),

+ 1 - 1
Plain Craft Launcher 2/Controls/MyIconTextButton.xaml.vb

@@ -72,7 +72,7 @@ Public Class MyIconTextButton
     Public Event Click(sender As Object, e As RouteEventArgs)
     Public Event Click(sender As Object, e As RouteEventArgs)
     Private IsMouseDown As Boolean = False
     Private IsMouseDown As Boolean = False
     Private Sub MyIconTextButton_MouseUp() Handles Me.MouseLeftButtonUp
     Private Sub MyIconTextButton_MouseUp() Handles Me.MouseLeftButtonUp
-        If Not IsMouseDown Then Exit Sub
+        If Not IsMouseDown Then Return
         Log("[Control] 按下带图标按钮:" & Text)
         Log("[Control] 按下带图标按钮:" & Text)
         IsMouseDown = False
         IsMouseDown = False
         RaiseEvent Click(Me, New RouteEventArgs(True))
         RaiseEvent Click(Me, New RouteEventArgs(True))

+ 9 - 9
Plain Craft Launcher 2/Controls/MyImage.vb

@@ -34,9 +34,9 @@
         End Get
         End Get
         Set(value As String)
         Set(value As String)
             If value = "" Then value = Nothing
             If value = "" Then value = Nothing
-            If _Source = value Then Exit Property
+            If _Source = value Then Return
             _Source = value
             _Source = value
-            If Not IsInitialized Then Exit Property '属性读取顺序修正:在完成 XAML 属性读取后再触发图片加载(#4868)
+            If Not IsInitialized Then Return '属性读取顺序修正:在完成 XAML 属性读取后再触发图片加载(#4868)
             Load()
             Load()
         End Set
         End Set
     End Property
     End Property
@@ -82,7 +82,7 @@
         End Get
         End Get
         Set(value As String)
         Set(value As String)
             If value = "" Then value = Nothing
             If value = "" Then value = Nothing
-            If _ActualSource = value Then Exit Property
+            If _ActualSource = value Then Return
             _ActualSource = value
             _ActualSource = value
             Try
             Try
                 Dim Bitmap As MyBitmap = If(value Is Nothing, Nothing, New MyBitmap(value)) '在这里先触发可能的文件读取,尽量避免在 UI 线程中读取文件
                 Dim Bitmap As MyBitmap = If(value Is Nothing, Nothing, New MyBitmap(value)) '在这里先触发可能的文件读取,尽量避免在 UI 线程中读取文件
@@ -103,12 +103,12 @@
         '空
         '空
         If Source Is Nothing Then
         If Source Is Nothing Then
             ActualSource = Nothing
             ActualSource = Nothing
-            Exit Sub
+            Return
         End If
         End If
         '本地图片
         '本地图片
         If Not Source.StartsWithF("http") Then
         If Not Source.StartsWithF("http") Then
             ActualSource = Source
             ActualSource = Source
-            Exit Sub
+            Return
         End If
         End If
         '从缓存加载网络图片
         '从缓存加载网络图片
         Dim Url As String = Source
         Dim Url As String = Source
@@ -118,7 +118,7 @@
         Dim EnableCache As Boolean = Me.EnableCache
         Dim EnableCache As Boolean = Me.EnableCache
         If EnableCache AndAlso TempFile.Exists Then
         If EnableCache AndAlso TempFile.Exists Then
             ActualSource = TempPath
             ActualSource = TempPath
-            If (Date.Now - TempFile.LastWriteTime) < FileCacheExpiredTime Then Exit Sub '无需刷新缓存
+            If (Date.Now - TempFile.LastWriteTime) < FileCacheExpiredTime Then Return '无需刷新缓存
         End If
         End If
         RunInNewThread(
         RunInNewThread(
         Sub()
         Sub()
@@ -159,19 +159,19 @@ RetryStart:
                     '空
                     '空
                     If Url Is Nothing Then
                     If Url Is Nothing Then
                         ActualSource = Nothing
                         ActualSource = Nothing
-                        Exit Sub
+                        Return
                     End If
                     End If
                     '本地图片
                     '本地图片
                     If Not Url.StartsWithF("http") Then
                     If Not Url.StartsWithF("http") Then
                         ActualSource = Url
                         ActualSource = Url
-                        Exit Sub
+                        Return
                     End If
                     End If
                     '从缓存加载网络图片
                     '从缓存加载网络图片
                     TempPath = GetTempPath(Url)
                     TempPath = GetTempPath(Url)
                     TempFile = New FileInfo(TempPath)
                     TempFile = New FileInfo(TempPath)
                     If EnableCache AndAlso TempFile.Exists() Then
                     If EnableCache AndAlso TempFile.Exists() Then
                         ActualSource = TempPath
                         ActualSource = TempPath
-                        If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Exit Sub '无需刷新缓存
+                        If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Return '无需刷新缓存
                     End If
                     End If
                     '下载
                     '下载
                     If Source = Url Then Thread.Sleep(1000) '延迟 1s 重试
                     If Source = Url Then Thread.Sleep(1000) '延迟 1s 重试

+ 12 - 12
Plain Craft Launcher 2/Controls/MyListItem.xaml.vb

@@ -197,7 +197,7 @@ Public Class MyListItem
             Return _Info
             Return _Info
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If _Info = value Then Exit Property
+            If _Info = value Then Return
             value = value.Replace(vbCr, "").Replace(vbLf, "")
             value = value.Replace(vbCr, "").Replace(vbLf, "")
             _Info = value
             _Info = value
             LabInfo.Text = value
             LabInfo.Text = value
@@ -212,7 +212,7 @@ Public Class MyListItem
             Return _Logo
             Return _Logo
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If _Logo = value Then Exit Property
+            If _Logo = value Then Return
             _Logo = value
             _Logo = value
             '删除旧 Logo
             '删除旧 Logo
             If Not IsNothing(PathLogo) Then Children.Remove(PathLogo)
             If Not IsNothing(PathLogo) Then Children.Remove(PathLogo)
@@ -297,7 +297,7 @@ Public Class MyListItem
             Return _Type
             Return _Type
         End Get
         End Get
         Set(value As CheckType)
         Set(value As CheckType)
-            If _Type = value Then Exit Property
+            If _Type = value Then Return
             _Type = value
             _Type = value
             '切换左栏大小
             '切换左栏大小
             ColumnCheck.Width = New GridLength(If(_Type = CheckType.None OrElse _Type = CheckType.Clickable, If(Height < 40, 4, 2), 6))
             ColumnCheck.Width = New GridLength(If(_Type = CheckType.None OrElse _Type = CheckType.Clickable, If(Height < 40, 4, 2), 6))
@@ -367,31 +367,31 @@ Public Class MyListItem
                     RaiseEvent Changed(Me, ChangedEventArgs)
                     RaiseEvent Changed(Me, ChangedEventArgs)
                     If ChangedEventArgs.Handled Then
                     If ChangedEventArgs.Handled Then
                         _Checked = RawValue
                         _Checked = RawValue
-                        Exit Sub
+                        Return
                     End If
                     End If
                 End If
                 End If
                 _Checked = value
                 _Checked = value
             Else
             Else
-                If value = _Checked Then Exit Sub
+                If value = _Checked Then Return
                 _Checked = value
                 _Checked = value
                 If IsInitialized Then
                 If IsInitialized Then
                     RaiseEvent Changed(Me, ChangedEventArgs)
                     RaiseEvent Changed(Me, ChangedEventArgs)
                     If ChangedEventArgs.Handled Then
                     If ChangedEventArgs.Handled Then
                         _Checked = RawValue
                         _Checked = RawValue
-                        Exit Sub
+                        Return
                     End If
                     End If
                 End If
                 End If
             End If
             End If
             If value Then
             If value Then
                 Dim CheckEventArgs As New RouteEventArgs(user)
                 Dim CheckEventArgs As New RouteEventArgs(user)
                 RaiseEvent Check(Me, CheckEventArgs)
                 RaiseEvent Check(Me, CheckEventArgs)
-                If CheckEventArgs.Handled Then Exit Sub
+                If CheckEventArgs.Handled Then Return
             End If
             End If
 
 
             '保证只有一个单选 ListItem 选中
             '保证只有一个单选 ListItem 选中
 
 
             If Type = CheckType.RadioBox Then
             If Type = CheckType.RadioBox Then
-                If IsNothing(Parent) Then Exit Sub
+                If IsNothing(Parent) Then Return
                 Dim RadioboxList As New List(Of MyListItem)
                 Dim RadioboxList As New List(Of MyListItem)
                 Dim CheckedCount As Integer = 0
                 Dim CheckedCount As Integer = 0
                 '收集控件列表与选中个数
                 '收集控件列表与选中个数
@@ -502,15 +502,15 @@ Public Class MyListItem
 
 
     '触发点击事件
     '触发点击事件
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
-        If Not IsMouseDown Then Exit Sub
+        If Not IsMouseDown Then Return
         RaiseEvent Click(sender, e)
         RaiseEvent Click(sender, e)
-        If e.Handled Then Exit Sub
+        If e.Handled Then Return
         '触发自定义事件
         '触发自定义事件
         If Not String.IsNullOrEmpty(EventType) Then
         If Not String.IsNullOrEmpty(EventType) Then
             ModEvent.TryStartEvent(EventType, EventData)
             ModEvent.TryStartEvent(EventType, EventData)
             e.Handled = True
             e.Handled = True
         End If
         End If
-        If e.Handled Then Exit Sub
+        If e.Handled Then Return
         '实际的单击处理
         '实际的单击处理
         Select Case Type
         Select Case Type
             Case CheckType.Clickable
             Case CheckType.Clickable
@@ -581,7 +581,7 @@ Public Class MyListItem
                 Time = 180
                 Time = 180
             End If
             End If
         End If
         End If
-        If StateLast = StateNew Then Exit Sub
+        If StateLast = StateNew Then Return
         StateLast = StateNew
         StateLast = StateNew
         '触发颜色动画
         '触发颜色动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画

+ 6 - 6
Plain Craft Launcher 2/Controls/MyLoading.xaml.vb

@@ -35,7 +35,7 @@ Public Class MyLoading
             Return _ShowProgress
             Return _ShowProgress
         End Get
         End Get
         Set(value As Boolean)
         Set(value As Boolean)
-            If _ShowProgress = value Then Exit Property
+            If _ShowProgress = value Then Return
             _ShowProgress = value
             _ShowProgress = value
             RefreshText()
             RefreshText()
         End Set
         End Set
@@ -82,7 +82,7 @@ Public Class MyLoading
                         LabText.Text = StrTrim(Ex.Message)
                         LabText.Text = StrTrim(Ex.Message)
                         If {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
                         If {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
                             "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) LabText.Text.Contains(s)) Then
                             "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) LabText.Text.Contains(s)) Then
-                            LabText.Text = "网络环境不佳,请重试或尝试使用 VPN"
+                            LabText.Text = "网络环境不佳,请稍后重试,或使用 VPN 以改善网络环境"
                         End If
                         End If
                     End If
                     End If
                 Else
                 Else
@@ -142,7 +142,7 @@ Public Class MyLoading
             Return _OuterState
             Return _OuterState
         End Get
         End Get
         Set(value As MyLoadingState)
         Set(value As MyLoadingState)
-            If _OuterState = value Then Exit Property
+            If _OuterState = value Then Return
             Dim OldValue = _OuterState
             Dim OldValue = _OuterState
             _OuterState = value
             _OuterState = value
             '引发事件
             '引发事件
@@ -159,7 +159,7 @@ Public Class MyLoading
             Return _InnerState
             Return _InnerState
         End Get
         End Get
         Set(value As MyLoadingState)
         Set(value As MyLoadingState)
-            If _InnerState = value Then Exit Property
+            If _InnerState = value Then Return
             Dim OldValue = _InnerState
             Dim OldValue = _InnerState
             _InnerState = value
             _InnerState = value
             '引发事件
             '引发事件
@@ -183,7 +183,7 @@ Public Class MyLoading
     Private IsLooping As Boolean = False
     Private IsLooping As Boolean = False
     Private Sub AniLoop()
     Private Sub AniLoop()
         '这坨循环代码也是老屎坑了,救救.jpg
         '这坨循环代码也是老屎坑了,救救.jpg
-        If Not HasAnimation OrElse IsLooping OrElse Not InnerState = MyLoadingState.Run OrElse AniSpeed > 10 OrElse Not IsLoaded Then Exit Sub
+        If Not HasAnimation OrElse IsLooping OrElse Not InnerState = MyLoadingState.Run OrElse AniSpeed > 10 OrElse Not IsLoaded Then Return
         IsLooping = True
         IsLooping = True
         ErrorAnimationWaiting = True
         ErrorAnimationWaiting = True
         AniStart({
         AniStart({
@@ -271,7 +271,7 @@ Public Class MyLoadingStateSimulator
             Return _LoadingState
             Return _LoadingState
         End Get
         End Get
         Set(value As MyLoadingState)
         Set(value As MyLoadingState)
-            If _LoadingState = value Then Exit Property
+            If _LoadingState = value Then Return
             Dim OldState = _LoadingState
             Dim OldState = _LoadingState
             _LoadingState = value
             _LoadingState = value
             RaiseEvent LoadingStateChanged(value, OldState)
             RaiseEvent LoadingStateChanged(value, OldState)

+ 1 - 1
Plain Craft Launcher 2/Controls/MyMenuItem.vb

@@ -37,7 +37,7 @@
             Time = AnimationTimeOut
             Time = AnimationTimeOut
         End If
         End If
         '重复性验证
         '重复性验证
-        If ColorName = BackName Then Exit Sub
+        If ColorName = BackName Then Return
         ColorName = BackName
         ColorName = BackName
         '触发颜色动画
         '触发颜色动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画

+ 2 - 2
Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml.vb

@@ -73,13 +73,13 @@
 
 
     Public Sub Btn1_Click() Handles Btn1.Click
     Public Sub Btn1_Click() Handles Btn1.Click
         TextArea.Validate() '#5773
         TextArea.Validate() '#5773
-        If MyConverter.IsExited OrElse Not TextArea.IsValidated Then Exit Sub
+        If MyConverter.IsExited OrElse Not TextArea.IsValidated Then Return
         MyConverter.IsExited = True
         MyConverter.IsExited = True
         MyConverter.Result = TextArea.Text
         MyConverter.Result = TextArea.Text
         Close()
         Close()
     End Sub
     End Sub
     Public Sub Btn2_Click() Handles Btn2.Click
     Public Sub Btn2_Click() Handles Btn2.Click
-        If MyConverter.IsExited Then Exit Sub
+        If MyConverter.IsExited Then Return
         MyConverter.IsExited = True
         MyConverter.IsExited = True
         MyConverter.Result = Nothing
         MyConverter.Result = Nothing
         Close()
         Close()

+ 2 - 2
Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml.vb

@@ -77,13 +77,13 @@
     End Sub
     End Sub
 
 
     Public Sub Btn1_Click() Handles Btn1.Click
     Public Sub Btn1_Click() Handles Btn1.Click
-        If MyConverter.IsExited OrElse SelectedIndex = -1 Then Exit Sub
+        If MyConverter.IsExited OrElse SelectedIndex = -1 Then Return
         MyConverter.IsExited = True
         MyConverter.IsExited = True
         MyConverter.Result = SelectedIndex
         MyConverter.Result = SelectedIndex
         Close()
         Close()
     End Sub
     End Sub
     Public Sub Btn2_Click() Handles Btn2.Click
     Public Sub Btn2_Click() Handles Btn2.Click
-        If MyConverter.IsExited Then Exit Sub
+        If MyConverter.IsExited Then Return
         MyConverter.IsExited = True
         MyConverter.IsExited = True
         MyConverter.Result = Nothing
         MyConverter.Result = Nothing
         Close()
         Close()

+ 3 - 3
Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml.vb

@@ -70,7 +70,7 @@
     End Sub
     End Sub
 
 
     Public Sub Btn1_Click() Handles Btn1.Click
     Public Sub Btn1_Click() Handles Btn1.Click
-        If MyConverter.IsExited Then Exit Sub
+        If MyConverter.IsExited Then Return
         If MyConverter.Button1Action IsNot Nothing Then
         If MyConverter.Button1Action IsNot Nothing Then
             MyConverter.Button1Action()
             MyConverter.Button1Action()
         Else
         Else
@@ -80,7 +80,7 @@
         End If
         End If
     End Sub
     End Sub
     Public Sub Btn2_Click() Handles Btn2.Click
     Public Sub Btn2_Click() Handles Btn2.Click
-        If MyConverter.IsExited Then Exit Sub
+        If MyConverter.IsExited Then Return
         If MyConverter.Button2Action IsNot Nothing Then
         If MyConverter.Button2Action IsNot Nothing Then
             MyConverter.Button2Action()
             MyConverter.Button2Action()
         Else
         Else
@@ -90,7 +90,7 @@
         End If
         End If
     End Sub
     End Sub
     Public Sub Btn3_Click() Handles Btn3.Click
     Public Sub Btn3_Click() Handles Btn3.Click
-        If MyConverter.IsExited Then Exit Sub
+        If MyConverter.IsExited Then Return
         If MyConverter.Button3Action IsNot Nothing Then
         If MyConverter.Button3Action IsNot Nothing Then
             MyConverter.Button3Action()
             MyConverter.Button3Action()
         Else
         Else

+ 12 - 11
Plain Craft Launcher 2/Controls/MyPageLeft.vb

@@ -39,16 +39,17 @@
                     Element.Opacity = 0
                     Element.Opacity = 0
                     Element.RenderTransform = New TranslateTransform(-25, 0)
                     Element.RenderTransform = New TranslateTransform(-25, 0)
                     If TypeOf Element Is MyListItem Then CType(Element, MyListItem).IsMouseOverAnimationEnabled = False
                     If TypeOf Element Is MyListItem Then CType(Element, MyListItem).IsMouseOverAnimationEnabled = False
-                    AniList.Add(AaOpacity(Element, If(TypeOf Element Is TextBlock, 0.6, 1), 200, Delay, New AniEaseOutFluent(AniEasePower.Weak)))
+                    AniList.Add(AaOpacity(Element, If(TypeOf Element Is TextBlock, 0.6, 1), 100, Delay, New AniEaseOutFluent(AniEasePower.Weak)))
                     AniList.Add(AaTranslateX(Element, 5, 200, Delay, New AniEaseOutFluent))
                     AniList.Add(AaTranslateX(Element, 5, 200, Delay, New AniEaseOutFluent))
                     AniList.Add(AaTranslateX(Element, 20, 300, Delay, New AniEaseOutBack(AniEasePower.Weak)))
                     AniList.Add(AaTranslateX(Element, 20, 300, Delay, New AniEaseOutBack(AniEasePower.Weak)))
                     If TypeOf Element Is MyListItem Then
                     If TypeOf Element Is MyListItem Then
-                        AniList.Add(AaCode(Sub()
-                                               CType(Element, MyListItem).IsMouseOverAnimationEnabled = True
-                                               CType(Element, MyListItem).RefreshColor(Me, New EventArgs)
-                                           End Sub, Delay + 280))
+                        AniList.Add(AaCode(
+                        Sub()
+                            CType(Element, MyListItem).IsMouseOverAnimationEnabled = True
+                            CType(Element, MyListItem).RefreshColor(Me, New EventArgs)
+                        End Sub, Delay + 280))
                     End If
                     End If
-                    Delay += Math.Max(8, 20 - Id) * 2.5
+                    Delay += Math.Max(15 - Id, 7) * 2
                     Id += 1
                     Id += 1
                 End If
                 End If
             Next
             Next
@@ -63,8 +64,8 @@
                 RenderTransformOrigin = New Point(0.5, 0.5)
                 RenderTransformOrigin = New Point(0.5, 0.5)
             End If
             End If
             AniStart({
             AniStart({
-                AaScaleTransform(Me, 0.95 - CType(RenderTransform, ScaleTransform).ScaleX, 130,, New AniEaseInFluent(AniEasePower.Weak)),
-                AaOpacity(Me, -Opacity, 100, 30)
+                AaScaleTransform(Me, 0.95 - CType(RenderTransform, ScaleTransform).ScaleX, 110,, New AniEaseInFluent(AniEasePower.Weak)),
+                AaOpacity(Me, -Opacity, 80, 30)
             }, "PageLeft PageChange " & Uuid)
             }, "PageLeft PageChange " & Uuid)
         Else
         Else
             '逐个退出动画
             '逐个退出动画
@@ -72,8 +73,8 @@
             Dim Id As Integer = 0
             Dim Id As Integer = 0
             Dim Controls = GetAllAnimControls()
             Dim Controls = GetAllAnimControls()
             For Each Element As FrameworkElement In Controls
             For Each Element As FrameworkElement In Controls
-                AniList.Add(AaOpacity(Element, -Element.Opacity, 60, 80 / Controls.Count * Id))
-                AniList.Add(AaTranslateX(Element, -6, 60, 80 / Controls.Count * Id))
+                AniList.Add(AaOpacity(Element, -Element.Opacity, 50, 70 / Controls.Count * Id))
+                AniList.Add(AaTranslateX(Element, -6, 50, 70 / Controls.Count * Id))
                 Id += 1
                 Id += 1
             Next
             Next
             AniStart(AniList, "PageLeft PageChange " & Uuid)
             AniStart(AniList, "PageLeft PageChange " & Uuid)
@@ -87,7 +88,7 @@
         Return AllControls
         Return AllControls
     End Function
     End Function
     Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
     Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
-        If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Exit Sub
+        If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Return
         If TypeOf Element Is MyTextButton Then
         If TypeOf Element Is MyTextButton Then
             AllControls.Add(Element)
             AllControls.Add(Element)
         ElseIf TypeOf Element Is MyListItem Then
         ElseIf TypeOf Element Is MyListItem Then

+ 11 - 11
Plain Craft Launcher 2/Controls/MyPageRight.vb

@@ -33,7 +33,7 @@
             Return _PageState
             Return _PageState
         End Get
         End Get
         Set(value As PageStates)
         Set(value As PageStates)
-            If _PageState = value Then Exit Property
+            If _PageState = value Then Return
             _PageState = value
             _PageState = value
             If ModeDebug Then Log("[UI] 页面状态切换为 " & GetStringFromEnum(value))
             If ModeDebug Then Log("[UI] 页面状态切换为 " & GetStringFromEnum(value))
         End Set
         End Set
@@ -106,7 +106,7 @@
     End Sub
     End Sub
     '重试
     '重试
     Public Sub PageLoaderRestart(Optional Input As Object = Nothing, Optional IsForceRestart As Boolean = True) '由外部调用的重试
     Public Sub PageLoaderRestart(Optional Input As Object = Nothing, Optional IsForceRestart As Boolean = True) '由外部调用的重试
-        If Not PageLoaderAutoRun Then Exit Sub
+        If Not PageLoaderAutoRun Then Return
         If PageLoader.GetType.Name.StartsWithF("LoaderTask") Then
         If PageLoader.GetType.Name.StartsWithF("LoaderTask") Then
             PageLoader.Start(CType(PageLoader, Object).StartGetInput(Input, PageLoaderInputInvoke), IsForceRestart:=IsForceRestart)
             PageLoader.Start(CType(PageLoader, Object).StartGetInput(Input, PageLoaderInputInvoke), IsForceRestart:=IsForceRestart)
         Else
         Else
@@ -187,7 +187,7 @@
     ''' 需要立即切换至 Empty。
     ''' 需要立即切换至 Empty。
     ''' </summary>
     ''' </summary>
     Public Sub PageOnForceExit()
     Public Sub PageOnForceExit()
-        If PageState = PageStates.Empty Then Exit Sub
+        If PageState = PageStates.Empty Then Return
         If ModeDebug Then Log("[UI] 已触发 PageOnForceExit")
         If ModeDebug Then Log("[UI] 已触发 PageOnForceExit")
         PageState = PageStates.Empty
         PageState = PageStates.Empty
         AniStop("PageRight PageChange " & PageUuid)
         AniStop("PageRight PageChange " & PageUuid)
@@ -302,7 +302,7 @@
     Private Sub PageLoaderState(sender As Object, NewState As LoadState, OldState As LoadState)
     Private Sub PageLoaderState(sender As Object, NewState As LoadState, OldState As LoadState)
         Select Case NewState
         Select Case NewState
             Case LoadState.Failed, LoadState.Loading
             Case LoadState.Failed, LoadState.Loading
-                If OldState = LoadState.Failed OrElse OldState = LoadState.Loading Then Exit Sub
+                If OldState = LoadState.Failed OrElse OldState = LoadState.Loading Then Return
                 If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Start/Refresh)")
                 If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Start/Refresh)")
                 '(重新)开始运行
                 '(重新)开始运行
                 '需要从部分状态切换到 ReloadExit
                 '需要从部分状态切换到 ReloadExit
@@ -314,7 +314,7 @@
                         PageState = PageStates.ContentExit
                         PageState = PageStates.ContentExit
                 End Select
                 End Select
             Case LoadState.Finished, LoadState.Aborted, LoadState.Waiting
             Case LoadState.Finished, LoadState.Aborted, LoadState.Waiting
-                If Not (OldState = LoadState.Failed OrElse OldState = LoadState.Loading) Then Exit Sub
+                If Not (OldState = LoadState.Failed OrElse OldState = LoadState.Loading) Then Return
                 If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Stop/Abort)")
                 If ModeDebug Then Log("[UI] 已触发 PageLoaderState (Stop/Abort)")
                 '运行结束
                 '运行结束
                 '需要从 LoaderWait 切换到 ContentEnter,或从 LoaderStay 切换到 LoaderExit
                 '需要从 LoaderWait 切换到 ContentEnter,或从 LoaderStay 切换到 LoaderExit
@@ -358,10 +358,10 @@
                 Else
                 Else
                     Control.Opacity = 0
                     Control.Opacity = 0
                     Control.RenderTransform = New TranslateTransform(0, -16)
                     Control.RenderTransform = New TranslateTransform(0, -16)
-                    AniList.Add(AaOpacity(Control, 1, 150, Delay, New AniEaseOutFluent(AniEasePower.Weak)))
+                    AniList.Add(AaOpacity(Control, 1, 100, Delay, New AniEaseOutFluent(AniEasePower.Weak)))
                     AniList.Add(AaTranslateY(Control, 5, 250, Delay, New AniEaseOutFluent))
                     AniList.Add(AaTranslateY(Control, 5, 250, Delay, New AniEaseOutFluent))
                     AniList.Add(AaTranslateY(Control, 11, 350, Delay, New AniEaseOutBack))
                     AniList.Add(AaTranslateY(Control, 11, 350, Delay, New AniEaseOutBack))
-                    Delay += 40
+                    Delay += 25
                 End If
                 End If
             Next
             Next
         Next
         Next
@@ -387,9 +387,9 @@
                     CType(Control, MyExtraTextButton).Show = False
                     CType(Control, MyExtraTextButton).Show = False
                 Else
                 Else
                     Control.IsHitTestVisible = False
                     Control.IsHitTestVisible = False
-                    AniList.Add(AaOpacity(Control, -1, 90, Delay))
-                    AniList.Add(AaTranslateY(Control, -6, 90, Delay))
-                    Delay += 20
+                    AniList.Add(AaOpacity(Control, -1, 70, Delay))
+                    AniList.Add(AaTranslateY(Control, -6, 70, Delay))
+                    Delay += 15
                 End If
                 End If
             Next
             Next
         Next
         Next
@@ -423,7 +423,7 @@
         Return AllControls.Except(DisabledPageAnimControls)
         Return AllControls.Except(DisabledPageAnimControls)
     End Function
     End Function
     Private Sub _GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
     Private Sub _GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
-        If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Exit Sub
+        If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Return
         If TypeOf Element Is MyCard OrElse TypeOf Element Is MyHint OrElse TypeOf Element Is MyExtraTextButton OrElse TypeOf Element Is TextBlock OrElse TypeOf Element Is MyTextButton Then
         If TypeOf Element Is MyCard OrElse TypeOf Element Is MyHint OrElse TypeOf Element Is MyExtraTextButton OrElse TypeOf Element Is TextBlock OrElse TypeOf Element Is MyTextButton Then
             AllControls.Add(Element)
             AllControls.Add(Element)
         ElseIf TypeOf Element Is ContentControl Then
         ElseIf TypeOf Element Is ContentControl Then

+ 5 - 5
Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb

@@ -41,7 +41,7 @@ Public Class MyRadioBox
                 RaiseEvent PreviewCheck(Me, e)
                 RaiseEvent PreviewCheck(Me, e)
                 If e.Handled Then
                 If e.Handled Then
                     Radiobox_MouseLeave()
                     Radiobox_MouseLeave()
-                    Exit Sub
+                    Return
                 End If
                 End If
             End If
             End If
 
 
@@ -54,7 +54,7 @@ Public Class MyRadioBox
             End If
             End If
 
 
             '保证只有一个单选框选中
             '保证只有一个单选框选中
-            If Parent Is Nothing Then Exit Sub
+            If Parent Is Nothing Then Return
             Dim RadioboxList As New List(Of MyRadioBox)
             Dim RadioboxList As New List(Of MyRadioBox)
             Dim CheckedCount As Integer = 0
             Dim CheckedCount As Integer = 0
             For Each Control In CType(Parent, Object).Children '收集控件列表与选中个数
             For Each Control In CType(Parent, Object).Children '收集控件列表与选中个数
@@ -172,7 +172,7 @@ Public Class MyRadioBox
     Private MouseDowned As Boolean = False
     Private MouseDowned As Boolean = False
     Private AllowMouseDown As Boolean = True
     Private AllowMouseDown As Boolean = True
     Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
     Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
-        If Not MouseDowned Then Exit Sub
+        If Not MouseDowned Then Return
         Log("[Control] 按下单选框:" & Text)
         Log("[Control] 按下单选框:" & Text)
         SetChecked(True, True)
         SetChecked(True, True)
         MouseDowned = False
         MouseDowned = False
@@ -187,7 +187,7 @@ Public Class MyRadioBox
         End If
         End If
     End Sub
     End Sub
     Private Sub Radiobox_MouseLeave() Handles Me.MouseLeave
     Private Sub Radiobox_MouseLeave() Handles Me.MouseLeave
-        If Not MouseDowned Then Exit Sub
+        If Not MouseDowned Then Return
         MouseDowned = False
         MouseDowned = False
         AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
         AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
         If Not Checked Then
         If Not Checked Then
@@ -224,7 +224,7 @@ Public Class MyRadioBox
         AniStart(AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfMouseIn), "MyRadioBox TextColor " & Uuid)
         AniStart(AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfMouseIn), "MyRadioBox TextColor " & Uuid)
     End Sub
     End Sub
     Private Sub Radiobox_MouseLeaveAnimation() Handles Me.MouseLeave
     Private Sub Radiobox_MouseLeaveAnimation() Handles Me.MouseLeave
-        If Not Me.IsEnabled Then Exit Sub 'MouseLeave 比 IsEnabledChanged 后执行,所以如果自定义事件修改了 IsEnabled,将导致显示错误
+        If Not Me.IsEnabled Then Return 'MouseLeave 比 IsEnabledChanged 后执行,所以如果自定义事件修改了 IsEnabled,将导致显示错误
         If IsLoaded AndAlso AniControlEnabled = 0 Then
         If IsLoaded AndAlso AniControlEnabled = 0 Then
             AniStart(AaColor(ShapeBorder, Ellipse.StrokeProperty, If(IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray4"), AnimationTimeOfMouseOut), "MyRadioBox BorderColor " & Uuid)
             AniStart(AaColor(ShapeBorder, Ellipse.StrokeProperty, If(IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray4"), AnimationTimeOfMouseOut), "MyRadioBox BorderColor " & Uuid)
             AniStart(AaColor(LabText, TextBlock.ForegroundProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"), AnimationTimeOfMouseOut), "MyRadioBox TextColor " & Uuid)
             AniStart(AaColor(LabText, TextBlock.ForegroundProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"), AnimationTimeOfMouseOut), "MyRadioBox TextColor " & Uuid)

+ 6 - 6
Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb

@@ -62,7 +62,7 @@ Public Class MyRadioButton
 
 
             '保证只有一个单选框选中
             '保证只有一个单选框选中
 
 
-            If IsNothing(Parent) Then Exit Sub
+            If IsNothing(Parent) Then Return
             Dim RadioboxList As New List(Of MyRadioButton)
             Dim RadioboxList As New List(Of MyRadioButton)
             Dim CheckedCount As Integer = 0
             Dim CheckedCount As Integer = 0
             '收集控件列表与选中个数
             '收集控件列表与选中个数
@@ -101,7 +101,7 @@ Public Class MyRadioButton
 
 
             '更改动画
             '更改动画
 
 
-            If Not IsChanged Then Exit Sub
+            If Not IsChanged Then Return
             RefreshColor(Nothing, anime)
             RefreshColor(Nothing, anime)
 
 
             '触发事件
             '触发事件
@@ -147,17 +147,17 @@ Public Class MyRadioButton
     Public Event PreviewClick(sender As Object, e As RouteEventArgs)
     Public Event PreviewClick(sender As Object, e As RouteEventArgs)
     Private IsMouseDown As Boolean = False
     Private IsMouseDown As Boolean = False
     Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
     Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
-        If Checked Then Exit Sub
-        If Not IsMouseDown Then Exit Sub
+        If Checked Then Return
+        If Not IsMouseDown Then Return
         Log("[Control] 按下单选按钮:" & Text)
         Log("[Control] 按下单选按钮:" & Text)
         IsMouseDown = False
         IsMouseDown = False
         Dim e As New RouteEventArgs(True)
         Dim e As New RouteEventArgs(True)
         RaiseEvent PreviewClick(Me, e)
         RaiseEvent PreviewClick(Me, e)
-        If e.Handled Then Exit Sub
+        If e.Handled Then Return
         SetChecked(True, True, True)
         SetChecked(True, True, True)
     End Sub
     End Sub
     Private Sub Radiobox_MouseDown() Handles Me.MouseLeftButtonDown
     Private Sub Radiobox_MouseDown() Handles Me.MouseLeftButtonDown
-        If Checked Then Exit Sub
+        If Checked Then Return
         IsMouseDown = True
         IsMouseDown = True
         RefreshColor()
         RefreshColor()
     End Sub
     End Sub

+ 2 - 2
Plain Craft Launcher 2/Controls/MyScrollViewer.vb

@@ -6,7 +6,7 @@
 
 
     Private RealOffset As Double
     Private RealOffset As Double
     Private Sub MyScrollViewer_PreviewMouseWheel(sender As Object, e As MouseWheelEventArgs) Handles Me.PreviewMouseWheel
     Private Sub MyScrollViewer_PreviewMouseWheel(sender As Object, e As MouseWheelEventArgs) Handles Me.PreviewMouseWheel
-        If e.Delta = 0 OrElse ActualHeight = 0 OrElse ScrollableHeight = 0 Then Exit Sub
+        If e.Delta = 0 OrElse ActualHeight = 0 OrElse ScrollableHeight = 0 Then Return
         Dim SourceType = e.Source.GetType
         Dim SourceType = e.Source.GetType
         If Content.TemplatedParent Is Nothing AndAlso (
         If Content.TemplatedParent Is Nothing AndAlso (
                 (GetType(ComboBox).IsAssignableFrom(SourceType) AndAlso CType(e.Source, ComboBox).IsDropDownOpen) OrElse
                 (GetType(ComboBox).IsAssignableFrom(SourceType) AndAlso CType(e.Source, ComboBox).IsDropDownOpen) OrElse
@@ -14,7 +14,7 @@
                 GetType(ComboBoxItem).IsAssignableFrom(SourceType) OrElse
                 GetType(ComboBoxItem).IsAssignableFrom(SourceType) OrElse
                 TypeOf e.Source Is CheckBox) Then
                 TypeOf e.Source Is CheckBox) Then
             '如果当前是在对有滚动条的下拉框或文本框执行,则不接管操作
             '如果当前是在对有滚动条的下拉框或文本框执行,则不接管操作
-            Exit Sub
+            Return
         End If
         End If
         e.Handled = True
         e.Handled = True
         PerformVerticalOffsetDelta(-e.Delta)
         PerformVerticalOffsetDelta(-e.Delta)

+ 7 - 7
Plain Craft Launcher 2/Controls/MySlider.xaml.vb

@@ -14,7 +14,7 @@
             Return _MaxValue
             Return _MaxValue
         End Get
         End Get
         Set(value As Integer)
         Set(value As Integer)
-            If value = _MaxValue Then Exit Property
+            If value = _MaxValue Then Return
             _MaxValue = value
             _MaxValue = value
             RefreshWidth(Nothing, Nothing)
             RefreshWidth(Nothing, Nothing)
         End Set
         End Set
@@ -29,7 +29,7 @@
             Try
             Try
 
 
                 newValue = MathClamp(newValue, 0, MaxValue)
                 newValue = MathClamp(newValue, 0, MaxValue)
-                If _Value = newValue Then Exit Property
+                If _Value = newValue Then Return
 
 
                 '触发 Preview 事件,修改新值
                 '触发 Preview 事件,修改新值
                 Dim OldValue = _Value
                 Dim OldValue = _Value
@@ -40,12 +40,12 @@
                     If e.Handled Then
                     If e.Handled Then
                         _Value = OldValue
                         _Value = OldValue
                         DragStop()
                         DragStop()
-                        Exit Property
+                        Return
                     End If
                     End If
                 End If
                 End If
 
 
                 If IsLoaded AndAlso AniControlEnabled = 0 Then
                 If IsLoaded AndAlso AniControlEnabled = 0 Then
-                    If ActualWidth < ShapeDot.Width Then Exit Property
+                    If ActualWidth < ShapeDot.Width Then Return
                     Dim NewWidth As Double = _Value / MaxValue * (ActualWidth - ShapeDot.Width)
                     Dim NewWidth As Double = _Value / MaxValue * (ActualWidth - ShapeDot.Width)
                     Dim DeltaProcess As Double = Math.Abs(LineFore.Width / (ActualWidth - ShapeDot.Width) - _Value / MaxValue)
                     Dim DeltaProcess As Double = Math.Abs(LineFore.Width / (ActualWidth - ShapeDot.Width) - _Value / MaxValue)
                     Dim Time As Double = (1 - Math.Pow(1 - DeltaProcess, 3)) * 300 + If(ChangeByKey, 100, 0)
                     Dim Time As Double = (1 - Math.Pow(1 - DeltaProcess, 3)) * 300 + If(ChangeByKey, 100, 0)
@@ -103,7 +103,7 @@
         Popup.IsOpen = False
         Popup.IsOpen = False
     End Sub
     End Sub
     Public Sub RefreshPopup()
     Public Sub RefreshPopup()
-        If GetHintText Is Nothing Then Exit Sub
+        If GetHintText Is Nothing Then Return
         Popup.IsOpen = True
         Popup.IsOpen = True
         TextHint.Text = GetHintText.DynamicInvoke(Value)
         TextHint.Text = GetHintText.DynamicInvoke(Value)
         Dim typeface As New Typeface(TextHint.FontFamily, TextHint.FontStyle, TextHint.FontWeight, TextHint.FontStretch)
         Dim typeface As New Typeface(TextHint.FontFamily, TextHint.FontStyle, TextHint.FontWeight, TextHint.FontStretch)
@@ -165,7 +165,7 @@
     End Sub
     End Sub
     Private Sub MySlider_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
     Private Sub MySlider_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
         '拒绝一边拖动一边用按键改变
         '拒绝一边拖动一边用按键改变
-        If ReferenceEquals(Me, DragControl) Then Exit Sub
+        If ReferenceEquals(Me, DragControl) Then Return
         '改变值
         '改变值
         If e.Key = Key.Left Then
         If e.Key = Key.Left Then
             ChangeByKey = True
             ChangeByKey = True
@@ -178,7 +178,7 @@
             ChangeByKey = False
             ChangeByKey = False
             e.Handled = True
             e.Handled = True
         Else
         Else
-            Exit Sub
+            Return
         End If
         End If
         '更新 Popup
         '更新 Popup
         If GetHintText IsNot Nothing Then
         If GetHintText IsNot Nothing Then

+ 5 - 5
Plain Craft Launcher 2/Controls/MyTextBox.vb

@@ -36,7 +36,7 @@
     End Property
     End Property
     Public Overrides Sub OnApplyTemplate()
     Public Overrides Sub OnApplyTemplate()
         MyBase.OnApplyTemplate()
         MyBase.OnApplyTemplate()
-        If HintText = "" OrElse labHint.Text <> "" Then Exit Sub
+        If HintText = "" OrElse labHint.Text <> "" Then Return
         labHint.Text = If(Text = "", HintText, "")
         labHint.Text = If(Text = "", HintText, "")
     End Sub
     End Sub
 
 
@@ -217,11 +217,11 @@
             IsTextChanged = IsLoaded
             IsTextChanged = IsLoaded
             '进行输入验证
             '进行输入验证
             Validate()
             Validate()
-            If Not IsValidated Then Exit Sub
+            If Not IsValidated Then Return
             '改变文本
             '改变文本
             RaiseEvent ValidatedTextChanged(sender, e)
             RaiseEvent ValidatedTextChanged(sender, e)
         Catch ex As Exception
         Catch ex As Exception
-            Log(ex, "进行输入验证时出错", LogLevel.Assert)
+            Log(ex, "进行输入验证时出错", LogLevel.Critical)
         End Try
         End Try
     End Sub
     End Sub
 
 
@@ -230,7 +230,7 @@
     Private Sub RefreshColor() Handles Me.IsEnabledChanged, Me.MouseEnter, Me.MouseLeave, Me.GotFocus, Me.LostFocus
     Private Sub RefreshColor() Handles Me.IsEnabledChanged, Me.MouseEnter, Me.MouseLeave, Me.GotFocus, Me.LostFocus
         Try
         Try
             '不对 ComboBox 从属进行动画
             '不对 ComboBox 从属进行动画
-            If TemplatedParent IsNot Nothing AndAlso TypeOf TemplatedParent Is MyComboBox Then Exit Sub
+            If TemplatedParent IsNot Nothing AndAlso TypeOf TemplatedParent Is MyComboBox Then Return
             '判断当前颜色
             '判断当前颜色
             Dim ForeColorName As String, BackColorName As String
             Dim ForeColorName As String, BackColorName As String
             Dim AnimationTime As Integer
             Dim AnimationTime As Integer
@@ -280,7 +280,7 @@
     End Sub
     End Sub
     Private Sub RefreshTextColor() Handles Me.IsEnabledChanged
     Private Sub RefreshTextColor() Handles Me.IsEnabledChanged
         Dim NewColor As MyColor = If(IsEnabled, ColorGray1, ColorGray4)
         Dim NewColor As MyColor = If(IsEnabled, ColorGray1, ColorGray4)
-        If CType(Foreground, SolidColorBrush).Color.R = NewColor.R Then Exit Sub
+        If CType(Foreground, SolidColorBrush).Color.R = NewColor.R Then Return
         If IsLoaded AndAlso AniControlEnabled = 0 AndAlso Not Text = "" Then
         If IsLoaded AndAlso AniControlEnabled = 0 AndAlso Not Text = "" Then
             '有动画
             '有动画
             AniStart({AaColor(Me, ForegroundProperty, If(IsEnabled, "ColorBrushGray1", "ColorBrushGray4"), 200)}, "MyTextBox TextColor " & Uuid)
             AniStart({AaColor(Me, ForegroundProperty, If(IsEnabled, "ColorBrushGray1", "ColorBrushGray4"), 200)}, "MyTextBox TextColor " & Uuid)

+ 1 - 1
Plain Craft Launcher 2/Controls/MyTextButton.vb

@@ -72,7 +72,7 @@
             Time = AnimationTimeOut
             Time = AnimationTimeOut
         End If
         End If
         '重复性验证
         '重复性验证
-        If ColorName = ForeName Then Exit Sub
+        If ColorName = ForeName Then Return
         ColorName = ForeName
         ColorName = ForeName
         '触发颜色动画
         '触发颜色动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画

+ 8 - 10
Plain Craft Launcher 2/FormMain.xaml

@@ -99,9 +99,7 @@
                 <Grid x:Name="PanTitle" Height="48">
                 <Grid x:Name="PanTitle" Height="48">
                     <Grid.Background>
                     <Grid.Background>
                         <LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
                         <LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
-                            <GradientStop Color="{StaticResource ColorObject3}" Offset="0"/>
-                            <GradientStop Color="{StaticResource ColorObject2}" Offset="0.5"/>
-                            <GradientStop Color="{StaticResource ColorObject3}" Offset="1"/>
+                            <GradientStop Color="{StaticResource ColorObject4}" Offset="0"/>
                         </LinearGradientBrush>
                         </LinearGradientBrush>
                     </Grid.Background>
                     </Grid.Background>
                     <local:MyImage x:Name="ImgTitle" IsHitTestVisible="False" Stretch="UniformToFill" IsEnabled="False" RenderOptions.BitmapScalingMode="LowQuality" />
                     <local:MyImage x:Name="ImgTitle" IsHitTestVisible="False" Stretch="UniformToFill" IsEnabled="False" RenderOptions.BitmapScalingMode="LowQuality" />
@@ -115,19 +113,19 @@
                             <ColumnDefinition Width="Auto" />
                             <ColumnDefinition Width="Auto" />
                             <ColumnDefinition Width="1*" />
                             <ColumnDefinition Width="1*" />
                         </Grid.ColumnDefinitions>
                         </Grid.ColumnDefinitions>
-                        <Path x:Name="ShapeTitleLogo" Data="M26,29 v-25 h5 a7,7 180 0 1 0,14 h-5 M61,6.5 a10,11.5 180 1 0 0,18 M68,2.5 v24.5 h12 M98,2 v27 M107,2 v27" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="19,15.5,0,15.5" Stretch="fill" Stroke="White" StrokeThickness="1.9" Width="53" />
+                        <Path x:Name="ShapeTitleLogo" Data="M26,29 v-25 h6 a7,7 180 0 1 0,14 h-6 M62.5,6.5 a10,11.5 180 1 0 0,18 M71,2.5 v24.5 h13.5" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="19,15.5,0,15.5" Stretch="fill" Stroke="White" StrokeThickness="2.2" Width="39" />
                         <TextBlock x:Name="LabTitleLogo" Visibility="Collapsed" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="18,0,0,0" Foreground="White" FontSize="17" VerticalAlignment="Center" />
                         <TextBlock x:Name="LabTitleLogo" Visibility="Collapsed" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="18,0,0,0" Foreground="White" FontSize="17" VerticalAlignment="Center" />
                         <local:MyImage x:Name="ImageTitleLogo" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="7" VerticalAlignment="Center" Visibility="Collapsed" />
                         <local:MyImage x:Name="ImageTitleLogo" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="7" VerticalAlignment="Center" Visibility="Collapsed" />
                         <StackPanel Grid.Column="1" x:Name="PanTitleSelect" HorizontalAlignment="Left" Height="27" VerticalAlignment="Center" Orientation="Horizontal" Margin="13,0">
                         <StackPanel Grid.Column="1" x:Name="PanTitleSelect" HorizontalAlignment="Left" Height="27" VerticalAlignment="Center" Orientation="Horizontal" Margin="13,0">
-                            <local:MyRadioButton x:Name="BtnTitleSelect0" Text="{DynamicResource LangTitleHome}" Tag="0" Margin="5,0" Checked="True" Padding="2,0"
-                                             LogoScale="0.95" Logo="M985.403 552.96C985.403 812.702 773.041 1024 512 1024S38.597 812.702 38.597 552.96c0-158.208 79.163-304.955 211.771-392.625 31.074-20.52 72.94-11.973 93.46 19.101s12.012 72.94-19.062 93.46c-94.681 62.622-151.237 167.306-151.237 280.064 0 185.344 151.788 336.108 338.471 336.108S850.471 738.304 850.471 552.96c0-114.649-57.974-220.278-155.096-282.585-31.35-20.125-40.448-61.833-20.362-93.184s61.794-40.448 93.184-20.4c135.995 87.236 217.206 235.362 217.206 396.169zM512 560.128c37.258 0 67.466-30.208 67.466-67.466V67.466C579.466 30.208 549.258 0 512 0s-67.466 30.208-67.466 67.466v425.196c0 37.258 30.208 67.466 67.466 67.466z" />
-                            <local:MyRadioButton x:Name="BtnTitleSelect1" Text="{DynamicResource LangTitleDownload}" Tag="1" Margin="5,0" Padding="2,0"
+                            <local:MyRadioButton x:Name="BtnTitleSelect0" Text="启动" Tag="0" Margin="5,0" Checked="True" Padding="2,0"
+                                             LogoScale="0.9" Logo="M52.1,164.5c-1.4,0-3.1-0.5-4.2-1.3c-2.6-1.7-4-4.2-4-7V43.8c0-2.9,1.6-5.8,4.1-7c1.2-0.8,2.7-1.2,4.1-1.2c1.5,0,2.9,0.4,4.2,1.2L153.1,93c0,0,0.1,0,0.1,0.1c2.6,1.7,4,4.2,4,7c0,3-1.7,5.8-4.2,7.1l-96.8,56.2C55.1,164,53.5,164.5,52.1,164.5z M60.4,142.1l72.1-42.1L60.4,58.2V142.1z" />
+                            <local:MyRadioButton x:Name="BtnTitleSelect1" Text="下载" Tag="1" Margin="5,0" Padding="2,0"
                                              LogoScale="0.9" Logo="M955 610h-59c-15 0-29 13-29 29v196c0 15-13 29-29 29h-649c-15 0-29-13-29-29v-196c0-15-13-29-29-29h-59c-15 0-29 13-29 29V905c0 43 35 78 78 78h787c43 0 78-35 78-78V640c0-15-13-29-29-29zM492 740c11 11 29 11 41 0l265-265c11-11 11-29 0-41l-41-41c-11-11-29-11-41 0l-110 110c-11 11-33 3-33-13V68C571 53 555 39 541 39h-59c-15 0-29 13-29 29v417c0 17-21 25-33 13l-110-110c-11-11-29-11-41 0L226 433c-11 11-11 29 0 41L492 740z" />
                                              LogoScale="0.9" Logo="M955 610h-59c-15 0-29 13-29 29v196c0 15-13 29-29 29h-649c-15 0-29-13-29-29v-196c0-15-13-29-29-29h-59c-15 0-29 13-29 29V905c0 43 35 78 78 78h787c43 0 78-35 78-78V640c0-15-13-29-29-29zM492 740c11 11 29 11 41 0l265-265c11-11 11-29 0-41l-41-41c-11-11-29-11-41 0l-110 110c-11 11-33 3-33-13V68C571 53 555 39 541 39h-59c-15 0-29 13-29 29v417c0 17-21 25-33 13l-110-110c-11-11-29-11-41 0L226 433c-11 11-11 29 0 41L492 740z" />
                             <local:MyRadioButton x:Name="BtnTitleSelect2" Text="联机" Tag="2" Margin="5,0" Padding="2,0"
                             <local:MyRadioButton x:Name="BtnTitleSelect2" Text="联机" Tag="2" Margin="5,0" Padding="2,0"
                                              LogoScale="1.05" Logo="M512 817c-48.601 0-88-39.399-88-88s39.399-88 88-88 88 39.399 88 88-39.399 88-88 88zM237.671 565.74C308.335 474.58 397.369 429 504.774 429c118.433 0 214.225 55.421 287.377 166.264l-53.407 30.369c-13.84 7.87-31.362 4.367-41.114-8.219-50.291-64.911-114.577-97.367-192.856-97.367-86.851 0-156.835 40.318-209.95 120.953l-47.995-28.02c-15.263-8.91-20.412-28.507-11.502-43.77a32 32 0 0 1 2.344-3.47zM107.691 419.47C205.24 278.491 337.805 208 505.379 208c178.77 0 317.694 80.224 416.772 240.672l-56.54 31.73c-13.686 7.68-30.922 4.303-40.697-7.975C735.581 360.213 629.07 303.009 505.38 300.815 373.997 298.485 261.637 362.88 168.3 494l-50.116-28.505c-15.362-8.738-20.732-28.275-11.994-43.637a32 32 0 0 1 1.5-2.387z"/>
                                              LogoScale="1.05" Logo="M512 817c-48.601 0-88-39.399-88-88s39.399-88 88-88 88 39.399 88 88-39.399 88-88 88zM237.671 565.74C308.335 474.58 397.369 429 504.774 429c118.433 0 214.225 55.421 287.377 166.264l-53.407 30.369c-13.84 7.87-31.362 4.367-41.114-8.219-50.291-64.911-114.577-97.367-192.856-97.367-86.851 0-156.835 40.318-209.95 120.953l-47.995-28.02c-15.263-8.91-20.412-28.507-11.502-43.77a32 32 0 0 1 2.344-3.47zM107.691 419.47C205.24 278.491 337.805 208 505.379 208c178.77 0 317.694 80.224 416.772 240.672l-56.54 31.73c-13.686 7.68-30.922 4.303-40.697-7.975C735.581 360.213 629.07 303.009 505.38 300.815 373.997 298.485 261.637 362.88 168.3 494l-50.116-28.505c-15.362-8.738-20.732-28.275-11.994-43.637a32 32 0 0 1 1.5-2.387z"/>
-                            <local:MyRadioButton x:Name="BtnTitleSelect3" Text="{DynamicResource LangTitleSetup}" Tag="3" Margin="5,0" Padding="2,0"
+                            <local:MyRadioButton x:Name="BtnTitleSelect3" Text="设置" Tag="3" Margin="5,0" Padding="2,0"
                                              LogoScale="1.1" Logo="M940.4 463.7L773.3 174.2c-17.3-30-49.2-48.4-83.8-48.4H340.2c-34.6 0-66.5 18.5-83.8 48.4L89.2 463.7c-17.3 30-17.3 66.9 0 96.8L256.4 850c17.3 30 49.2 48.4 83.8 48.4h349.2c34.6 0 66.5-18.5 83.8-48.4l167.2-289.5c17.3-29.9 17.3-66.8 0-96.8z m-94.6 96.8L725.9 768.1c-17.3 30-49.2 48.4-83.8 48.4H387.5c-34.6 0-66.5-18.5-83.8-48.4L183.9 560.5c-17.3-30-17.3-66.9 0-96.8l119.8-207.5c17.3-30 49.2-48.4 83.8-48.4h254.6c34.6 0 66.5 18.5 83.8 48.4l119.8 207.5c17.3 30 17.3 66.9 0.1 96.8z M522.3 321.2c-2.5-0.1-5-0.2-7.5-0.2-119.9 0-214 110.3-186.3 235 15.8 70.9 71.5 126.6 142.4 142.4 17.5 3.9 34.7 5.4 51.4 4.7 102.1-3.9 183.6-87.9 183.6-191 0.1-103-81.5-187-183.6-190.9z m68.6 269.1c-18.5 18-43 28.9-68.6 30.7l-6 0.3c-30.2 0.4-58.6-11.4-79.7-33-19.5-20.1-30.7-47-30.9-75-0.3-29.6 11.1-57.4 32-78.3 20.6-20.6 48-32 77.2-32 2.5 0 5 0.1 7.5 0.3 26.7 1.8 51.5 13.2 70.5 32.5 19.6 20 30.8 46.9 31.2 74.9 0.2 30.2-11.5 58.6-33.2 79.6z"/>
                                              LogoScale="1.1" Logo="M940.4 463.7L773.3 174.2c-17.3-30-49.2-48.4-83.8-48.4H340.2c-34.6 0-66.5 18.5-83.8 48.4L89.2 463.7c-17.3 30-17.3 66.9 0 96.8L256.4 850c17.3 30 49.2 48.4 83.8 48.4h349.2c34.6 0 66.5-18.5 83.8-48.4l167.2-289.5c17.3-29.9 17.3-66.8 0-96.8z m-94.6 96.8L725.9 768.1c-17.3 30-49.2 48.4-83.8 48.4H387.5c-34.6 0-66.5-18.5-83.8-48.4L183.9 560.5c-17.3-30-17.3-66.9 0-96.8l119.8-207.5c17.3-30 49.2-48.4 83.8-48.4h254.6c34.6 0 66.5 18.5 83.8 48.4l119.8 207.5c17.3 30 17.3 66.9 0.1 96.8z M522.3 321.2c-2.5-0.1-5-0.2-7.5-0.2-119.9 0-214 110.3-186.3 235 15.8 70.9 71.5 126.6 142.4 142.4 17.5 3.9 34.7 5.4 51.4 4.7 102.1-3.9 183.6-87.9 183.6-191 0.1-103-81.5-187-183.6-190.9z m68.6 269.1c-18.5 18-43 28.9-68.6 30.7l-6 0.3c-30.2 0.4-58.6-11.4-79.7-33-19.5-20.1-30.7-47-30.9-75-0.3-29.6 11.1-57.4 32-78.3 20.6-20.6 48-32 77.2-32 2.5 0 5 0.1 7.5 0.3 26.7 1.8 51.5 13.2 70.5 32.5 19.6 20 30.8 46.9 31.2 74.9 0.2 30.2-11.5 58.6-33.2 79.6z"/>
-                            <local:MyRadioButton x:Name="BtnTitleSelect4" Text="{DynamicResource LangTitleOther}" Tag="4" Margin="5,0" Padding="2,0"
+                            <local:MyRadioButton x:Name="BtnTitleSelect4" Text="更多" Tag="4" Margin="5,0" Padding="2,0"
                                              LogoScale="0.93" Logo="M364 0h-273C40 0 0 40 0 91v273C0 414 40 455 91 455h273C414 455 455 414 455 364V91C455 40 414 0 364 0zM341 341H113V113h227v227zM933 0h-273C609 0 568 40 568 91v273c0 50 40 91 91 91h273C983 455 1024 414 1024 364V91c0-50-40-91-90-91zM910 341h-227V113h227v227zM364 568h-273C40 568 0 609 0 659v273c0 50 40 91 91 91h273C414 1024 455 983 455 932v-273C455 609 414 568 364 568zM341 910H113v-227h227v227zM933 568h-273c-50 0-91 40-91 91v273c0 50 40 91 91 91h273c50 0 90-40 90-91v-273c0-50-40-90-90-90zM910 910h-227v-227h227v227z"/>
                                              LogoScale="0.93" Logo="M364 0h-273C40 0 0 40 0 91v273C0 414 40 455 91 455h273C414 455 455 414 455 364V91C455 40 414 0 364 0zM341 341H113V113h227v227zM933 0h-273C609 0 568 40 568 91v273c0 50 40 91 91 91h273C983 455 1024 414 1024 364V91c0-50-40-91-90-91zM910 341h-227V113h227v227zM364 568h-273C40 568 0 609 0 659v273c0 50 40 91 91 91h273C414 1024 455 983 455 932v-273C455 609 414 568 364 568zM341 910H113v-227h227v227zM933 568h-273c-50 0-91 40-91 91v273c0 50 40 91 91 91h273c50 0 90-40 90-91v-273c0-50-40-90-90-90zM910 910h-227v-227h227v227z"/>
                         </StackPanel>
                         </StackPanel>
                     </Grid>
                     </Grid>
@@ -145,7 +143,7 @@
                     <Rectangle x:Name="RectLeftBackground" Width="0" Fill="{DynamicResource ColorBrushBackgroundTransparentSidebar}" IsHitTestVisible="False" />
                     <Rectangle x:Name="RectLeftBackground" Width="0" Fill="{DynamicResource ColorBrushBackgroundTransparentSidebar}" IsHitTestVisible="False" />
                     <Rectangle x:Name="RectLeftShadow" Width="4" HorizontalAlignment="Left" IsHitTestVisible="False" Grid.Column="1" >
                     <Rectangle x:Name="RectLeftShadow" Width="4" HorizontalAlignment="Left" IsHitTestVisible="False" Grid.Column="1" >
                         <Rectangle.Fill>
                         <Rectangle.Fill>
-                            <LinearGradientBrush EndPoint="1,0" StartPoint="0,0" Opacity="0.085">
+                            <LinearGradientBrush EndPoint="1,0" StartPoint="0,0" Opacity="0.04">
                                 <GradientStop Color="#000000" Offset="0"/>
                                 <GradientStop Color="#000000" Offset="0"/>
                                 <GradientStop Color="#00000000" Offset="1"/>
                                 <GradientStop Color="#00000000" Offset="1"/>
                             </LinearGradientBrush>
                             </LinearGradientBrush>

+ 91 - 60
Plain Craft Launcher 2/FormMain.xaml.vb

@@ -72,6 +72,12 @@ Public Class FormMain
         '3:BUG+ IMP* FEAT-
         '3:BUG+ IMP* FEAT-
         '2:BUG* IMP-
         '2:BUG* IMP-
         '1:BUG-
         '1:BUG-
+        If LastVersion < 358 Then 'Snapshot 2.10.1
+            If LastVersion >= 356 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:下载资源包、光影包时能自动跳转到对应的文件夹"))
+            FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:调整界面样式与动画,让整体视觉更干净,操作体验更顺滑"))
+            FeatureCount += 25
+            BugCount += 23
+        End If
         If LastVersion < 356 Then 'Snapshot 2.10.0
         If LastVersion < 356 Then 'Snapshot 2.10.0
             FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "新增:下载资源包、光影包、数据包"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "新增:下载资源包、光影包、数据包"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "新增:允许设置文件下载源"))
             FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "新增:允许设置文件下载源"))
@@ -211,6 +217,9 @@ Public Class FormMain
         '刷新主题
         '刷新主题
         ThemeCheckAll(False)
         ThemeCheckAll(False)
         Setup.Load("UiLauncherTheme")
         Setup.Load("UiLauncherTheme")
+        '注册拖拽事件(不能直接加 Handles,否则没用;#6340)
+        [AddHandler](DragDrop.DragEnterEvent, New DragEventHandler(AddressOf HandleDrag), handledEventsToo:=True)
+        [AddHandler](DragDrop.DragOverEvent, New DragEventHandler(AddressOf HandleDrag), handledEventsToo:=True)
         '加载 UI
         '加载 UI
         InitializeComponent()
         InitializeComponent()
         Opacity = 0
         Opacity = 0
@@ -267,7 +276,7 @@ Public Class FormMain
         Resizer.addResizerUp(ResizerT)
         Resizer.addResizerUp(ResizerT)
         'PLC 彩蛋
         'PLC 彩蛋
         If RandomInteger(1, 1000) = 233 Then
         If RandomInteger(1, 1000) = 233 Then
-            ShapeTitleLogo.Data = New GeometryConverter().ConvertFromString("M26,29 v-25 h5 a7,7 180 0 1 0,14 h-5 M80,6.5 a10,11.5 180 1 0 0,18   M47,2.5 v24.5 h12   M98,2 v27   M107,2 v27")
+            ShapeTitleLogo.Data = New GeometryConverter().ConvertFromString("M26,29 v-25 h6 a7,7 180 0 1 0,14 h-6 M83,6.5 a10,11.5 180 1 0 0,18 M48,2.5 v24.5 h13.5")
         End If
         End If
         '加载窗口
         '加载窗口
         ThemeRefreshMain()
         ThemeRefreshMain()
@@ -433,8 +442,8 @@ Public Class FormMain
             Log("[Start] 已从老版本迁移 Mod 命名设置")
             Log("[Start] 已从老版本迁移 Mod 命名设置")
         End If
         End If
         '输出更新日志
         '输出更新日志
-        If LastVersionCode <= 0 Then Exit Sub
-        If LowerVersionCode >= VersionCode Then Exit Sub
+        If LastVersionCode <= 0 Then Return
+        If LowerVersionCode >= VersionCode Then Return
         ShowUpdateLog(LowerVersionCode)
         ShowUpdateLog(LowerVersionCode)
     End Sub
     End Sub
     Private Sub DowngradeSub(LastVersionCode As Integer)
     Private Sub DowngradeSub(LastVersionCode As Integer)
@@ -468,7 +477,7 @@ Public Class FormMain
                     Next
                     Next
                 End Sub, "强行停止下载任务")
                 End Sub, "强行停止下载任务")
             Else
             Else
-                Exit Sub
+                Return
             End If
             End If
         End If
         End If
         '关闭
         '关闭
@@ -508,8 +517,6 @@ Public Class FormMain
         On Error Resume Next
         On Error Resume Next
         IsProgramEnded = True
         IsProgramEnded = True
         AniControlEnabled += 1
         AniControlEnabled += 1
-        PageLinkIoi.IoiStop(False)
-        PageLinkHiper.HiperStop(False)
         If IsUpdateWaitingRestart Then UpdateRestart(False)
         If IsUpdateWaitingRestart Then UpdateRestart(False)
         If ReturnCode = ProcessReturnValues.Exception Then
         If ReturnCode = ProcessReturnValues.Exception Then
             If Not IsLogShown Then
             If Not IsLogShown Then
@@ -520,14 +527,10 @@ Public Class FormMain
             End If
             End If
             Thread.Sleep(500) '防止 PCL 在记事本打开前就被掐掉
             Thread.Sleep(500) '防止 PCL 在记事本打开前就被掐掉
         End If
         End If
-        Log("[System] 程序已退出,返回值:" & GetStringFromEnum(CType(ReturnCode, [Enum])))
+        Log("[System] 程序已退出,返回值:" & GetStringFromEnum(ReturnCode))
         LogFlush()
         LogFlush()
-        If ReturnCode = ProcessReturnValues.Success Then
-            Process.GetCurrentProcess.Kill()
-        Else
-            Environment.Exit(ReturnCode)
-            Process.GetCurrentProcess.Kill()
-        End If
+        If ReturnCode <> ProcessReturnValues.Success Then Environment.Exit(ReturnCode)
+        Process.GetCurrentProcess.Kill()
     End Sub
     End Sub
     Private Sub BtnTitleClose_Click(sender As Object, e As RoutedEventArgs) Handles BtnTitleClose.Click
     Private Sub BtnTitleClose_Click(sender As Object, e As RoutedEventArgs) Handles BtnTitleClose.Click
         EndProgram(True)
         EndProgram(True)
@@ -568,12 +571,12 @@ Public Class FormMain
 
 
     '按键事件
     '按键事件
     Private Sub FormMain_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
     Private Sub FormMain_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
-        If e.IsRepeat Then Exit Sub
+        If e.IsRepeat Then Return
         '调用弹窗:回车选择第一个,Esc 选择最后一个
         '调用弹窗:回车选择第一个,Esc 选择最后一个
         If PanMsg.Children.Count > 0 Then
         If PanMsg.Children.Count > 0 Then
             If e.Key = Key.Enter Then
             If e.Key = Key.Enter Then
                 CType(PanMsg.Children(0), Object).Btn1_Click()
                 CType(PanMsg.Children(0), Object).Btn1_Click()
-                Exit Sub
+                Return
             ElseIf e.Key = Key.Escape Then
             ElseIf e.Key = Key.Escape Then
                 Dim Msg As Object = PanMsg.Children(0)
                 Dim Msg As Object = PanMsg.Children(0)
                 If TypeOf Msg IsNot MyMsgInput AndAlso TypeOf Msg IsNot MyMsgSelect AndAlso Msg.Btn3.Visibility = Visibility.Visible Then
                 If TypeOf Msg IsNot MyMsgInput AndAlso TypeOf Msg IsNot MyMsgSelect AndAlso Msg.Btn3.Visibility = Visibility.Visible Then
@@ -583,7 +586,7 @@ Public Class FormMain
                 Else
                 Else
                     Msg.Btn1_Click()
                     Msg.Btn1_Click()
                 End If
                 End If
-                Exit Sub
+                Return
             End If
             End If
         End If
         End If
         '按 ESC 返回上一级
         '按 ESC 返回上一级
@@ -592,7 +595,7 @@ Public Class FormMain
         If e.Key = Key.F11 AndAlso PageCurrent = FormMain.PageType.VersionSelect Then
         If e.Key = Key.F11 AndAlso PageCurrent = FormMain.PageType.VersionSelect Then
             FrmSelectRight.ShowHidden = Not FrmSelectRight.ShowHidden
             FrmSelectRight.ShowHidden = Not FrmSelectRight.ShowHidden
             LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
             LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
-            Exit Sub
+            Return
         End If
         End If
         '更改功能隐藏可见性
         '更改功能隐藏可见性
         If e.Key = Key.F12 Then
         If e.Key = Key.F12 Then
@@ -603,13 +606,13 @@ Public Class FormMain
                 Hint("功能隐藏设置已重新开启!", HintType.Finish)
                 Hint("功能隐藏设置已重新开启!", HintType.Finish)
             End If
             End If
             PageSetupUI.HiddenRefresh()
             PageSetupUI.HiddenRefresh()
-            Exit Sub
+            Return
         End If
         End If
         '按 F5 刷新页面
         '按 F5 刷新页面
         If e.Key = Key.F5 Then
         If e.Key = Key.F5 Then
             If TypeOf PageLeft Is IRefreshable Then CType(PageLeft, IRefreshable).Refresh()
             If TypeOf PageLeft Is IRefreshable Then CType(PageLeft, IRefreshable).Refresh()
             If TypeOf PageRight Is IRefreshable Then CType(PageRight, IRefreshable).Refresh()
             If TypeOf PageRight Is IRefreshable Then CType(PageRight, IRefreshable).Refresh()
-            Exit Sub
+            Return
         End If
         End If
         '调用启动游戏
         '调用启动游戏
         If e.Key = Key.Enter AndAlso PageCurrent = FormMain.PageType.Launch Then
         If e.Key = Key.Enter AndAlso PageCurrent = FormMain.PageType.Launch Then
@@ -624,7 +627,7 @@ Public Class FormMain
     End Sub
     End Sub
     Private Sub FormMain_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseDown
     Private Sub FormMain_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseDown
         '鼠标侧键返回上一级
         '鼠标侧键返回上一级
-        If FrmMain.PanMsg.Children.Count > 0 OrElse WaitingMyMsgBox.Any Then Exit Sub '弹窗中(#5513)
+        If FrmMain.PanMsg.Children.Count > 0 OrElse WaitingMyMsgBox.Any Then Return '弹窗中(#5513)
         If e.ChangedButton = MouseButton.XButton1 OrElse e.ChangedButton = MouseButton.XButton2 Then TriggerPageBack()
         If e.ChangedButton = MouseButton.XButton1 OrElse e.ChangedButton = MouseButton.XButton2 Then TriggerPageBack()
     End Sub
     End Sub
     Private Sub TriggerPageBack()
     Private Sub TriggerPageBack()
@@ -651,14 +654,39 @@ Public Class FormMain
     End Sub
     End Sub
 
 
     '文件拖放
     '文件拖放
-    Private Sub FrmMain_PreviewDragOver(sender As Object, e As DragEventArgs) Handles Me.PreviewDragOver
-        If e.Data.GetFormats.Contains("FileDrop") Then
-            e.Effects = DragDropEffects.Link
-        Else
+    Private Sub HandleDrag(sender As Object, e As DragEventArgs)
+        Try
+            If e.Handled AndAlso (e.Effects <> DragDropEffects.None) Then Return
+            e.Handled = True
+            '缓存
+            Static PrevData As IDataObject, PrevEffects As DragDropEffects
+            If e.Data Is PrevData Then
+                e.Effects = PrevEffects
+                Return
+            End If
+            '确定拖放效果
             e.Effects = DragDropEffects.None
             e.Effects = DragDropEffects.None
-        End If
+            If e.Data.GetDataPresent(DataFormats.Text) Then
+                Dim Str As String = e.Data.GetData(DataFormats.Text)
+                If Str.StartsWithF("authlib-injector:yggdrasil-server:") Then
+                    e.Effects = DragDropEffects.Copy
+                ElseIf Str.StartsWithF("file:///") Then
+                    e.Effects = DragDropEffects.Copy
+                End If
+            ElseIf e.Data.GetDataPresent(DataFormats.FileDrop) Then
+                Dim Files As String() = e.Data.GetData(DataFormats.FileDrop)
+                If Files IsNot Nothing AndAlso Files.Length > 0 Then
+                    e.Effects = DragDropEffects.Link
+                End If
+            End If
+            PrevData = e.Data
+            PrevEffects = e.Effects
+            Log("[System] 设置拖放类型:" & GetStringFromEnum(e.Effects))
+        Catch ex As Exception
+            Log(ex, "处理拖放时出错", LogLevel.Feedback)
+        End Try
     End Sub
     End Sub
-    Private Sub FrmMain_Drop(sender As Object, e As DragEventArgs) Handles Me.PreviewDrop
+    Private Sub FrmMain_Drop(sender As Object, e As DragEventArgs) Handles Me.Drop
         Try
         Try
             If e.Data.GetDataPresent(DataFormats.Text) Then
             If e.Data.GetDataPresent(DataFormats.Text) Then
                 '获取文本
                 '获取文本
@@ -668,22 +696,23 @@ Public Class FormMain
                     If Str.StartsWithF("authlib-injector:yggdrasil-server:") Then
                     If Str.StartsWithF("authlib-injector:yggdrasil-server:") Then
                         'Authlib 拖拽
                         'Authlib 拖拽
                         e.Handled = True
                         e.Handled = True
+                        e.Effects = DragDropEffects.Copy
                         Dim AuthlibServer As String = Net.WebUtility.UrlDecode(Str.Substring("authlib-injector:yggdrasil-server:".Length))
                         Dim AuthlibServer As String = Net.WebUtility.UrlDecode(Str.Substring("authlib-injector:yggdrasil-server:".Length))
                         Log("[System] Authlib 拖拽:" & AuthlibServer)
                         Log("[System] Authlib 拖拽:" & AuthlibServer)
                         If Not String.IsNullOrEmpty(New ValidateHttp().Validate(AuthlibServer)) Then
                         If Not String.IsNullOrEmpty(New ValidateHttp().Validate(AuthlibServer)) Then
                             Hint($"输入的 Authlib 验证服务器不符合网址格式({AuthlibServer})!", HintType.Critical)
                             Hint($"输入的 Authlib 验证服务器不符合网址格式({AuthlibServer})!", HintType.Critical)
-                            Exit Sub
+                            Return
                         End If
                         End If
                         Dim TargetVersion = If(PageCurrent = PageType.VersionSetup, PageVersionLeft.Version, McVersionCurrent)
                         Dim TargetVersion = If(PageCurrent = PageType.VersionSetup, PageVersionLeft.Version, McVersionCurrent)
                         If TargetVersion Is Nothing Then
                         If TargetVersion Is Nothing Then
                             Hint("请先下载游戏,再设置第三方登录!", HintType.Critical)
                             Hint("请先下载游戏,再设置第三方登录!", HintType.Critical)
-                            Exit Sub
+                            Return
                         End If
                         End If
                         If AuthlibServer = "https://littleskin.cn/api/yggdrasil" Then
                         If AuthlibServer = "https://littleskin.cn/api/yggdrasil" Then
                             'LittleSkin
                             'LittleSkin
                             If MyMsgBox($"是否要在版本 {TargetVersion.Name} 中开启 LittleSkin 登录?" & vbCrLf &
                             If MyMsgBox($"是否要在版本 {TargetVersion.Name} 中开启 LittleSkin 登录?" & vbCrLf &
                                         "你可以在 版本设置 → 设置 → 服务器选项 中修改登录方式。", "第三方登录开启确认", "确定", "取消") = 2 Then
                                         "你可以在 版本设置 → 设置 → 服务器选项 中修改登录方式。", "第三方登录开启确认", "确定", "取消") = 2 Then
-                                Exit Sub
+                                Return
                             End If
                             End If
                             Setup.Set("VersionServerLogin", 4, Version:=TargetVersion)
                             Setup.Set("VersionServerLogin", 4, Version:=TargetVersion)
                             Setup.Set("VersionServerAuthServer", "https://littleskin.cn/api/yggdrasil", Version:=TargetVersion)
                             Setup.Set("VersionServerAuthServer", "https://littleskin.cn/api/yggdrasil", Version:=TargetVersion)
@@ -694,7 +723,7 @@ Public Class FormMain
                             If MyMsgBox($"是否要在版本 {TargetVersion.Name} 中开启第三方登录?" & vbCrLf &
                             If MyMsgBox($"是否要在版本 {TargetVersion.Name} 中开启第三方登录?" & vbCrLf &
                                         $"登录服务器:{AuthlibServer}" & vbCrLf & vbCrLf &
                                         $"登录服务器:{AuthlibServer}" & vbCrLf & vbCrLf &
                                         "你可以在 版本设置 → 设置 → 服务器选项 中修改登录方式。", "第三方登录开启确认", "确定", "取消") = 2 Then
                                         "你可以在 版本设置 → 设置 → 服务器选项 中修改登录方式。", "第三方登录开启确认", "确定", "取消") = 2 Then
-                                Exit Sub
+                                Return
                             End If
                             End If
                             Setup.Set("VersionServerLogin", 4, Version:=TargetVersion)
                             Setup.Set("VersionServerLogin", 4, Version:=TargetVersion)
                             Setup.Set("VersionServerAuthServer", AuthlibServer, Version:=TargetVersion)
                             Setup.Set("VersionServerAuthServer", AuthlibServer, Version:=TargetVersion)
@@ -712,20 +741,22 @@ Public Class FormMain
                         '文件拖拽(例如从浏览器下载窗口拖入)
                         '文件拖拽(例如从浏览器下载窗口拖入)
                         Dim FilePath = Net.WebUtility.UrlDecode(Str).Substring("file:///".Length).Replace("/", "\")
                         Dim FilePath = Net.WebUtility.UrlDecode(Str).Substring("file:///".Length).Replace("/", "\")
                         e.Handled = True
                         e.Handled = True
+                        e.Effects = DragDropEffects.Copy
                         FileDrag(New List(Of String) From {FilePath})
                         FileDrag(New List(Of String) From {FilePath})
                     End If
                     End If
                 Catch ex As Exception
                 Catch ex As Exception
                     Log(ex, "无法接取文本拖拽事件", LogLevel.Developer)
                     Log(ex, "无法接取文本拖拽事件", LogLevel.Developer)
-                    Exit Sub
+                    Return
                 End Try
                 End Try
             ElseIf e.Data.GetDataPresent(DataFormats.FileDrop) Then
             ElseIf e.Data.GetDataPresent(DataFormats.FileDrop) Then
                 '获取文件并检查
                 '获取文件并检查
                 Dim FilePathRaw = e.Data.GetData(DataFormats.FileDrop)
                 Dim FilePathRaw = e.Data.GetData(DataFormats.FileDrop)
                 If FilePathRaw Is Nothing Then '#2690
                 If FilePathRaw Is Nothing Then '#2690
                     Hint("请将文件解压后再拖入!", HintType.Critical)
                     Hint("请将文件解压后再拖入!", HintType.Critical)
-                    Exit Sub
+                    Return
                 End If
                 End If
                 e.Handled = True
                 e.Handled = True
+                e.Effects = DragDropEffects.Link
                 FileDrag(CType(FilePathRaw, IEnumerable(Of String)))
                 FileDrag(CType(FilePathRaw, IEnumerable(Of String)))
             End If
             End If
         Catch ex As Exception
         Catch ex As Exception
@@ -740,10 +771,10 @@ Public Class FormMain
             '基础检查
             '基础检查
             If Directory.Exists(FilePathList.First) AndAlso Not File.Exists(FilePathList.First) Then
             If Directory.Exists(FilePathList.First) AndAlso Not File.Exists(FilePathList.First) Then
                 Hint("请拖入一个文件,而非文件夹!", HintType.Critical)
                 Hint("请拖入一个文件,而非文件夹!", HintType.Critical)
-                Exit Sub
+                Return
             ElseIf Not File.Exists(FilePathList.First) Then
             ElseIf Not File.Exists(FilePathList.First) Then
                 Hint("拖入的文件不存在:" & FilePathList.First, HintType.Critical)
                 Hint("拖入的文件不存在:" & FilePathList.First, HintType.Critical)
-                Exit Sub
+                Return
             End If
             End If
             '多文件拖拽
             '多文件拖拽
             If FilePathList.Count > 1 Then
             If FilePathList.Count > 1 Then
@@ -751,7 +782,7 @@ Public Class FormMain
                 For Each File In FilePathList
                 For Each File In FilePathList
                     If Not {"jar", "litemod", "disabled", "old"}.Contains(File.AfterLast(".").ToLower) Then
                     If Not {"jar", "litemod", "disabled", "old"}.Contains(File.AfterLast(".").ToLower) Then
                         Hint("一次请只拖入一个文件!", HintType.Critical)
                         Hint("一次请只拖入一个文件!", HintType.Critical)
-                        Exit Sub
+                        Return
                     End If
                     End If
                 Next
                 Next
             End If
             End If
@@ -761,7 +792,7 @@ Public Class FormMain
                 Log("[System] 文件后缀为 XAML,作为主页加载")
                 Log("[System] 文件后缀为 XAML,作为主页加载")
                 If File.Exists(Path & "PCL\Custom.xaml") Then
                 If File.Exists(Path & "PCL\Custom.xaml") Then
                     If MyMsgBox("已存在一个主页文件,是否要将它覆盖?", "覆盖确认", "覆盖", "取消") = 2 Then
                     If MyMsgBox("已存在一个主页文件,是否要将它覆盖?", "覆盖确认", "覆盖", "取消") = 2 Then
-                        Exit Sub
+                        Return
                     End If
                     End If
                 End If
                 End If
                 CopyFile(FilePath, Path & "PCL\Custom.xaml")
                 CopyFile(FilePath, Path & "PCL\Custom.xaml")
@@ -771,18 +802,18 @@ Public Class FormMain
                     FrmLaunchRight.ForceRefresh()
                     FrmLaunchRight.ForceRefresh()
                     Hint("已加载主页自定义文件!", HintType.Finish)
                     Hint("已加载主页自定义文件!", HintType.Finish)
                 End Sub)
                 End Sub)
-                Exit Sub
+                Return
             End If
             End If
             '安装 Mod
             '安装 Mod
-            If PageVersionMod.InstallMods(FilePathList) Then Exit Sub
+            If PageVersionMod.InstallMods(FilePathList) Then Return
             '安装整合包
             '安装整合包
             If {"zip", "rar", "mrpack"}.Any(Function(t) t = Extension) Then '部分压缩包是 zip 格式但后缀为 rar,总之试一试
             If {"zip", "rar", "mrpack"}.Any(Function(t) t = Extension) Then '部分压缩包是 zip 格式但后缀为 rar,总之试一试
                 Log("[System] 文件为压缩包,尝试作为整合包安装")
                 Log("[System] 文件为压缩包,尝试作为整合包安装")
                 Try
                 Try
                     ModpackInstall(FilePath)
                     ModpackInstall(FilePath)
-                    Exit Sub
+                    Return
                 Catch ex As CancelledException
                 Catch ex As CancelledException
-                    Exit Sub '用户主动取消
+                    Return '用户主动取消
                 Catch ex As Exception
                 Catch ex As Exception
                     '安装失败,继续往后尝试
                     '安装失败,继续往后尝试
                 End Try
                 End Try
@@ -790,17 +821,17 @@ Public Class FormMain
             'RAR 处理
             'RAR 处理
             If Extension = "rar" Then
             If Extension = "rar" Then
                 Hint("PCL 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试!")
                 Hint("PCL 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试!")
-                Exit Sub
+                Return
             End If
             End If
             '错误报告分析
             '错误报告分析
             Try
             Try
                 Log("[System] 尝试进行错误报告分析")
                 Log("[System] 尝试进行错误报告分析")
                 Dim Analyzer As New CrashAnalyzer(GetUuid())
                 Dim Analyzer As New CrashAnalyzer(GetUuid())
                 Analyzer.Import(FilePath)
                 Analyzer.Import(FilePath)
-                If Analyzer.Prepare() = 0 Then Exit Try
+                If Not Analyzer.Prepare() Then Exit Try
                 Analyzer.Analyze()
                 Analyzer.Analyze()
                 Analyzer.Output(True, New List(Of String))
                 Analyzer.Output(True, New List(Of String))
-                Exit Sub
+                Return
             Catch ex As Exception
             Catch ex As Exception
                 Log(ex, "自主错误报告分析失败", LogLevel.Feedback)
                 Log(ex, "自主错误报告分析失败", LogLevel.Feedback)
             End Try
             End Try
@@ -840,7 +871,7 @@ Public Class FormMain
             Return _Hidden
             Return _Hidden
         End Get
         End Get
         Set(value As Boolean)
         Set(value As Boolean)
-            If _Hidden = value Then Exit Property
+            If _Hidden = value Then Return
             _Hidden = value
             _Hidden = value
             If value Then
             If value Then
                 '隐藏
                 '隐藏
@@ -1103,7 +1134,7 @@ Public Class FormMain
     ''' 通过点击导航栏改变页面。
     ''' 通过点击导航栏改变页面。
     ''' </summary>
     ''' </summary>
     Private Sub BtnTitleSelect_Click(sender As MyRadioButton, raiseByMouse As Boolean) Handles BtnTitleSelect0.Check, BtnTitleSelect1.Check, BtnTitleSelect2.Check, BtnTitleSelect3.Check, BtnTitleSelect4.Check
     Private Sub BtnTitleSelect_Click(sender As MyRadioButton, raiseByMouse As Boolean) Handles BtnTitleSelect0.Check, BtnTitleSelect1.Check, BtnTitleSelect2.Check, BtnTitleSelect3.Check, BtnTitleSelect4.Check
-        If IsChangingPage Then Exit Sub
+        If IsChangingPage Then Return
         PageChangeActual(Val(sender.Tag))
         PageChangeActual(Val(sender.Tag))
     End Sub
     End Sub
     ''' <summary>
     ''' <summary>
@@ -1122,7 +1153,7 @@ Public Class FormMain
     ''' 切换现有页面的实际方法。
     ''' 切换现有页面的实际方法。
     ''' </summary>
     ''' </summary>
     Private Sub PageChangeActual(Stack As PageStackData, Optional SubType As PageSubType = -1)
     Private Sub PageChangeActual(Stack As PageStackData, Optional SubType As PageSubType = -1)
-        If PageCurrent = Stack AndAlso (PageCurrentSub = SubType OrElse SubType = -1) Then Exit Sub
+        If PageCurrent = Stack AndAlso (PageCurrentSub = SubType OrElse SubType = -1) Then Return
         AniControlEnabled += 1
         AniControlEnabled += 1
         Try
         Try
 
 
@@ -1241,14 +1272,14 @@ Public Class FormMain
                 PanMainLeft.Background = Nothing
                 PanMainLeft.Background = Nothing
                 AniControlEnabled -= 1
                 AniControlEnabled -= 1
                 RunInUi(Sub() PanMainLeft_Resize(PanMainLeft.ActualWidth), True)
                 RunInUi(Sub() PanMainLeft_Resize(PanMainLeft.ActualWidth), True)
-            End Sub, 130),
+            End Sub, 110),
             AaCode(
             AaCode(
             Sub()
             Sub()
                 '延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
                 '延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
                 PageLeft.Opacity = 1
                 PageLeft.Opacity = 1
                 PageLeft.TriggerShowAnimation()
                 PageLeft.TriggerShowAnimation()
             End Sub, 30, True)
             End Sub, 30, True)
-            }, "FrmMain PageChangeLeft")
+        }, "FrmMain PageChangeLeft")
         AniStart({
         AniStart({
             AaCode(
             AaCode(
             Sub()
             Sub()
@@ -1260,14 +1291,14 @@ Public Class FormMain
                 PanMainRight.Background = Nothing
                 PanMainRight.Background = Nothing
                 AniControlEnabled -= 1
                 AniControlEnabled -= 1
                 RunInUi(Sub() BtnExtraBack.ShowRefresh(), True)
                 RunInUi(Sub() BtnExtraBack.ShowRefresh(), True)
-            End Sub, 130),
+            End Sub, 110),
             AaCode(
             AaCode(
             Sub()
             Sub()
                 '延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
                 '延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
                 PageRight.Opacity = 1
                 PageRight.Opacity = 1
                 PageRight.PageOnEnter()
                 PageRight.PageOnEnter()
             End Sub, 30, True)
             End Sub, 30, True)
-            }, "FrmMain PageChangeRight")
+        }, "FrmMain PageChangeRight")
     End Sub
     End Sub
     ''' <summary>
     ''' <summary>
     ''' 退出子界面。
     ''' 退出子界面。
@@ -1293,7 +1324,7 @@ Public Class FormMain
 
 
     '左边栏改变
     '左边栏改变
     Private Sub PanMainLeft_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles PanMainLeft.SizeChanged
     Private Sub PanMainLeft_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles PanMainLeft.SizeChanged
-        If Not e.WidthChanged Then Exit Sub
+        If Not e.WidthChanged Then Return
         PanMainLeft_Resize(e.NewSize.Width)
         PanMainLeft_Resize(e.NewSize.Width)
     End Sub
     End Sub
     Private Sub PanMainLeft_Resize(NewWidth As Double)
     Private Sub PanMainLeft_Resize(NewWidth As Double)
@@ -1303,16 +1334,16 @@ Public Class FormMain
             If NewWidth > 0 Then
             If NewWidth > 0 Then
                 '宽度足够,显示
                 '宽度足够,显示
                 AniStart({
                 AniStart({
-                    AaWidth(RectLeftBackground, NewWidth - RectLeftBackground.Width, 400,, New AniEaseOutFluent(AniEasePower.ExtraStrong)),
-                    AaOpacity(RectLeftShadow, 1 - RectLeftShadow.Opacity, 200),
-                    AaCode(Sub() PanMainLeft.IsHitTestVisible = True, 250)
+                    AaWidth(RectLeftBackground, NewWidth - RectLeftBackground.Width, 180,, New AniEaseOutFluent(AniEasePower.ExtraStrong)),
+                    AaOpacity(RectLeftShadow, 1 - RectLeftShadow.Opacity, 180),
+                    AaCode(Sub() PanMainLeft.IsHitTestVisible = True, 150)
                 }, "FrmMain LeftChange", True)
                 }, "FrmMain LeftChange", True)
             Else
             Else
                 '宽度不足,隐藏
                 '宽度不足,隐藏
                 AniStart({
                 AniStart({
-                    AaWidth(RectLeftBackground, -RectLeftBackground.Width, 200,, New AniEaseOutFluent),
-                    AaOpacity(RectLeftShadow, -RectLeftShadow.Opacity, 200),
-                    AaCode(Sub() PanMainLeft.IsHitTestVisible = True, 170)
+                    AaWidth(RectLeftBackground, -RectLeftBackground.Width, 180,, New AniEaseOutFluent),
+                    AaOpacity(RectLeftShadow, -RectLeftShadow.Opacity, 180),
+                    AaCode(Sub() PanMainLeft.IsHitTestVisible = True, 150)
                 }, "FrmMain LeftChange", True)
                 }, "FrmMain LeftChange", True)
             End If
             End If
         Else
         Else
@@ -1328,14 +1359,14 @@ Public Class FormMain
 
 
     '在时钟中调用,使得即使鼠标在窗口外松开,也可以释放控件
     '在时钟中调用,使得即使鼠标在窗口外松开,也可以释放控件
     Public Sub DragTick()
     Public Sub DragTick()
-        If DragControl Is Nothing Then Exit Sub
+        If DragControl Is Nothing Then Return
         If Not Mouse.LeftButton = MouseButtonState.Pressed Then
         If Not Mouse.LeftButton = MouseButtonState.Pressed Then
             DragStop()
             DragStop()
         End If
         End If
     End Sub
     End Sub
     '在鼠标移动时调用,以改变 Slider 位置
     '在鼠标移动时调用,以改变 Slider 位置
     Public Sub DragDoing() Handles PanBack.MouseMove
     Public Sub DragDoing() Handles PanBack.MouseMove
-        If DragControl Is Nothing Then Exit Sub
+        If DragControl Is Nothing Then Return
         If Mouse.LeftButton = MouseButtonState.Pressed Then
         If Mouse.LeftButton = MouseButtonState.Pressed Then
             DragControl.DragDoing()
             DragControl.DragDoing()
         Else
         Else
@@ -1345,7 +1376,7 @@ Public Class FormMain
     Public Sub DragStop()
     Public Sub DragStop()
         '存在其他线程调用的可能性,因此需要确保在 UI 线程运行
         '存在其他线程调用的可能性,因此需要确保在 UI 线程运行
         RunInUi(Sub()
         RunInUi(Sub()
-                    If DragControl Is Nothing Then Exit Sub
+                    If DragControl Is Nothing Then Return
                     Dim Control = DragControl
                     Dim Control = DragControl
                     DragControl = Nothing
                     DragControl = Nothing
                     Control.DragStop() '控件会在该事件中判断 DragControl,所以得放在后面
                     Control.DragStop() '控件会在该事件中判断 DragControl,所以得放在后面

+ 21 - 1
Plain Craft Launcher 2/Modules/Base/ModAnimation.vb

@@ -624,6 +624,26 @@ Public Module ModAnimation
             Return Ease.GetValue(t)
             Return Ease.GetValue(t)
         End Function
         End Function
     End Class
     End Class
+    ''' <summary>
+    ''' 以特定速度开始的平滑结束。
+    ''' </summary>
+    Public Class AniEaseOutFluentWithInitial
+        Inherits AniEase
+        Private ReadOnly alpha As Double '(初速度 / 平均速度) – 1
+        ''' <param name="InitialPixelPerSecond">初速度,px/s</param>
+        ''' <param name="TotalSecond">总时长,s</param>
+        ''' <param name="TotalDistance">总路程,px</param>
+        Public Sub New(InitialPixelPerSecond As Double, TotalSecond As Double, TotalDistance As Double)
+            Dim v0_norm As Double = InitialPixelPerSecond * TotalSecond / TotalDistance '归一化初速度
+            alpha = v0_norm - 1.0
+            If alpha < 0 Then alpha = 0 '初速度小于平均速度时,退化为线性
+        End Sub
+        Public Overrides Function GetValue(percent As Double) As Double
+            Dim p As Double = MathClamp(percent, 0, 1)
+            If alpha = 0 Then Return p '退化到线性
+            Return (alpha + 1) * p / (1 + alpha * p)
+        End Function
+    End Class
 
 
     'Back / 回弹
     'Back / 回弹
     ''' <summary>
     ''' <summary>
@@ -807,7 +827,7 @@ Sleeper:
                                    Thread.Sleep(1)
                                    Thread.Sleep(1)
                                Loop
                                Loop
                            Catch ex As Exception
                            Catch ex As Exception
-                               Log(ex, "动画帧执行失败", LogLevel.Assert)
+                               Log(ex, "动画帧执行失败", LogLevel.Critical)
                            End Try
                            End Try
                        End Sub, "Animation", ThreadPriority.AboveNormal)
                        End Sub, "Animation", ThreadPriority.AboveNormal)
     End Sub
     End Sub

+ 35 - 37
Plain Craft Launcher 2/Modules/Base/ModBase.vb

@@ -13,13 +13,13 @@ Public Module ModBase
 #Region "声明"
 #Region "声明"
 
 
     '下列版本信息由更新器自动修改
     '下列版本信息由更新器自动修改
-    Public Const VersionBaseName As String = "2.10.0" '不含分支前缀的显示用版本名
-    Public Const VersionStandardCode As String = "2.10.0." & VersionBranchCode '标准格式的四段式版本号
+    Public Const VersionBaseName As String = "2.10.1" '不含分支前缀的显示用版本名
+    Public Const VersionStandardCode As String = "2.10.1." & VersionBranchCode '标准格式的四段式版本号
     Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
     Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
 #If BETA Then
 #If BETA Then
     Public Const VersionCode As Integer = 357 'Release
     Public Const VersionCode As Integer = 357 'Release
 #Else
 #Else
-    Public Const VersionCode As Integer = 356 'Snapshot
+    Public Const VersionCode As Integer = 358 'Snapshot
 #End If
 #End If
     '自动生成的版本信息
     '自动生成的版本信息
     Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
     Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -785,13 +785,16 @@ Public Module ModBase
     End Function
     End Function
 
 
     '读取、写入、复制文件
     '读取、写入、复制文件
+    ''' <summary>
+    ''' 复制文件。会自动创建文件夹、会覆盖已有的文件。
+    ''' </summary>
     Public Sub CopyFile(FromPath As String, ToPath As String)
     Public Sub CopyFile(FromPath As String, ToPath As String)
         Try
         Try
             '还原文件路径
             '还原文件路径
             If Not FromPath.Contains(":\") Then FromPath = Path & FromPath
             If Not FromPath.Contains(":\") Then FromPath = Path & FromPath
             If Not ToPath.Contains(":\") Then ToPath = Path & ToPath
             If Not ToPath.Contains(":\") Then ToPath = Path & ToPath
             '如果复制同一个文件则跳过
             '如果复制同一个文件则跳过
-            If FromPath = ToPath Then Exit Sub
+            If FromPath = ToPath Then Return
             '确保目录存在
             '确保目录存在
             Directory.CreateDirectory(GetPathFromFullPath(ToPath))
             Directory.CreateDirectory(GetPathFromFullPath(ToPath))
             '复制文件
             '复制文件
@@ -803,7 +806,6 @@ Public Module ModBase
     ''' <summary>
     ''' <summary>
     ''' 读取文件,如果失败则返回空数组。
     ''' 读取文件,如果失败则返回空数组。
     ''' </summary>
     ''' </summary>
-    ''' <param name="FilePath">文件完整或相对路径。</param>
     Public Function ReadFileBytes(FilePath As String, Optional Encoding As Encoding = Nothing) As Byte()
     Public Function ReadFileBytes(FilePath As String, Optional Encoding As Encoding = Nothing) As Byte()
         Try
         Try
             '还原文件路径
             '还原文件路径
@@ -1363,7 +1365,7 @@ RetryDir:
         Try
         Try
             Directory.Delete(Path, True)
             Directory.Delete(Path, True)
         Catch ex As Exception
         Catch ex As Exception
-            If Not RetriedDir Then
+            If Not RetriedDir AndAlso Not RunInUi() Then
                 RetriedDir = True
                 RetriedDir = True
                 Log(ex, $"删除文件夹失败,将在 0.3s 后重试({Path})")
                 Log(ex, $"删除文件夹失败,将在 0.3s 后重试({Path})")
                 Thread.Sleep(300)
                 Thread.Sleep(300)
@@ -1459,7 +1461,7 @@ RetryDir:
             CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
             CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
         ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
         ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
                 "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) DescList.Any(Function(l) l.Contains(s))) Then
                 "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) DescList.Any(Function(l) l.Contains(s))) Then
-            CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
+            CommonReason = "你的网络环境不佳,导致难以连接到服务器。请稍后重试,或使用 VPN 以改善网络环境。"
         End If
         End If
 
 
         '构造输出信息
         '构造输出信息
@@ -1502,7 +1504,7 @@ RetryDir:
             CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
             CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
         ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
         ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
                 "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
                 "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
-            CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
+            CommonReason = "你的网络环境不佳,导致难以连接到服务器。请稍后重试,或使用 VPN 以改善网络环境。"
         End If
         End If
 
 
         '构造输出信息
         '构造输出信息
@@ -1981,8 +1983,8 @@ RetryDir:
 #Region "系统"
 #Region "系统"
 
 
     ''' <summary>
     ''' <summary>
-    ''' 线程安全的,可以直接使用 For Each 的 List。
-    ''' 在使用 For Each 循环时,列表的结果可能并非最新,但不会抛出异常。
+    ''' 线程安全的 List。
+    ''' 通过在 For Each 循环中使用一个浅表副本规避多线程操作或移除自身导致的异常。
     ''' </summary>
     ''' </summary>
     Public Class SafeList(Of T)
     Public Class SafeList(Of T)
         Inherits SynchronizedCollection(Of T)
         Inherits SynchronizedCollection(Of T)
@@ -2014,8 +2016,8 @@ RetryDir:
     End Class
     End Class
 
 
     ''' <summary>
     ''' <summary>
-    ''' 线程安全的,可以直接使用 For Each 的字典。
-    ''' 在使用 For Each 循环时,字典的结果可能并非最新,但不会抛出异常。
+    ''' 线程安全的字典。
+    ''' 通过在 For Each 循环中使用一个浅表副本规避多线程操作或移除自身导致的异常。
     ''' </summary>
     ''' </summary>
     Public Class SafeDictionary(Of TKey, TValue)
     Public Class SafeDictionary(Of TKey, TValue)
         Implements IDictionary(Of TKey, TValue)
         Implements IDictionary(Of TKey, TValue)
@@ -2674,7 +2676,7 @@ Retry:
             End Select
             End Select
         End If
         End If
 
 
-        'If Double.IsNaN(newValue) OrElse Double.IsInfinity(newValue) Then Exit Sub '安全性检查
+        'If Double.IsNaN(newValue) OrElse Double.IsInfinity(newValue) Then Return '安全性检查
         'Select Case control.VerticalAlignment
         'Select Case control.VerticalAlignment
         '  Case VerticalAlignment.Top, VerticalAlignment.Stretch, VerticalAlignment.Center
         '  Case VerticalAlignment.Top, VerticalAlignment.Stretch, VerticalAlignment.Center
         '      control.Margin = New Thickness(control.Margin.Left, newValue, control.Margin.Right, control.Margin.Bottom)
         '      control.Margin = New Thickness(control.Margin.Left, newValue, control.Margin.Right, control.Margin.Bottom)
@@ -2847,9 +2849,10 @@ Retry:
         ''' </summary>
         ''' </summary>
         Feedback = 5
         Feedback = 5
         ''' <summary>
         ''' <summary>
-        ''' 弹窗,结束程序。
+        ''' 弹出 Windows 原生弹窗,要求反馈。在无法保证 WPF 窗口能正常运行时使用此级别。
+        ''' 在第二次触发后会直接结束程序。
         ''' </summary>
         ''' </summary>
-        Assert = 6
+        Critical = 6
     End Enum
     End Enum
     Private LogList As New StringBuilder
     Private LogList As New StringBuilder
     Private LogWritter As StreamWriter
     Private LogWritter As StreamWriter
@@ -2892,7 +2895,7 @@ Retry:
     Private ReadOnly LogFlushLock As New Object '防止外部调用 LogFlush 时同时输出多次日志
     Private ReadOnly LogFlushLock As New Object '防止外部调用 LogFlush 时同时输出多次日志
     Public Sub LogFlush()
     Public Sub LogFlush()
         On Error Resume Next
         On Error Resume Next
-        If LogWritter Is Nothing Then Exit Sub
+        If LogWritter Is Nothing Then Return
         Dim Log As String = Nothing
         Dim Log As String = Nothing
         SyncLock LogFlushLock
         SyncLock LogFlushLock
             If LogList.Length > 0 Then
             If LogList.Length > 0 Then
@@ -2908,6 +2911,7 @@ Retry:
     End Sub
     End Sub
 
 
     Private ReadOnly LogListLock As New Object '防止日志乱码,只在调试模式下启用
     Private ReadOnly LogListLock As New Object '防止日志乱码,只在调试模式下启用
+    Private IsCriticalErrorTriggered As Boolean = False
     ''' <summary>
     ''' <summary>
     ''' 输出 Log。
     ''' 输出 Log。
     ''' </summary>
     ''' </summary>
@@ -2929,7 +2933,7 @@ Retry:
 #If DEBUG Then
 #If DEBUG Then
         Console.Write(AppendText)
         Console.Write(AppendText)
 #End If
 #End If
-        If IsProgramEnded OrElse Level = LogLevel.Normal Then Exit Sub
+        If IsProgramEnded OrElse Level = LogLevel.Normal Then Return
 
 
         '去除前缀
         '去除前缀
         Text = Text.RegexReplace("\[[^\]]+?\] ", "")
         Text = Text.RegexReplace("\[[^\]]+?\] ", "")
@@ -2956,20 +2960,17 @@ Retry:
                 Else
                 Else
                     MyMsgBox(Text & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", Title, IsWarn:=True)
                     MyMsgBox(Text & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", Title, IsWarn:=True)
                 End If
                 End If
-            Case LogLevel.Assert
-                Dim Time As Long = GetTimeTick()
+            Case LogLevel.Critical
+                If IsCriticalErrorTriggered Then
+                    FormMain.EndProgramForce(ProcessReturnValues.Exception)
+                    Return
+                End If
+                IsCriticalErrorTriggered = True
                 If CanFeedback(False) Then
                 If CanFeedback(False) Then
                     If MsgBox(Text & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", MsgBoxStyle.Critical + MsgBoxStyle.YesNo, Title) = MsgBoxResult.Yes Then Feedback(False, True)
                     If MsgBox(Text & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", MsgBoxStyle.Critical + MsgBoxStyle.YesNo, Title) = MsgBoxResult.Yes Then Feedback(False, True)
                 Else
                 Else
                     MsgBox(Text & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", MsgBoxStyle.Critical, Title)
                     MsgBox(Text & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", MsgBoxStyle.Critical, Title)
                 End If
                 End If
-                If GetTimeTick() - Time < 1500 Then
-                    '弹窗无法保留
-                    Log("[System] PCL 已崩溃:" & vbCrLf & Text)
-                    FormMain.EndProgramForce(ProcessReturnValues.Exception)
-                Else
-                    FormMain.EndProgramForce(ProcessReturnValues.Fail)
-                End If
         End Select
         End Select
 
 
     End Sub
     End Sub
@@ -2979,7 +2980,7 @@ Retry:
     ''' <param name="Desc">错误描述。会在处理时在末尾加入冒号。</param>
     ''' <param name="Desc">错误描述。会在处理时在末尾加入冒号。</param>
     Public Sub Log(Ex As Exception, Desc As String, Optional Level As LogLevel = LogLevel.Debug, Optional Title As String = "出现错误")
     Public Sub Log(Ex As Exception, Desc As String, Optional Level As LogLevel = LogLevel.Debug, Optional Title As String = "出现错误")
         On Error Resume Next
         On Error Resume Next
-        If TypeOf Ex Is ThreadInterruptedException Then Exit Sub
+        If TypeOf Ex Is ThreadInterruptedException Then Return
 
 
         '获取错误信息
         '获取错误信息
         Dim ExFull As String = Desc & ":" & GetExceptionDetail(Ex)
         Dim ExFull As String = Desc & ":" & GetExceptionDetail(Ex)
@@ -2996,7 +2997,7 @@ Retry:
 #If DEBUG Then
 #If DEBUG Then
         Console.Write(AppendText)
         Console.Write(AppendText)
 #End If
 #End If
-        If IsProgramEnded Then Exit Sub
+        If IsProgramEnded Then Return
 
 
         '输出提示
         '输出提示
         Select Case Level
         Select Case Level
@@ -3025,20 +3026,17 @@ Retry:
                 Else
                 Else
                     MyMsgBox(ExFull & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", Title, IsWarn:=True)
                     MyMsgBox(ExFull & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", Title, IsWarn:=True)
                 End If
                 End If
-            Case LogLevel.Assert
-                Dim Time As Long = GetTimeTick()
+            Case LogLevel.Critical
+                If IsCriticalErrorTriggered Then
+                    FormMain.EndProgramForce(ProcessReturnValues.Exception)
+                    Return
+                End If
+                IsCriticalErrorTriggered = True
                 If CanFeedback(False) Then
                 If CanFeedback(False) Then
                     If MsgBox(ExFull & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", MsgBoxStyle.Critical + MsgBoxStyle.YesNo, Title) = MsgBoxResult.Yes Then Feedback(False, True)
                     If MsgBox(ExFull & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", MsgBoxStyle.Critical + MsgBoxStyle.YesNo, Title) = MsgBoxResult.Yes Then Feedback(False, True)
                 Else
                 Else
                     MsgBox(ExFull & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", MsgBoxStyle.Critical, Title)
                     MsgBox(ExFull & vbCrLf & vbCrLf & "将 PCL 更新至最新版或许可以解决这个问题……", MsgBoxStyle.Critical, Title)
                 End If
                 End If
-                If GetTimeTick() - Time < 1500 Then
-                    '弹窗无法保留
-                    Log("[System] PCL 已崩溃:" & vbCrLf & ExFull)
-                    FormMain.EndProgramForce(ProcessReturnValues.Exception)
-                Else
-                    FormMain.EndProgramForce(ProcessReturnValues.Fail)
-                End If
         End Select
         End Select
 
 
     End Sub
     End Sub

+ 48 - 52
Plain Craft Launcher 2/Modules/Base/ModLoader.vb

@@ -85,7 +85,7 @@
                 Return _State
                 Return _State
             End Get
             End Get
             Set(value As LoadState)
             Set(value As LoadState)
-                If _State = value Then Exit Property
+                If _State = value Then Return
                 Dim OldState = _State
                 Dim OldState = _State
                 If value = LoadState.Finished AndAlso Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(100, 2000))
                 If value = LoadState.Finished AndAlso Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(100, 2000))
                 _State = value
                 _State = value
@@ -112,7 +112,7 @@
                 Return _LoadingState
                 Return _LoadingState
             End Get
             End Get
             Set(value As MyLoading.MyLoadingState)
             Set(value As MyLoading.MyLoadingState)
-                If _LoadingState = value Then Exit Property
+                If _LoadingState = value Then Return
                 Dim OldState = _LoadingState
                 Dim OldState = _LoadingState
                 _LoadingState = value
                 _LoadingState = value
                 RaiseEvent LoadingStateChanged(value, OldState)
                 RaiseEvent LoadingStateChanged(value, OldState)
@@ -154,7 +154,7 @@
                 End Select
                 End Select
             End Get
             End Get
             Set(value As Double)
             Set(value As Double)
-                If _Progress = value Then Exit Property
+                If _Progress = value Then Return
                 Dim OldValue = _Progress
                 Dim OldValue = _Progress
                 _Progress = value
                 _Progress = value
                 RaiseEvent ProgressChanged(value, OldValue)
                 RaiseEvent ProgressChanged(value, OldValue)
@@ -184,7 +184,7 @@
                 Thread.Sleep(10)
                 Thread.Sleep(10)
             Loop
             Loop
             If State = LoadState.Finished Then
             If State = LoadState.Finished Then
-                Exit Sub
+                Return
             ElseIf State = LoadState.Aborted Then
             ElseIf State = LoadState.Aborted Then
                 Throw New ThreadInterruptedException("加载器执行已中断。")
                 Throw New ThreadInterruptedException("加载器执行已中断。")
             ElseIf IsNothing([Error]) Then
             ElseIf IsNothing([Error]) Then
@@ -207,7 +207,7 @@
                 If Timeout < 0 Then Throw New TimeoutException(TimeoutMessage)
                 If Timeout < 0 Then Throw New TimeoutException(TimeoutMessage)
             Loop
             Loop
             If State = LoadState.Finished Then
             If State = LoadState.Finished Then
-                Exit Sub
+                Return
             ElseIf State = LoadState.Aborted Then
             ElseIf State = LoadState.Aborted Then
                 Throw New ThreadInterruptedException("加载器执行已中断。")
                 Throw New ThreadInterruptedException("加载器执行已中断。")
             ElseIf IsNothing([Error]) Then
             ElseIf IsNothing([Error]) Then
@@ -308,48 +308,49 @@
                     Progress = -1
                     Progress = -1
                 End SyncLock
                 End SyncLock
             Else
             Else
-                Exit Sub
+                Return
             End If
             End If
 
 
             LastRunningThread = New Thread(
             LastRunningThread = New Thread(
-                Sub()
-                    Try
-                        IsForceRestarting = IsForceRestart
-                        If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已{If(IsForceRestarting, "强制", "")}启动")
-                        LoadDelegate(Me)
-                        If IsAborted Then
-                            Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已中断但线程正常运行至结束,输出被弃用(最新线程:{If(LastRunningThread Is Nothing, -1, LastRunningThread.ManagedThreadId)})", LogLevel.Developer)
-                        Else
-                            RaisePreviewFinish()
-                            State = LoadState.Finished
-                            LastFinishedTime = GetTimeTick() '未中断,本次输出有效
-                        End If
-                    Catch ex As CancelledException
-                        If ModeDebug Then Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已触发取消中断,已完成 {Math.Round(Progress * 100)}%")
-                        If Not IsAborted Then State = LoadState.Aborted
-                    Catch ex As ThreadInterruptedException
-                        If ModeDebug Then Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已触发线程中断,已完成 {Math.Round(Progress * 100)}%")
-                        '如果线程是因为判断到 IsAborted 而提前中止,则代表已有新线程被重启,此时不应当改为 Aborted
-                        '如果线程是在没有 IsAborted 时手动引发了 ThreadInterruptedException,则代表没有重启线程,这通常代表用户手动取消,应当改为 Aborted
-                        If Not IsAborted Then State = LoadState.Aborted
-                    Catch ex As Exception
-                        If IsAborted Then Exit Sub
-                        Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 出错,已完成 {Math.Round(Progress * 100)}%", LogLevel.Developer)
-                        [Error] = ex
-                        State = LoadState.Failed
-                    End Try
-                End Sub) With {.Name = Name, .Priority = ThreadPriority}
+            Sub()
+                Try
+                    IsForceRestarting = IsForceRestart
+                    If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已{If(IsForceRestarting, "强制", "")}启动")
+                    LoadDelegate(Me)
+                    If IsAborted Then
+                        Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已中断但线程正常运行至结束,输出被弃用(最新线程:{If(LastRunningThread Is Nothing, -1, LastRunningThread.ManagedThreadId)})", LogLevel.Developer)
+                        Return
+                    End If
+                    If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已完成")
+                    RaisePreviewFinish()
+                    State = LoadState.Finished
+                    LastFinishedTime = GetTimeTick() '未中断,本次输出有效
+                Catch ex As CancelledException
+                    If ModeDebug Then Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已触发取消中断,已完成 {Math.Round(Progress * 100)}%")
+                    If Not IsAborted Then State = LoadState.Aborted
+                Catch ex As ThreadInterruptedException
+                    If ModeDebug Then Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已触发线程中断,已完成 {Math.Round(Progress * 100)}%")
+                    '如果线程是因为判断到 IsAborted 而提前中止,则代表已有新线程被重启,此时不应当改为 Aborted
+                    '如果线程是在没有 IsAborted 时手动引发了 ThreadInterruptedException,则代表没有重启线程,这通常代表用户手动取消,应当改为 Aborted
+                    If Not IsAborted Then State = LoadState.Aborted
+                Catch ex As Exception
+                    If IsAborted Then Return
+                    Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 出错,已完成 {Math.Round(Progress * 100)}%", LogLevel.Developer)
+                    [Error] = ex
+                    State = LoadState.Failed
+                End Try
+            End Sub) With {.Name = Name, .Priority = ThreadPriority}
             LastRunningThread.Start() '不能使用 RunInNewThread,否则在函数返回前线程就会运行完,导致误判 IsAborted
             LastRunningThread.Start() '不能使用 RunInNewThread,否则在函数返回前线程就会运行完,导致误判 IsAborted
         End Sub
         End Sub
         Public Overrides Sub Abort()
         Public Overrides Sub Abort()
-            If State <> LoadState.Loading Then Exit Sub
+            If State <> LoadState.Loading Then Return
             SyncLock LockState
             SyncLock LockState
                 State = LoadState.Aborted
                 State = LoadState.Aborted
             End SyncLock
             End SyncLock
             TriggerThreadAbort()
             TriggerThreadAbort()
         End Sub
         End Sub
         Private Sub TriggerThreadAbort()
         Private Sub TriggerThreadAbort()
-            If LastRunningThread Is Nothing Then Exit Sub
+            If LastRunningThread Is Nothing Then Return
             If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({LastRunningThread.ManagedThreadId}) 已中断")
             If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({LastRunningThread.ManagedThreadId}) 已中断")
             If LastRunningThread.IsAlive Then LastRunningThread.Interrupt()
             If LastRunningThread.IsAlive Then LastRunningThread.Interrupt()
             LastRunningThread = Nothing
             LastRunningThread = Nothing
@@ -419,7 +420,7 @@
             '改变状态
             '改变状态
             SyncLock LockState
             SyncLock LockState
                 If State = LoadState.Loading Then
                 If State = LoadState.Loading Then
-                    Exit Sub
+                    Return
                 Else
                 Else
                     State = LoadState.Loading
                     State = LoadState.Loading
                 End If
                 End If
@@ -439,7 +440,7 @@
                 If State = LoadState.Loading OrElse State = LoadState.Waiting Then
                 If State = LoadState.Loading OrElse State = LoadState.Waiting Then
                     State = LoadState.Aborted
                     State = LoadState.Aborted
                 Else
                 Else
-                    Exit Sub
+                    Return
                 End If
                 End If
             End SyncLock
             End SyncLock
             RunInThread(
             RunInThread(
@@ -470,7 +471,7 @@
                 Case Else
                 Case Else
                     '完蛋,出错了
                     '完蛋,出错了
                     SyncLock LockState
                     SyncLock LockState
-                        If State >= LoadState.Finished Then Exit Sub
+                        If State >= LoadState.Finished Then Return
                         [Error] = New Exception(Loader.Name & "失败", Loader.Error)
                         [Error] = New Exception(Loader.Name & "失败", Loader.Error)
                         State = Loader.State
                         State = Loader.State
                     End SyncLock
                     End SyncLock
@@ -478,14 +479,14 @@
                         Loader.Abort()
                         Loader.Abort()
                     Next
                     Next
                     FrmMain.BtnExtraDownload.ShowRefresh()
                     FrmMain.BtnExtraDownload.ShowRefresh()
-                    Exit Sub
+                    Return
             End Select
             End Select
         End Sub
         End Sub
         ''' <summary>
         ''' <summary>
         ''' 触发一次更新,以启动新加载器或完成。
         ''' 触发一次更新,以启动新加载器或完成。
         ''' </summary>
         ''' </summary>
         Private Sub Update()
         Private Sub Update()
-            If State = LoadState.Finished OrElse State = LoadState.Failed OrElse State = LoadState.Aborted Then Exit Sub
+            If State = LoadState.Finished OrElse State = LoadState.Failed OrElse State = LoadState.Aborted Then Return
             Dim IsFinished As Boolean = True
             Dim IsFinished As Boolean = True
             Dim Blocked As Boolean = False
             Dim Blocked As Boolean = False
             Dim Input As Object = Me.Input
             Dim Input As Object = Me.Input
@@ -584,16 +585,11 @@ Restart:
         Try
         Try
             Dim NewState As Shell.TaskbarItemProgressState
             Dim NewState As Shell.TaskbarItemProgressState
             Dim NewProgress As Double = LoaderTaskbarProgressGet()
             Dim NewProgress As Double = LoaderTaskbarProgressGet()
-            '检查任务是否完成,若完成则移除
-            '外显任务是否已经全部完成
-            Dim IsAllDownloadTaskCompleted As Boolean = True
-            For Each Loader In LoaderTaskbar.ToList()
-                If Loader.State = LoadState.Loading Then IsAllDownloadTaskCompleted = False
-            Next
-            '若单个任务已中止或全部任务已完成,则刷新并移除
-            For Each Task In LoaderTaskbar.ToList()
-                If IsAllDownloadTaskCompleted OrElse Task.State = LoadState.Aborted OrElse Task.State = LoadState.Waiting Then
-                    If FrmSpeedLeft IsNot Nothing Then FrmSpeedLeft.TaskRefresh(Task)
+            '若单个任务已中止,或全部任务已完成,则刷新并移除
+            For Each Task In LoaderTaskbar
+                If LoaderTaskbar.All(Function(l) l.State <> LoadState.Loading) OrElse
+                   (Task.State = LoadState.Waiting OrElse Task.State = LoadState.Aborted) Then
+                    FrmSpeedLeft?.TaskRefresh(Task)
                     LoaderTaskbar.Remove(Task)
                     LoaderTaskbar.Remove(Task)
                     Log($"[Taskbar] {Task.Name} 已移出任务列表")
                     Log($"[Taskbar] {Task.Name} 已移出任务列表")
                 End If
                 End If
@@ -625,8 +621,8 @@ Restart:
     End Sub
     End Sub
     Public Function LoaderTaskbarProgressGet() As Double
     Public Function LoaderTaskbarProgressGet() As Double
         Try
         Try
-            If Not LoaderTaskbar.Where(Function(l) l.Show).Any Then Return 1
-            Return MathClamp(LoaderTaskbar.Where(Function(l) l.Show).Select(Function(l) l.Progress).Average(), 0, 1)
+            If Not LoaderTaskbar.Any Then Return 1
+            Return MathClamp(LoaderTaskbar.Select(Function(l) l.Progress).Average(), 0, 1)
         Catch ex As Exception
         Catch ex As Exception
             Log(ex, "获取任务栏进度出错", LogLevel.Feedback)
             Log(ex, "获取任务栏进度出错", LogLevel.Feedback)
             Return 0.5
             Return 0.5

+ 19 - 19
Plain Craft Launcher 2/Modules/Base/ModNet.vb

@@ -1345,7 +1345,7 @@ Wrong:
                 If State < NetState.Merge Then
                 If State < NetState.Merge Then
                     State = NetState.Merge
                     State = NetState.Merge
                 Else
                 Else
-                    Exit Sub
+                    Return
                 End If
                 End If
             End SyncLock
             End SyncLock
             Dim RetryCount As Integer = 0
             Dim RetryCount As Integer = 0
@@ -1355,8 +1355,7 @@ Retry:
                 SyncLock LockChain
                 SyncLock LockChain
                     '创建文件夹
                     '创建文件夹
                     If File.Exists(LocalPath) Then File.Delete(LocalPath)
                     If File.Exists(LocalPath) Then File.Delete(LocalPath)
-                    Dim Info As New FileInfo(LocalPath)
-                    Info.Directory.Create()
+                    Directory.CreateDirectory(GetPathFromFullPath(LocalPath))
                     '合并文件
                     '合并文件
                     If IsNoSplit Then
                     If IsNoSplit Then
                         '仅有一个线程,从缓存中输出
                         '仅有一个线程,从缓存中输出
@@ -1435,7 +1434,7 @@ Retry:
         ''' </summary>
         ''' </summary>
         Private Sub Fail(Optional RaiseEx As Exception = Nothing)
         Private Sub Fail(Optional RaiseEx As Exception = Nothing)
             SyncLock LockState
             SyncLock LockState
-                If State >= NetState.Finish Then Exit Sub
+                If State >= NetState.Finish Then Return
                 If RaiseEx IsNot Nothing Then Ex.Add(RaiseEx)
                 If RaiseEx IsNot Nothing Then Ex.Add(RaiseEx)
                 '凉凉
                 '凉凉
                 State = NetState.Error
                 State = NetState.Error
@@ -1451,10 +1450,10 @@ Retry:
         Public Sub Abort(CausedByTask As LoaderDownload)
         Public Sub Abort(CausedByTask As LoaderDownload)
             '从特定任务中移除,如果它还属于其他任务,则继续下载
             '从特定任务中移除,如果它还属于其他任务,则继续下载
             Tasks.Remove(CausedByTask)
             Tasks.Remove(CausedByTask)
-            If Tasks.Any Then Exit Sub
+            If Tasks.Any Then Return
             '确认中断
             '确认中断
             SyncLock LockState
             SyncLock LockState
-                If State >= NetState.Finish Then Exit Sub
+                If State >= NetState.Finish Then Return
                 State = NetState.Error
                 State = NetState.Error
             End SyncLock
             End SyncLock
             InterruptAndDelete()
             InterruptAndDelete()
@@ -1474,7 +1473,7 @@ Retry:
         ''' </summary>
         ''' </summary>
         Public Sub Finish(Optional PrintLog As Boolean = True)
         Public Sub Finish(Optional PrintLog As Boolean = True)
             SyncLock LockState
             SyncLock LockState
-                If State >= NetState.Finish Then Exit Sub
+                If State >= NetState.Finish Then Return
                 State = NetState.Finish
                 State = NetState.Finish
             End SyncLock
             End SyncLock
             SyncLock NetManager.LockRemain
             SyncLock NetManager.LockRemain
@@ -1601,7 +1600,7 @@ NextElement:
                     '输入检测
                     '输入检测
                     If Not Files.Any() Then
                     If Not Files.Any() Then
                         OnFinish()
                         OnFinish()
-                        Exit Sub
+                        Return
                     End If
                     End If
                     For Each File As NetFile In Files
                     For Each File As NetFile In Files
                         If File Is Nothing Then Throw New ArgumentException("存在空文件请求!")
                         If File Is Nothing Then Throw New ArgumentException("存在空文件请求!")
@@ -1658,13 +1657,14 @@ NextElement:
         End Sub
         End Sub
         Private Sub StartCopy(Files As List(Of NetFile), FolderList As List(Of String))
         Private Sub StartCopy(Files As List(Of NetFile), FolderList As List(Of String))
             Try
             Try
-                If ModeDebug Then Log("[Download] 检查线程分配文件数:" & Files.Count & ",线程名:" & Thread.CurrentThread.Name)
+                If ModeDebug Then Log($"[Download] 检查线程分配文件数:{Files.Count},线程名:{Thread.CurrentThread.Name}")
                 '试图从已存在的 Minecraft 文件夹中寻找目标文件
                 '试图从已存在的 Minecraft 文件夹中寻找目标文件
                 Dim ExistFiles As New List(Of KeyValuePair(Of NetFile, String)) '{NetFile, Target As String}
                 Dim ExistFiles As New List(Of KeyValuePair(Of NetFile, String)) '{NetFile, Target As String}
                 For Each File As NetFile In Files
                 For Each File As NetFile In Files
                     Dim ExistFilePath As String = Nothing
                     Dim ExistFilePath As String = Nothing
                     '判断是否有已存在的文件
                     '判断是否有已存在的文件
-                    If File.Check IsNot Nothing AndAlso McFolderList IsNot Nothing AndAlso PathMcFolder IsNot Nothing AndAlso File.Check.CanUseExistsFile AndAlso File.LocalPath.StartsWithF(PathMcFolder) Then
+                    If File.Check IsNot Nothing AndAlso McFolderList IsNot Nothing AndAlso PathMcFolder IsNot Nothing AndAlso
+                        File.Check.CanUseExistsFile AndAlso File.LocalPath.StartsWithF(PathMcFolder) Then
                         Dim Relative = File.LocalPath.Replace(PathMcFolder, "")
                         Dim Relative = File.LocalPath.Replace(PathMcFolder, "")
                         For Each Folder In FolderList
                         For Each Folder In FolderList
                             Dim Target = Folder & Relative
                             Dim Target = Folder & Relative
@@ -1690,7 +1690,7 @@ NextElement:
                 For Each FileToken In ExistFiles
                 For Each FileToken In ExistFiles
                     Dim File As NetFile = FileToken.Key
                     Dim File As NetFile = FileToken.Key
                     SyncLock LockState
                     SyncLock LockState
-                        If File.State > NetState.WaitForCopy Then Exit Sub
+                        If File.State > NetState.WaitForCopy Then Return
                     End SyncLock
                     End SyncLock
                     Dim LocalPath As String = FileToken.Value
                     Dim LocalPath As String = FileToken.Value
                     Dim RetryCount As Integer = 0
                     Dim RetryCount As Integer = 0
@@ -1701,7 +1701,7 @@ Retry:
                         File.Finish(False)
                         File.Finish(False)
                     Catch ex As Exception
                     Catch ex As Exception
                         RetryCount += 1
                         RetryCount += 1
-                        Log(ex, String.Format("复制已存在的文件失败,重试第 {2} 次({0} -> {1})", LocalPath, File.LocalPath, RetryCount))
+                        Log(ex, $"复制已存在的文件失败,重试第 {RetryCount} 次({LocalPath} -> {File.LocalPath})")
                         If RetryCount < 3 Then
                         If RetryCount < 3 Then
                             Thread.Sleep(200)
                             Thread.Sleep(200)
                             GoTo Retry
                             GoTo Retry
@@ -1719,14 +1719,14 @@ Retry:
             '要求全部文件完成
             '要求全部文件完成
             SyncLock FileRemainLock
             SyncLock FileRemainLock
                 FileRemain -= 1
                 FileRemain -= 1
-                If FileRemain > 0 Then Exit Sub
+                If FileRemain > 0 Then Return
             End SyncLock
             End SyncLock
             OnFinish()
             OnFinish()
         End Sub
         End Sub
         Public Sub OnFinish()
         Public Sub OnFinish()
             RaisePreviewFinish()
             RaisePreviewFinish()
             SyncLock LockState
             SyncLock LockState
-                If State > LoadState.Loading Then Exit Sub
+                If State > LoadState.Loading Then Return
                 State = LoadState.Finished
                 State = LoadState.Finished
             End SyncLock
             End SyncLock
         End Sub
         End Sub
@@ -1739,7 +1739,7 @@ Retry:
         End Sub
         End Sub
         Public Sub OnFail(ExList As List(Of Exception))
         Public Sub OnFail(ExList As List(Of Exception))
             SyncLock LockState
             SyncLock LockState
-                If State > LoadState.Loading Then Exit Sub
+                If State > LoadState.Loading Then Return
                 If ExList Is Nothing OrElse Not ExList.Any() Then ExList = New List(Of Exception) From {New Exception("未知错误!")}
                 If ExList Is Nothing OrElse Not ExList.Any() Then ExList = New List(Of Exception) From {New Exception("未知错误!")}
                 '寻找第一个不是 404 的下载源
                 '寻找第一个不是 404 的下载源
                 Dim UsefulExs = ExList.Where(Function(e) Not e.Message.Contains("(404)")).ToList
                 Dim UsefulExs = ExList.Where(Function(e) Not e.Message.Contains("(404)")).ToList
@@ -1768,7 +1768,7 @@ Retry:
         End Sub
         End Sub
         Public Overrides Sub Abort()
         Public Overrides Sub Abort()
             SyncLock LockState
             SyncLock LockState
-                If State >= LoadState.Finished Then Exit Sub
+                If State >= LoadState.Finished Then Return
                 State = LoadState.Aborted
                 State = LoadState.Aborted
             End SyncLock
             End SyncLock
             Log("[Download] " & Name & " 已取消!")
             Log("[Download] " & Name & " 已取消!")
@@ -1885,7 +1885,7 @@ Retry:
         ''' 启动监控线程,用于新增下载线程。
         ''' 启动监控线程,用于新增下载线程。
         ''' </summary>
         ''' </summary>
         Private Sub StartManager()
         Private Sub StartManager()
-            If IsManagerStarted Then Exit Sub
+            If IsManagerStarted Then Return
             IsManagerStarted = True
             IsManagerStarted = True
             Dim ThreadStarter =
             Dim ThreadStarter =
             Sub(Id As Integer) '0 或 1
             Sub(Id As Integer) '0 或 1
@@ -1936,7 +1936,7 @@ Retry:
                         Next
                         Next
                     End While
                     End While
                 Catch ex As Exception
                 Catch ex As Exception
-                    Log(ex, $"下载管理启动线程 {Id} 出错", LogLevel.Assert)
+                    Log(ex, $"下载管理启动线程 {Id} 出错", LogLevel.Critical)
                 End Try
                 End Try
             End Sub
             End Sub
             RunInNewThread(Sub() ThreadStarter(0), "NetManager ThreadStarter 0")
             RunInNewThread(Sub() ThreadStarter(0), "NetManager ThreadStarter 0")
@@ -1960,7 +1960,7 @@ Retry:
                         Loop
                         Loop
                     End While
                     End While
                 Catch ex As Exception
                 Catch ex As Exception
-                    Log(ex, "下载管理刷新线程出错", LogLevel.Assert)
+                    Log(ex, "下载管理刷新线程出错", LogLevel.Critical)
                 End Try
                 End Try
             End Sub, "NetManager StatRefresher")
             End Sub, "NetManager StatRefresher")
         End Sub
         End Sub

+ 57 - 42
Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb

@@ -491,6 +491,9 @@
                             Case "path-tracing" : Tags.Add("路径追踪")
                             Case "path-tracing" : Tags.Add("路径追踪")
                             Case "pbr" : Tags.Add("PBR")
                             Case "pbr" : Tags.Add("PBR")
                             Case "reflections" : Tags.Add("反射")
                             Case "reflections" : Tags.Add("反射")
+
+                            Case "iris" : Tags.Add("Iris")
+                            Case "optifine" : Tags.Add("OptiFine")
                             Case "vanilla" : Tags.Add("原版可用")
                             Case "vanilla" : Tags.Add("原版可用")
                         End Select
                         End Select
                     Next
                     Next
@@ -947,38 +950,39 @@ NoSubtitle:
     ''' 根据搜索请求获取一系列的工程列表。需要基于加载器运行。
     ''' 根据搜索请求获取一系列的工程列表。需要基于加载器运行。
     ''' </summary>
     ''' </summary>
     Public Sub CompProjectsGet(Task As LoaderTask(Of CompProjectRequest, Integer))
     Public Sub CompProjectsGet(Task As LoaderTask(Of CompProjectRequest, Integer))
-        Dim Storage = Task.Input.Storage '避免多线程问题
-
-        If Task.Input.Storage.Results.Count >= Task.Input.TargetResultCount Then
-            Log($"[Comp] 已有 {Task.Input.Storage.Results.Count} 个结果,多于所需的 {Task.Input.TargetResultCount} 个结果,结束处理")
-            Exit Sub
-        ElseIf Not Task.Input.CanContinue Then
-            If Not Task.Input.Storage.Results.Any() Then
+        Dim Request As CompProjectRequest = Task.Input
+        Dim Storage = Request.Storage '避免多线程问题
+
+        If Request.Storage.Results.Count >= Request.TargetResultCount Then
+            Log($"[Comp] 已有 {Request.Storage.Results.Count} 个结果,多于所需的 {Request.TargetResultCount} 个结果,结束处理")
+            Return
+        ElseIf Not Request.CanContinue Then
+            If Not Request.Storage.Results.Any() Then
                 Throw New Exception("没有符合条件的结果")
                 Throw New Exception("没有符合条件的结果")
             Else
             Else
-                Log($"[Comp] 已有 {Task.Input.Storage.Results.Count} 个结果,少于所需的 {Task.Input.TargetResultCount} 个结果,但无法继续获取,结束处理")
-                Exit Sub
+                Log($"[Comp] 已有 {Request.Storage.Results.Count} 个结果,少于所需的 {Request.TargetResultCount} 个结果,但无法继续获取,结束处理")
+                Return
             End If
             End If
         End If
         End If
 
 
 #Region "拒绝 1.13- Quilt(这个版本根本没有 Quilt)"
 #Region "拒绝 1.13- Quilt(这个版本根本没有 Quilt)"
 
 
-        If Task.Input.ModLoader = CompModLoaderType.Quilt AndAlso VersionSortInteger(If(Task.Input.GameVersion, "1.15"), "1.14") = -1 Then
-            Throw New Exception("Quilt 不支持 Minecraft " & Task.Input.GameVersion)
+        If Request.ModLoader = CompModLoaderType.Quilt AndAlso VersionSortInteger(If(Request.GameVersion, "1.15"), "1.14") = -1 Then
+            Throw New Exception("Quilt 不支持 Minecraft " & Request.GameVersion)
         End If
         End If
 
 
 #End Region
 #End Region
 
 
 #Region "处理搜索文本,赋值回 Task.Input.SearchText"
 #Region "处理搜索文本,赋值回 Task.Input.SearchText"
 
 
-        Dim RawFilter As String = If(Task.Input.SearchText, "").Trim
-        Task.Input.SearchText = RawFilter
+        Dim RawFilter As String = If(Request.SearchText, "").Trim
+        Request.SearchText = RawFilter
         RawFilter = RawFilter.ToLower
         RawFilter = RawFilter.ToLower
         Log("[Comp] 工程列表搜索原始文本:" & RawFilter)
         Log("[Comp] 工程列表搜索原始文本:" & RawFilter)
 
 
         '中文请求关键字处理
         '中文请求关键字处理
         Dim IsChineseSearch As Boolean = RegexCheck(RawFilter, "[\u4e00-\u9fbb]") AndAlso Not String.IsNullOrEmpty(RawFilter)
         Dim IsChineseSearch As Boolean = RegexCheck(RawFilter, "[\u4e00-\u9fbb]") AndAlso Not String.IsNullOrEmpty(RawFilter)
-        If IsChineseSearch AndAlso (Task.Input.Type = CompType.Mod OrElse Task.Input.Type = CompType.DataPack) Then
+        If IsChineseSearch AndAlso (Request.Type = CompType.Mod OrElse Request.Type = CompType.DataPack) Then
             '构造搜索请求
             '构造搜索请求
             Dim SearchEntries As New List(Of SearchEntry(Of CompDatabaseEntry))
             Dim SearchEntries As New List(Of SearchEntry(Of CompDatabaseEntry))
             For Each Entry In CompDatabase
             For Each Entry In CompDatabase
@@ -991,7 +995,7 @@ NoSubtitle:
                 })
                 })
             Next
             Next
             '获取搜索结果
             '获取搜索结果
-            Dim SearchResults = Search(SearchEntries, Task.Input.SearchText, 3)
+            Dim SearchResults = Search(SearchEntries, Request.SearchText, 3)
             If Not SearchResults.Any() Then Throw New Exception("无搜索结果,请尝试搜索英文名称")
             If Not SearchResults.Any() Then Throw New Exception("无搜索结果,请尝试搜索英文名称")
             Dim SearchResult As String = ""
             Dim SearchResult As String = ""
             For i = 0 To Math.Min(4, SearchResults.Count - 1) '就算全是准确的,也最多只要 5 个
             For i = 0 To Math.Min(4, SearchResults.Count - 1) '就算全是准确的,也最多只要 5 个
@@ -1009,14 +1013,14 @@ NoSubtitle:
                 If SearchResult.Split(" ").Count > 3 AndAlso {"ftb"}.Contains(Word.ToLower) Then Continue For
                 If SearchResult.Split(" ").Count > 3 AndAlso {"ftb"}.Contains(Word.ToLower) Then Continue For
                 RealFilter += Word.TrimStart("{[(").TrimEnd("}])") & " "
                 RealFilter += Word.TrimStart("{[(").TrimEnd("}])") & " "
             Next
             Next
-            Task.Input.SearchText = RealFilter
+            Request.SearchText = RealFilter
             Log("[Comp] 中文搜索最终关键词:" & RealFilter, LogLevel.Developer)
             Log("[Comp] 中文搜索最终关键词:" & RealFilter, LogLevel.Developer)
         End If
         End If
 
 
         '驼峰英文请求关键字处理
         '驼峰英文请求关键字处理
-        Dim SpacedKeywords = Task.Input.SearchText.RegexReplace("([A-Z]+|[a-z]+?)(?=[A-Z]+[a-z]+[a-z ]*)", "$& ")
-        Dim ConnectedKeywords = Task.Input.SearchText.Replace(" ", "")
-        Dim AllPossibleKeywords = (SpacedKeywords & " " & If(IsChineseSearch, Task.Input.SearchText, ConnectedKeywords & " " & RawFilter)).ToLower
+        Dim SpacedKeywords = Request.SearchText.RegexReplace("([A-Z]+|[a-z]+?)(?=[A-Z]+[a-z]+[a-z ]*)", "$& ")
+        Dim ConnectedKeywords = Request.SearchText.Replace(" ", "")
+        Dim AllPossibleKeywords = (SpacedKeywords & " " & If(IsChineseSearch, Request.SearchText, ConnectedKeywords & " " & RawFilter)).ToLower
 
 
         '最终处理关键字:分割、去重
         '最终处理关键字:分割、去重
         Dim RightKeywords As New List(Of String)
         Dim RightKeywords As New List(Of String)
@@ -1030,15 +1034,15 @@ NoSubtitle:
             RightKeywords.Add(Keyword)
             RightKeywords.Add(Keyword)
         Next
         Next
         If RawFilter.Length > 0 AndAlso Not RightKeywords.Any() Then
         If RawFilter.Length > 0 AndAlso Not RightKeywords.Any() Then
-            Task.Input.SearchText = RawFilter '全都被过滤掉了
+            Request.SearchText = RawFilter '全都被过滤掉了
         Else
         Else
-            Task.Input.SearchText = Join(RightKeywords.Distinct.ToList, " ").ToLower
+            Request.SearchText = Join(RightKeywords.Distinct.ToList, " ").ToLower
         End If
         End If
 
 
         '例外项:OptiForge、OptiFabric(拆词后因为包含 Forge/Fabric 导致无法搜到实际的 Mod)
         '例外项:OptiForge、OptiFabric(拆词后因为包含 Forge/Fabric 导致无法搜到实际的 Mod)
-        If RawFilter.Replace(" ", "").ContainsF("optiforge", True) Then Task.Input.SearchText = "optiforge"
-        If RawFilter.Replace(" ", "").ContainsF("optifabric", True) Then Task.Input.SearchText = "optifabric"
-        Log("[Comp] 工程列表搜索最终文本:" & Task.Input.SearchText, LogLevel.Debug)
+        If RawFilter.Replace(" ", "").ContainsF("optiforge", True) Then Request.SearchText = "optiforge"
+        If RawFilter.Replace(" ", "").ContainsF("optifabric", True) Then Request.SearchText = "optifabric"
+        Log("[Comp] 工程列表搜索最终文本:" & Request.SearchText, LogLevel.Debug)
         Task.Progress = 0.1
         Task.Progress = 0.1
 
 
 #End Region
 #End Region
@@ -1054,10 +1058,17 @@ Retry:
         Dim ModrinthThread As Thread = Nothing
         Dim ModrinthThread As Thread = Nothing
         Dim ResultsLock As New Object
         Dim ResultsLock As New Object
 
 
+        '在 1.14-,部分老 Mod 没有设置支持的加载器,因此添加 Forge 筛选就会出现遗漏
+        '所以,在发起请求时不筛选加载器,然后在返回的结果中自行筛除不是 Forge 的 Mod
+        Dim IsOldForgeRequest = Request.ModLoader = CompModLoaderType.Forge AndAlso Request.GameVersion?.Contains(".") AndAlso Val(Request.GameVersion.Split(".")(1)) < 14
+        If IsOldForgeRequest Then Request.ModLoader = CompModLoaderType.Any
+        Dim CurseForgeUrl As String = Request.GetCurseForgeAddress()
+        Dim ModrinthUrl As String = Request.GetModrinthAddress()
+        If IsOldForgeRequest Then Request.ModLoader = CompModLoaderType.Forge '设置回去
+
         Try
         Try
 
 
             '启动 CurseForge 线程
             '启动 CurseForge 线程
-            Dim CurseForgeUrl As String = Task.Input.GetCurseForgeAddress()
             Dim CurseForgeFailed As Boolean = False
             Dim CurseForgeFailed As Boolean = False
             If CurseForgeUrl IsNot Nothing Then
             If CurseForgeUrl IsNot Nothing Then
                 CurseForgeThread = RunInNewThread(
                 CurseForgeThread = RunInNewThread(
@@ -1070,7 +1081,7 @@ Retry:
                         Dim ProjectList As New List(Of CompProject)
                         Dim ProjectList As New List(Of CompProject)
                         For Each JsonEntry As JObject In RequestResult("data")
                         For Each JsonEntry As JObject In RequestResult("data")
                             Dim Project As New CompProject(JsonEntry)
                             Dim Project As New CompProject(JsonEntry)
-                            If Task.Input.Type = CompType.ResourcePack AndAlso Project.Tags.Contains("数据包") Then Continue For 'CurseForge 将一些数据包分类成了资源包
+                            If Request.Type = CompType.ResourcePack AndAlso Project.Tags.Contains("数据包") Then Continue For 'CurseForge 将一些数据包分类成了资源包
                             ProjectList.Add(Project)
                             ProjectList.Add(Project)
                         Next
                         Next
                         '更新结果
                         '更新结果
@@ -1090,7 +1101,6 @@ Retry:
             End If
             End If
 
 
             '启动 Modrinth 线程
             '启动 Modrinth 线程
-            Dim ModrinthUrl As String = Task.Input.GetModrinthAddress()
             Dim ModrinthFailed As Boolean = False
             Dim ModrinthFailed As Boolean = False
             If ModrinthUrl IsNot Nothing Then
             If ModrinthUrl IsNot Nothing Then
                 ModrinthThread = RunInNewThread(
                 ModrinthThread = RunInNewThread(
@@ -1123,9 +1133,9 @@ Retry:
 
 
             '等待线程结束
             '等待线程结束
             If CurseForgeThread IsNot Nothing Then CurseForgeThread.Join()
             If CurseForgeThread IsNot Nothing Then CurseForgeThread.Join()
-            If Task.IsAborted Then Exit Sub '会自动触发 Finally
+            If Task.IsAborted Then Return '会自动触发 Finally
             If ModrinthThread IsNot Nothing Then ModrinthThread.Join()
             If ModrinthThread IsNot Nothing Then ModrinthThread.Join()
-            If Task.IsAborted Then Exit Sub
+            If Task.IsAborted Then Return
 
 
             '确保存在结果
             '确保存在结果
             Storage.ErrorMessage = Nothing
             Storage.ErrorMessage = Nothing
@@ -1133,11 +1143,11 @@ Retry:
                 If [Error] IsNot Nothing Then
                 If [Error] IsNot Nothing Then
                     Throw [Error]
                     Throw [Error]
                 Else
                 Else
-                    If IsChineseSearch AndAlso Not (Task.Input.Type = CompType.Mod OrElse Task.Input.Type = CompType.DataPack) Then
+                    If IsChineseSearch AndAlso Not (Request.Type = CompType.Mod OrElse Request.Type = CompType.DataPack) Then
                         Throw New Exception("没有搜索结果,请尝试使用英文搜索")
                         Throw New Exception("没有搜索结果,请尝试使用英文搜索")
-                    ElseIf Task.Input.Source = CompSourceType.CurseForge AndAlso Task.Input.Tag.StartsWithF("/") Then
+                    ElseIf Request.Source = CompSourceType.CurseForge AndAlso Request.Tag.StartsWithF("/") Then
                         Throw New Exception("CurseForge 不兼容所选的类型")
                         Throw New Exception("CurseForge 不兼容所选的类型")
-                    ElseIf Task.Input.Source = CompSourceType.Modrinth AndAlso Task.Input.Tag.EndsWithF("/") Then
+                    ElseIf Request.Source = CompSourceType.Modrinth AndAlso Request.Tag.EndsWithF("/") Then
                         Throw New Exception("Modrinth 不兼容所选的类型")
                         Throw New Exception("Modrinth 不兼容所选的类型")
                     Else
                     Else
                         Throw New Exception("没有搜索结果")
                         Throw New Exception("没有搜索结果")
@@ -1146,17 +1156,22 @@ Retry:
             ElseIf [Error] IsNot Nothing Then
             ElseIf [Error] IsNot Nothing Then
                 '有结果但是有错误
                 '有结果但是有错误
                 If CurseForgeFailed Then
                 If CurseForgeFailed Then
-                    Storage.ErrorMessage = $"无法连接到 CurseForge,所以目前仅显示了来自 Modrinth 的内容,结果可能不全。{vbCrLf}请尝试使用 VPN 或加速器以改善网络。"
+                    Storage.ErrorMessage = $"无法连接到 CurseForge,所以目前仅显示了来自 Modrinth 的内容,搜索结果可能不全。{vbCrLf}请稍后重试,或使用 VPN 以改善网络环境。"
                 Else
                 Else
-                    Storage.ErrorMessage = $"无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,结果可能不全。{vbCrLf}请尝试使用 VPN 或加速器以改善网络。"
+                    Storage.ErrorMessage = $"无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,搜索结果可能不全。{vbCrLf}请稍后重试,或使用 VPN 以改善网络环境。"
                 End If
                 End If
             End If
             End If
 
 
         Finally
         Finally
-            If CurseForgeThread IsNot Nothing Then CurseForgeThread.Interrupt()
-            If ModrinthThread IsNot Nothing Then ModrinthThread.Interrupt()
+            CurseForgeThread?.Interrupt()
+            ModrinthThread?.Interrupt()
         End Try
         End Try
 
 
+        '筛除不是 Forge 的 Mod
+        If IsOldForgeRequest Then
+            RawResults = RawResults.Where(Function(p) Not p.ModLoaders.Any() OrElse p.ModLoaders.Contains(CompModLoaderType.Forge)).ToList
+        End If
+
 #End Region
 #End Region
 
 
 #Region "提取非重复项,存储于 RealResults"
 #Region "提取非重复项,存储于 RealResults"
@@ -1177,9 +1192,9 @@ Retry:
 
 
 #Region "检查结果数量,如果不足且可继续,会继续加载下一页"
 #Region "检查结果数量,如果不足且可继续,会继续加载下一页"
 
 
-        If RealResults.Count + Storage.Results.Count < Task.Input.TargetResultCount Then
-            Log($"[Comp] 总结果数需求最少 {Task.Input.TargetResultCount} 个,仅获得了 {RealResults.Count + Storage.Results.Count} 个")
-            If Task.Input.CanContinue AndAlso [Error] Is Nothing Then '如果有下载源失败则不再重试,这时候重试可能导致无限循环
+        If RealResults.Count + Storage.Results.Count < Request.TargetResultCount Then
+            Log($"[Comp] 总结果数需求最少 {Request.TargetResultCount} 个,仅获得了 {RealResults.Count + Storage.Results.Count} 个")
+            If Request.CanContinue AndAlso [Error] Is Nothing Then '如果有下载源失败则不再重试,这时候重试可能导致无限循环
                 Log("[Comp] 将继续尝试加载下一页")
                 Log("[Comp] 将继续尝试加载下一页")
                 GoTo Retry
                 GoTo Retry
             Else
             Else
@@ -1194,7 +1209,7 @@ Retry:
         Dim Scores As New Dictionary(Of CompProject, Double) '排序分
         Dim Scores As New Dictionary(Of CompProject, Double) '排序分
         Dim GetDownloadCountMult =
         Dim GetDownloadCountMult =
         Function(Project As CompProject) As Double
         Function(Project As CompProject) As Double
-            Select Case Task.Input.Type
+            Select Case Request.Type
                 Case CompType.Mod, CompType.ModPack
                 Case CompType.Mod, CompType.ModPack
                     Return If(Project.FromCurseForge, 1, 7)
                     Return If(Project.FromCurseForge, 1, 7)
                 Case CompType.DataPack
                 Case CompType.DataPack
@@ -1205,7 +1220,7 @@ Retry:
                     Return 1
                     Return 1
             End Select
             End Select
         End Function
         End Function
-        If String.IsNullOrEmpty(Task.Input.SearchText) Then
+        If String.IsNullOrEmpty(Request.SearchText) Then
             '如果没有搜索文本,按下载量将结果排序
             '如果没有搜索文本,按下载量将结果排序
             For Each Result As CompProject In RealResults
             For Each Result As CompProject In RealResults
                 Scores.Add(Result, Result.DownloadCount * GetDownloadCountMult(Result))
                 Scores.Add(Result, Result.DownloadCount * GetDownloadCountMult(Result))
@@ -1638,7 +1653,7 @@ Retry:
         '如果为整合包就不会有 Dependencies 信息,所以不用管
         '如果为整合包就不会有 Dependencies 信息,所以不用管
         Dim Deps As List(Of String) = Files.SelectMany(Function(f) f.Dependencies).Distinct.ToList()
         Dim Deps As List(Of String) = Files.SelectMany(Function(f) f.Dependencies).Distinct.ToList()
         Deps.Sort()
         Deps.Sort()
-        If Not Deps.Any() Then Exit Sub
+        If Not Deps.Any() Then Return
         Deps = Deps.Where(
         Deps = Deps.Where(
         Function(dep)
         Function(dep)
             If Not CompProjectCache.ContainsKey(dep) Then Log($"[Comp] 未找到 ID {dep} 的前置信息", LogLevel.Debug)
             If Not CompProjectCache.ContainsKey(dep) Then Log($"[Comp] 未找到 ID {dep} 的前置信息", LogLevel.Debug)

+ 82 - 77
Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb

@@ -71,11 +71,7 @@
         '将可能可用的日志文件导出
         '将可能可用的日志文件导出
         For Each FilePath In RightLogs
         For Each FilePath In RightLogs
             Try
             Try
-                If FilePath.Contains("crash-") Then
-                    AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(FilePath, ReadFile(FilePath).Split(vbCrLf.ToCharArray)))
-                Else
-                    AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(FilePath, ReadFile(FilePath, Encoding.UTF8).Split(vbCrLf.ToCharArray)))
-                End If
+                AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(FilePath, ReadFile(FilePath).Split(vbCrLf.ToCharArray)))
             Catch ex As Exception
             Catch ex As Exception
                 Log(ex, "读取可能的崩溃日志文件失败(" & FilePath & ")")
                 Log(ex, "读取可能的崩溃日志文件失败(" & FilePath & ")")
             End Try
             End Try
@@ -117,11 +113,7 @@ Extracted:
                 If Not TargetFile.Exists OrElse TargetFile.Length = 0 Then Continue For
                 If Not TargetFile.Exists OrElse TargetFile.Length = 0 Then Continue For
                 Dim Ext As String = TargetFile.Extension.ToLower
                 Dim Ext As String = TargetFile.Extension.ToLower
                 If Ext = ".log" OrElse Ext = ".txt" Then
                 If Ext = ".log" OrElse Ext = ".txt" Then
-                    If TargetFile.Name.StartsWithF("crash-") Then
-                        AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(TargetFile.FullName, ReadFile(TargetFile.FullName).Split(vbCrLf.ToCharArray)))
-                    Else
-                        AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(TargetFile.FullName, ReadFile(TargetFile.FullName, Encoding.UTF8).Split(vbCrLf.ToCharArray)))
-                    End If
+                    AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(TargetFile.FullName, ReadFile(TargetFile.FullName).Split(vbCrLf.ToCharArray)))
                 Else
                 Else
                     File.Delete(TargetFile.FullName)
                     File.Delete(TargetFile.FullName)
                 End If
                 End If
@@ -137,20 +129,21 @@ Extracted:
     Private Enum AnalyzeFileType
     Private Enum AnalyzeFileType
         HsErr
         HsErr
         MinecraftLog
         MinecraftLog
-        ExtraLog
+        ExtraLogFile
+        ExtraReportFile
         CrashReport
         CrashReport
     End Enum
     End Enum
     Private DirectFile As KeyValuePair(Of String, String())? = Nothing '在弹窗中选择直接打开的文件
     Private DirectFile As KeyValuePair(Of String, String())? = Nothing '在弹窗中选择直接打开的文件
     ''' <summary>
     ''' <summary>
     ''' 从 AnalyzeRawFiles 中提取实际有用的文本片段存储到 AnalyzeFiles,并整理可用于生成报告的文件。
     ''' 从 AnalyzeRawFiles 中提取实际有用的文本片段存储到 AnalyzeFiles,并整理可用于生成报告的文件。
-    ''' 返回找到的用于分析的项目数。
+    ''' 返回是否有足够信息可用于分析。
     ''' </summary>
     ''' </summary>
-    Public Function Prepare() As Integer
+    Public Function Prepare() As Boolean
         Log("[Crash] 步骤 2:准备日志文本")
         Log("[Crash] 步骤 2:准备日志文本")
 
 
         '对日志文件进行分类
         '对日志文件进行分类
         DirectFile = Nothing
         DirectFile = Nothing
-        Dim TotalFiles As New List(Of KeyValuePair(Of AnalyzeFileType, KeyValuePair(Of String, String())))
+        Dim AllFiles As New List(Of KeyValuePair(Of AnalyzeFileType, KeyValuePair(Of String, String())))
         For Each LogFile In AnalyzeRawFiles
         For Each LogFile In AnalyzeRawFiles
             Dim MatchName As String = GetFileNameFromPath(LogFile.Key).ToLower
             Dim MatchName As String = GetFileNameFromPath(LogFile.Key).ToLower
             Dim TargetType As AnalyzeFileType
             Dim TargetType As AnalyzeFileType
@@ -170,27 +163,35 @@ Extracted:
                     TargetType = AnalyzeFileType.MinecraftLog
                     TargetType = AnalyzeFileType.MinecraftLog
                     If DirectFile Is Nothing Then DirectFile = LogFile
                     If DirectFile Is Nothing Then DirectFile = LogFile
                 Else
                 Else
-                    TargetType = AnalyzeFileType.ExtraLog
+                    TargetType = AnalyzeFileType.ExtraLogFile
                 End If
                 End If
-            ElseIf MatchName.EndsWithF(".log", True) OrElse MatchName.EndsWithF(".txt", True) Then
-                TargetType = AnalyzeFileType.ExtraLog
+            ElseIf MatchName.EndsWithF(".log", True) Then
+                TargetType = AnalyzeFileType.ExtraLogFile
+            ElseIf MatchName.EndsWithF(".txt", True) Then
+                TargetType = AnalyzeFileType.ExtraReportFile
             Else
             Else
                 Log("[Crash] " & MatchName & " 分类为 Ignore")
                 Log("[Crash] " & MatchName & " 分类为 Ignore")
                 Continue For
                 Continue For
             End If
             End If
-            If Not LogFile.Value.Any() Then
-                Log("[Crash] " & MatchName & " 由于内容为空跳过")
-            Else
-                TotalFiles.Add(New KeyValuePair(Of AnalyzeFileType, KeyValuePair(Of String, String()))(TargetType, LogFile))
+            If LogFile.Value.Any Then
+                AllFiles.Add(New KeyValuePair(Of AnalyzeFileType, KeyValuePair(Of String, String()))(TargetType, LogFile))
                 Log("[Crash] " & MatchName & " 分类为 " & GetStringFromEnum(TargetType))
                 Log("[Crash] " & MatchName & " 分类为 " & GetStringFromEnum(TargetType))
+            Else
+                Log("[Crash] " & MatchName & " 由于内容为空跳过")
             End If
             End If
         Next
         Next
 
 
+        '若只有额外日志,则将它们视作 Minecraft 日志
+        If AllFiles.Any() AndAlso AllFiles.All(Function(p) p.Key = AnalyzeFileType.ExtraLogFile) Then
+            Log("[Crash] 由于仅发现了额外日志,将它们视作 Minecraft 日志进行分析")
+            AllFiles = AllFiles.Select(Function(p) New KeyValuePair(Of AnalyzeFileType, KeyValuePair(Of String, String()))(AnalyzeFileType.MinecraftLog, p.Value)).ToList
+        End If
+
         '将分类后的文件分别写入
         '将分类后的文件分别写入
-        For Each SelectType In {AnalyzeFileType.MinecraftLog, AnalyzeFileType.HsErr, AnalyzeFileType.ExtraLog, AnalyzeFileType.CrashReport}
+        For Each SelectType In {AnalyzeFileType.MinecraftLog, AnalyzeFileType.HsErr, AnalyzeFileType.ExtraLogFile, AnalyzeFileType.CrashReport}
             '获取该种类的所有文件 {文件路径 -> 文件内容行}
             '获取该种类的所有文件 {文件路径 -> 文件内容行}
             Dim SelectedFiles As New List(Of KeyValuePair(Of String, String()))
             Dim SelectedFiles As New List(Of KeyValuePair(Of String, String()))
-            For Each File In TotalFiles
+            For Each File In AllFiles
                 If SelectType = File.Key Then SelectedFiles.Add(File.Value)
                 If SelectType = File.Key Then SelectedFiles.Add(File.Value)
             Next
             Next
             If Not SelectedFiles.Any() Then Continue For
             If Not SelectedFiles.Any() Then Continue For
@@ -232,54 +233,59 @@ Extracted:
                         Next
                         Next
                         '选择一份最佳的来自启动器的游戏日志
                         '选择一份最佳的来自启动器的游戏日志
                         For Each FileName As String In {"rawoutput.log", "启动器日志.txt", "log1.txt", "游戏崩溃前的输出.txt", "PCL2 启动器日志.txt", "PCL 启动器日志.txt"}
                         For Each FileName As String In {"rawoutput.log", "启动器日志.txt", "log1.txt", "游戏崩溃前的输出.txt", "PCL2 启动器日志.txt", "PCL 启动器日志.txt"}
-                            If FileNameDict.ContainsKey(FileName) Then
-                                Dim CurrentLog = FileNameDict(FileName)
-                                '截取 “以下为游戏输出的最后一段内容” 后的内容
-                                Dim HasLauncherMark As Boolean = False
-                                For Each Line In CurrentLog.Value
-                                    If HasLauncherMark Then
-                                        LogMc += Line & vbLf
-                                    ElseIf Line.Contains("以下为游戏输出的最后一段内容") Then
-                                        HasLauncherMark = True
-                                        Log("[Crash] 找到 PCL 输出的游戏实时日志头")
-                                    End If
-                                Next
-                                '导入后 500 行
-                                If Not HasLauncherMark Then LogMc += GetHeadTailLines(CurrentLog.Value, 0, 500)
-                                LogMc = LogMc.TrimEnd(vbCrLf.ToCharArray)
-                                Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为启动器日志")
-                                Exit For
-                            End If
+                            If Not FileNameDict.ContainsKey(FileName) Then Continue For
+                            Dim CurrentLog = FileNameDict(FileName)
+                            '截取 “以下为游戏输出的最后一段内容” 后的内容
+                            Dim HasLauncherMark As Boolean = False
+                            For Each Line In CurrentLog.Value
+                                If HasLauncherMark Then
+                                    LogMc += Line & vbLf
+                                ElseIf Line.Contains("以下为游戏输出的最后一段内容") Then
+                                    HasLauncherMark = True
+                                    Log("[Crash] 找到 PCL 输出的游戏实时日志头")
+                                End If
+                            Next
+                            '导入后 500 行
+                            If Not HasLauncherMark Then LogMc += GetHeadTailLines(CurrentLog.Value, 0, 500)
+                            LogMc = LogMc.TrimEnd(vbCrLf.ToCharArray)
+                            Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为启动器日志")
+                            Exit For
                         Next
                         Next
                         '选择一份最佳的 Minecraft Log
                         '选择一份最佳的 Minecraft Log
                         For Each FileName As String In {"latest.log", "latest log.txt", "debug.log", "debug log.txt"}
                         For Each FileName As String In {"latest.log", "latest log.txt", "debug.log", "debug log.txt"}
-                            If FileNameDict.ContainsKey(FileName) Then
-                                Dim CurrentLog = FileNameDict(FileName)
-                                LogMc += GetHeadTailLines(CurrentLog.Value, 250, 500)
-                                Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为 Minecraft 日志")
-                                Exit For
-                            End If
+                            If Not FileNameDict.ContainsKey(FileName) Then Continue For
+                            Dim CurrentLog = FileNameDict(FileName)
+                            LogMc += GetHeadTailLines(CurrentLog.Value, 1500, 500)
+                            Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为 Minecraft 日志")
+                            Exit For
                         Next
                         Next
                         '查找 Debug Log
                         '查找 Debug Log
                         For Each FileName As String In {"debug.log", "debug log.txt"}
                         For Each FileName As String In {"debug.log", "debug log.txt"}
-                            If FileNameDict.ContainsKey(FileName) Then
-                                Dim CurrentLog = FileNameDict(FileName)
-                                LogMcDebug += GetHeadTailLines(CurrentLog.Value, 1000, 0)
-                                Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为 Minecraft Debug 日志")
-                                Exit For
-                            End If
+                            If Not FileNameDict.ContainsKey(FileName) Then Continue For
+                            Dim CurrentLog = FileNameDict(FileName)
+                            LogMcDebug += GetHeadTailLines(CurrentLog.Value, 1000, 0)
+                            Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为 Minecraft Debug 日志")
+                            Exit For
                         Next
                         Next
-                        '检查错误
+                        '兜底
                         If LogMc = "" Then
                         If LogMc = "" Then
-                            LogMc = Nothing
-                            Throw New Exception("无法找到匹配的 Minecraft Log")
+                            If LogMcDebug <> "" Then '如果没有找到 Minecraft 日志,则使用 Debug 日志作为兜底
+                                LogMc = LogMcDebug
+                            ElseIf FileNameDict.Any() Then '如果都没有找到,则使用第一个文件
+                                Dim CurrentLog = FileNameDict.First.Value
+                                LogMc += GetHeadTailLines(CurrentLog.Value, 1500, 500)
+                                Log("[Crash] 导入分析:" & CurrentLog.Key & ",作为兜底日志")
+                            Else
+                                LogMc = Nothing
+                                Throw New Exception("无法找到匹配的 Minecraft Log")
+                            End If
                         End If
                         End If
                         If LogMcDebug = "" Then LogMcDebug = Nothing
                         If LogMcDebug = "" Then LogMcDebug = Nothing
-                    Case AnalyzeFileType.ExtraLog
+                    Case AnalyzeFileType.ExtraLogFile, AnalyzeFileType.ExtraReportFile
                         '全部丢过去
                         '全部丢过去
                         For Each SelectedFile In SelectedFiles
                         For Each SelectedFile In SelectedFiles
                             OutputFiles.Add(SelectedFile.Key)
                             OutputFiles.Add(SelectedFile.Key)
-                            Log("[Crash] 输出报告:" & SelectedFile.Key & ",作为额外日志")
+                            Log("[Crash] 输出报告:" & SelectedFile.Key & ",不用作分析")
                         Next
                         Next
                 End Select
                 End Select
             Catch ex As Exception
             Catch ex As Exception
@@ -287,15 +293,13 @@ Extracted:
             End Try
             End Try
         Next
         Next
 
 
-        '获取种类数
-        Dim ResultCount As Integer = If(LogMc Is Nothing, 0, 1) + If(LogHs Is Nothing, 0, 1) + If(LogCrash Is Nothing, 0, 1)
-        If ResultCount = 0 Then
-            Log("[Crash] 步骤 2:准备日志文本完成,没有任何可供分析的日志")
-        Else
+        '结束
+        Prepare = LogMc IsNot Nothing OrElse LogHs IsNot Nothing OrElse LogCrash IsNot Nothing
+        If Prepare Then
             Log(("[Crash] 步骤 2:准备日志文本完成,找到" & If(LogMc Is Nothing, "", "游戏日志、") & If(LogMcDebug Is Nothing, "", "游戏 Debug 日志、") & If(LogHs Is Nothing, "", "虚拟机日志、") & If(LogCrash Is Nothing, "", "崩溃日志、")).TrimEnd("、") & "用作分析")
             Log(("[Crash] 步骤 2:准备日志文本完成,找到" & If(LogMc Is Nothing, "", "游戏日志、") & If(LogMcDebug Is Nothing, "", "游戏 Debug 日志、") & If(LogHs Is Nothing, "", "虚拟机日志、") & If(LogCrash Is Nothing, "", "崩溃日志、")).TrimEnd("、") & "用作分析")
+        Else
+            Log("[Crash] 步骤 2:准备日志文本完成,没有任何可供分析的日志")
         End If
         End If
-        Return ResultCount
-
     End Function
     End Function
     ''' <summary>
     ''' <summary>
     ''' 输出字符串的前后某些行,并统一行尾为 vbLf (正则 \n)、删除空行和重复行。
     ''' 输出字符串的前后某些行,并统一行尾为 vbLf (正则 \n)、删除空行和重复行。
@@ -386,7 +390,7 @@ Extracted:
     ''' </summary>
     ''' </summary>
     Public Sub Analyze(Optional Version As McVersion = Nothing)
     Public Sub Analyze(Optional Version As McVersion = Nothing)
         Log("[Crash] 步骤 3:分析崩溃原因")
         Log("[Crash] 步骤 3:分析崩溃原因")
-        LogAll = (If(LogMc, "") & If(LogMcDebug, "") & If(LogHs, "") & If(LogCrash, ""))
+        LogAll = If(LogMc, If(LogMcDebug, "")) & If(LogHs, "") & If(LogCrash, "")
 
 
         '1. 精准日志匹配,中/高优先级
         '1. 精准日志匹配,中/高优先级
         AnalyzeCrit1()
         AnalyzeCrit1()
@@ -472,7 +476,7 @@ Done:
         '空白分析
         '空白分析
         If LogMc Is Nothing AndAlso LogHs Is Nothing AndAlso LogCrash Is Nothing Then
         If LogMc Is Nothing AndAlso LogHs Is Nothing AndAlso LogCrash Is Nothing Then
             AppendReason(CrashReason.没有可用的分析文件)
             AppendReason(CrashReason.没有可用的分析文件)
-            Exit Sub
+            Return
         End If
         End If
 
 
         '崩溃报告分析,高优先级
         '崩溃报告分析,高优先级
@@ -614,9 +618,9 @@ Done:
             Dim IsMixin As Boolean = MixinAnalyze(LogMc)
             Dim IsMixin As Boolean = MixinAnalyze(LogMc)
             '常规信息
             '常规信息
             If LogMc.Contains("An exception was thrown, the game will display an error screen and halt.") Then AppendReason(CrashReason.Forge报错, RegexSeek(LogMc, "(?<=the game will display an error screen and halt.[\n\r]+[^\n]+?Exception: )[\s\S]+?(?=\n\tat)")?.Trim(vbCrLf))
             If LogMc.Contains("An exception was thrown, the game will display an error screen and halt.") Then AppendReason(CrashReason.Forge报错, RegexSeek(LogMc, "(?<=the game will display an error screen and halt.[\n\r]+[^\n]+?Exception: )[\s\S]+?(?=\n\tat)")?.Trim(vbCrLf))
-            If LogMc.Contains("A potential solution has been determined:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
-            If LogMc.Contains("A potential solution has been determined, this may resolve your problem:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined, this may resolve your problem:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
-            If LogMc.Contains("确定了一种可能的解决方法,这样做可能会解决你的问题:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=确定了一种可能的解决方法,这样做可能会解决你的问题:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
+            If LogMc.Contains("A potential solution has been determined:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)(\s+ - [^\n]+\n)+"), ""), "(?<=\s+)[^\n]+"), vbLf))
+            If LogMc.Contains("A potential solution has been determined, this may resolve your problem:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined, this may resolve your problem:\n)(\s+ - [^\n]+\n)+"), ""), "(?<=\s+)[^\n]+"), vbLf))
+            If LogMc.Contains("确定了一种可能的解决方法,这样做可能会解决你的问题:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=确定了一种可能的解决方法,这样做可能会解决你的问题:\n)(\s+ - [^\n]+\n)+"), ""), "(?<=\s+)[^\n]+"), vbLf))
             If Not IsMixin AndAlso LogMc.Contains("due to errors, provided by ") Then '在 #3104 的情况下,这一句导致 OptiFabric 的 Mixin 失败错判为 Fabric Loader 加载失败
             If Not IsMixin AndAlso LogMc.Contains("due to errors, provided by ") Then '在 #3104 的情况下,这一句导致 OptiFabric 的 Mixin 失败错判为 Fabric Loader 加载失败
                 AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogMc, "(?<=due to errors, provided by ')[^']+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
                 AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogMc, "(?<=due to errors, provided by ')[^']+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
             End If
             End If
@@ -873,7 +877,7 @@ NextStack:
                 Try
                 Try
                     '获取文件路径
                     '获取文件路径
                     RunInUiWait(Sub() FileAddress = SelectSaveFile("选择保存位置", "错误报告-" & Date.Now.ToString("G").Replace("/", "-").Replace(":", ".").Replace(" ", "_") & ".zip", "Minecraft 错误报告(*.zip)|*.zip"))
                     RunInUiWait(Sub() FileAddress = SelectSaveFile("选择保存位置", "错误报告-" & Date.Now.ToString("G").Replace("/", "-").Replace(":", ".").Replace(" ", "_") & ".zip", "Minecraft 错误报告(*.zip)|*.zip"))
-                    If String.IsNullOrEmpty(FileAddress) Then Exit Sub
+                    If String.IsNullOrEmpty(FileAddress) Then Return
                     Directory.CreateDirectory(GetPathFromFullPath(FileAddress))
                     Directory.CreateDirectory(GetPathFromFullPath(FileAddress))
                     If File.Exists(FileAddress) Then File.Delete(FileAddress)
                     If File.Exists(FileAddress) Then File.Delete(FileAddress)
                     '输出诊断信息
                     '输出诊断信息
@@ -896,9 +900,10 @@ NextStack:
                         End Select
                         End Select
                         If File.Exists(OutputFile) Then
                         If File.Exists(OutputFile) Then
                             If FileEncoding Is Nothing Then FileEncoding = GetEncoding(ReadFileBytes(OutputFile))
                             If FileEncoding Is Nothing Then FileEncoding = GetEncoding(ReadFileBytes(OutputFile))
-                            WriteFile(TempFolder & "Report\" & FileName,
-                                      SecretFilter(ReadFile(OutputFile, FileEncoding), If(FileName = "启动脚本.bat", "F", "*")),
-                                      Encoding:=FileEncoding)
+                            Dim FileContent As String = ReadFile(OutputFile, FileEncoding)
+                            FileContent = FilterAccessToken(FileContent, If(FileName = "启动脚本.bat", "F", "*"))
+                            FileContent = FilterUserName(FileContent, "*")
+                            WriteFile(TempFolder & "Report\" & FileName, FileContent, Encoding:=FileEncoding)
                             Log($"[Crash] 导出文件:{FileName},编码:{FileEncoding.HeaderName}")
                             Log($"[Crash] 导出文件:{FileName},编码:{FileEncoding.HeaderName}")
                         End If
                         End If
                     Next
                     Next
@@ -908,7 +913,7 @@ NextStack:
                     Hint("错误报告已导出!", HintType.Finish)
                     Hint("错误报告已导出!", HintType.Finish)
                 Catch ex As Exception
                 Catch ex As Exception
                     Log(ex, "导出错误报告失败", LogLevel.Feedback)
                     Log(ex, "导出错误报告失败", LogLevel.Feedback)
-                    Exit Sub
+                    Return
                 End Try
                 End Try
                 OpenExplorer(FileAddress)
                 OpenExplorer(FileAddress)
         End Select
         End Select
@@ -937,7 +942,7 @@ NextStack:
                 Case CrashReason.内存不足
                 Case CrashReason.内存不足
                     Results.Add("Minecraft 内存不足,导致其无法继续运行。\n这很可能是因为电脑内存不足、游戏分配的内存不足,或是配置要求过高。\n\n你可以尝试在 更多 → 百宝箱 中选择 内存优化,然后再启动游戏。\n如果还是不行,请在启动设置中增加为游戏分配的内存,并删除配置要求较高的材质、Mod、光影。\n如果依然不奏效,请在开始游戏前尽量关闭其他软件,或者……换台电脑?\h")
                     Results.Add("Minecraft 内存不足,导致其无法继续运行。\n这很可能是因为电脑内存不足、游戏分配的内存不足,或是配置要求过高。\n\n你可以尝试在 更多 → 百宝箱 中选择 内存优化,然后再启动游戏。\n如果还是不行,请在启动设置中增加为游戏分配的内存,并删除配置要求较高的材质、Mod、光影。\n如果依然不奏效,请在开始游戏前尽量关闭其他软件,或者……换台电脑?\h")
                 Case CrashReason.使用OpenJ9
                 Case CrashReason.使用OpenJ9
-                    Results.Add("游戏因为使用 Open J9 而崩溃了。\n请在启动设置的 Java 选择一项中改用非 OpenJ9 的 Java,然后再启动游戏。")
+                    Results.Add("游戏因为使用 OpenJ9 而崩溃了。\n请在启动设置的 Java 选择一项中改用非 OpenJ9 的 Java,然后再启动游戏。")
                 Case CrashReason.使用JDK
                 Case CrashReason.使用JDK
                     Results.Add("游戏似乎因为使用 JDK,或 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用 JRE 8(Java 8),然后再启动游戏。\n如果你没有安装 JRE 8,你可以从网络中下载、安装一个。")
                     Results.Add("游戏似乎因为使用 JDK,或 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用 JRE 8(Java 8),然后再启动游戏。\n如果你没有安装 JRE 8,你可以从网络中下载、安装一个。")
                 Case CrashReason.Java版本过高
                 Case CrashReason.Java版本过高
@@ -1019,7 +1024,7 @@ NextStack:
                 Case CrashReason.OptiFine与Forge不兼容
                 Case CrashReason.OptiFine与Forge不兼容
                     Results.Add("由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。\n\n请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。")
                     Results.Add("由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。\n\n请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。")
                 Case CrashReason.ShadersMod与OptiFine同时安装
                 Case CrashReason.ShadersMod与OptiFine同时安装
-                    Results.Add("无需同时安装 Optifine 和 Shaders Mod,OptiFine 已经集成了 Shaders Mod 的功能。\n在删除 Shaders Mod 后,游戏即可正常运行。")
+                    Results.Add("无需同时安装 OptiFine 和 Shaders Mod,OptiFine 已经集成了 Shaders Mod 的功能。\n在删除 Shaders Mod 后,游戏即可正常运行。")
                 Case CrashReason.低版本Forge与高版本Java不兼容
                 Case CrashReason.低版本Forge与高版本Java不兼容
                     Results.Add("由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。\n\n请尝试以下解决方案:\n - 更新 Forge 到 36.2.26 或更高版本\n - 换用版本低于 1.8.0.320 的 Java")
                     Results.Add("由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。\n\n请尝试以下解决方案:\n - 更新 Forge 到 36.2.26 或更高版本\n - 换用版本低于 1.8.0.320 的 Java")
                 Case CrashReason.版本Json中存在多个Forge
                 Case CrashReason.版本Json中存在多个Forge

+ 3 - 3
Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb

@@ -244,7 +244,7 @@
             '检查是否有要求的版本(#5195)
             '检查是否有要求的版本(#5195)
             If Not String.IsNullOrEmpty(Loader.Input) Then
             If Not String.IsNullOrEmpty(Loader.Input) Then
                 Dim Id = Loader.Input
                 Dim Id = Loader.Input
-                If Not DlClientListLoader.Output.Value("versions").Any(Function(v) v("id") = Id) Then
+                If DlClientListLoader.Output.Value IsNot Nothing AndAlso Not DlClientListLoader.Output.Value("versions").Any(Function(v) v("id") = Id) Then
                     Throw New Exception("BMCLAPI 源未包含目标版本 " & Id)
                     Throw New Exception("BMCLAPI 源未包含目标版本 " & Id)
                 End If
                 End If
             End If
             End If
@@ -1291,7 +1291,7 @@
                     '检查加载器成功
                     '检查加载器成功
                     MainLoader.Output = SubLoader.Key.Output
                     MainLoader.Output = SubLoader.Key.Output
                     DlSourceLoaderAbort(LoaderList)
                     DlSourceLoaderAbort(LoaderList)
-                    Exit Sub
+                    Return
                 ElseIf BeforeLoadersAllFailed Then
                 ElseIf BeforeLoadersAllFailed Then
                     '此前的加载器全部失败,直接启动后续加载器
                     '此前的加载器全部失败,直接启动后续加载器
                     If WaitCycle < SubLoader.Value * 100 Then WaitCycle = SubLoader.Value * 100
                     If WaitCycle < SubLoader.Value * 100 Then WaitCycle = SubLoader.Value * 100
@@ -1333,7 +1333,7 @@
             '检查父加载器中断
             '检查父加载器中断
             If MainLoader.IsAborted Then
             If MainLoader.IsAborted Then
                 DlSourceLoaderAbort(LoaderList)
                 DlSourceLoaderAbort(LoaderList)
-                Exit Sub
+                Return
             End If
             End If
         Loop
         Loop
     End Sub
     End Sub

+ 5 - 2
Plain Craft Launcher 2/Modules/Minecraft/ModJava.vb

@@ -98,7 +98,7 @@
         ''' 检查并获取 Java 详细信息。在 Java 存在异常时抛出错误。
         ''' 检查并获取 Java 详细信息。在 Java 存在异常时抛出错误。
         ''' </summary>
         ''' </summary>
         Public Sub Check()
         Public Sub Check()
-            If IsChecked Then Exit Sub
+            If IsChecked Then Return
             Dim Output As String = Nothing
             Dim Output As String = Nothing
             Try
             Try
                 '确定文件存在
                 '确定文件存在
@@ -108,6 +108,9 @@
                 If Not File.Exists(PathFolder & "java.exe") Then
                 If Not File.Exists(PathFolder & "java.exe") Then
                     Throw New FileNotFoundException("未找到 java.exe 文件", PathFolder & "java.exe")
                     Throw New FileNotFoundException("未找到 java.exe 文件", PathFolder & "java.exe")
                 End If
                 End If
+                If File.Exists(PathFolder & "pdf-bookmark") Then
+                    Throw New Exception("不兼容 PDF Bookmark 的 Java") '#5326
+                End If
                 IsJre = Not File.Exists(PathFolder & "javac.exe")
                 IsJre = Not File.Exists(PathFolder & "javac.exe")
                 '运行 -version
                 '运行 -version
                 Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 15000).ToLower
                 Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 15000).ToLower
@@ -668,7 +671,7 @@ Wait:
     Private Sub JavaSearchFolder(OriginalPath As DirectoryInfo, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
     Private Sub JavaSearchFolder(OriginalPath As DirectoryInfo, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
         Try
         Try
             '确认目录存在
             '确认目录存在
-            If Not OriginalPath.Exists Then Exit Sub
+            If Not OriginalPath.Exists Then Return
             Dim Path As String = OriginalPath.FullName.Replace("\\", "\")
             Dim Path As String = OriginalPath.FullName.Replace("\\", "\")
             If Not Path.EndsWithF("\") Then Path += "\"
             If Not Path.EndsWithF("\") Then Path += "\"
             '若该目录有 Java,则加入结果
             '若该目录有 Java,则加入结果

+ 19 - 27
Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb

@@ -65,7 +65,7 @@ Public Module ModLaunch
     ''' 记录启动日志。
     ''' 记录启动日志。
     ''' </summary>
     ''' </summary>
     Public Sub McLaunchLog(Text As String)
     Public Sub McLaunchLog(Text As String)
-        Text = SecretFilter(Text, "*")
+        Text = FilterUserName(FilterAccessToken(Text, "*"), "*")
         RunInUi(Sub() FrmLaunchRight.LabLog.Text += vbCrLf & "[" & GetTimeNow() & "] " & Text)
         RunInUi(Sub() FrmLaunchRight.LabLog.Text += vbCrLf & "[" & GetTimeNow() & "] " & Text)
         Log("[Launch] " & Text)
         Log("[Launch] " & Text)
     End Sub
     End Sub
@@ -578,11 +578,7 @@ SkipLogin:
     Private Sub McLoginServerStart(Data As LoaderTask(Of McLoginServer, McLoginResult))
     Private Sub McLoginServerStart(Data As LoaderTask(Of McLoginServer, McLoginResult))
         Dim Input As McLoginServer = Data.Input
         Dim Input As McLoginServer = Data.Input
         Dim NeedRefresh As Boolean = False, WasRefreshed As Boolean = False
         Dim NeedRefresh As Boolean = False, WasRefreshed As Boolean = False
-        Dim LogUsername As String = Input.UserName
-        If LogUsername.Contains("@") AndAlso Setup.Get("UiLauncherEmail") Then
-            LogUsername = AccountFilter(LogUsername)
-        End If
-        McLaunchLog("登录方式:" & Input.Description & "(" & LogUsername & ")")
+        McLaunchLog("登录方式:" & Input.Description)
         Data.Progress = 0.05
         Data.Progress = 0.05
         '尝试登录
         '尝试登录
         If (Not Data.Input.ForceReselectProfile) AndAlso
         If (Not Data.Input.ForceReselectProfile) AndAlso
@@ -602,7 +598,7 @@ SkipLogin:
                 McLaunchLog("验证登录失败:" & AllMessage)
                 McLaunchLog("验证登录失败:" & AllMessage)
                 If (AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout")) AndAlso Not AllMessage.Contains("403") Then
                 If (AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout")) AndAlso Not AllMessage.Contains("403") Then
                     McLaunchLog("已触发超时登录失败")
                     McLaunchLog("已触发超时登录失败")
-                    Throw New Exception("$登录失败:连接登录服务器超时。" & vbCrLf & "请检查你的网络状况是否良好,或尝试使用 VPN!")
+                    Throw New Exception("$登录失败:你的网络环境不佳,导致难以连接到海外服务器。" & vbCrLf & "请稍后重试,或使用加速器或 VPN 以改善网络环境。")
                 End If
                 End If
             End Try
             End Try
             Data.Progress = 0.25
             Data.Progress = 0.25
@@ -845,7 +841,7 @@ LoginFinish:
                                             " - 只注册了账号,但没有加入对应服务器。")
                                             " - 只注册了账号,但没有加入对应服务器。")
                 End Select
                 End Select
             ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") OrElse AllMessage.Contains("网络请求失败") Then
             ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") OrElse AllMessage.Contains("网络请求失败") Then
-                Throw New Exception("$登录失败:连接登录服务器超时。" & vbCrLf & "请检查你的网络状况是否良好,或尝试使用 VPN!")
+                Throw New Exception("$登录失败:你的网络环境不佳,导致难以连接到海外服务器。" & vbCrLf & "请稍后重试,或使用加速器或 VPN 以改善网络环境。")
             ElseIf ex.Message.StartsWithF("$") Then
             ElseIf ex.Message.StartsWithF("$") Then
                 Throw
                 Throw
             Else
             Else
@@ -956,7 +952,7 @@ Retry:
                 End If
                 End If
                 Throw New Exception("$$")
                 Throw New Exception("$$")
             ElseIf ex.Message.Contains("2148916235") Then
             ElseIf ex.Message.Contains("2148916235") Then
-                MyMsgBox($"你的网络所在的国家或地区无法登录微软账号。{vbCrLf}请尝试使用加速器或 VPN。", "登录失败", "我知道了")
+                MyMsgBox($"你的网络所在的国家或地区无法登录微软账号。{vbCrLf}请使用加速器或 VPN。", "登录失败", "我知道了")
                 Throw New Exception("$$")
                 Throw New Exception("$$")
             ElseIf ex.Message.Contains("2148916238") Then
             ElseIf ex.Message.Contains("2148916238") Then
                 If MyMsgBox("该账号年龄不足,你需要先修改出生日期,然后才能登录。" & vbCrLf &
                 If MyMsgBox("该账号年龄不足,你需要先修改出生日期,然后才能登录。" & vbCrLf &
@@ -1084,8 +1080,7 @@ Retry:
                         Uuid = McLoginMojangUuid(SkinName, False)
                         Uuid = McLoginMojangUuid(SkinName, False)
                     End If
                     End If
                 Catch ex As Exception
                 Catch ex As Exception
-                    Log(ex, "离线启动时使用的正版皮肤获取失败")
-                    MyMsgBox("由于设置的离线启动时使用的正版皮肤获取失败,游戏将以无皮肤的方式启动。" & vbCrLf & "请检查你的网络是否通畅,或尝试使用 VPN!" & vbCrLf & vbCrLf & "详细的错误信息:" & ex.Message, "皮肤获取失败")
+                    Log(ex, "皮肤信息获取失败,游戏将以无皮肤的方式启动", LogLevel.Hint)
                 End Try
                 End Try
             Case 4
             Case 4
                 '自定义
                 '自定义
@@ -1221,14 +1216,14 @@ Retry:
             '选择 Java
             '选择 Java
             McLaunchLog("Java 版本需求:最低 " & MinVer.ToString & ",最高 " & MaxVer.ToString)
             McLaunchLog("Java 版本需求:最低 " & MinVer.ToString & ",最高 " & MaxVer.ToString)
             McLaunchJavaSelected = JavaSelect("$$", MinVer, MaxVer, McVersionCurrent)
             McLaunchJavaSelected = JavaSelect("$$", MinVer, MaxVer, McVersionCurrent)
-            If Task.IsAborted Then Exit Sub
+            If Task.IsAborted Then Return
             If McLaunchJavaSelected IsNot Nothing Then
             If McLaunchJavaSelected IsNot Nothing Then
                 McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
                 McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
-                Exit Sub
+                Return
             End If
             End If
 
 
             '无合适的 Java
             '无合适的 Java
-            If Task.IsAborted Then Exit Sub '中断加载会导致 JavaSelect 异常地返回空值,误判找不到 Java
+            If Task.IsAborted Then Return '中断加载会导致 JavaSelect 异常地返回空值,误判找不到 Java
             McLaunchLog("无合适的 Java,需要确认是否自动下载")
             McLaunchLog("无合适的 Java,需要确认是否自动下载")
             Dim JavaCode As String
             Dim JavaCode As String
             If MinVer >= New Version(1, 22) Then '潜在的向后兼容
             If MinVer >= New Version(1, 22) Then '潜在的向后兼容
@@ -1276,7 +1271,7 @@ Retry:
             '检查下载结果
             '检查下载结果
             If JavaSearchLoader.State <> LoadState.Loading Then JavaSearchLoader.State = LoadState.Waiting '2872#
             If JavaSearchLoader.State <> LoadState.Loading Then JavaSearchLoader.State = LoadState.Waiting '2872#
             McLaunchJavaSelected = JavaSelect("$$", MinVer, MaxVer, McVersionCurrent)
             McLaunchJavaSelected = JavaSelect("$$", MinVer, MaxVer, McVersionCurrent)
-            If Task.IsAborted Then Exit Sub
+            If Task.IsAborted Then Return
             If McLaunchJavaSelected IsNot Nothing Then
             If McLaunchJavaSelected IsNot Nothing Then
                 McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
                 McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
             Else
             Else
@@ -1355,11 +1350,11 @@ Retry:
         End If
         End If
         '编码参数(#4700、#5892、#5909)
         '编码参数(#4700、#5892、#5909)
         If McLaunchJavaSelected.VersionCode > 8 Then
         If McLaunchJavaSelected.VersionCode > 8 Then
-            If Not Arguments.Contains("-Dstdout.encoding=") Then Arguments += " -Dstdout.encoding=UTF-8"
-            If Not Arguments.Contains("-Dstderr.encoding=") Then Arguments += " -Dstderr.encoding=UTF-8"
+            If Not Arguments.Contains("-Dstdout.encoding=") Then Arguments = "-Dstdout.encoding=UTF-8 " & Arguments
+            If Not Arguments.Contains("-Dstderr.encoding=") Then Arguments = "-Dstderr.encoding=UTF-8 " & Arguments
         End If
         End If
         If McLaunchJavaSelected.VersionCode >= 18 Then
         If McLaunchJavaSelected.VersionCode >= 18 Then
-            If Not Arguments.Contains("-Dfile.encoding=") Then Arguments += " -Dfile.encoding=COMPAT"
+            If Not Arguments.Contains("-Dfile.encoding=") Then Arguments = "-Dfile.encoding=COMPAT " & Arguments
         End If
         End If
         '替换参数
         '替换参数
         Dim ReplaceArguments = McLaunchArgumentsReplace(McVersionCurrent, Loader)
         Dim ReplaceArguments = McLaunchArgumentsReplace(McVersionCurrent, Loader)
@@ -1688,7 +1683,7 @@ NextVersion:
             Case 3 '自定义
             Case 3 '自定义
                 GameSize = New Size(Math.Max(100, Setup.Get("LaunchArgumentWindowWidth")), Math.Max(100, Setup.Get("LaunchArgumentWindowHeight")))
                 GameSize = New Size(Math.Max(100, Setup.Get("LaunchArgumentWindowWidth")), Math.Max(100, Setup.Get("LaunchArgumentWindowHeight")))
             Case Else
             Case Else
-                GameSize = New Size(875, 540)
+                GameSize = New Size(854, 480)
         End Select
         End Select
         If McVersionCurrent.Version.McCodeMain <= 12 AndAlso
         If McVersionCurrent.Version.McCodeMain <= 12 AndAlso
             McLaunchJavaSelected.VersionCode <= 8 AndAlso McLaunchJavaSelected.Version.Revision >= 200 AndAlso McLaunchJavaSelected.Version.Revision <= 321 AndAlso
             McLaunchJavaSelected.VersionCode <= 8 AndAlso McLaunchJavaSelected.Version.Revision >= 200 AndAlso McLaunchJavaSelected.Version.Revision <= 321 AndAlso
@@ -1785,7 +1780,7 @@ NextVersion:
             Catch ex As UnauthorizedAccessException
             Catch ex As UnauthorizedAccessException
                 McLaunchLog("删除多余文件访问被拒绝,跳过删除步骤")
                 McLaunchLog("删除多余文件访问被拒绝,跳过删除步骤")
                 McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
                 McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
-                Exit Sub
+                Return
             End Try
             End Try
         Next
         Next
 
 
@@ -2100,25 +2095,24 @@ IgnoreCustomSkin:
         '输出 bat
         '输出 bat
         Try
         Try
             Dim CmdString As String =
             Dim CmdString As String =
-                $"{If(McLaunchJavaSelected.VersionCode > 8 AndAlso McLaunchJavaSelected.VersionCode < 18, "chcp 65001>nul" & vbCrLf, "")}" &
+                $"{If(McLaunchJavaSelected.VersionCode > 8, "chcp 65001>nul" & vbCrLf, "")}" &
                 "@echo off" & vbCrLf &
                 "@echo off" & vbCrLf &
                 $"title 启动 - {McVersionCurrent.Name}" & vbCrLf &
                 $"title 启动 - {McVersionCurrent.Name}" & vbCrLf &
                 "echo 游戏正在启动,请稍候。" & vbCrLf &
                 "echo 游戏正在启动,请稍候。" & vbCrLf &
-                $"set APPDATA=""{ShortenPath(McVersionCurrent.PathIndie)}""" & vbCrLf &
                 $"cd /D ""{ShortenPath(McVersionCurrent.PathIndie)}""" & vbCrLf &
                 $"cd /D ""{ShortenPath(McVersionCurrent.PathIndie)}""" & vbCrLf &
                 CustomCommandGlobal & vbCrLf &
                 CustomCommandGlobal & vbCrLf &
                 CustomCommandVersion & vbCrLf &
                 CustomCommandVersion & vbCrLf &
                 $"""{McLaunchJavaSelected.PathJava}"" {McLaunchArgument}" & vbCrLf &
                 $"""{McLaunchJavaSelected.PathJava}"" {McLaunchArgument}" & vbCrLf &
                 "echo 游戏已退出。" & vbCrLf &
                 "echo 游戏已退出。" & vbCrLf &
                 "pause"
                 "pause"
-            WriteFile(If(CurrentLaunchOptions.SaveBatch, Path & "PCL\LatestLaunch.bat"), SecretFilter(CmdString, "F"),
+            WriteFile(If(CurrentLaunchOptions.SaveBatch, Path & "PCL\LatestLaunch.bat"), FilterAccessToken(CmdString, "F"),
                       Encoding:=If(McLaunchJavaSelected.VersionCode > 8, Encoding.UTF8, Encoding.Default))
                       Encoding:=If(McLaunchJavaSelected.VersionCode > 8, Encoding.UTF8, Encoding.Default))
             If CurrentLaunchOptions.SaveBatch IsNot Nothing Then
             If CurrentLaunchOptions.SaveBatch IsNot Nothing Then
                 McLaunchLog("导出启动脚本完成,强制结束启动过程")
                 McLaunchLog("导出启动脚本完成,强制结束启动过程")
                 AbortHint = "导出启动脚本成功!"
                 AbortHint = "导出启动脚本成功!"
                 OpenExplorer(CurrentLaunchOptions.SaveBatch)
                 OpenExplorer(CurrentLaunchOptions.SaveBatch)
                 Loader.Parent.Abort()
                 Loader.Parent.Abort()
-                Exit Sub '导出脚本完成
+                Return '导出脚本完成
             End If
             End If
         Catch ex As Exception
         Catch ex As Exception
             Log(ex, "输出启动脚本失败")
             Log(ex, "输出启动脚本失败")
@@ -2189,8 +2183,6 @@ IgnoreCustomSkin:
         StartInfo.EnvironmentVariables("appdata") = ShortenPath(PathMcFolder)
         StartInfo.EnvironmentVariables("appdata") = ShortenPath(PathMcFolder)
 
 
         '设置其他参数
         '设置其他参数
-        StartInfo.StandardErrorEncoding = If(McLaunchJavaSelected.VersionCode > 8, Encoding.UTF8, Nothing)
-        StartInfo.StandardOutputEncoding = If(McLaunchJavaSelected.VersionCode > 8, Encoding.UTF8, Nothing)
         StartInfo.WorkingDirectory = ShortenPath(McVersionCurrent.PathIndie)
         StartInfo.WorkingDirectory = ShortenPath(McVersionCurrent.PathIndie)
         StartInfo.UseShellExecute = False
         StartInfo.UseShellExecute = False
         StartInfo.RedirectStandardOutput = True
         StartInfo.RedirectStandardOutput = True
@@ -2205,7 +2197,7 @@ IgnoreCustomSkin:
         If Loader.IsAborted Then
         If Loader.IsAborted Then
             McLaunchLog("由于取消启动,已强制结束游戏进程") '#1631
             McLaunchLog("由于取消启动,已强制结束游戏进程") '#1631
             GameProcess.Kill()
             GameProcess.Kill()
-            Exit Sub
+            Return
         End If
         End If
         Loader.Output = GameProcess
         Loader.Output = GameProcess
         McLaunchProcess = GameProcess
         McLaunchProcess = GameProcess

+ 37 - 29
Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb

@@ -127,7 +127,7 @@ Public Module ModMinecraft
     ''' </summary>
     ''' </summary>
     Public Sub McFolderLauncherProfilesJsonCreate(Folder As String)
     Public Sub McFolderLauncherProfilesJsonCreate(Folder As String)
         Try
         Try
-            If File.Exists(Folder & "launcher_profiles.json") Then Exit Sub
+            If File.Exists(Folder & "launcher_profiles.json") Then Return
             Dim ResultJson As String =
             Dim ResultJson As String =
 "{
 "{
     ""profiles"":  {
     ""profiles"":  {
@@ -165,10 +165,10 @@ Public Module ModMinecraft
             Return _McVersionCurrent
             Return _McVersionCurrent
         End Get
         End Get
         Set(value As McVersion)
         Set(value As McVersion)
-            If ReferenceEquals(_McVersionLast, value) Then Exit Property
+            If ReferenceEquals(_McVersionLast, value) Then Return
             _McVersionCurrent = value '由于有可能是 Nothing,导致无法初始化,才得这样弄一圈
             _McVersionCurrent = value '由于有可能是 Nothing,导致无法初始化,才得这样弄一圈
             _McVersionLast = value
             _McVersionLast = value
-            If value Is Nothing Then Exit Property
+            If value Is Nothing Then Return
             '重置缓存的 Mod 文件夹
             '重置缓存的 Mod 文件夹
             PageDownloadCompDetail.CachedFolder = Nothing
             PageDownloadCompDetail.CachedFolder = Nothing
             '统一通行证重判
             '统一通行证重判
@@ -208,6 +208,7 @@ Public Module ModMinecraft
         Public ReadOnly Property PathIndie As String
         Public ReadOnly Property PathIndie As String
             Get
             Get
                 If Setup.IsUnset("VersionArgumentIndieV2", Version:=Me) Then
                 If Setup.IsUnset("VersionArgumentIndieV2", Version:=Me) Then
+                    If Not IsLoaded Then Load()
                     '决定该版本是否应该被隔离
                     '决定该版本是否应该被隔离
                     Dim ShouldBeIndie =
                     Dim ShouldBeIndie =
                     Function() As Boolean
                     Function() As Boolean
@@ -224,17 +225,17 @@ Public Module ModMinecraft
                             Return True
                             Return True
                         End If
                         End If
                         '根据全局的默认设置决定是否隔离
                         '根据全局的默认设置决定是否隔离
-                        Log($"[Minecraft] 版本隔离初始化({Name}):从全局默认设置中({Setup.Get("LaunchArgumentIndieV2")})判断")
-                        Dim IsRelease As Boolean = State = McVersionState.Fool OrElse State = McVersionState.Old OrElse State = McVersionState.Snapshot
+                        Dim IsRelease As Boolean = State <> McVersionState.Fool AndAlso State <> McVersionState.Old AndAlso State <> McVersionState.Snapshot
+                        Log($"[Minecraft] 版本隔离初始化({Name}):从全局默认设置中({Setup.Get("LaunchArgumentIndieV2")})判断,State {GetStringFromEnum(State)},IsRelease {IsRelease},Modable {Modable}")
                         Select Case Setup.Get("LaunchArgumentIndieV2")
                         Select Case Setup.Get("LaunchArgumentIndieV2")
                             Case 0 '关闭
                             Case 0 '关闭
                                 Return False
                                 Return False
                             Case 1 '仅隔离可安装 Mod 的版本
                             Case 1 '仅隔离可安装 Mod 的版本
                                 Return Modable
                                 Return Modable
                             Case 2 '仅隔离非正式版
                             Case 2 '仅隔离非正式版
-                                Return IsRelease
+                                Return Not IsRelease
                             Case 3 '隔离非正式版与可安装 Mod 的版本
                             Case 3 '隔离非正式版与可安装 Mod 的版本
-                                Return Modable OrElse IsRelease
+                                Return Not IsRelease OrElse Modable
                             Case Else '隔离所有版本
                             Case Else '隔离所有版本
                                 Return True
                                 Return True
                         End Select
                         End Select
@@ -1133,7 +1134,7 @@ Reload:
 
 
             '改变当前选择的版本
             '改变当前选择的版本
 OnLoaded:
 OnLoaded:
-            If Loader.IsAborted Then Exit Sub
+            If Loader.IsAborted Then Return
             If McVersionList.Any(Function(v) v.Key <> McVersionCardType.Error) Then
             If McVersionList.Any(Function(v) v.Key <> McVersionCardType.Error) Then
                 '尝试读取已储存的选择
                 '尝试读取已储存的选择
                 Dim SavedSelection As String = ReadIni(Path & "PCL.ini", "Version")
                 Dim SavedSelection As String = ReadIni(Path & "PCL.ini", "Version")
@@ -1145,7 +1146,7 @@ OnLoaded:
                                 McVersionCurrent = Version
                                 McVersionCurrent = Version
                                 Setup.Set("LaunchVersionSelect", McVersionCurrent.Name)
                                 Setup.Set("LaunchVersionSelect", McVersionCurrent.Name)
                                 Log("[Minecraft] 选择该文件夹储存的 Minecraft 版本:" & McVersionCurrent.Path)
                                 Log("[Minecraft] 选择该文件夹储存的 Minecraft 版本:" & McVersionCurrent.Path)
-                                Exit Sub
+                                Return
                             End If
                             End If
                         Next
                         Next
                     Next
                     Next
@@ -1595,7 +1596,7 @@ OnLoaded:
         Try
         Try
             For Each SkinProperty In GetJson(SkinString)("properties")
             For Each SkinProperty In GetJson(SkinString)("properties")
                 If SkinProperty("name") = "textures" Then
                 If SkinProperty("name") = "textures" Then
-                    SkinValue = SkinProperty("value")
+                    SkinValue = SkinProperty("value").Replace("http:", "https:")
                     Exit Try
                     Exit Try
                 End If
                 End If
             Next
             Next
@@ -2263,7 +2264,7 @@ OnLoaded:
                 End If
                 End If
             Next
             Next
             '进行提示
             '进行提示
-            If Version Is Nothing Then Exit Sub
+            If Version Is Nothing Then Return
             Dim Time As Date = Version("releaseTime")
             Dim Time As Date = Version("releaseTime")
             Dim MsgBoxText As String = $"新版本:{VersionName}{vbCrLf}" &
             Dim MsgBoxText As String = $"新版本:{VersionName}{vbCrLf}" &
                 If((Date.Now - Time).TotalDays > 1, "更新时间:" & Time.ToString, "更新于:" & GetTimeSpanString(Time - Date.Now, False))
                 If((Date.Now - Time).TotalDays > 1, "更新时间:" & Time.ToString, "更新于:" & GetTimeSpanString(Time - Date.Now, False))
@@ -2368,26 +2369,33 @@ NextEntry:
     End Function
     End Function
 
 
     ''' <summary>
     ''' <summary>
-    ''' 为邮箱地址或手机号账号进行部分打码。
+    ''' 打码字符串中的 AccessToken。
     ''' </summary>
     ''' </summary>
-    Public Function AccountFilter(Account As String) As String
-        If Account.Contains("@") Then
-            '是邮箱
-            Dim Splits = Account.Split("@")
-            'If Splits(0).Count >= 6 Then
-            '    '前半部分至少 6 位,屏蔽后 4 位
-            '    Return Mid(Splits(0), 1, Splits(0).Count - 4) & "****" & "@" & Splits(1)
-            'Else
-            '前半部分不到 6 位,返回全 *
-            Return "".PadLeft(Splits(0).Count, "*") & "@" & Splits(1)
-            'End If
-        ElseIf Account.Count >= 6 Then
-            '至少 6 位,屏蔽后 4 位
-            Return Mid(Account, 1, Account.Count - 4) & "****"
-        Else
-            '不到 6 位,返回全 *
-            Return "".PadLeft(Account.Count, "*")
+    Public Function FilterAccessToken(Raw As String, FilterChar As Char) As String
+        '打码 "accessToken " 后的内容
+        If Raw.Contains("accessToken ") Then
+            For Each Token In RegexSearch(Raw, "(?<=accessToken ([^ ]{5}))[^ ]+(?=[^ ]{5})")
+                Raw = Raw.Replace(Token, New String(FilterChar, Token.Count))
+            Next
+        End If
+        '打码当前登录的结果
+        Dim AccessToken As String = McLoginLoader.Output.AccessToken
+        If AccessToken IsNot Nothing AndAlso AccessToken.Length >= 10 AndAlso Raw.ContainsF(AccessToken, True) AndAlso
+            McLoginLoader.Output.Uuid <> McLoginLoader.Output.AccessToken Then 'UUID 和 AccessToken 一样则不打码
+            Raw = Raw.Replace(AccessToken, Left(AccessToken, 5) & New String(FilterChar, AccessToken.Length - 10) & Right(AccessToken, 5))
+        End If
+        Return Raw
+    End Function
+    ''' <summary>
+    ''' 打码字符串中的 Windows 用户名。
+    ''' </summary>
+    Public Function FilterUserName(Raw As String, FilterChar As Char) As String
+        If Raw.Contains(":\Users\") Then
+            For Each Token In RegexSearch(Raw, "(?<=:\\Users\\)[^\\]+")
+                Raw = Raw.Replace(Token, New String(FilterChar, Token.Count))
+            Next
         End If
         End If
+        Return Raw
     End Function
     End Function
 
 
 End Module
 End Module

+ 16 - 16
Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb

@@ -188,9 +188,9 @@ Public Module ModMod
         Private _Dependencies As New Dictionary(Of String, String)
         Private _Dependencies As New Dictionary(Of String, String)
         Private Sub AddDependency(ModID As String, Optional VersionRequirement As String = Nothing)
         Private Sub AddDependency(ModID As String, Optional VersionRequirement As String = Nothing)
             '确保信息正确
             '确保信息正确
-            If ModID Is Nothing OrElse ModID.Count < 2 Then Exit Sub
+            If ModID Is Nothing OrElse ModID.Count < 2 Then Return
             ModID = ModID.ToLower
             ModID = ModID.ToLower
-            If ModID = "name" OrElse Val(ModID).ToString = ModID Then Exit Sub '跳过 name 与纯数字 id
+            If ModID = "name" OrElse Val(ModID).ToString = ModID Then Return '跳过 name 与纯数字 id
             If VersionRequirement Is Nothing OrElse ((Not VersionRequirement.Contains(".")) AndAlso (Not VersionRequirement.Contains("-"))) OrElse VersionRequirement.Contains("$") Then
             If VersionRequirement Is Nothing OrElse ((Not VersionRequirement.Contains(".")) AndAlso (Not VersionRequirement.Contains("-"))) OrElse VersionRequirement.Contains("$") Then
                 VersionRequirement = Nothing
                 VersionRequirement = Nothing
             Else
             Else
@@ -279,7 +279,7 @@ Public Module ModMod
         ''' 进行文件可用性检查与 .class 以外的信息获取。
         ''' 进行文件可用性检查与 .class 以外的信息获取。
         ''' </summary>
         ''' </summary>
         Public Sub Load(Optional ForceReload As Boolean = False)
         Public Sub Load(Optional ForceReload As Boolean = False)
-            If IsLoaded AndAlso Not ForceReload Then Exit Sub
+            If IsLoaded AndAlso Not ForceReload Then Return
             '初始化
             '初始化
             Init()
             Init()
             Dim Jar As ZipArchive = Nothing
             Dim Jar As ZipArchive = Nothing
@@ -819,7 +819,7 @@ Finished:
                 Try
                 Try
                     RunInUiWait(Sub() If FrmVersionMod IsNot Nothing Then FrmVersionMod.Load.Text = "正在更新 Mod")
                     RunInUiWait(Sub() If FrmVersionMod IsNot Nothing Then FrmVersionMod.Load.Text = "正在更新 Mod")
                     Do Until Not PageVersionMod.UpdatingVersions.Contains(Loader.Input)
                     Do Until Not PageVersionMod.UpdatingVersions.Contains(Loader.Input)
-                        If Loader.IsAborted Then Exit Sub
+                        If Loader.IsAborted Then Return
                         Thread.Sleep(100)
                         Thread.Sleep(100)
                     Loop
                     Loop
                 Finally
                 Finally
@@ -872,7 +872,7 @@ Finished:
             Dim ModUpdateList As New List(Of McMod)
             Dim ModUpdateList As New List(Of McMod)
             For Each ModFile As FileInfo In ModFileList
             For Each ModFile As FileInfo In ModFileList
                 Loader.Progress += 0.94 / ModFileList.Count
                 Loader.Progress += 0.94 / ModFileList.Count
-                If Loader.IsAborted Then Exit Sub
+                If Loader.IsAborted Then Return
                 '加载 McMod 对象
                 '加载 McMod 对象
                 Dim ModEntry As New McMod(ModFile.FullName)
                 Dim ModEntry As New McMod(ModFile.FullName)
                 ModEntry.Load()
                 ModEntry.Load()
@@ -912,7 +912,7 @@ Finished:
             End Function)
             End Function)
 
 
             '回设
             '回设
-            If Loader.IsAborted Then Exit Sub
+            If Loader.IsAborted Then Return
             Loader.Output = ModList
             Loader.Output = ModList
 
 
             '开始联网加载
             '开始联网加载
@@ -950,7 +950,7 @@ Finished:
                     $"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject)
                     $"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject)
                 Log($"[Mod] 从 Modrinth 获取到 {ModrinthVersion.Count} 个本地 Mod 的对应信息")
                 Log($"[Mod] 从 Modrinth 获取到 {ModrinthVersion.Count} 个本地 Mod 的对应信息")
                 '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
                 '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
-                If ModrinthVersion.Count = 0 Then Exit Sub
+                If ModrinthVersion.Count = 0 Then Return
                 Dim ModrinthMapping As New Dictionary(Of String, List(Of McMod))
                 Dim ModrinthMapping As New Dictionary(Of String, List(Of McMod))
                 For Each Entry In Mods
                 For Each Entry In Mods
                     If Not ModrinthVersion.ContainsKey(Entry.ModrinthHash) Then Continue For
                     If Not ModrinthVersion.ContainsKey(Entry.ModrinthHash) Then Continue For
@@ -963,10 +963,10 @@ Finished:
                     Dim File As New CompFile(ModrinthVersion(Entry.ModrinthHash), CompType.Mod)
                     Dim File As New CompFile(ModrinthVersion(Entry.ModrinthHash), CompType.Mod)
                     If Entry.CompFile Is Nothing OrElse Entry.CompFile.ReleaseDate < File.ReleaseDate Then Entry.CompFile = File
                     If Entry.CompFile Is Nothing OrElse Entry.CompFile.ReleaseDate < File.ReleaseDate Then Entry.CompFile = File
                 Next
                 Next
-                If Loader.IsAbortedWithThread(MainThread) Then Exit Sub
+                If Loader.IsAbortedWithThread(MainThread) Then Return
                 Log($"[Mod] 需要从 Modrinth 获取 {ModrinthMapping.Count} 个本地 Mod 的工程信息")
                 Log($"[Mod] 需要从 Modrinth 获取 {ModrinthMapping.Count} 个本地 Mod 的工程信息")
                 '步骤 3:获取工程信息
                 '步骤 3:获取工程信息
-                If Not ModrinthMapping.Any() Then Exit Sub
+                If Not ModrinthMapping.Any() Then Return
                 Dim ModrinthProject = CType(GetJson(DlModRequest(
                 Dim ModrinthProject = CType(GetJson(DlModRequest(
                     $"https://api.modrinth.com/v2/projects?ids=[""{ModrinthMapping.Keys.Join(""",""")}""]",
                     $"https://api.modrinth.com/v2/projects?ids=[""{ModrinthMapping.Keys.Join(""",""")}""]",
                     "GET", "", "application/json")), JArray)
                     "GET", "", "application/json")), JArray)
@@ -1013,13 +1013,13 @@ Finished:
                 Dim CurseForgeHashes As New List(Of UInteger)
                 Dim CurseForgeHashes As New List(Of UInteger)
                 For Each Entry In Mods
                 For Each Entry In Mods
                     CurseForgeHashes.Add(Entry.CurseForgeHash)
                     CurseForgeHashes.Add(Entry.CurseForgeHash)
-                    If Loader.IsAbortedWithThread(MainThread) Then Exit Sub
+                    If Loader.IsAbortedWithThread(MainThread) Then Return
                 Next
                 Next
                 Dim CurseForgeRaw = CType(CType(GetJson(DlModRequest("https://api.curseforge.com/v1/fingerprints/432", "POST",
                 Dim CurseForgeRaw = CType(CType(GetJson(DlModRequest("https://api.curseforge.com/v1/fingerprints/432", "POST",
                     $"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer)
                     $"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer)
                 Log($"[Mod] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息")
                 Log($"[Mod] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息")
                 '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
                 '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系
-                If Not CurseForgeRaw.Any() Then Exit Sub
+                If Not CurseForgeRaw.Any() Then Return
                 Dim CurseForgeMapping As New Dictionary(Of Integer, List(Of McMod))
                 Dim CurseForgeMapping As New Dictionary(Of Integer, List(Of McMod))
                 For Each Project In CurseForgeRaw
                 For Each Project In CurseForgeRaw
                     Dim ProjectId = Project("id").ToString
                     Dim ProjectId = Project("id").ToString
@@ -1034,10 +1034,10 @@ Finished:
                         If Entry.CompFile Is Nothing OrElse Entry.CompFile.ReleaseDate < File.ReleaseDate Then Entry.CompFile = File
                         If Entry.CompFile Is Nothing OrElse Entry.CompFile.ReleaseDate < File.ReleaseDate Then Entry.CompFile = File
                     Next
                     Next
                 Next
                 Next
-                If Loader.IsAbortedWithThread(MainThread) Then Exit Sub
+                If Loader.IsAbortedWithThread(MainThread) Then Return
                 Log($"[Mod] 需要从 CurseForge 获取 {CurseForgeMapping.Count} 个本地 Mod 的工程信息")
                 Log($"[Mod] 需要从 CurseForge 获取 {CurseForgeMapping.Count} 个本地 Mod 的工程信息")
                 '步骤 3:获取工程信息
                 '步骤 3:获取工程信息
-                If Not CurseForgeMapping.Any() Then Exit Sub
+                If Not CurseForgeMapping.Any() Then Return
                 Dim CurseForgeProject = CType(GetJson(DlModRequest("https://api.curseforge.com/v1/mods", "POST",
                 Dim CurseForgeProject = CType(GetJson(DlModRequest("https://api.curseforge.com/v1/mods", "POST",
                     $"{{""modIds"": [{CurseForgeMapping.Keys.Join(",")}]}}", "application/json")), JObject)("data")
                     $"{{""modIds"": [{CurseForgeMapping.Keys.Join(",")}]}}", "application/json")), JObject)("data")
                 Dim UpdateFileIds As New Dictionary(Of Integer, List(Of McMod)) 'FileId -> 本地 Mod 文件列表
                 Dim UpdateFileIds As New Dictionary(Of Integer, List(Of McMod)) 'FileId -> 本地 Mod 文件列表
@@ -1078,7 +1078,7 @@ Finished:
                 Next
                 Next
                 Log($"[Mod] 已从 CurseForge 获取本地 Mod 信息,需要获取 {UpdateFileIds.Count} 个用于检查更新的文件信息")
                 Log($"[Mod] 已从 CurseForge 获取本地 Mod 信息,需要获取 {UpdateFileIds.Count} 个用于检查更新的文件信息")
                 '步骤 4:获取更新文件信息
                 '步骤 4:获取更新文件信息
-                If Not UpdateFileIds.Any() Then Exit Sub
+                If Not UpdateFileIds.Any() Then Return
                 Dim CurseForgeFiles = CType(GetJson(DlModRequest("https://api.curseforge.com/v1/mods/files", "POST",
                 Dim CurseForgeFiles = CType(GetJson(DlModRequest("https://api.curseforge.com/v1/mods/files", "POST",
                                     $"{{""fileIds"": [{UpdateFileIds.Keys.Join(",")}]}}", "application/json")), JObject)("data")
                                     $"{{""fileIds"": [{UpdateFileIds.Keys.Join(",")}]}}", "application/json")), JObject)("data")
                 Dim UpdateFiles As New Dictionary(Of McMod, CompFile)
                 Dim UpdateFiles As New Dictionary(Of McMod, CompFile)
@@ -1114,13 +1114,13 @@ Finished:
         End Sub, "Mod List Detail Loader CurseForge")
         End Sub, "Mod List Detail Loader CurseForge")
         '等待线程结束
         '等待线程结束
         Do Until EndedThreadCount = 2
         Do Until EndedThreadCount = 2
-            If Loader.IsAborted Then Exit Sub
+            If Loader.IsAborted Then Return
             Thread.Sleep(10)
             Thread.Sleep(10)
         Loop
         Loop
         '保存缓存
         '保存缓存
         Mods = Mods.Where(Function(m) m.Comp IsNot Nothing).ToList()
         Mods = Mods.Where(Function(m) m.Comp IsNot Nothing).ToList()
         Log($"[Mod] 联网获取本地 Mod 信息完成,为 {Mods.Count} 个 Mod 更新缓存")
         Log($"[Mod] 联网获取本地 Mod 信息完成,为 {Mods.Count} 个 Mod 更新缓存")
-        If Not Mods.Any() Then Exit Sub
+        If Not Mods.Any() Then Return
         For Each Entry In Mods
         For Each Entry In Mods
             Entry.CompLoaded = Not IsFailed
             Entry.CompLoaded = Not IsFailed
             Cache(Entry.ModrinthHash & McVersion & ModLoaders.Join("")) = Entry.ToJson()
             Cache(Entry.ModrinthHash & McVersion & ModLoaders.Join("")) = Entry.ToJson()

+ 9 - 2
Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb

@@ -8,7 +8,7 @@ Public Module ModModpack
     ''' </summary>
     ''' </summary>
     Public Sub ModpackInstall()
     Public Sub ModpackInstall()
         Dim File As String = SelectFile("整合包文件(*.rar;*.zip;*.mrpack)|*.rar;*.zip;*.mrpack", "选择整合包压缩文件") '选择整合包文件
         Dim File As String = SelectFile("整合包文件(*.rar;*.zip;*.mrpack)|*.rar;*.zip;*.mrpack", "选择整合包压缩文件") '选择整合包文件
-        If String.IsNullOrEmpty(File) Then Exit Sub
+        If String.IsNullOrEmpty(File) Then Return
         RunInThread(
         RunInThread(
         Sub()
         Sub()
             Try
             Try
@@ -128,7 +128,7 @@ Retry:
             '完全不知道为啥会出现文件正在被另一进程使用的问题,总之加个重试
             '完全不知道为啥会出现文件正在被另一进程使用的问题,总之加个重试
             If RetryCount < 5 Then
             If RetryCount < 5 Then
                 Thread.Sleep(RetryCount * 2000)
                 Thread.Sleep(RetryCount * 2000)
-                If Loader IsNot Nothing AndAlso Loader.LoadingState <> MyLoading.MyLoadingState.Run Then Exit Sub
+                If Loader IsNot Nothing AndAlso Loader.LoadingState <> MyLoading.MyLoadingState.Run Then Return
                 RetryCount += 1
                 RetryCount += 1
                 GoTo Retry
                 GoTo Retry
             Else
             Else
@@ -693,6 +693,7 @@ Retry:
         End If
         End If
         '解压
         '解压
         Dim InstallTemp As String = RequestTaskTempFolder()
         Dim InstallTemp As String = RequestTaskTempFolder()
+        Dim SetupFile As String = $"{PathMcFolder}versions\{VersionName}\PCL\Setup.ini"
         Dim InstallLoaders As New List(Of LoaderBase)
         Dim InstallLoaders As New List(Of LoaderBase)
         InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
         InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
         Sub(Task As LoaderTask(Of String, Integer))
         Sub(Task As LoaderTask(Of String, Integer))
@@ -701,6 +702,12 @@ Retry:
                 InstallTemp & ArchiveBaseFolder & "overrides",
                 InstallTemp & ArchiveBaseFolder & "overrides",
                 PathMcFolder & "versions\" & VersionName,
                 PathMcFolder & "versions\" & VersionName,
                 Task, 0.4)
                 Task, 0.4)
+            'JVM 参数
+            If Json("launchInfo") IsNot Nothing Then
+                Dim LaunchInfo As JObject = Json("launchInfo")
+                If LaunchInfo.ContainsKey("javaArgument") Then WriteIni(SetupFile, "VersionAdvanceJvm", String.Join(" ", LaunchInfo("javaArgument")))
+                If LaunchInfo.ContainsKey("launchArgument") Then WriteIni(SetupFile, "VersionAdvanceGame", String.Join(" ", LaunchInfo("launchArgument")))
+            End If
         End Sub) With {.ProgressWeight = New FileInfo(FileAddress).Length / 1024 / 1024 / 6, .Block = False}) '每 6M 需要 1s
         End Sub) With {.ProgressWeight = New FileInfo(FileAddress).Length / 1024 / 1024 / 6, .Block = False}) '每 6M 需要 1s
         '构造加载器
         '构造加载器
         If Json("addons") Is Nothing Then Throw New Exception("该 MCBBS 整合包未提供游戏版本附加信息,无法安装!")
         If Json("addons") Is Nothing Then Throw New Exception("该 MCBBS 整合包未提供游戏版本附加信息,无法安装!")

+ 15 - 14
Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb

@@ -15,7 +15,7 @@
                 TriggerLauncherShutdown = False
                 TriggerLauncherShutdown = False
             End If
             End If
         Next
         Next
-        If IsWatcherRunning = IsRunning Then Exit Sub
+        If IsWatcherRunning = IsRunning Then Return
         IsWatcherRunning = IsRunning
         IsWatcherRunning = IsRunning
         If IsWatcherRunning Then
         If IsWatcherRunning Then
             MinecraftStart()
             MinecraftStart()
@@ -81,7 +81,7 @@
             WatcherStateChanged()
             WatcherStateChanged()
 
 
             '初始化进程与日志读取
             '初始化进程与日志读取
-            Me.GameProcess = Loader.Input
+            GameProcess = Loader.Input
             GameProcess.BeginOutputReadLine()
             GameProcess.BeginOutputReadLine()
             GameProcess.BeginErrorReadLine()
             GameProcess.BeginErrorReadLine()
             AddHandler GameProcess.OutputDataReceived, AddressOf LogReceived
             AddHandler GameProcess.OutputDataReceived, AddressOf LogReceived
@@ -118,7 +118,7 @@
                 Return _State
                 Return _State
             End Get
             End Get
             Set(value As MinecraftState)
             Set(value As MinecraftState)
-                If _State = value Then Exit Property
+                If _State = value Then Return
                 _State = value
                 _State = value
                 WatcherStateChanged()
                 WatcherStateChanged()
             End Set
             End Set
@@ -144,7 +144,7 @@
                 '输出文本
                 '输出文本
                 Dim Copyed As New List(Of String)
                 Dim Copyed As New List(Of String)
                 SyncLock WaitingLogLock
                 SyncLock WaitingLogLock
-                    If Not WaitingLog.Any() Then Exit Sub
+                    If Not WaitingLog.Any() Then Return
                     Copyed = WaitingLog
                     Copyed = WaitingLog
                     WaitingLog = New List(Of String)(1000)
                     WaitingLog = New List(Of String)(1000)
                 End SyncLock
                 End SyncLock
@@ -180,8 +180,9 @@
         Public LatestLog As New Queue(Of String)
         Public LatestLog As New Queue(Of String)
         Private Sub GameLog(Text As String)
         Private Sub GameLog(Text As String)
             '预处理
             '预处理
-            If Text Is Nothing Then Exit Sub
+            If Text Is Nothing Then Return
             Text = Text.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr, vbCrLf)
             Text = Text.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr, vbCrLf)
+            'If Text.Contains("�����") Then Hint("检测到错误的日志编码:" & Text)
             '加入预存储
             '加入预存储
             LatestLog.Enqueue(Text)
             LatestLog.Enqueue(Text)
             If LatestLog.Count >= 501 Then LatestLog.Dequeue()
             If LatestLog.Count >= 501 Then LatestLog.Dequeue()
@@ -256,8 +257,8 @@
         Private WindowHandle As IntPtr
         Private WindowHandle As IntPtr
         Private Sub TimerWindow()
         Private Sub TimerWindow()
             Try
             Try
-                If GameProcess.HasExited Then Exit Sub
-                If IsWindowFinished Then Exit Sub
+                If GameProcess.HasExited Then Return
+                If IsWindowFinished Then Return
                 '获取全部窗口,检查是否有新增的
                 '获取全部窗口,检查是否有新增的
                 Dim MinecraftWindow As KeyValuePair(Of IntPtr, String)? = Nothing
                 Dim MinecraftWindow As KeyValuePair(Of IntPtr, String)? = Nothing
                 Try
                 Try
@@ -267,7 +268,7 @@
                     Log(ex, "由于反作弊或安全软件拦截,PCL 无法操作游戏窗口", LogLevel.Hint)
                     Log(ex, "由于反作弊或安全软件拦截,PCL 无法操作游戏窗口", LogLevel.Hint)
                     IsWindowFinished = True
                     IsWindowFinished = True
                 End Try
                 End Try
-                If MinecraftWindow Is Nothing Then Exit Sub
+                If MinecraftWindow Is Nothing Then Return
                 Dim MinecraftWindowName = MinecraftWindow.Value.Value, MinecraftWindowHandle = MinecraftWindow.Value.Key
                 Dim MinecraftWindowName = MinecraftWindow.Value.Value, MinecraftWindowHandle = MinecraftWindow.Value.Key
                 '已找到窗口
                 '已找到窗口
                 If Not MinecraftWindowName.StartsWithF("FML") Then
                 If Not MinecraftWindowName.StartsWithF("FML") Then
@@ -307,27 +308,27 @@
             TryGetMinecraftWindow = Nothing
             TryGetMinecraftWindow = Nothing
             EnumWindows(
             EnumWindows(
                 Sub(hwnd As IntPtr, lParam As Integer)
                 Sub(hwnd As IntPtr, lParam As Integer)
-                    If TryGetMinecraftWindow IsNot Nothing Then Exit Sub
+                    If TryGetMinecraftWindow IsNot Nothing Then Return
                     '检查类名
                     '检查类名
                     Dim str As New StringBuilder(512)
                     Dim str As New StringBuilder(512)
                     GetClassName(hwnd, str, str.Capacity)
                     GetClassName(hwnd, str, str.Capacity)
                     Dim ClassName As String = str.ToString
                     Dim ClassName As String = str.ToString
-                    If Not (ClassName = "GLFW30" OrElse ClassName = "LWJGL" OrElse ClassName = "SunAwtFrame") Then Exit Sub
+                    If Not (ClassName = "GLFW30" OrElse ClassName = "LWJGL" OrElse ClassName = "SunAwtFrame") Then Return
                     '获取窗口标题名
                     '获取窗口标题名
                     str = New StringBuilder(512)
                     str = New StringBuilder(512)
                     GetWindowText(hwnd, str, str.Capacity)
                     GetWindowText(hwnd, str, str.Capacity)
                     Dim WindowText As String = str.ToString
                     Dim WindowText As String = str.ToString
                     '有的 Mod 可以修改窗口标题,所以不能检测是否为 Minecraft 打头,这并不准确
                     '有的 Mod 可以修改窗口标题,所以不能检测是否为 Minecraft 打头,这并不准确
                     '部分版本会搞个 GLFW message window 出来所以得反选
                     '部分版本会搞个 GLFW message window 出来所以得反选
-                    If Not (WindowText.StartsWithF("FML") OrElse (WindowText <> "PopupMessageWindow") AndAlso Not WindowText.StartsWithF("GLFW")) Then Exit Sub
+                    If Not (WindowText.StartsWithF("FML") OrElse (WindowText <> "PopupMessageWindow") AndAlso Not WindowText.StartsWithF("GLFW")) Then Return
                     '获取窗口关联的进程
                     '获取窗口关联的进程
                     Dim ProcessId As Integer
                     Dim ProcessId As Integer
                     GetWindowThreadProcessId(hwnd, ProcessId)
                     GetWindowThreadProcessId(hwnd, ProcessId)
                     Try
                     Try
-                        If Process.GetProcessById(ProcessId).StartTime < GameProcess.StartTime Then Exit Sub '需要是此后启动的进程
+                        If Process.GetProcessById(ProcessId).StartTime < GameProcess.StartTime Then Return '需要是此后启动的进程
                     Catch ex As Exception
                     Catch ex As Exception
                         Log(ex, "枚举 Minecraft 窗口进程失败")
                         Log(ex, "枚举 Minecraft 窗口进程失败")
-                        Exit Sub
+                        Return
                     End Try
                     End Try
                     '返回
                     '返回
                     TryGetMinecraftWindow = New KeyValuePair(Of IntPtr, String)(hwnd, WindowText)
                     TryGetMinecraftWindow = New KeyValuePair(Of IntPtr, String)(hwnd, WindowText)
@@ -344,7 +345,7 @@
 
 
         '崩溃处理
         '崩溃处理
         Private Sub Crashed()
         Private Sub Crashed()
-            If State = MinecraftState.Crashed OrElse State = MinecraftState.Ended Then Exit Sub
+            If State = MinecraftState.Crashed OrElse State = MinecraftState.Ended Then Return
             State = MinecraftState.Crashed
             State = MinecraftState.Crashed
             '崩溃分析
             '崩溃分析
             WatcherLog("Minecraft 已崩溃,将在 2 秒后开始崩溃分析")
             WatcherLog("Minecraft 已崩溃,将在 2 秒后开始崩溃分析")

+ 5 - 5
Plain Craft Launcher 2/Modules/ModEvent.vb

@@ -1,7 +1,7 @@
 Public Module ModEvent
 Public Module ModEvent
 
 
     Public Sub TryStartEvent(Type As String, Data As String)
     Public Sub TryStartEvent(Type As String, Data As String)
-        If String.IsNullOrWhiteSpace(Type) Then Exit Sub
+        If String.IsNullOrWhiteSpace(Type) Then Return
         Dim RealData As String() = {""}
         Dim RealData As String() = {""}
         If Data IsNot Nothing Then RealData = Data.Split("|")
         If Data IsNot Nothing Then RealData = Data.Split("|")
         StartEvent(Type, RealData)
         StartEvent(Type, RealData)
@@ -15,7 +15,7 @@
                     Data(0) = Data(0).Replace("\", "/")
                     Data(0) = Data(0).Replace("\", "/")
                     If Not Data(0).Contains("://") OrElse Data(0).StartsWithF("file", True) Then '为了支持更多协议(#2200)
                     If Not Data(0).Contains("://") OrElse Data(0).StartsWithF("file", True) Then '为了支持更多协议(#2200)
                         MyMsgBox("EventData 必须为一个网址。" & vbCrLf & "如果想要启动程序,请将 EventType 改为 打开文件。", "事件执行失败")
                         MyMsgBox("EventData 必须为一个网址。" & vbCrLf & "如果想要启动程序,请将 EventType 改为 打开文件。", "事件执行失败")
-                        Exit Sub
+                        Return
                     End If
                     End If
                     Hint("正在开启中,请稍候……")
                     Hint("正在开启中,请稍候……")
                     OpenWebsite(Data(0))
                     OpenWebsite(Data(0))
@@ -39,7 +39,7 @@
                                         Case 2
                                         Case 2
                                             Setup.Set("HintCustomCommand", True)
                                             Setup.Set("HintCustomCommand", True)
                                         Case 3
                                         Case 3
-                                            Exit Sub
+                                            Return
                                     End Select
                                     End Select
                                 End If
                                 End If
                                 Dim Info As New ProcessStartInfo With {
                                 Dim Info As New ProcessStartInfo With {
@@ -58,7 +58,7 @@
                     If Data(0) = "\current" Then
                     If Data(0) = "\current" Then
                         If McVersionCurrent Is Nothing Then
                         If McVersionCurrent Is Nothing Then
                             Hint("请先选择一个 Minecraft 版本!", HintType.Critical)
                             Hint("请先选择一个 Minecraft 版本!", HintType.Critical)
-                            Exit Sub
+                            Return
                         Else
                         Else
                             Data(0) = McVersionCurrent.Name
                             Data(0) = McVersionCurrent.Name
                         End If
                         End If
@@ -100,7 +100,7 @@
                     Data(0) = Data(0).Replace("\", "/")
                     Data(0) = Data(0).Replace("\", "/")
                     If Not (Data(0).StartsWithF("http://", True) OrElse Data(0).StartsWithF("https://", True)) Then
                     If Not (Data(0).StartsWithF("http://", True) OrElse Data(0).StartsWithF("https://", True)) Then
                         MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败")
                         MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败")
-                        Exit Sub
+                        Return
                     End If
                     End If
                     Try
                     Try
                         Select Case Data.Length
                         Select Case Data.Length

+ 19 - 18
Plain Craft Launcher 2/Modules/ModMain.vb

@@ -34,12 +34,12 @@ Public Module ModMain
     ''' <summary>
     ''' <summary>
     ''' 等待弹出的提示列表。以 {String, HintType, Log As Boolean} 形式存储为数组。
     ''' 等待弹出的提示列表。以 {String, HintType, Log As Boolean} 形式存储为数组。
     ''' </summary>
     ''' </summary>
-    Private HintWaiting As List(Of HintMessage) = If(HintWaiting, New List(Of HintMessage))
+    Private HintWaiting As SafeList(Of HintMessage) = If(HintWaiting, New SafeList(Of HintMessage))
     ''' <summary>
     ''' <summary>
     ''' 在窗口左下角弹出提示文本。
     ''' 在窗口左下角弹出提示文本。
     ''' </summary>
     ''' </summary>
     Public Sub Hint(Text As String, Optional Type As HintType = HintType.Info, Optional Log As Boolean = True)
     Public Sub Hint(Text As String, Optional Type As HintType = HintType.Info, Optional Log As Boolean = True)
-        If HintWaiting Is Nothing Then HintWaiting = New List(Of HintMessage)
+        If HintWaiting Is Nothing Then HintWaiting = New SafeList(Of HintMessage)
         HintWaiting.Add(New HintMessage With {.Text = If(Text, ""), .Type = Type, .Log = Log})
         HintWaiting.Add(New HintMessage With {.Text = If(Text, ""), .Type = Type, .Log = Log})
     End Sub
     End Sub
 
 
@@ -47,7 +47,7 @@ Public Module ModMain
         Try
         Try
 
 
             'Tag 存储了:{ 是否可以重用, Uuid }
             'Tag 存储了:{ 是否可以重用, Uuid }
-            If Not HintWaiting.Any() Then Exit Sub
+            If Not HintWaiting.Any() Then Return
             Do While HintWaiting.Any
             Do While HintWaiting.Any
                 ''清除空提示
                 ''清除空提示
                 'If IsNothing(HintWaiting(0)) OrElse IsNothing(HintWaiting(0)(0)) Then
                 'If IsNothing(HintWaiting(0)) OrElse IsNothing(HintWaiting(0)(0)) Then
@@ -343,7 +343,7 @@ EndHint:
     Public WaitingMyMsgBox As List(Of MyMsgBoxConverter) = If(WaitingMyMsgBox, New List(Of MyMsgBoxConverter))
     Public WaitingMyMsgBox As List(Of MyMsgBoxConverter) = If(WaitingMyMsgBox, New List(Of MyMsgBoxConverter))
     Public Sub MyMsgBoxTick()
     Public Sub MyMsgBoxTick()
         Try
         Try
-            If FrmMain Is Nothing OrElse FrmMain.PanMsg Is Nothing OrElse FrmMain.WindowState = WindowState.Minimized Then Exit Sub
+            If FrmMain Is Nothing OrElse FrmMain.PanMsg Is Nothing OrElse FrmMain.WindowState = WindowState.Minimized Then Return
             If FrmMain.PanMsg.Children.Count > 0 Then
             If FrmMain.PanMsg.Children.Count > 0 Then
                 '弹窗中
                 '弹窗中
                 FrmMain.PanMsg.Visibility = Visibility.Visible
                 FrmMain.PanMsg.Visibility = Visibility.Visible
@@ -637,7 +637,7 @@ NextFile:
                 Catch ex As Exception
                 Catch ex As Exception
                     Log(ex, "检查帮助文件夹失败", LogLevel.Msgbox)
                     Log(ex, "检查帮助文件夹失败", LogLevel.Msgbox)
                 End Try
                 End Try
-                If Loader.IsAborted Then Exit Sub
+                If Loader.IsAborted Then Return
 
 
                 '将文件实例化
                 '将文件实例化
                 Dim Dict As New List(Of HelpEntry)
                 Dim Dict As New List(Of HelpEntry)
@@ -653,7 +653,7 @@ NextFile:
 
 
                 '回设
                 '回设
                 If Not Dict.Any() Then Throw New Exception("未找到可用的帮助;若不需要帮助页面,可以在 设置 → 个性化 → 功能隐藏 中将其隐藏")
                 If Not Dict.Any() Then Throw New Exception("未找到可用的帮助;若不需要帮助页面,可以在 设置 → 个性化 → 功能隐藏 中将其隐藏")
-                If Loader.IsAborted Then Exit Sub
+                If Loader.IsAborted Then Return
                 Loader.Output = Dict
                 Loader.Output = Dict
 
 
             Catch ex As Exception
             Catch ex As Exception
@@ -696,8 +696,8 @@ NextFile:
     Private AprilDistance As Integer = 0
     Private AprilDistance As Integer = 0
     Private Sub TimerFool()
     Private Sub TimerFool()
         Try
         Try
-            If FrmLaunchLeft Is Nothing OrElse FrmLaunchLeft.AprilPosTrans Is Nothing OrElse FrmMain.lastMouseArg Is Nothing Then Exit Sub
-            If IsAprilGiveup OrElse FrmMain.PageCurrent <> FormMain.PageType.Launch OrElse AniControlEnabled <> 0 OrElse Not FrmLaunchLeft.BtnLaunch.IsLoaded Then Exit Sub
+            If FrmLaunchLeft Is Nothing OrElse FrmLaunchLeft.AprilPosTrans Is Nothing OrElse FrmMain.lastMouseArg Is Nothing Then Return
+            If IsAprilGiveup OrElse FrmMain.PageCurrent <> FormMain.PageType.Launch OrElse AniControlEnabled <> 0 OrElse Not FrmLaunchLeft.BtnLaunch.IsLoaded Then Return
 
 
             '计算是否空闲
             '计算是否空闲
             Dim MousePos = FrmMain.lastMouseArg.GetPosition(FrmMain)
             Dim MousePos = FrmMain.lastMouseArg.GetPosition(FrmMain)
@@ -766,7 +766,7 @@ NextFile:
             '移动
             '移动
             AprilSpeed = AprilSpeed * 0.8 + Acc
             AprilSpeed = AprilSpeed * 0.8 + Acc
             Dim SpeedValue = Math.Min(60, AprilSpeed.Length)
             Dim SpeedValue = Math.Min(60, AprilSpeed.Length)
-            If SpeedValue < 0.01 Then Exit Sub
+            If SpeedValue < 0.01 Then Return
             AprilSpeed.Normalize()
             AprilSpeed.Normalize()
             AprilSpeed *= SpeedValue
             AprilSpeed *= SpeedValue
             AprilDistance += SpeedValue
             AprilDistance += SpeedValue
@@ -913,7 +913,7 @@ NextFile:
             If ThemeDontClick = 2 Then ThemeRefresh()
             If ThemeDontClick = 2 Then ThemeRefresh()
 #End Region
 #End Region
         Catch ex As Exception
         Catch ex As Exception
-            Log(ex, "短程主时钟执行异常", LogLevel.Assert)
+            Log(ex, "短程主时钟执行异常", LogLevel.Critical)
         End Try
         End Try
         Timer4Count += 1
         Timer4Count += 1
         If Timer4Count = 4 Then
         If Timer4Count = 4 Then
@@ -933,15 +933,16 @@ NextFile:
 #Region "每 7.5s 执行一次的代码"
 #Region "每 7.5s 执行一次的代码"
                 If FrmMain.BtnExtraApril_ShowCheck AndAlso AprilDistance <> 0 Then FrmMain.BtnExtraApril.Ribble()
                 If FrmMain.BtnExtraApril_ShowCheck AndAlso AprilDistance <> 0 Then FrmMain.BtnExtraApril.Ribble()
                 '以未知原因窗口被丢到一边去的修复(Top、Left = -25600),还有 #745
                 '以未知原因窗口被丢到一边去的修复(Top、Left = -25600),还有 #745
-                RunInUi(Sub()
-                            If Not FrmMain.Hidden Then
-                                If FrmMain.Top < -9000 Then FrmMain.Top = 100
-                                If FrmMain.Left < -9000 Then FrmMain.Left = 100 '窗口拉至最大时 Left = -18.8
-                            End If
-                        End Sub)
+                RunInUi(
+                Sub()
+                    If Not FrmMain.Hidden Then
+                        If FrmMain.Top < -9000 Then FrmMain.Top = 100
+                        If FrmMain.Left < -9000 Then FrmMain.Left = 100 '窗口拉至最大时 Left = -18.8
+                    End If
+                End Sub)
 #End Region
 #End Region
             Catch ex As Exception
             Catch ex As Exception
-                Log(ex, "长程主时钟执行异常", LogLevel.Assert)
+                Log(ex, "长程主时钟执行异常", LogLevel.Critical)
             End Try
             End Try
         End If
         End If
     End Sub
     End Sub
@@ -957,7 +958,7 @@ NextFile:
                 Log(ex, "程序主时钟出错", LogLevel.Feedback)
                 Log(ex, "程序主时钟出错", LogLevel.Feedback)
             End Try
             End Try
         End Sub, "Timer Main")
         End Sub, "Timer Main")
-        If Not IsAprilEnabled Then Exit Sub
+        If Not IsAprilEnabled Then Return
         RunInNewThread(
         RunInNewThread(
         Sub()
         Sub()
             Try
             Try

+ 44 - 25
Plain Craft Launcher 2/Modules/ModSecret.vb

@@ -68,26 +68,6 @@ Friend Module ModSecret
         If Not DataList.Any(Function(d) d.Contains("-Dlog4j2.formatMsgNoLookups=true")) Then DataList.Add("-Dlog4j2.formatMsgNoLookups=true")
         If Not DataList.Any(Function(d) d.Contains("-Dlog4j2.formatMsgNoLookups=true")) Then DataList.Add("-Dlog4j2.formatMsgNoLookups=true")
     End Sub
     End Sub
 
 
-    ''' <summary>
-    ''' 打码字符串中的 AccessToken。
-    ''' </summary>
-    Friend Function SecretFilter(Raw As String, FilterChar As Char) As String
-        '打码 "accessToken " 后的内容
-        If Raw.Contains("accessToken ") Then
-            For Each Token In RegexSearch(Raw, "(?<=accessToken ([^ ]{5}))[^ ]+(?=[^ ]{5})")
-                Raw = Raw.Replace(Token, New String(FilterChar, Token.Count))
-            Next
-        End If
-        '打码当前登录的结果
-        Dim AccessToken As String = McLoginLoader.Output.AccessToken
-        If AccessToken Is Nothing OrElse AccessToken.Length < 10 OrElse Not Raw.ContainsF(AccessToken, True) OrElse
-            McLoginLoader.Output.Uuid = McLoginLoader.Output.AccessToken Then 'UUID 和 AccessToken 一样则不打码
-            Return Raw
-        Else
-            Return Raw.Replace(AccessToken, Left(AccessToken, 5) & New String(FilterChar, AccessToken.Length - 10) & Right(AccessToken, 5))
-        End If
-    End Function
-
 #End Region
 #End Region
 
 
 #Region "网络鉴权"
 #Region "网络鉴权"
@@ -199,12 +179,51 @@ Friend Module ModSecret
     Public ThemeDontClick As Integer = 0
     Public ThemeDontClick As Integer = 0
 
 
     Public Sub ThemeRefresh(Optional NewTheme As Integer = -1)
     Public Sub ThemeRefresh(Optional NewTheme As Integer = -1)
-        Hint("该版本中不包含主题功能……")
+        Try
+            If ThemeNow = NewTheme AndAlso NewTheme >= 0 Then Return
+            If NewTheme >= 0 Then ThemeNow = NewTheme
+
+            Color1 = New MyColor().FromHSL2(ColorHue, ColorSat * 0.2, 25 + ColorLightAdjust * 0.3)
+            Color2 = New MyColor().FromHSL2(ColorHue, ColorSat, 45 + ColorLightAdjust)
+            Color3 = New MyColor().FromHSL2(ColorHue, ColorSat, 55 + ColorLightAdjust)
+            Color4 = New MyColor().FromHSL2(ColorHue, ColorSat, 65 + ColorLightAdjust)
+            Color5 = New MyColor().FromHSL2(ColorHue, ColorSat, 80 + ColorLightAdjust * 0.4)
+            Color6 = New MyColor().FromHSL2(ColorHue, ColorSat, 91 + ColorLightAdjust * 0.1)
+            Color7 = New MyColor().FromHSL2(ColorHue, ColorSat, 95)
+            Color8 = New MyColor().FromHSL2(ColorHue, ColorSat, 97)
+            ColorBg0 = Color4 * 0.4 + Color5 * 0.4 + ColorGray4 * 0.2
+            ColorBg1 = New MyColor(190, Color7)
+
+            ColorSemiTransparent = New MyColor(1, Color8)
+            Application.Current.Resources("ColorBrush1") = New SolidColorBrush(Color1)
+            Application.Current.Resources("ColorBrush2") = New SolidColorBrush(Color2)
+            Application.Current.Resources("ColorBrush3") = New SolidColorBrush(Color3)
+            Application.Current.Resources("ColorBrush4") = New SolidColorBrush(Color4)
+            Application.Current.Resources("ColorBrush5") = New SolidColorBrush(Color5)
+            Application.Current.Resources("ColorBrush6") = New SolidColorBrush(Color6)
+            Application.Current.Resources("ColorBrush7") = New SolidColorBrush(Color7)
+            Application.Current.Resources("ColorBrush8") = New SolidColorBrush(Color8)
+            Application.Current.Resources("ColorBrushBg0") = New SolidColorBrush(ColorBg0)
+            Application.Current.Resources("ColorBrushBg1") = New SolidColorBrush(ColorBg1)
+            Application.Current.Resources("ColorObject1") = CType(Color1, Color)
+            Application.Current.Resources("ColorObject2") = CType(Color2, Color)
+            Application.Current.Resources("ColorObject3") = CType(Color3, Color)
+            Application.Current.Resources("ColorObject4") = CType(Color4, Color)
+            Application.Current.Resources("ColorObject5") = CType(Color5, Color)
+            Application.Current.Resources("ColorObject6") = CType(Color6, Color)
+            Application.Current.Resources("ColorObject7") = CType(Color7, Color)
+            Application.Current.Resources("ColorObject8") = CType(Color8, Color)
+            Application.Current.Resources("ColorObjectBg0") = CType(ColorBg0, Color)
+            Application.Current.Resources("ColorObjectBg1") = CType(ColorBg1, Color)
+            ThemeRefreshMain()
+        Catch ex As Exception
+            Log(ex, "刷新主题颜色失败", LogLevel.Hint)
+        End Try
     End Sub
     End Sub
     Public Sub ThemeRefreshMain()
     Public Sub ThemeRefreshMain()
         RunInUi(
         RunInUi(
         Sub()
         Sub()
-            If Not FrmMain.IsLoaded Then Exit Sub
+            If Not FrmMain.IsLoaded Then Return
             '顶部条背景
             '顶部条背景
             Dim Brush = New LinearGradientBrush With {.EndPoint = New Point(1, 0), .StartPoint = New Point(0, 0)}
             Dim Brush = New LinearGradientBrush With {.EndPoint = New Point(1, 0), .StartPoint = New Point(0, 0)}
             If ThemeNow = 5 Then
             If ThemeNow = 5 Then
@@ -235,9 +254,9 @@ Friend Module ModSecret
             '主页面背景
             '主页面背景
             If Setup.Get("UiBackgroundColorful") Then
             If Setup.Get("UiBackgroundColorful") Then
                 Brush = New LinearGradientBrush With {.EndPoint = New Point(0.1, 1), .StartPoint = New Point(0.9, 0)}
                 Brush = New LinearGradientBrush With {.EndPoint = New Point(0.1, 1), .StartPoint = New Point(0.9, 0)}
-                Brush.GradientStops.Add(New GradientStop With {.Offset = -0.1, .Color = New MyColor().FromHSL2(ColorHue - 20, Math.Min(60, ColorSat) * 0.5, 80)})
-                Brush.GradientStops.Add(New GradientStop With {.Offset = 0.4, .Color = New MyColor().FromHSL2(ColorHue, ColorSat * 0.9, 90)})
-                Brush.GradientStops.Add(New GradientStop With {.Offset = 1.1, .Color = New MyColor().FromHSL2(ColorHue + 20, Math.Min(60, ColorSat) * 0.5, 80)})
+                Brush.GradientStops.Add(New GradientStop With {.Offset = -0.1, .Color = New MyColor().FromHSL2(ColorHue - 15, ColorSat * 0.8, 91)})
+                Brush.GradientStops.Add(New GradientStop With {.Offset = 0.4, .Color = New MyColor().FromHSL2(ColorHue, ColorSat * 0.8, 91)})
+                Brush.GradientStops.Add(New GradientStop With {.Offset = 1.1, .Color = New MyColor().FromHSL2(ColorHue + 15, ColorSat * 0.8, 91)})
                 FrmMain.PanForm.Background = Brush
                 FrmMain.PanForm.Background = Brush
             Else
             Else
                 FrmMain.PanForm.Background = New MyColor(245, 245, 245)
                 FrmMain.PanForm.Background = New MyColor(245, 245, 245)

+ 2 - 2
Plain Craft Launcher 2/My Project/AssemblyInfo.vb

@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
 ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
 ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
 ' 方法是按如下所示使用“*”
 ' 方法是按如下所示使用“*”
 
 
-<Assembly: AssemblyVersion("2.10.0.0")>
-<Assembly: AssemblyFileVersion("2.10.0.0")>
+<Assembly: AssemblyVersion("2.10.1.0")>
+<Assembly: AssemblyFileVersion("2.10.1.0")>
 <Assembly: NeutralResourcesLanguage("")>
 <Assembly: NeutralResourcesLanguage("")>

+ 6 - 6
Plain Craft Launcher 2/Pages/PageDownload/Comp/MyCompItem.xaml.vb

@@ -19,7 +19,7 @@
             Return LabTitle.Text
             Return LabTitle.Text
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If LabTitle.Text = value Then Exit Property
+            If LabTitle.Text = value Then Return
             LabTitle.Text = value
             LabTitle.Text = value
         End Set
         End Set
     End Property
     End Property
@@ -30,7 +30,7 @@
             Return If(LabTitleRaw?.Text, "")
             Return If(LabTitleRaw?.Text, "")
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If LabTitleRaw.Text = value Then Exit Property
+            If LabTitleRaw.Text = value Then Return
             LabTitleRaw.Text = value
             LabTitleRaw.Text = value
             LabTitleRaw.Visibility = If(value = "", Visibility.Collapsed, Visibility.Visible)
             LabTitleRaw.Visibility = If(value = "", Visibility.Collapsed, Visibility.Visible)
         End Set
         End Set
@@ -42,7 +42,7 @@
             Return LabInfo.Text
             Return LabInfo.Text
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If LabInfo.Text = value Then Exit Property
+            If LabInfo.Text = value Then Return
             LabInfo.Text = value
             LabInfo.Text = value
         End Set
         End Set
     End Property
     End Property
@@ -88,7 +88,7 @@
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
         If IsMouseDown Then
         If IsMouseDown Then
             RaiseEvent Click(sender, e)
             RaiseEvent Click(sender, e)
-            If e.Handled Then Exit Sub
+            If e.Handled Then Return
             Log("[Control] 按下资源工程列表项:" & LabTitle.Text)
             Log("[Control] 按下资源工程列表项:" & LabTitle.Text)
         End If
         End If
     End Sub
     End Sub
@@ -185,7 +185,7 @@
     ''' </summary>
     ''' </summary>
     Public Property CanInteraction As Boolean = True
     Public Property CanInteraction As Boolean = True
     Public Sub RefreshColor(sender As Object, e As EventArgs) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonDown, Me.MouseLeftButtonUp
     Public Sub RefreshColor(sender As Object, e As EventArgs) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonDown, Me.MouseLeftButtonUp
-        If Not CanInteraction Then Exit Sub
+        If Not CanInteraction Then Return
         '判断当前颜色
         '判断当前颜色
         Dim StateNew As String, Time As Integer
         Dim StateNew As String, Time As Integer
         If IsMouseOver Then
         If IsMouseOver Then
@@ -200,7 +200,7 @@
             StateNew = "Idle"
             StateNew = "Idle"
             Time = 180
             Time = 180
         End If
         End If
-        If StateLast = StateNew Then Exit Sub
+        If StateLast = StateNew Then Return
         StateLast = StateNew
         StateLast = StateNew
         '触发颜色动画
         '触发颜色动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
         If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画

+ 1 - 1
Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml

@@ -71,7 +71,7 @@
             </StackPanel>
             </StackPanel>
         </local:MyCard>
         </local:MyCard>
         <StackPanel x:Name="PanContent">
         <StackPanel x:Name="PanContent">
-            <local:MyHint x:Name="HintError" Text="无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,结果可能不全。&#xa;请尝试使用 VPN 或加速器以改善网络。" IsWarn="True" Margin="0,0,0,15" />
+            <local:MyHint x:Name="HintError" HasBorder="True" Text="无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,搜索结果可能不全。&#xa;请稍后重试,或使用 VPN 以改善网络环境。" Theme="Yellow" Margin="0,0,0,15" />
             <local:MyCard x:Name="CardProjects" UseAnimation="False">
             <local:MyCard x:Name="CardProjects" UseAnimation="False">
                 <StackPanel x:Name="PanProjects" Margin="12" />
                 <StackPanel x:Name="PanProjects" Margin="12" />
             </local:MyCard>
             </local:MyCard>

+ 1 - 10
Plain Craft Launcher 2/Pages/PageDownload/Comp/PageComp.xaml.vb

@@ -108,19 +108,11 @@ Public Class PageComp
         Dim Request As New CompProjectRequest(PageType, Storage, (Page + 1) * PageSize)
         Dim Request As New CompProjectRequest(PageType, Storage, (Page + 1) * PageSize)
         Dim GameVersion As String = If(TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
         Dim GameVersion As String = If(TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
                 If(TextSearchVersion.Text.Contains(".") OrElse TextSearchVersion.Text.Contains("w"), TextSearchVersion.Text, Nothing))
                 If(TextSearchVersion.Text.Contains(".") OrElse TextSearchVersion.Text.Contains("w"), TextSearchVersion.Text, Nothing))
-        Dim ModLoader As CompModLoaderType = CompModLoaderType.Any
-        If PageType = CompType.Mod Then '只有 Mod 考虑加载器
-            ModLoader = Val(ComboSearchLoader.SelectedItem.Tag)
-            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
-        End If
         With Request
         With Request
             .SearchText = TextSearchName.Text
             .SearchText = TextSearchName.Text
             .GameVersion = GameVersion
             .GameVersion = GameVersion
             .Tag = ComboSearchTag.SelectedItem.Tag
             .Tag = ComboSearchTag.SelectedItem.Tag
-            .ModLoader = ModLoader
+            .ModLoader = If(PageType = CompType.Mod, Val(ComboSearchLoader.SelectedItem.Tag), CompModLoaderType.Any)
             .Source = CType(Val(ComboSearchSource.SelectedItem.Tag), CompSourceType)
             .Source = CType(Val(ComboSearchSource.SelectedItem.Tag), CompSourceType)
         End With
         End With
         Return Request
         Return Request
@@ -188,7 +180,6 @@ Public Class PageComp
     End Sub
     End Sub
 
 
     '切换页码
     '切换页码
-
     Private Sub BtnPageFirst_Click(sender As Object, e As RoutedEventArgs) Handles BtnPageFirst.Click
     Private Sub BtnPageFirst_Click(sender As Object, e As RoutedEventArgs) Handles BtnPageFirst.Click
         ChangePage(0)
         ChangePage(0)
     End Sub
     End Sub

+ 53 - 46
Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.vb

@@ -7,7 +7,9 @@
         "Comp File",
         "Comp File",
         Sub(Task)
         Sub(Task)
             LoadTargetFromAdditional()
             LoadTargetFromAdditional()
-            Task.Output = CompFilesGet(Project.Id, Project.FromCurseForge)
+            Dim Result = CompFilesGet(Project.Id, Project.FromCurseForge)
+            If Task.IsAborted Then Return
+            Task.Output = Result
         End Sub)
         End Sub)
 
 
     '初始化加载器信息
     '初始化加载器信息
@@ -204,7 +206,7 @@
                 End If
                 End If
                 '增加提示
                 '增加提示
                 If Pair.Key = "其他版本" Then
                 If Pair.Key = "其他版本" Then
-                    NewStack.Children.Add(New MyHint With {.Text = "由于版本信息更新缓慢,可能无法识别刚更新的 MC 版本,只需等待几天即可自动恢复正常。", .IsWarn = False, .Margin = New Thickness(0, 0, 0, 7)})
+                    NewStack.Children.Add(New MyHint With {.Text = "由于版本信息更新缓慢,可能无法识别刚更新的 MC 版本。几天后即可正常识别。", .Theme = MyHint.Themes.Yellow, .Margin = New Thickness(5, 0, 0, 8)})
                 End If
                 End If
             Next
             Next
             '如果只有一张卡片,展开第一张卡片
             '如果只有一张卡片,展开第一张卡片
@@ -270,7 +272,7 @@
             Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
             Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
             If Validate.Validate(PackName) <> "" Then PackName = ""
             If Validate.Validate(PackName) <> "" Then PackName = ""
             Dim VersionName As String = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
             Dim VersionName As String = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
-            If String.IsNullOrEmpty(VersionName) Then Exit Sub
+            If String.IsNullOrEmpty(VersionName) Then Return
 
 
             '构造步骤加载器
             '构造步骤加载器
             Dim Loaders As New List(Of LoaderBase)
             Dim Loaders As New List(Of LoaderBase)
@@ -289,7 +291,7 @@
                     Case LoadState.Aborted
                     Case LoadState.Aborted
                         Hint(MyLoader.Name & "已取消!", HintType.Info)
                         Hint(MyLoader.Name & "已取消!", HintType.Info)
                     Case LoadState.Loading
                     Case LoadState.Loading
-                        Exit Sub '不重新加载版本列表
+                        Return '不重新加载版本列表
                 End Select
                 End Select
                 McInstallFailedClearFolder(MyLoader)
                 McInstallFailedClearFolder(MyLoader)
             End Sub}
             End Sub}
@@ -319,67 +321,72 @@
                 End Select
                 End Select
                 '确认默认保存位置
                 '确认默认保存位置
                 Dim DefaultFolder As String = Nothing
                 Dim DefaultFolder As String = Nothing
-                If File.Type = CompType.Mod Then
-                    '获取 Mod 所需的加载器种类
-                    Dim AllowForge As Boolean? = Nothing, AllowFabric As Boolean? = Nothing
-                    If File.ModLoaders.Any Then '从文件中获取
-                        AllowForge = File.ModLoaders.Contains(CompModLoaderType.Forge) OrElse File.ModLoaders.Contains(CompModLoaderType.NeoForge)
-                        AllowFabric = File.ModLoaders.Contains(CompModLoaderType.Fabric)
-                    ElseIf Project.ModLoaders.Any Then '从工程中获取
-                        AllowForge = Project.ModLoaders.Contains(CompModLoaderType.Forge) OrElse File.ModLoaders.Contains(CompModLoaderType.NeoForge)
-                        AllowFabric = Project.ModLoaders.Contains(CompModLoaderType.Fabric)
-                    End If
-                    If AllowForge IsNot Nothing AndAlso Not AllowForge AndAlso
-                       AllowFabric IsNot Nothing AndAlso Not AllowFabric Then
-                        AllowForge = Nothing : AllowFabric = Nothing
+                If File.Type <> CompType.ModPack Then
+                    Dim SubFolder As String = Nothing
+                    Select Case Project.Type
+                        Case CompType.Mod : SubFolder = "mods\"
+                        Case CompType.ResourcePack : SubFolder = "resourcepacks\"
+                        Case CompType.Shader : SubFolder = "shaderpacks\"
+                        Case CompType.DataPack : SubFolder = "" '导航到版本根目录
+                    End Select
+                    Dim IsVersionSuitable As Func(Of McVersion, Boolean) = Nothing
+                    '获取资源所需的加载器
+                    Dim AllowedLoaders As New List(Of CompModLoaderType)
+                    If File.ModLoaders.Any Then
+                        AllowedLoaders = File.ModLoaders
+                    ElseIf Project.ModLoaders.Any Then
+                        AllowedLoaders = Project.ModLoaders
                     End If
                     End If
-                    Log("[Comp] 允许 Forge:" & If(AllowForge, "未知") & ",允许 Fabric:" & If(AllowFabric, "未知"))
-                    '判断某个版本是否符合要求
-                    Dim IsVersionSuitable As Func(Of McVersion, Boolean) =
+                    Log($"[Comp] {Desc}要求的加载器种类:" & If(AllowedLoaders.Any(), AllowedLoaders.Join(" / "), "无要求"))
+                    '判断某个版本是否符合资源要求
+                    IsVersionSuitable =
                     Function(Version)
                     Function(Version)
                         If Not Version.IsLoaded Then Version.Load()
                         If Not Version.IsLoaded Then Version.Load()
-                        If Not Version.Modable Then Return False
-                        If File.GameVersions.Any(Function(v) v.Contains(".")) AndAlso
-                           Not File.GameVersions.Any(Function(v) v.Contains(".") AndAlso v = Version.Version.McName) Then Return False
-                        If AllowForge Is Nothing OrElse AllowFabric Is Nothing Then Return True
-                        If AllowForge AndAlso (Version.Version.HasForge OrElse Version.Version.HasNeoForge) Then Return True
-                        If AllowFabric AndAlso Version.Version.HasFabric Then Return True
+                        '只对 Mod 和数据包进行版本检测
+                        If Project.Type = CompType.Mod OrElse Project.Type = CompType.DataPack Then
+                            If File.GameVersions.Any(Function(v) v.Contains(".")) AndAlso
+                               Not File.GameVersions.Any(Function(v) v.Contains(".") AndAlso v = Version.Version.McName) Then Return False
+                        End If
+                        '加载器
+                        If Not AllowedLoaders.Any() Then Return True '无要求
+                        If AllowedLoaders.Contains(CompModLoaderType.Forge) AndAlso Version.Version.HasForge Then Return True
+                        If AllowedLoaders.Contains(CompModLoaderType.Fabric) AndAlso Version.Version.HasFabric Then Return True
+                        If AllowedLoaders.Contains(CompModLoaderType.NeoForge) AndAlso Version.Version.HasNeoForge Then Return True
+                        If AllowedLoaders.Contains(CompModLoaderType.LiteLoader) AndAlso Version.Version.HasLiteLoader Then Return True
                         Return False
                         Return False
                     End Function
                     End Function
-                    '获取 Mod 默认下载位置
+                    '获取常规资源默认下载位置
                     If CachedFolder IsNot Nothing Then
                     If CachedFolder IsNot Nothing Then
                         DefaultFolder = CachedFolder
                         DefaultFolder = CachedFolder
-                        Log("[Comp] 使用上次下载时的文件夹作为默认下载位置")
+                        Log($"[Comp] 使用上次下载时的文件夹作为默认下载位置:{DefaultFolder}")
                     ElseIf McVersionCurrent IsNot Nothing AndAlso IsVersionSuitable(McVersionCurrent) Then
                     ElseIf McVersionCurrent IsNot Nothing AndAlso IsVersionSuitable(McVersionCurrent) Then
-                        DefaultFolder = McVersionCurrent.PathIndie & "mods\"
+                        DefaultFolder = $"{McVersionCurrent.PathIndie}{SubFolder}"
                         Directory.CreateDirectory(DefaultFolder)
                         Directory.CreateDirectory(DefaultFolder)
-                        Log("[Comp] 使用当前版本的 mods 文件夹作为默认下载位置(" & McVersionCurrent.Name & ")")
+                        Log($"[Comp] 使用当前版本作为默认下载位置:{DefaultFolder}")
                     Else
                     Else
+                        '查找所有可能的版本
                         Dim NeedLoad As Boolean = McVersionListLoader.State <> LoadState.Finished
                         Dim NeedLoad As Boolean = McVersionListLoader.State <> LoadState.Finished
                         If NeedLoad Then
                         If NeedLoad Then
                             Hint("正在查找适合的游戏版本……")
                             Hint("正在查找适合的游戏版本……")
                             LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True)
                             LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True)
                         End If
                         End If
-                        Dim SuitableVersions As New List(Of McVersion)
-                        For Each Version As McVersion In McVersionList.Values.SelectMany(Function(l) l)
-                            If IsVersionSuitable(Version) Then SuitableVersions.Add(Version)
-                        Next
-                        If Not SuitableVersions.Any() Then
+                        Dim SuitableVersions = McVersionList.Values.SelectMany(Function(l) l).Where(Function(v) IsVersionSuitable(v)).
+                            Select(Function(v) New DirectoryInfo($"{v.PathIndie}{SubFolder}"))
+                        If SuitableVersions.Any Then
+                            Dim SelectedVersion = SuitableVersions.
+                                OrderByDescending(Function(Dir) If(Dir.Exists, Dir.LastWriteTimeUtc, Date.MinValue)). '先按文件夹更改时间降序
+                                ThenByDescending(Function(Dir) If(Dir.Exists, Dir.GetFiles().Length, -1)). '再按文件夹中的文件数量降序
+                                First()
+                            DefaultFolder = SelectedVersion.FullName
+                            Directory.CreateDirectory(DefaultFolder)
+                            Log($"[Comp] 使用适合的游戏版本作为默认下载位置:{DefaultFolder}")
+                        Else
                             DefaultFolder = PathMcFolder
                             DefaultFolder = PathMcFolder
                             If NeedLoad Then
                             If NeedLoad Then
-                                Hint("当前 MC 文件夹中没有找到适合这个 Mod 的版本!")
+                                Hint("当前 MC 文件夹中没有找到适合此资源的版本!")
                             Else
                             Else
                                 Log("[Comp] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置")
                                 Log("[Comp] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置")
                             End If
                             End If
-                        Else '选择 Mod 数量最多的版本
-                            Dim SelectedVersion = SuitableVersions.OrderBy(
-                            Function(v)
-                                Dim Info As New DirectoryInfo(v.PathIndie & "mods\")
-                                Return If(Info.Exists, Info.GetFiles().Length, -1)
-                            End Function).LastOrDefault()
-                            DefaultFolder = SelectedVersion.PathIndie & "mods\"
-                            Directory.CreateDirectory(DefaultFolder)
-                            Log("[Comp] 使用适合的游戏版本作为默认下载位置(" & SelectedVersion.Name & ")")
                         End If
                         End If
                     End If
                     End If
                 End If
                 End If
@@ -412,7 +419,7 @@
                         If(File.Type = CompType.Mod,
                         If(File.Type = CompType.Mod,
                             If(File.FileName.EndsWith(".litemod"), "*.litemod", "*.jar"),
                             If(File.FileName.EndsWith(".litemod"), "*.litemod", "*.jar"),
                             If(File.FileName.EndsWith(".mrpack"), "*.mrpack", "*.zip")), DefaultFolder)
                             If(File.FileName.EndsWith(".mrpack"), "*.mrpack", "*.zip")), DefaultFolder)
-                    If Not Target.Contains("\") Then Exit Sub
+                    If Not Target.Contains("\") Then Return
                     '构造步骤加载器
                     '构造步骤加载器
                     Dim LoaderName As String = Desc & "下载:" & GetFileNameWithoutExtentionFromPath(Target) & " "
                     Dim LoaderName As String = Desc & "下载:" & GetFileNameWithoutExtentionFromPath(Target) & " "
                     If Target <> DefaultFolder AndAlso File.Type = CompType.Mod Then CachedFolder = GetPathFromFullPath(Target)
                     If Target <> DefaultFolder AndAlso File.Type = CompType.Mod Then CachedFolder = GetPathFromFullPath(Target)

+ 1 - 1
Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadResourcePack.xaml

@@ -19,7 +19,7 @@
         <local:MyComboBoxItem Margin="15,0,0,0" Content="战斗" Tag="/combat" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="战斗" Tag="/combat" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="实用" Tag="/utility" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="实用" Tag="/utility" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="改良" Tag="/tweaks" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="改良" Tag="/tweaks" />
-        <local:MyComboBoxItem Margin="15,0,0,0" Content="神经病" Tag="/cursed" />
+        <local:MyComboBoxItem Margin="15,0,0,0" Content="鬼畜" Tag="/cursed" />
 
 
         <local:MyComboBoxItem Content="特性" IsEnabled="False" />
         <local:MyComboBoxItem Content="特性" IsEnabled="False" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="含实体" Tag="/entities" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="含实体" Tag="/entities" />

+ 5 - 2
Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadShader.xaml

@@ -15,7 +15,6 @@
         <local:MyComboBoxItem Margin="15,0,0,0" Content="卡通风" Tag="/cartoon" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="卡通风" Tag="/cartoon" />
 
 
         <local:MyComboBoxItem Content="特性" IsEnabled="False" />
         <local:MyComboBoxItem Content="特性" IsEnabled="False" />
-        <local:MyComboBoxItem Margin="15,0,0,0" Content="原版可用" Tag="/vanilla" ToolTip="作为资源包加载,可以直接在原版游戏里使用。" ToolTipService.HorizontalOffset="70" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="彩色光照" Tag="/colored-lighting" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="彩色光照" Tag="/colored-lighting" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="路径追踪" Tag="/path-tracing" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="路径追踪" Tag="/path-tracing" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="PBR" Tag="/pbr" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="PBR" Tag="/pbr" />
@@ -26,6 +25,10 @@
         <local:MyComboBoxItem Margin="15,0,0,0" Content="低" Tag="/low" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="低" Tag="/low" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="中" Tag="/medium" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="中" Tag="/medium" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="高" Tag="/high" />
         <local:MyComboBoxItem Margin="15,0,0,0" Content="高" Tag="/high" />
-        
+
+        <local:MyComboBoxItem Content="加载器" IsEnabled="False" />
+        <local:MyComboBoxItem Margin="15,0,0,0" Content="原版可用s" Tag="/vanilla" ToolTip="作为资源包加载,可以直接在原版游戏里使用。" ToolTipService.HorizontalOffset="70" />
+        <local:MyComboBoxItem Margin="15,0,0,0" Content="Iris" Tag="/iris" />
+        <local:MyComboBoxItem Margin="15,0,0,0" Content="OptiFine" Tag="/optifine" />
     </local:PageComp>
     </local:PageComp>
 </local:MyPageRight>
 </local:MyPageRight>

+ 30 - 30
Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb

@@ -217,14 +217,14 @@ Public Module ModDownloadLib
             Dim Id = Version.Title
             Dim Id = Version.Title
             Dim JsonUrl = Version.Tag("url").ToString
             Dim JsonUrl = Version.Tag("url").ToString
             Dim VersionFolder As String = SelectFolder()
             Dim VersionFolder As String = SelectFolder()
-            If Not VersionFolder.Contains("\") Then Exit Sub
+            If Not VersionFolder.Contains("\") Then Return
             VersionFolder = VersionFolder & Id & "\"
             VersionFolder = VersionFolder & Id & "\"
 
 
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"Minecraft {Id} 服务端下载" Then Continue For
                 If OngoingLoader.Name <> $"Minecraft {Id} 服务端下载" Then Continue For
                 Hint("该服务端正在下载中!", HintType.Critical)
                 Hint("该服务端正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             Dim Loaders As New List(Of LoaderBase)
             Dim Loaders As New List(Of LoaderBase)
@@ -244,7 +244,7 @@ Public Module ModDownloadLib
                         Hint($"Mojang 没有给 Minecraft {Id} 提供官方服务端下载,没法下,撤退!", HintType.Critical)
                         Hint($"Mojang 没有给 Minecraft {Id} 提供官方服务端下载,没法下,撤退!", HintType.Critical)
                         Thread.Sleep(2000) '等玩家把上一个提示看完
                         Thread.Sleep(2000) '等玩家把上一个提示看完
                         Task.Abort()
                         Task.Abort()
-                        Exit Sub
+                        Return
                     End If
                     End If
                     Dim JarUrl As String = McVersion.JsonObject("downloads")("server")("url")
                     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"))
                     Dim Checker As New FileChecker(MinSize:=1024, ActualSize:=If(McVersion.JsonObject("downloads")("server")("size"), -1), Hash:=McVersion.JsonObject("downloads")("server")("sha1"))
@@ -294,14 +294,14 @@ pause"
             Dim Id = Version.Title
             Dim Id = Version.Title
             Dim JsonUrl = Version.Tag("url").ToString
             Dim JsonUrl = Version.Tag("url").ToString
             Dim VersionFolder As String = SelectFolder()
             Dim VersionFolder As String = SelectFolder()
-            If Not VersionFolder.Contains("\") Then Exit Sub
+            If Not VersionFolder.Contains("\") Then Return
             VersionFolder = VersionFolder & Id & "\"
             VersionFolder = VersionFolder & Id & "\"
 
 
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For
                 If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For
                 Hint("该版本正在下载中!", HintType.Critical)
                 Hint("该版本正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             Dim Loaders As New List(Of LoaderBase)
             Dim Loaders As New List(Of LoaderBase)
@@ -383,7 +383,7 @@ pause"
             WikiName = "Java版Pre-classic_" & Id
             WikiName = "Java版Pre-classic_" & Id
         Else
         Else
             Log("[Error] 未知的版本格式:" & Id & "。", LogLevel.Feedback)
             Log("[Error] 未知的版本格式:" & Id & "。", LogLevel.Feedback)
-            Exit Sub
+            Return
         End If
         End If
         OpenWebsite("https://zh.minecraft.wiki/w/" & WikiName.Replace("_experimental-snapshot-", "-exp"))
         OpenWebsite("https://zh.minecraft.wiki/w/" & WikiName.Replace("_experimental-snapshot-", "-exp"))
     End Sub
     End Sub
@@ -396,13 +396,13 @@ pause"
         Try
         Try
             Dim Id As String = DownloadInfo.NameVersion
             Dim Id As String = DownloadInfo.NameVersion
             Dim Target As String = SelectSaveFile("选择保存位置", DownloadInfo.NameFile, "OptiFine Jar (*.jar)|*.jar")
             Dim Target As String = SelectSaveFile("选择保存位置", DownloadInfo.NameFile, "OptiFine Jar (*.jar)|*.jar")
-            If Not Target.Contains("\") Then Exit Sub
+            If Not Target.Contains("\") Then Return
 
 
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"OptiFine {DownloadInfo.NameDisplay} 下载" Then Continue For
                 If OngoingLoader.Name <> $"OptiFine {DownloadInfo.NameDisplay} 下载" Then Continue For
                 Hint("该版本正在下载中!", HintType.Critical)
                 Hint("该版本正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             Dim Loader As New LoaderCombo(Of DlOptiFineListEntry)("OptiFine " & DownloadInfo.NameDisplay & " 下载", McDownloadOptiFineSaveLoader(DownloadInfo, Target)) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
             Dim Loader As New LoaderCombo(Of DlOptiFineListEntry)("OptiFine " & DownloadInfo.NameDisplay & " 下载", McDownloadOptiFineSaveLoader(DownloadInfo, Target)) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
@@ -434,7 +434,7 @@ pause"
                 End Try
                 End Try
                 '检查下载结果
                 '检查下载结果
                 Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
                 Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
-                If Task.IsAborted Then Exit Sub
+                If Task.IsAborted Then Return
                 If Java Is Nothing Then Throw New Exception("由于未找到 Java,已取消安装。")
                 If Java Is Nothing Then Throw New Exception("由于未找到 Java,已取消安装。")
             End If
             End If
         End SyncLock
         End SyncLock
@@ -584,7 +584,7 @@ pause"
         Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("等待原版下载",
         Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("等待原版下载",
         Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
         Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
             '等待原版文件下载完成
             '等待原版文件下载完成
-            If ClientDownloadLoader Is Nothing Then Exit Sub
+            If ClientDownloadLoader Is Nothing Then Return
             Dim TargetLoaders As List(Of LoaderBase) =
             Dim TargetLoaders As List(Of LoaderBase) =
                ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
                ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
                Where(Function(l) l.State <> LoadState.Finished).ToList
                Where(Function(l) l.State <> LoadState.Finished).ToList
@@ -593,9 +593,9 @@ pause"
                 TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
                 TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
                 Thread.Sleep(50)
                 Thread.Sleep(50)
             Loop
             Loop
-            If Task.IsAborted Then Exit Sub
+            If Task.IsAborted Then Return
             '拷贝原版文件
             '拷贝原版文件
-            If Not IsCustomFolder Then Exit Sub
+            If Not IsCustomFolder Then Return
             SyncLock VanillaSyncLock
             SyncLock VanillaSyncLock
                 Dim ClientName As String = GetFolderNameFromPath(ClientFolder)
                 Dim ClientName As String = GetFolderNameFromPath(ClientFolder)
                 Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit)
                 Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit)
@@ -707,7 +707,7 @@ Retry:
         '下载支持库
         '下载支持库
         If FixLibrary Then
         If FixLibrary Then
             Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析 OptiFine 支持库文件",
             Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析 OptiFine 支持库文件",
-                                                                Sub(Task As LoaderTask(Of String, List(Of NetFile))) Task.Output = McLibFix(New McVersion(VersionFolder))) With {.ProgressWeight = 1, .Show = False})
+                Sub(Task) Task.Output = McLibFix(New McVersion(VersionFolder))) With {.ProgressWeight = 1, .Show = False})
             Loaders.Add(New LoaderDownload("下载 OptiFine 支持库文件", New List(Of NetFile)) With {.ProgressWeight = 4})
             Loaders.Add(New LoaderDownload("下载 OptiFine 支持库文件", New List(Of NetFile)) With {.ProgressWeight = 4})
         End If
         End If
 
 
@@ -831,7 +831,7 @@ Retry:
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"LiteLoader {Id} 下载" Then Continue For
                 If OngoingLoader.Name <> $"LiteLoader {Id} 下载" Then Continue For
                 Hint("该版本正在下载中!", HintType.Critical)
                 Hint("该版本正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             '已有版本检查
             '已有版本检查
@@ -840,7 +840,7 @@ Retry:
                     File.Delete(VersionFolder & VersionName & ".jar")
                     File.Delete(VersionFolder & VersionName & ".jar")
                     File.Delete(VersionFolder & VersionName & ".json")
                     File.Delete(VersionFolder & VersionName & ".json")
                 Else
                 Else
-                    Exit Sub
+                    Return
                 End If
                 End If
             End If
             End If
 
 
@@ -859,13 +859,13 @@ Retry:
         Try
         Try
             Dim Id As String = DownloadInfo.Inherit
             Dim Id As String = DownloadInfo.Inherit
             Dim Target As String = SelectSaveFile("选择保存位置", DownloadInfo.FileName.Replace("-SNAPSHOT", ""), "LiteLoader 安装器 (*.jar)|*.jar")
             Dim Target As String = SelectSaveFile("选择保存位置", DownloadInfo.FileName.Replace("-SNAPSHOT", ""), "LiteLoader 安装器 (*.jar)|*.jar")
-            If Not Target.Contains("\") Then Exit Sub
+            If Not Target.Contains("\") Then Return
 
 
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"LiteLoader {Id} 下载" Then Continue For
                 If OngoingLoader.Name <> $"LiteLoader {Id} 下载" Then Continue For
                 Hint("该版本正在下载中!", HintType.Critical)
                 Hint("该版本正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             '构造步骤加载器
             '构造步骤加载器
@@ -1041,13 +1041,13 @@ Retry:
             Dim Target As String = SelectSaveFile("选择保存位置", $"{Info.LoaderName}-{Info.Inherit}-{Info.VersionName}.{Info.FileExtension}",
             Dim Target As String = SelectSaveFile("选择保存位置", $"{Info.LoaderName}-{Info.Inherit}-{Info.VersionName}.{Info.FileExtension}",
                                             $"{Info.LoaderName} 安装器 (*.{Info.FileExtension})|*.{Info.FileExtension}")
                                             $"{Info.LoaderName} 安装器 (*.{Info.FileExtension})|*.{Info.FileExtension}")
             Dim DisplayName As String = $"{Info.LoaderName} {Info.Inherit} - {Info.VersionName}"
             Dim DisplayName As String = $"{Info.LoaderName} {Info.Inherit} - {Info.VersionName}"
-            If Not Target.Contains("\") Then Exit Sub
+            If Not Target.Contains("\") Then Return
 
 
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"{DisplayName} 下载" Then Continue For
                 If OngoingLoader.Name <> $"{DisplayName} 下载" Then Continue For
                 Hint("该版本正在下载中!", HintType.Critical)
                 Hint("该版本正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             '获取下载地址
             '获取下载地址
@@ -1103,7 +1103,7 @@ Retry:
                 End Try
                 End Try
                 '检查下载结果
                 '检查下载结果
                 Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 60))
                 Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 60))
-                If Task.IsAborted Then Exit Sub
+                If Task.IsAborted Then Return
                 If Java Is Nothing Then Throw New Exception("由于未找到 Java,已取消安装。")
                 If Java Is Nothing Then Throw New Exception("由于未找到 Java,已取消安装。")
             End If
             End If
         End SyncLock
         End SyncLock
@@ -1189,7 +1189,7 @@ Retry:
                     errorWaitHandle.WaitOne(10000)
                     errorWaitHandle.WaitOne(10000)
                     process.Dispose()
                     process.Dispose()
                     '检查是否安装成功:最后 5 行中是否有 true(true 可能在倒数数行,见 #832)
                     '检查是否安装成功:最后 5 行中是否有 true(true 可能在倒数数行,见 #832)
-                    If LastResults.Reverse().Take(5).Any(Function(l) l = "true") Then Exit Sub
+                    If LastResults.Reverse().Take(5).Any(Function(l) l = "true") Then Return
                     Log(Join(LastResults, vbCrLf))
                     Log(Join(LastResults, vbCrLf))
                     Dim LastLines As String = ""
                     Dim LastLines As String = ""
                     For i As Integer = Math.Max(0, LastResults.Count - 5) To LastResults.Count - 1 '最后 5 行
                     For i As Integer = Math.Max(0, LastResults.Count - 5) To LastResults.Count - 1 '最后 5 行
@@ -1237,7 +1237,7 @@ Retry:
                 Task.Progress = 0.91
                 Task.Progress = 0.91
             Case Else
             Case Else
                 If ModeDebug Then Log("[Installer] " & Content)
                 If ModeDebug Then Log("[Installer] " & Content)
-                Exit Sub
+                Return
         End Select
         End Select
         Log("[Installer] " & Content)
         Log("[Installer] " & Content)
     End Sub
     End Sub
@@ -1282,7 +1282,7 @@ Retry:
                 For Each ForgeVersion In ForgeLoader.Output
                 For Each ForgeVersion In ForgeLoader.Output
                     If VersionSortInteger(ForgeVersion.Version.ToString, LoaderVersion) = 0 Then
                     If VersionSortInteger(ForgeVersion.Version.ToString, LoaderVersion) = 0 Then
                         Info = ForgeVersion
                         Info = ForgeVersion
-                        Exit Sub
+                        Return
                     End If
                     End If
                 Next
                 Next
                 Throw New Exception($"未能找到 {LoaderName} " & Inherit & "-" & LoaderVersion & " 的详细信息!")
                 Throw New Exception($"未能找到 {LoaderName} " & Inherit & "-" & LoaderVersion & " 的详细信息!")
@@ -1385,7 +1385,7 @@ Retry:
 #End Region
 #End Region
 #Region "原版文件"
 #Region "原版文件"
                 '等待原版文件下载完成
                 '等待原版文件下载完成
-                If ClientDownloadLoader Is Nothing Then Exit Sub
+                If ClientDownloadLoader Is Nothing Then Return
                 Dim TargetLoaders As List(Of LoaderBase) =
                 Dim TargetLoaders As List(Of LoaderBase) =
                     ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
                     ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
                     Where(Function(l) l.State <> LoadState.Finished).ToList()
                     Where(Function(l) l.State <> LoadState.Finished).ToList()
@@ -1394,9 +1394,9 @@ Retry:
                     TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
                     TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
                     Thread.Sleep(50)
                     Thread.Sleep(50)
                 Loop
                 Loop
-                If Task.IsAborted Then Exit Sub
+                If Task.IsAborted Then Return
                 '拷贝原版文件
                 '拷贝原版文件
-                If Not IsCustomFolder Then Exit Sub
+                If Not IsCustomFolder Then Return
                 SyncLock VanillaSyncLock
                 SyncLock VanillaSyncLock
                     Dim ClientName As String = GetFolderNameFromPath(ClientFolder)
                     Dim ClientName As String = GetFolderNameFromPath(ClientFolder)
                     Directory.CreateDirectory(McFolder & "versions\" & Inherit)
                     Directory.CreateDirectory(McFolder & "versions\" & Inherit)
@@ -1639,7 +1639,7 @@ Retry:
     ''' 尝试刷新 Forge 推荐版本缓存。
     ''' 尝试刷新 Forge 推荐版本缓存。
     ''' </summary>
     ''' </summary>
     Public Sub McDownloadForgeRecommendedRefresh()
     Public Sub McDownloadForgeRecommendedRefresh()
-        If IsForgeRecommendedRefreshed Then Exit Sub
+        If IsForgeRecommendedRefreshed Then Return
         IsForgeRecommendedRefreshed = True
         IsForgeRecommendedRefreshed = True
         RunInNewThread(Sub()
         RunInNewThread(Sub()
                            Try
                            Try
@@ -1795,13 +1795,13 @@ Retry:
             Dim FileName As String = GetFileNameFromPath(Url)
             Dim FileName As String = GetFileNameFromPath(Url)
             Dim Version As String = GetFileNameFromPath(DownloadInfo("version").ToString)
             Dim Version As String = GetFileNameFromPath(DownloadInfo("version").ToString)
             Dim Target As String = SelectSaveFile("选择保存位置", FileName, "Fabric 安装器 (*.jar)|*.jar")
             Dim Target As String = SelectSaveFile("选择保存位置", FileName, "Fabric 安装器 (*.jar)|*.jar")
-            If Not Target.Contains("\") Then Exit Sub
+            If Not Target.Contains("\") Then Return
 
 
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar.ToList()
             For Each OngoingLoader In LoaderTaskbar.ToList()
                 If OngoingLoader.Name <> $"Fabric {Version} 安装器下载" Then Continue For
                 If OngoingLoader.Name <> $"Fabric {Version} 安装器下载" Then Continue For
                 Hint("该版本正在下载中!", HintType.Critical)
                 Hint("该版本正在下载中!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
 
 
             '构造步骤加载器
             '构造步骤加载器
@@ -2006,7 +2006,7 @@ Retry:
             Case LoadState.Aborted
             Case LoadState.Aborted
                 Hint(Loader.Name & "已取消!", HintType.Info)
                 Hint(Loader.Name & "已取消!", HintType.Info)
             Case LoadState.Loading
             Case LoadState.Loading
-                Exit Sub '不重新加载版本列表
+                Return '不重新加载版本列表
         End Select
         End Select
         McInstallFailedClearFolder(Loader)
         McInstallFailedClearFolder(Loader)
         LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
         LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")

+ 1 - 1
Plain Craft Launcher 2/Pages/PageDownload/PageDownloadForge.xaml.vb

@@ -42,7 +42,7 @@
         End If
         End If
     End Sub
     End Sub
     Public Sub Forge_StateChanged(sender As MyLoading, newState As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState)
     Public Sub Forge_StateChanged(sender As MyLoading, newState As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState)
-        If newState <> MyLoading.MyLoadingState.Stop Then Exit Sub
+        If newState <> MyLoading.MyLoadingState.Stop Then Return
 
 
         Dim Card As MyCard = CType(sender.Parent, FrameworkElement).Parent
         Dim Card As MyCard = CType(sender.Parent, FrameworkElement).Parent
         Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = sender.State
         Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = sender.State

+ 4 - 4
Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml

@@ -23,10 +23,10 @@
                             <local:MyImage x:Name="ImgLogo" Margin="52,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" Height="32" RenderOptions.BitmapScalingMode="HighQuality" />
                             <local:MyImage x:Name="ImgLogo" Margin="52,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" Height="32" RenderOptions.BitmapScalingMode="HighQuality" />
                             <local:MyTextBox Margin="93,0,16,0" Padding="-1,0" MinHeight="30" FontSize="15" VerticalAlignment="Center" x:Name="TextSelectName" MaxLength="70" HasBackground="False" />
                             <local:MyTextBox Margin="93,0,16,0" Padding="-1,0" MinHeight="30" FontSize="15" VerticalAlignment="Center" x:Name="TextSelectName" MaxLength="70" HasBackground="False" />
                         </local:MyCard>
                         </local:MyCard>
-                        <local:MyHint Text="如果不安装 Fabric API,大多数 Mod 都会无法使用!" Margin="0,10,0,0" x:Name="HintFabricAPI" IsWarn="True" />
-                        <local:MyHint Text="必须安装 OptiFabric 才能正常使用 OptiFine!" Margin="0,10,0,0" x:Name="HintOptiFabric" IsWarn="True" />
-                        <local:MyHint Text="安装结束后,请在 Mod 下载中搜索 OptiFabric Origins 并下载,否则 OptiFine 会无法使用!" Margin="0,10,0,0" x:Name="HintOptiFabricOld" IsWarn="False" />
-                        <local:MyHint Text="OptiFine 与一部分 Mod 的兼容性不佳,请谨慎安装。" Margin="0,10,0,0" x:Name="HintModOptiFine" IsWarn="False" />
+                        <local:MyHint Text="如果不安装 Fabric API,大多数 Mod 都会无法使用!" Margin="0,10,0,0" x:Name="HintFabricAPI" Theme="Red" />
+                        <local:MyHint Text="必须安装 OptiFabric 才能正常使用 OptiFine!" Margin="0,10,0,0" x:Name="HintOptiFabric" Theme="Red" />
+                        <local:MyHint Text="安装结束后,请在 Mod 下载中搜索 OptiFabric Origins 并下载,否则 OptiFine 会无法使用!" Margin="0,10,0,0" x:Name="HintOptiFabricOld" Theme="Yellow" />
+                        <local:MyHint Text="OptiFine 与一部分 Mod 的兼容性不佳,请谨慎安装。" Margin="0,10,0,0" x:Name="HintModOptiFine" Theme="Yellow" />
                         <local:MyCard Title="Forge" Height="40" Margin="0,12,0,0" x:Name="CardForge" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
                         <local:MyCard Title="Forge" Height="40" Margin="0,12,0,0" x:Name="CardForge" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
                         <StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanForge" />
                         <StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanForge" />
                         <Grid x:Name="PanForgeInfo" Height="18" Margin="132,11,15,0" VerticalAlignment="Top" Tag="True">
                         <Grid x:Name="PanForgeInfo" Height="18" Margin="132,11,15,0" VerticalAlignment="Top" Tag="True">

+ 70 - 70
Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml.vb

@@ -19,7 +19,7 @@
         SelectReload()
         SelectReload()
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
 
 
         McDownloadForgeRecommendedRefresh()
         McDownloadForgeRecommendedRefresh()
@@ -38,7 +38,7 @@
     Public IsInSelectPage As Boolean = False
     Public IsInSelectPage As Boolean = False
     Private IsFirstLoaded As Boolean = False
     Private IsFirstLoaded As Boolean = False
     Private Sub EnterSelectPage()
     Private Sub EnterSelectPage()
-        If IsInSelectPage Then Exit Sub
+        If IsInSelectPage Then Return
         IsInSelectPage = True
         IsInSelectPage = True
 
 
         PanInner.Margin = New Thickness(25, 10, 25, 40)
         PanInner.Margin = New Thickness(25, 10, 25, 40)
@@ -87,8 +87,8 @@
         DlOptiFabricLoader.Start()
         DlOptiFabricLoader.Start()
 
 
         AniStart({
         AniStart({
-            AaOpacity(PanMinecraft, -PanMinecraft.Opacity, 90, 10),
-            AaTranslateX(PanMinecraft, -50 - CType(PanMinecraft.RenderTransform, TranslateTransform).X, 100, 10),
+            AaOpacity(PanMinecraft, -PanMinecraft.Opacity, 70, 10),
+            AaTranslateX(PanMinecraft, -50 - CType(PanMinecraft.RenderTransform, TranslateTransform).X, 90, 10),
             AaCode(
             AaCode(
             Sub()
             Sub()
                 PanBack.ScrollToHome()
                 PanBack.ScrollToHome()
@@ -103,13 +103,13 @@
                 SelectReload()
                 SelectReload()
                 PanMinecraft.Visibility = Visibility.Collapsed
                 PanMinecraft.Visibility = Visibility.Collapsed
             End Sub, After:=True),
             End Sub, After:=True),
-            AaOpacity(PanSelect, 1 - PanSelect.Opacity, 90, 100),
-            AaTranslateX(PanSelect, -CType(PanSelect.RenderTransform, TranslateTransform).X, 200, 100, Ease:=New AniEaseOutFluent(AniEasePower.ExtraStrong)),
+            AaOpacity(PanSelect, 1 - PanSelect.Opacity, 70, 100),
+            AaTranslateX(PanSelect, -CType(PanSelect.RenderTransform, TranslateTransform).X, 160, 100, Ease:=New AniEaseOutFluent(AniEasePower.ExtraStrong)),
             AaCode(
             AaCode(
             Sub()
             Sub()
                 PanBack.IsHitTestVisible = True
                 PanBack.IsHitTestVisible = True
                 '初始化 Binding
                 '初始化 Binding
-                If IsFirstLoaded Then Exit Sub
+                If IsFirstLoaded Then Return
                 IsFirstLoaded = True
                 IsFirstLoaded = True
                 BtnOptiFineClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFine.MainTextBlock, .Mode = BindingMode.OneWay})
                 BtnOptiFineClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFine.MainTextBlock, .Mode = BindingMode.OneWay})
                 BtnLiteLoaderClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardLiteLoader.MainTextBlock, .Mode = BindingMode.OneWay})
                 BtnLiteLoaderClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardLiteLoader.MainTextBlock, .Mode = BindingMode.OneWay})
@@ -122,7 +122,7 @@
         }, "FrmDownloadInstall SelectPageSwitch", True)
         }, "FrmDownloadInstall SelectPageSwitch", True)
     End Sub
     End Sub
     Public Sub ExitSelectPage() Handles BtnBack.Click
     Public Sub ExitSelectPage() Handles BtnBack.Click
-        If Not IsInSelectPage Then Exit Sub
+        If Not IsInSelectPage Then Return
         IsInSelectPage = False
         IsInSelectPage = False
 
 
         PanInner.Margin = New Thickness(25, 10, 25, 25)
         PanInner.Margin = New Thickness(25, 10, 25, 25)
@@ -137,11 +137,11 @@
         PanBack.ScrollToHome()
         PanBack.ScrollToHome()
 
 
         AniStart({
         AniStart({
-            AaOpacity(PanSelect, -PanSelect.Opacity, 90, 10),
-            AaTranslateX(PanSelect, 50 - CType(PanSelect.RenderTransform, TranslateTransform).X, 100, 10),
+            AaOpacity(PanSelect, -PanSelect.Opacity, 70, 10),
+            AaTranslateX(PanSelect, 50 - CType(PanSelect.RenderTransform, TranslateTransform).X, 90, 10),
             AaCode(Sub() PanBack.ScrollToHome(), After:=True),
             AaCode(Sub() PanBack.ScrollToHome(), After:=True),
-            AaOpacity(PanMinecraft, 1 - PanMinecraft.Opacity, 90, 100),
-            AaTranslateX(PanMinecraft, -CType(PanMinecraft.RenderTransform, TranslateTransform).X, 200, 100, Ease:=New AniEaseOutFluent(AniEasePower.ExtraStrong)),
+            AaOpacity(PanMinecraft, 1 - PanMinecraft.Opacity, 70, 100),
+            AaTranslateX(PanMinecraft, -CType(PanMinecraft.RenderTransform, TranslateTransform).X, 160, 100, Ease:=New AniEaseOutFluent(AniEasePower.ExtraStrong)),
             AaCode(
             AaCode(
             Sub()
             Sub()
                 PanSelect.Visibility = Visibility.Collapsed
                 PanSelect.Visibility = Visibility.Collapsed
@@ -168,19 +168,19 @@
     'OptiFine
     'OptiFine
     Private SelectedOptiFine As DlOptiFineListEntry = Nothing
     Private SelectedOptiFine As DlOptiFineListEntry = Nothing
     Private Sub SetOptiFineInfoShow(IsShow As String)
     Private Sub SetOptiFineInfoShow(IsShow As String)
-        If PanOptiFineInfo.Tag = IsShow Then Exit Sub
+        If PanOptiFineInfo.Tag = IsShow Then Return
         PanOptiFineInfo.Tag = IsShow
         PanOptiFineInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanOptiFineInfo, -CType(PanOptiFineInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanOptiFineInfo, 1 - PanOptiFineInfo.Opacity, 100, 90)
+                AaTranslateY(PanOptiFineInfo, -CType(PanOptiFineInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanOptiFineInfo, 1 - PanOptiFineInfo.Opacity, 80, 90)
             }, "SetOptiFineInfoShow")
             }, "SetOptiFineInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanOptiFineInfo, 6 - CType(PanOptiFineInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanOptiFineInfo, -PanOptiFineInfo.Opacity, 100)
+                AaTranslateY(PanOptiFineInfo, 6 - CType(PanOptiFineInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanOptiFineInfo, -PanOptiFineInfo.Opacity, 50)
             }, "SetOptiFineInfoShow")
             }, "SetOptiFineInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -188,19 +188,19 @@
     'LiteLoader
     'LiteLoader
     Private SelectedLiteLoader As DlLiteLoaderListEntry = Nothing
     Private SelectedLiteLoader As DlLiteLoaderListEntry = Nothing
     Private Sub SetLiteLoaderInfoShow(IsShow As String)
     Private Sub SetLiteLoaderInfoShow(IsShow As String)
-        If PanLiteLoaderInfo.Tag = IsShow Then Exit Sub
+        If PanLiteLoaderInfo.Tag = IsShow Then Return
         PanLiteLoaderInfo.Tag = IsShow
         PanLiteLoaderInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanLiteLoaderInfo, -CType(PanLiteLoaderInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanLiteLoaderInfo, 1 - PanLiteLoaderInfo.Opacity, 100, 90)
+                AaTranslateY(PanLiteLoaderInfo, -CType(PanLiteLoaderInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanLiteLoaderInfo, 1 - PanLiteLoaderInfo.Opacity, 80, 90)
             }, "SetLiteLoaderInfoShow")
             }, "SetLiteLoaderInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanLiteLoaderInfo, 6 - CType(PanLiteLoaderInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanLiteLoaderInfo, -PanLiteLoaderInfo.Opacity, 100)
+                AaTranslateY(PanLiteLoaderInfo, 6 - CType(PanLiteLoaderInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanLiteLoaderInfo, -PanLiteLoaderInfo.Opacity, 50)
             }, "SetLiteLoaderInfoShow")
             }, "SetLiteLoaderInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -208,19 +208,19 @@
     'Forge
     'Forge
     Private SelectedForge As DlForgeVersionEntry = Nothing
     Private SelectedForge As DlForgeVersionEntry = Nothing
     Private Sub SetForgeInfoShow(IsShow As String)
     Private Sub SetForgeInfoShow(IsShow As String)
-        If PanForgeInfo.Tag = IsShow Then Exit Sub
+        If PanForgeInfo.Tag = IsShow Then Return
         PanForgeInfo.Tag = IsShow
         PanForgeInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanForgeInfo, -CType(PanForgeInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanForgeInfo, 1 - PanForgeInfo.Opacity, 100, 90)
+                AaTranslateY(PanForgeInfo, -CType(PanForgeInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanForgeInfo, 1 - PanForgeInfo.Opacity, 80, 90)
             }, "SetForgeInfoShow")
             }, "SetForgeInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanForgeInfo, 6 - CType(PanForgeInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanForgeInfo, -PanForgeInfo.Opacity, 100)
+                AaTranslateY(PanForgeInfo, 6 - CType(PanForgeInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanForgeInfo, -PanForgeInfo.Opacity, 50)
             }, "SetForgeInfoShow")
             }, "SetForgeInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -228,19 +228,19 @@
     'NeoForge
     'NeoForge
     Private SelectedNeoForge As DlNeoForgeListEntry = Nothing
     Private SelectedNeoForge As DlNeoForgeListEntry = Nothing
     Private Sub SetNeoForgeInfoShow(IsShow As String)
     Private Sub SetNeoForgeInfoShow(IsShow As String)
-        If PanNeoForgeInfo.Tag = IsShow Then Exit Sub
+        If PanNeoForgeInfo.Tag = IsShow Then Return
         PanNeoForgeInfo.Tag = IsShow
         PanNeoForgeInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanNeoForgeInfo, -CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanNeoForgeInfo, 1 - PanNeoForgeInfo.Opacity, 100, 90)
+                AaTranslateY(PanNeoForgeInfo, -CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanNeoForgeInfo, 1 - PanNeoForgeInfo.Opacity, 80, 90)
             }, "SetNeoForgeInfoShow")
             }, "SetNeoForgeInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanNeoForgeInfo, 6 - CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanNeoForgeInfo, -PanNeoForgeInfo.Opacity, 100)
+                AaTranslateY(PanNeoForgeInfo, 6 - CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanNeoForgeInfo, -PanNeoForgeInfo.Opacity, 50)
             }, "SetNeoForgeInfoShow")
             }, "SetNeoForgeInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -248,19 +248,19 @@
     'Fabric
     'Fabric
     Private SelectedFabric As String = Nothing
     Private SelectedFabric As String = Nothing
     Private Sub SetFabricInfoShow(IsShow As String)
     Private Sub SetFabricInfoShow(IsShow As String)
-        If PanFabricInfo.Tag = IsShow Then Exit Sub
+        If PanFabricInfo.Tag = IsShow Then Return
         PanFabricInfo.Tag = IsShow
         PanFabricInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanFabricInfo, -CType(PanFabricInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanFabricInfo, 1 - PanFabricInfo.Opacity, 100, 90)
+                AaTranslateY(PanFabricInfo, -CType(PanFabricInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanFabricInfo, 1 - PanFabricInfo.Opacity, 80, 90)
             }, "SetFabricInfoShow")
             }, "SetFabricInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanFabricInfo, 6 - CType(PanFabricInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanFabricInfo, -PanFabricInfo.Opacity, 100)
+                AaTranslateY(PanFabricInfo, 6 - CType(PanFabricInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanFabricInfo, -PanFabricInfo.Opacity, 50)
             }, "SetFabricInfoShow")
             }, "SetFabricInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -268,19 +268,19 @@
     'FabricApi
     'FabricApi
     Private SelectedFabricApi As CompFile = Nothing
     Private SelectedFabricApi As CompFile = Nothing
     Private Sub SetFabricApiInfoShow(IsShow As String)
     Private Sub SetFabricApiInfoShow(IsShow As String)
-        If PanFabricApiInfo.Tag = IsShow Then Exit Sub
+        If PanFabricApiInfo.Tag = IsShow Then Return
         PanFabricApiInfo.Tag = IsShow
         PanFabricApiInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanFabricApiInfo, -CType(PanFabricApiInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanFabricApiInfo, 1 - PanFabricApiInfo.Opacity, 100, 90)
+                AaTranslateY(PanFabricApiInfo, -CType(PanFabricApiInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanFabricApiInfo, 1 - PanFabricApiInfo.Opacity, 80, 90)
             }, "SetFabricApiInfoShow")
             }, "SetFabricApiInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanFabricApiInfo, 6 - CType(PanFabricApiInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanFabricApiInfo, -PanFabricApiInfo.Opacity, 100)
+                AaTranslateY(PanFabricApiInfo, 6 - CType(PanFabricApiInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanFabricApiInfo, -PanFabricApiInfo.Opacity, 50)
             }, "SetFabricApiInfoShow")
             }, "SetFabricApiInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -288,19 +288,19 @@
     'OptiFabric
     'OptiFabric
     Private SelectedOptiFabric As CompFile = Nothing
     Private SelectedOptiFabric As CompFile = Nothing
     Private Sub SetOptiFabricInfoShow(IsShow As String)
     Private Sub SetOptiFabricInfoShow(IsShow As String)
-        If PanOptiFabricInfo.Tag = IsShow Then Exit Sub
+        If PanOptiFabricInfo.Tag = IsShow Then Return
         PanOptiFabricInfo.Tag = IsShow
         PanOptiFabricInfo.Tag = IsShow
         If IsShow = "True" Then
         If IsShow = "True" Then
             '显示信息栏
             '显示信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanOptiFabricInfo, -CType(PanOptiFabricInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
-                AaOpacity(PanOptiFabricInfo, 1 - PanOptiFabricInfo.Opacity, 100, 90)
+                AaTranslateY(PanOptiFabricInfo, -CType(PanOptiFabricInfo.RenderTransform, TranslateTransform).Y, 200, 100, Ease:=New AniEaseOutFluent),
+                AaOpacity(PanOptiFabricInfo, 1 - PanOptiFabricInfo.Opacity, 80, 90)
             }, "SetOptiFabricInfoShow")
             }, "SetOptiFabricInfoShow")
         Else
         Else
             '隐藏信息栏
             '隐藏信息栏
             AniStart({
             AniStart({
-                AaTranslateY(PanOptiFabricInfo, 6 - CType(PanOptiFabricInfo.RenderTransform, TranslateTransform).Y, 200),
-                AaOpacity(PanOptiFabricInfo, -PanOptiFabricInfo.Opacity, 100)
+                AaTranslateY(PanOptiFabricInfo, 6 - CType(PanOptiFabricInfo.RenderTransform, TranslateTransform).Y, 120),
+                AaOpacity(PanOptiFabricInfo, -PanOptiFabricInfo.Opacity, 50)
             }, "SetOptiFabricInfoShow")
             }, "SetOptiFabricInfoShow")
         End If
         End If
     End Sub
     End Sub
@@ -310,7 +310,7 @@
     ''' 重载已选择的项目的显示。
     ''' 重载已选择的项目的显示。
     ''' </summary>
     ''' </summary>
     Private Sub SelectReload() Handles CardOptiFine.Swap, LoadOptiFine.StateChanged, CardForge.Swap, LoadForge.StateChanged, CardNeoForge.Swap, LoadNeoForge.StateChanged, CardFabric.Swap, LoadFabric.StateChanged, CardFabricApi.Swap, LoadFabricApi.StateChanged, CardOptiFabric.Swap, LoadOptiFabric.StateChanged, CardLiteLoader.Swap, LoadLiteLoader.StateChanged
     Private Sub SelectReload() Handles CardOptiFine.Swap, LoadOptiFine.StateChanged, CardForge.Swap, LoadForge.StateChanged, CardNeoForge.Swap, LoadNeoForge.StateChanged, CardFabric.Swap, LoadFabric.StateChanged, CardFabricApi.Swap, LoadFabricApi.StateChanged, CardOptiFabric.Swap, LoadOptiFabric.StateChanged, CardLiteLoader.Swap, LoadLiteLoader.StateChanged
-        If SelectedMinecraftId Is Nothing OrElse IsReloading Then Exit Sub
+        If SelectedMinecraftId Is Nothing OrElse IsReloading Then Return
         IsReloading = True
         IsReloading = True
         '主预览
         '主预览
         SelectNameUpdate()
         SelectNameUpdate()
@@ -540,13 +540,13 @@
     Private IsSelectNameEdited As Boolean = False
     Private IsSelectNameEdited As Boolean = False
     Private IsSelectNameChanging As Boolean = False
     Private IsSelectNameChanging As Boolean = False
     Private Sub SelectNameUpdate()
     Private Sub SelectNameUpdate()
-        If IsSelectNameEdited OrElse IsSelectNameChanging Then Exit Sub
+        If IsSelectNameEdited OrElse IsSelectNameChanging Then Return
         IsSelectNameChanging = True
         IsSelectNameChanging = True
         TextSelectName.Text = GetSelectName()
         TextSelectName.Text = GetSelectName()
         IsSelectNameChanging = False
         IsSelectNameChanging = False
     End Sub
     End Sub
     Private Sub TextSelectName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles TextSelectName.TextChanged
     Private Sub TextSelectName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles TextSelectName.TextChanged
-        If IsSelectNameChanging Then Exit Sub
+        If IsSelectNameChanging Then Return
         IsSelectNameEdited = True
         IsSelectNameEdited = True
         SelectReload()
         SelectReload()
     End Sub
     End Sub
@@ -717,7 +717,7 @@
     ''' </summary>
     ''' </summary>
     Private Sub OptiFine_Loaded() Handles LoadOptiFine.StateChanged
     Private Sub OptiFine_Loaded() Handles LoadOptiFine.StateChanged
         Try
         Try
-            If DlOptiFineListLoader.State <> LoadState.Finished Then Exit Sub
+            If DlOptiFineListLoader.State <> LoadState.Finished Then Return
 
 
             '获取版本列表
             '获取版本列表
             Dim Versions As New List(Of DlOptiFineListEntry)
             Dim Versions As New List(Of DlOptiFineListEntry)
@@ -725,7 +725,7 @@
                 If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(Version, SelectedForge) Then Continue For
                 If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(Version, SelectedForge) Then Continue For
                 If Version.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then Versions.Add(Version)
                 If Version.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then Versions.Add(Version)
             Next
             Next
-            If Not Versions.Any() Then Exit Sub
+            If Not Versions.Any() Then Return
             '排序
             '排序
             Versions = Versions.Sort(
             Versions = Versions.Sort(
             Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean
             Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean
@@ -791,13 +791,13 @@
     ''' </summary>
     ''' </summary>
     Private Sub LiteLoader_Loaded() Handles LoadLiteLoader.StateChanged
     Private Sub LiteLoader_Loaded() Handles LoadLiteLoader.StateChanged
         Try
         Try
-            If DlLiteLoaderListLoader.State <> LoadState.Finished Then Exit Sub
+            If DlLiteLoaderListLoader.State <> LoadState.Finished Then Return
             '获取版本列表
             '获取版本列表
             Dim Versions As New List(Of DlLiteLoaderListEntry)
             Dim Versions As New List(Of DlLiteLoaderListEntry)
             For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
             For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
                 If Version.Inherit = SelectedMinecraftId Then Versions.Add(Version)
                 If Version.Inherit = SelectedMinecraftId Then Versions.Add(Version)
             Next
             Next
-            If Not Versions.Any() Then Exit Sub
+            If Not Versions.Any() Then Return
             '可视化
             '可视化
             PanLiteLoader.Children.Clear()
             PanLiteLoader.Children.Clear()
             For Each Version In Versions
             For Each Version In Versions
@@ -871,13 +871,13 @@
     ''' </summary>
     ''' </summary>
     Private Sub Forge_Loaded() Handles LoadForge.StateChanged
     Private Sub Forge_Loaded() Handles LoadForge.StateChanged
         Try
         Try
-            If Not LoadForge.State.IsLoader Then Exit Sub
+            If Not LoadForge.State.IsLoader Then Return
             Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = LoadForge.State
             Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = LoadForge.State
-            If SelectedMinecraftId <> Loader.Input Then Exit Sub
-            If Loader.State <> LoadState.Finished Then Exit Sub
+            If SelectedMinecraftId <> Loader.Input Then Return
+            If Loader.State <> LoadState.Finished Then Return
             '获取要显示的版本
             '获取要显示的版本
             Dim Versions = Loader.Output.ToList '复制数组,以免 Output 在实例化后变空
             Dim Versions = Loader.Output.ToList '复制数组,以免 Output 在实例化后变空
-            If Not Loader.Output.Any() Then Exit Sub
+            If Not Loader.Output.Any() Then Return
             PanForge.Children.Clear()
             PanForge.Children.Clear()
             Versions = Versions.Where(
             Versions = Versions.Where(
             Function(v)
             Function(v)
@@ -942,9 +942,9 @@
     Private Sub NeoForge_Loaded() Handles LoadNeoForge.StateChanged
     Private Sub NeoForge_Loaded() Handles LoadNeoForge.StateChanged
         Try
         Try
             '获取版本列表
             '获取版本列表
-            If DlNeoForgeListLoader.State <> LoadState.Finished Then Exit Sub
+            If DlNeoForgeListLoader.State <> LoadState.Finished Then Return
             Dim Versions = DlNeoForgeListLoader.Output.Value.Where(Function(v) v.Inherit = SelectedMinecraftId).ToList
             Dim Versions = DlNeoForgeListLoader.Output.Value.Where(Function(v) v.Inherit = SelectedMinecraftId).ToList
-            If Not Versions.Any() Then Exit Sub
+            If Not Versions.Any() Then Return
             '可视化
             '可视化
             PanNeoForge.Children.Clear()
             PanNeoForge.Children.Clear()
             NeoForgeDownloadListItemPreload(PanNeoForge, Versions, AddressOf NeoForge_Selected, False)
             NeoForgeDownloadListItemPreload(PanNeoForge, Versions, AddressOf NeoForge_Selected, False)
@@ -1001,10 +1001,10 @@
     ''' </summary>
     ''' </summary>
     Private Sub Fabric_Loaded() Handles LoadFabric.StateChanged
     Private Sub Fabric_Loaded() Handles LoadFabric.StateChanged
         Try
         Try
-            If DlFabricListLoader.State <> LoadState.Finished Then Exit Sub
+            If DlFabricListLoader.State <> LoadState.Finished Then Return
             '获取版本列表
             '获取版本列表
             Dim Versions As JArray = DlFabricListLoader.Output.Value("loader")
             Dim Versions As JArray = DlFabricListLoader.Output.Value("loader")
-            If Not Versions.Any() Then Exit Sub
+            If Not Versions.Any() Then Return
             '可视化
             '可视化
             PanFabric.Children.Clear()
             PanFabric.Children.Clear()
             PanFabric.Tag = Versions
             PanFabric.Tag = Versions
@@ -1106,8 +1106,8 @@
     ''' </summary>
     ''' </summary>
     Private Sub FabricApi_Loaded() Handles LoadFabricApi.StateChanged
     Private Sub FabricApi_Loaded() Handles LoadFabricApi.StateChanged
         Try
         Try
-            If DlFabricApiLoader.State <> LoadState.Finished Then Exit Sub
-            If SelectedMinecraftId Is Nothing OrElse SelectedFabric Is Nothing Then Exit Sub
+            If DlFabricApiLoader.State <> LoadState.Finished Then Return
+            If SelectedMinecraftId Is Nothing OrElse SelectedFabric Is Nothing Then Return
             '获取版本列表
             '获取版本列表
             Dim Versions As New List(Of CompFile)
             Dim Versions As New List(Of CompFile)
             For Each Version In DlFabricApiLoader.Output
             For Each Version In DlFabricApiLoader.Output
@@ -1119,7 +1119,7 @@
                     Versions.Add(Version)
                     Versions.Add(Version)
                 End If
                 End If
             Next
             Next
-            If Not Versions.Any() Then Exit Sub
+            If Not Versions.Any() Then Return
             Versions = Versions.OrderByDescending(Function(v) v.ReleaseDate).ToList
             Versions = Versions.OrderByDescending(Function(v) v.ReleaseDate).ToList
             '可视化
             '可视化
             PanFabricApi.Children.Clear()
             PanFabricApi.Children.Clear()
@@ -1202,14 +1202,14 @@
     ''' </summary>
     ''' </summary>
     Private Sub OptiFabric_Loaded() Handles LoadOptiFabric.StateChanged
     Private Sub OptiFabric_Loaded() Handles LoadOptiFabric.StateChanged
         Try
         Try
-            If DlOptiFabricLoader.State <> LoadState.Finished Then Exit Sub
-            If SelectedMinecraftId Is Nothing OrElse SelectedFabric Is Nothing OrElse SelectedOptiFine Is Nothing Then Exit Sub
+            If DlOptiFabricLoader.State <> LoadState.Finished Then Return
+            If SelectedMinecraftId Is Nothing OrElse SelectedFabric Is Nothing OrElse SelectedOptiFine Is Nothing Then Return
             '获取版本列表
             '获取版本列表
             Dim Versions As New List(Of CompFile)
             Dim Versions As New List(Of CompFile)
             For Each Version In DlOptiFabricLoader.Output
             For Each Version In DlOptiFabricLoader.Output
                 If IsSuitableOptiFabric(Version, SelectedMinecraftId) Then Versions.Add(Version)
                 If IsSuitableOptiFabric(Version, SelectedMinecraftId) Then Versions.Add(Version)
             Next
             Next
-            If Not Versions.Any() Then Exit Sub
+            If Not Versions.Any() Then Return
             '排序
             '排序
             Versions = Versions.OrderByDescending(Function(v) v.ReleaseDate).ToList
             Versions = Versions.OrderByDescending(Function(v) v.ReleaseDate).ToList
             '可视化
             '可视化
@@ -1257,7 +1257,7 @@
             If MyMsgBox("你尚未开启版本隔离,多个 MC 版本会共用同一个 Mod 文件夹。" & vbCrLf &
             If MyMsgBox("你尚未开启版本隔离,多个 MC 版本会共用同一个 Mod 文件夹。" & vbCrLf &
                         "因此,游戏可能会因为读取到与当前版本不符的 Mod 而崩溃。" & vbCrLf &
                         "因此,游戏可能会因为读取到与当前版本不符的 Mod 而崩溃。" & vbCrLf &
                         "推荐先在 设置 → 启动选项 → 默认版本隔离 中开启版本隔离!", "版本隔离提示", "取消下载", "继续") = 1 Then
                         "推荐先在 设置 → 启动选项 → 默认版本隔离 中开启版本隔离!", "版本隔离提示", "取消下载", "继续") = 1 Then
-                Exit Sub
+                Return
             End If
             End If
         End If
         End If
         '提交安装申请
         '提交安装申请
@@ -1275,7 +1275,7 @@
             .OptiFabric = SelectedOptiFabric,
             .OptiFabric = SelectedOptiFabric,
             .LiteLoaderEntry = SelectedLiteLoader
             .LiteLoaderEntry = SelectedLiteLoader
         }
         }
-        If Not McInstall(Request) Then Exit Sub
+        If Not McInstall(Request) Then Return
         '返回,这样在再次进入安装页面时这个版本就会显示文件夹已重复
         '返回,这样在再次进入安装页面时这个版本就会显示文件夹已重复
         ExitSelectPage()
         ExitSelectPage()
     End Sub
     End Sub

+ 4 - 4
Plain Craft Launcher 2/Pages/PageDownload/PageDownloadLeft.xaml.vb

@@ -65,7 +65,7 @@
     ''' 切换现有页面。
     ''' 切换现有页面。
     ''' </summary>
     ''' </summary>
     Public Sub PageChange(ID As FormMain.PageSubType)
     Public Sub PageChange(ID As FormMain.PageSubType)
-        If PageID = ID Then Exit Sub
+        If PageID = ID Then Return
         AniControlEnabled += 1
         AniControlEnabled += 1
         Try
         Try
             PageChangeRun(PageGet(ID))
             PageChangeRun(PageGet(ID))
@@ -187,13 +187,13 @@
 
 
     '点击返回
     '点击返回
     Private Sub ItemInstall_Click(sender As Object, e As MouseButtonEventArgs) Handles ItemInstall.Click
     Private Sub ItemInstall_Click(sender As Object, e As MouseButtonEventArgs) Handles ItemInstall.Click
-        If Not ItemInstall.Checked Then Exit Sub
+        If Not ItemInstall.Checked Then Return
         FrmDownloadInstall.ExitSelectPage()
         FrmDownloadInstall.ExitSelectPage()
     End Sub
     End Sub
 
 
     '展开手动安装
     '展开手动安装
     Private Sub ItemHand_Click(sender As Object, e As RouteEventArgs) Handles ItemHand.Changed
     Private Sub ItemHand_Click(sender As Object, e As RouteEventArgs) Handles ItemHand.Changed
-        If ItemHand.Checked = False Then Exit Sub
+        If ItemHand.Checked = False Then Return
         e.Handled = True
         e.Handled = True
         AniControlEnabled += 1
         AniControlEnabled += 1
         If Not Setup.Get("HintHandInstall") Then
         If Not Setup.Get("HintHandInstall") Then
@@ -202,7 +202,7 @@
                         "在自动安装页面先选择 MC 版本,然后就可以选择 OptiFine、Forge 等组件,让 PCL 自动进行安装了。", "自动安装提示", "返回自动安装", "继续下载手动安装包") = 1 Then
                         "在自动安装页面先选择 MC 版本,然后就可以选择 OptiFine、Forge 等组件,让 PCL 自动进行安装了。", "自动安装提示", "返回自动安装", "继续下载手动安装包") = 1 Then
                 FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.Download}, FormMain.PageSubType.DownloadInstall)
                 FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.Download}, FormMain.PageSubType.DownloadInstall)
                 AniControlEnabled -= 1
                 AniControlEnabled -= 1
-                Exit Sub
+                Return
             End If
             End If
         End If
         End If
         ItemHand.Visibility = Visibility.Collapsed
         ItemHand.Visibility = Visibility.Collapsed

+ 2 - 2
Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb

@@ -87,7 +87,7 @@
         LabTitle.Text = "登录 Minecraft"
         LabTitle.Text = "登录 Minecraft"
         LabCaption.Text =
         LabCaption.Text =
             $"登录网页将自动开启,请在网页中输入 {UserCode}(已自动复制)。" & vbCrLf & vbCrLf &
             $"登录网页将自动开启,请在网页中输入 {UserCode}(已自动复制)。" & vbCrLf & vbCrLf &
-            $"如果网络环境不佳,网页可能一直加载不出来,届时请使用 VPN 并重试。" & vbCrLf &
+            $"如果网络环境不佳,网页可能一直加载不出来,届时请使用使用加速器或 VPN 以改善网络环境。" & vbCrLf &
             $"你也可以用其他设备打开 {Website} 并输入上述代码。"
             $"你也可以用其他设备打开 {Website} 并输入上述代码。"
         Btn1.EventData = Website
         Btn1.EventData = Website
         Btn2.EventData = UserCode
         Btn2.EventData = UserCode
@@ -97,7 +97,7 @@
 
 
     Private Sub WorkThread()
     Private Sub WorkThread()
         Thread.Sleep(3000)
         Thread.Sleep(3000)
-        If MyConverter.IsExited Then Exit Sub
+        If MyConverter.IsExited Then Return
         OpenWebsite(Website)
         OpenWebsite(Website)
         ClipboardSet(UserCode)
         ClipboardSet(UserCode)
         Thread.Sleep((Data("interval").ToObject(Of Integer) - 1) * 1000)
         Thread.Sleep((Data("interval").ToObject(Of Integer) - 1) * 1000)

+ 9 - 8
Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb

@@ -49,7 +49,7 @@
         If Not Loader.State = LoadState.Finished Then
         If Not Loader.State = LoadState.Finished Then
             Hint("皮肤正在获取中,请稍候!", HintType.Critical)
             Hint("皮肤正在获取中,请稍候!", HintType.Critical)
             If Not Loader.State = LoadState.Loading Then Loader.Start()
             If Not Loader.State = LoadState.Loading Then Loader.Start()
-            Exit Sub
+            Return
         End If
         End If
         Try
         Try
             Dim FileAddress As String = SelectSaveFile("选取保存皮肤的位置", GetFileNameFromPath(Address), "皮肤图片文件(*.png)|*.png")
             Dim FileAddress As String = SelectSaveFile("选取保存皮肤的位置", GetFileNameFromPath(Address), "皮肤图片文件(*.png)|*.png")
@@ -87,7 +87,7 @@
             Catch ex As Exception '#2272
             Catch ex As Exception '#2272
                 Log(ex, $"皮肤文件已损坏:{Address}", LogLevel.Hint)
                 Log(ex, $"皮肤文件已损坏:{Address}", LogLevel.Hint)
                 File.Delete(Address)
                 File.Delete(Address)
-                Exit Sub
+                Return
             End Try
             End Try
             ImgBack.Tag = Address
             ImgBack.Tag = Address
             '大小检查
             '大小检查
@@ -209,11 +209,11 @@
         '检查条件,获取新披风
         '检查条件,获取新披风
         If IsChanging Then
         If IsChanging Then
             Hint("正在更改披风中,请稍候!")
             Hint("正在更改披风中,请稍候!")
-            Exit Sub
+            Return
         End If
         End If
         If McLoginMsLoader.State = LoadState.Failed Then
         If McLoginMsLoader.State = LoadState.Failed Then
             Hint("登录失败,无法更改披风!", HintType.Critical)
             Hint("登录失败,无法更改披风!", HintType.Critical)
-            Exit Sub
+            Return
         End If
         End If
         Hint("正在获取披风列表,请稍候……")
         Hint("正在获取披风列表,请稍候……")
         IsChanging = True
         IsChanging = True
@@ -226,7 +226,7 @@ Retry:
                 If McLoginMsLoader.State <> LoadState.Finished Then McLoginMsLoader.WaitForExit(PageLoginMsSkin.GetLoginData())
                 If McLoginMsLoader.State <> LoadState.Finished Then McLoginMsLoader.WaitForExit(PageLoginMsSkin.GetLoginData())
                 If McLoginMsLoader.State <> LoadState.Finished Then
                 If McLoginMsLoader.State <> LoadState.Finished Then
                     Hint("登录失败,无法更改披风!", HintType.Critical)
                     Hint("登录失败,无法更改披风!", HintType.Critical)
-                    Exit Sub
+                    Return
                 End If
                 End If
                 Dim AccessToken As String = McLoginMsLoader.Output.AccessToken
                 Dim AccessToken As String = McLoginMsLoader.Output.AccessToken
                 Dim Uuid As String = McLoginMsLoader.Output.Uuid
                 Dim Uuid As String = McLoginMsLoader.Output.Uuid
@@ -243,7 +243,8 @@ Retry:
                             {"Minecon2013", "Minecon 2013 参与者披风"}, {"Minecon2015", "Minecon 2015 参与者披风"}, {"Minecon2016", "Minecon 2016 参与者披风"},
                             {"Minecon2013", "Minecon 2013 参与者披风"}, {"Minecon2015", "Minecon 2015 参与者披风"}, {"Minecon2016", "Minecon 2016 参与者披风"},
                             {"Cherry Blossom", "樱花披风"}, {"15th Anniversary", "15 周年纪念披风"}, {"Purple Heart", "紫色心形披风"},
                             {"Cherry Blossom", "樱花披风"}, {"15th Anniversary", "15 周年纪念披风"}, {"Purple Heart", "紫色心形披风"},
                             {"Follower's", "追随者披风"}, {"MCC 15th Year", "MCC 15 周年披风"}, {"Minecraft Experience", "村民救援披风"},
                             {"Follower's", "追随者披风"}, {"MCC 15th Year", "MCC 15 周年披风"}, {"Minecraft Experience", "村民救援披风"},
-                            {"Mojang Office", "Mojang 办公室披风"}, {"Home", "家园披风"}, {"Menace", "入侵披风"}, {"Yearn", "渴望披风"}
+                            {"Mojang Office", "Mojang 办公室披风"}, {"Home", "家园披风"}, {"Menace", "入侵披风"}, {"Yearn", "渴望披风"},
+                            {"Common", "普通披风"}, {"Pan", "薄煎饼披风"}, {"Founder's", "创始人披风"}
                         }
                         }
                         Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}}
                         Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}}
                         For Each Cape In SkinData("capes")
                         For Each Cape In SkinData("capes")
@@ -256,7 +257,7 @@ Retry:
                         Log(ex, "获取玩家皮肤列表失败", LogLevel.Feedback)
                         Log(ex, "获取玩家皮肤列表失败", LogLevel.Feedback)
                     End Try
                     End Try
                 End Sub)
                 End Sub)
-                If SelId Is Nothing Then Exit Sub
+                If SelId Is Nothing Then Return
                 '发送请求
                 '发送请求
                 Dim Result As String = NetRequestRetry("https://api.minecraftservices.com/minecraft/profile/capes/active",
                 Dim Result As String = NetRequestRetry("https://api.minecraftservices.com/minecraft/profile/capes/active",
                     If(SelId = 0, "DELETE", "PUT"),
                     If(SelId = 0, "DELETE", "PUT"),
@@ -264,7 +265,7 @@ Retry:
                     "application/json", Headers:=New Dictionary(Of String, String) From {{"Authorization", "Bearer " & AccessToken}})
                     "application/json", Headers:=New Dictionary(Of String, String) From {{"Authorization", "Bearer " & AccessToken}})
                 If Result.Contains("""errorMessage""") Then
                 If Result.Contains("""errorMessage""") Then
                     Hint("更改披风失败:" & GetJson(Result)("errorMessage"), HintType.Critical)
                     Hint("更改披风失败:" & GetJson(Result)("errorMessage"), HintType.Critical)
-                    Exit Sub
+                    Return
                 Else
                 Else
                     Hint("更改披风成功!", HintType.Finish)
                     Hint("更改披风成功!", HintType.Finish)
                 End If
                 End If

+ 14 - 14
Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb

@@ -9,7 +9,7 @@
         AprilPosTrans.X = 0
         AprilPosTrans.X = 0
         AprilPosTrans.Y = 0
         AprilPosTrans.Y = 0
 
 
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
         AniControlEnabled += 1
         AniControlEnabled += 1
 
 
@@ -353,7 +353,7 @@ UnknownType:
                 GoTo UnknownType
                 GoTo UnknownType
         End Select
         End Select
         '刷新页面
         '刷新页面
-        If PageCurrent = Type Then Exit Sub
+        If PageCurrent = Type Then Return
         PageChange(Type, Anim).Reload(KeepInput)
         PageChange(Type, Anim).Reload(KeepInput)
         Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
         Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
         If Control IsNot Nothing Then Control.Checked = True
         If Control IsNot Nothing Then Control.Checked = True
@@ -393,7 +393,7 @@ UnknownType:
         Catch ex As Exception
         Catch ex As Exception
             If ex.GetType.Name = "ThreadInterruptedException" Then
             If ex.GetType.Name = "ThreadInterruptedException" Then
                 Data.Output = ""
                 Data.Output = ""
-                Exit Sub
+                Return
             ElseIf GetExceptionSummary(ex).Contains("429") Then
             ElseIf GetExceptionSummary(ex).Contains("429") Then
                 Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
                 Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
                 Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
                 Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
@@ -463,7 +463,7 @@ UseDefault:
                 Catch ex As Exception
                 Catch ex As Exception
                     If ex.GetType.Name = "ThreadInterruptedException" Then
                     If ex.GetType.Name = "ThreadInterruptedException" Then
                         Data.Output = ""
                         Data.Output = ""
-                        Exit Sub
+                        Return
                     ElseIf GetExceptionSummary(ex).Contains("429") Then
                     ElseIf GetExceptionSummary(ex).Contains("429") Then
                         Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
                         Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
                         Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
                         Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
@@ -515,7 +515,7 @@ UseDefault:
         Catch ex As Exception
         Catch ex As Exception
             If ex.GetType.Name = "ThreadInterruptedException" Then
             If ex.GetType.Name = "ThreadInterruptedException" Then
                 Data.Output = ""
                 Data.Output = ""
-                Exit Sub
+                Return
             ElseIf GetExceptionSummary(ex).Contains("429") Then
             ElseIf GetExceptionSummary(ex).Contains("429") Then
                 Data.Output = PathImage & "Skins/Steve.png"
                 Data.Output = PathImage & "Skins/Steve.png"
                 Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
                 Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
@@ -563,7 +563,7 @@ Finish:
         Catch ex As Exception
         Catch ex As Exception
             If ex.GetType.Name = "ThreadInterruptedException" Then
             If ex.GetType.Name = "ThreadInterruptedException" Then
                 Data.Output = ""
                 Data.Output = ""
-                Exit Sub
+                Return
             ElseIf GetExceptionSummary(ex).Contains("429") Then
             ElseIf GetExceptionSummary(ex).Contains("429") Then
                 Data.Output = PathImage & "Skins/Steve.png"
                 Data.Output = PathImage & "Skins/Steve.png"
                 Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
                 Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
@@ -592,13 +592,13 @@ Finish:
 
 
     '版本选择按钮
     '版本选择按钮
     Private Sub BtnVersion_Click(sender As Object, e As EventArgs) Handles BtnVersion.Click
     Private Sub BtnVersion_Click(sender As Object, e As EventArgs) Handles BtnVersion.Click
-        If McLaunchLoader.State = LoadState.Loading Then Exit Sub
+        If McLaunchLoader.State = LoadState.Loading Then Return
         FrmMain.PageChange(FormMain.PageType.VersionSelect)
         FrmMain.PageChange(FormMain.PageType.VersionSelect)
     End Sub
     End Sub
     '启动按钮
     '启动按钮
     Public Sub LaunchButtonClick() Handles BtnLaunch.Click
     Public Sub LaunchButtonClick() Handles BtnLaunch.Click
         If McLaunchLoader.State = LoadState.Loading OrElse Not BtnLaunch.IsEnabled OrElse
         If McLaunchLoader.State = LoadState.Loading OrElse Not BtnLaunch.IsEnabled OrElse
-            (FrmMain.PageRight IsNot Nothing AndAlso FrmMain.PageRight.PageState <> MyPageRight.PageStates.ContentStay AndAlso FrmMain.PageRight.PageState <> MyPageRight.PageStates.ContentEnter) Then Exit Sub
+            (FrmMain.PageRight IsNot Nothing AndAlso FrmMain.PageRight.PageState <> MyPageRight.PageStates.ContentStay AndAlso FrmMain.PageRight.PageState <> MyPageRight.PageStates.ContentEnter) Then Return
         '愚人节处理
         '愚人节处理
         If IsAprilEnabled AndAlso Not IsAprilGiveup Then
         If IsAprilEnabled AndAlso Not IsAprilGiveup Then
             ThemeUnlock(12, False, "隐藏主题 滑稽彩 已解锁!")
             ThemeUnlock(12, False, "隐藏主题 滑稽彩 已解锁!")
@@ -619,7 +619,7 @@ Finish:
     Private BtnLaunchState As Integer = 0
     Private BtnLaunchState As Integer = 0
     Private BtnLaunchVersion As McVersion = Nothing
     Private BtnLaunchVersion As McVersion = Nothing
     Public Sub RefreshButtonsUI() Handles BtnLaunch.Loaded
     Public Sub RefreshButtonsUI() Handles BtnLaunch.Loaded
-        If Not BtnLaunch.IsLoaded Then Exit Sub
+        If Not BtnLaunch.IsLoaded Then Return
         '获取当前状态
         '获取当前状态
         Dim CurrentState As Integer
         Dim CurrentState As Integer
         If (Not IsLoadFinished) OrElse McVersionListLoader.State = LoadState.Loading OrElse McFolderListLoader.State = LoadState.Loading Then
         If (Not IsLoadFinished) OrElse McVersionListLoader.State = LoadState.Loading OrElse McFolderListLoader.State = LoadState.Loading Then
@@ -695,7 +695,7 @@ ExitRefresh:
     End Sub
     End Sub
     '版本设置按钮
     '版本设置按钮
     Private Sub BtnMore_Click(sender As Object, e As EventArgs) Handles BtnMore.Click
     Private Sub BtnMore_Click(sender As Object, e As EventArgs) Handles BtnMore.Click
-        If McLaunchLoader.State = LoadState.Loading Then Exit Sub
+        If McLaunchLoader.State = LoadState.Loading Then Return
         McVersionCurrent.Load()
         McVersionCurrent.Load()
         PageVersionLeft.Version = McVersionCurrent
         PageVersionLeft.Version = McVersionCurrent
         FrmMain.PageChange(FormMain.PageType.VersionSetup, 0)
         FrmMain.PageChange(FormMain.PageType.VersionSetup, 0)
@@ -705,7 +705,7 @@ ExitRefresh:
     ''' </summary>
     ''' </summary>
     Public Sub LaunchingRefresh()
     Public Sub LaunchingRefresh()
         Try
         Try
-            If McLaunchLoaderReal.State = LoadState.Aborted Then Exit Sub
+            If McLaunchLoaderReal.State = LoadState.Aborted Then Return
             '阶段状态获取
             '阶段状态获取
             Dim IsLaunched As Boolean = False '是否已经启动游戏,只是在等待窗口
             Dim IsLaunched As Boolean = False '是否已经启动游戏,只是在等待窗口
             Try
             Try
@@ -719,7 +719,7 @@ ExitRefresh:
                 LabLaunchingStage.Text = "已完成"
                 LabLaunchingStage.Text = "已完成"
             Catch ex As Exception
             Catch ex As Exception
                 Log(ex, "获取是否启动完成失败,可能是由于启动状态改变导致集合已修改")
                 Log(ex, "获取是否启动完成失败,可能是由于启动状态改变导致集合已修改")
-                Exit Sub
+                Return
             End Try
             End Try
             If AniIsRun("Launch State Page") Then IsLaunched = False '等待页面切换动画完成
             If AniIsRun("Launch State Page") Then IsLaunched = False '等待页面切换动画完成
             '计算应显示的进度
             '计算应显示的进度
@@ -789,7 +789,7 @@ ExitRefresh:
     Private ActualUsedWidth As Double
     Private ActualUsedWidth As Double
     Private Sub PanLaunchingInfo_SizeChangedW(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
     Private Sub PanLaunchingInfo_SizeChangedW(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
         Dim DeltaWidth As Double = e.NewSize.Width - e.PreviousSize.Width
         Dim DeltaWidth As Double = e.NewSize.Width - e.PreviousSize.Width
-        If e.PreviousSize.Width = 0 OrElse IsWidthAnimating OrElse Math.Abs(DeltaWidth) < 1 OrElse PanLaunchingInfo.ActualWidth = 0 Then Exit Sub
+        If e.PreviousSize.Width = 0 OrElse IsWidthAnimating OrElse Math.Abs(DeltaWidth) < 1 OrElse PanLaunchingInfo.ActualWidth = 0 Then Return
         AniStart({
         AniStart({
             AaWidth(PanLaunchingInfo, DeltaWidth, 180,, New AniEaseOutFluent),
             AaWidth(PanLaunchingInfo, DeltaWidth, 180,, New AniEaseOutFluent),
             AaCode(Sub()
             AaCode(Sub()
@@ -805,7 +805,7 @@ ExitRefresh:
     Private ActualUsedHeight As Double
     Private ActualUsedHeight As Double
     Private Sub PanLaunchingInfo_SizeChangedH(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
     Private Sub PanLaunchingInfo_SizeChangedH(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
         Dim DeltaHeight As Double = e.NewSize.Height - e.PreviousSize.Height
         Dim DeltaHeight As Double = e.NewSize.Height - e.PreviousSize.Height
-        If e.PreviousSize.Height = 0 OrElse IsHeightAnimating OrElse Math.Abs(DeltaHeight) < 1 OrElse PanLaunchingInfo.ActualHeight = 0 Then Exit Sub
+        If e.PreviousSize.Height = 0 OrElse IsHeightAnimating OrElse Math.Abs(DeltaHeight) < 1 OrElse PanLaunchingInfo.ActualHeight = 0 Then Return
         AniStart({
         AniStart({
             AaHeight(PanLaunchingInfo, DeltaHeight, 180,, New AniEaseOutFluent),
             AaHeight(PanLaunchingInfo, DeltaHeight, 180,, New AniEaseOutFluent),
             AaCode(Sub()
             AaCode(Sub()

+ 9 - 5
Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb

@@ -65,7 +65,7 @@ Download:
                     RunInUiWait(Sub() LoadContent("")) '在加载结束前清空页面
                     RunInUiWait(Sub() LoadContent("")) '在加载结束前清空页面
                     Setup.Set("CacheSavedPageVersion", "")
                     Setup.Set("CacheSavedPageVersion", "")
                     OnlineLoader.Start(Url) '下载完成后将会再次触发更新
                     OnlineLoader.Start(Url) '下载完成后将会再次触发更新
-                    Exit Sub
+                    Return
                 End If
                 End If
             Case 3
             Case 3
                 Select Case Setup.Get("UiCustomPreset")
                 Select Case Setup.Get("UiCustomPreset")
@@ -146,7 +146,7 @@ Download:
                 VersionAddress = Address.BeforeFirst("?")
                 VersionAddress = Address.BeforeFirst("?")
                 If Not VersionAddress.EndsWith("/") Then VersionAddress += "/"
                 If Not VersionAddress.EndsWith("/") Then VersionAddress += "/"
                 VersionAddress += "version"
                 VersionAddress += "version"
-                If Address.Contains("?") Then VersionAddress += Address.AfterLast("?")
+                If Address.Contains("?") Then VersionAddress += "?" & Address.AfterFirst("?")
             End If
             End If
             '校验版本
             '校验版本
             Dim Version As String = ""
             Dim Version As String = ""
@@ -174,7 +174,7 @@ Download:
                 WriteFile(PathTemp & "Cache\Custom.xaml", FileContent)
                 WriteFile(PathTemp & "Cache\Custom.xaml", FileContent)
             End If
             End If
             '要求刷新
             '要求刷新
-            Refresh()
+            RunInUi(AddressOf Refresh) '不直接调用 Refresh,以防止死循环(#6245)
         Catch ex As Exception
         Catch ex As Exception
             Log(ex, $"下载主页失败({Address})", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
             Log(ex, $"下载主页失败({Address})", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
         End Try
         End Try
@@ -215,7 +215,7 @@ Download:
         SyncLock LoadContentLock
         SyncLock LoadContentLock
             '如果加载目标内容一致则不加载
             '如果加载目标内容一致则不加载
             Dim Hash = Content.GetHashCode()
             Dim Hash = Content.GetHashCode()
-            If Hash = LoadedContentHash Then Exit Sub
+            If Hash = LoadedContentHash Then Return
             LoadedContentHash = Hash
             LoadedContentHash = Hash
             '实际加载内容
             '实际加载内容
             PanCustom.Children.Clear()
             PanCustom.Children.Clear()
@@ -223,6 +223,7 @@ Download:
                 Log($"[Page] 实例化:清空主页 UI,来源为空")
                 Log($"[Page] 实例化:清空主页 UI,来源为空")
                 Return
                 Return
             End If
             End If
+            Dim LoadStartTime As Date = Date.Now
             Try
             Try
                 '修改时应同时修改 PageOtherHelpDetail.Init
                 '修改时应同时修改 PageOtherHelpDetail.Init
                 Content = HelpArgumentReplace(Content)
                 Content = HelpArgumentReplace(Content)
@@ -240,8 +241,11 @@ Download:
                 Else
                 Else
                     Log(ex, "加载主页界面失败", LogLevel.Hint)
                     Log(ex, "加载主页界面失败", LogLevel.Hint)
                 End If
                 End If
+                Return
             End Try
             End Try
-            Log($"[Page] 实例化:加载主页 UI 完成")
+            Dim LoadCostTime = (Date.Now - LoadStartTime).Milliseconds
+            Log($"[Page] 实例化:加载主页 UI 完成,耗时 {LoadCostTime}ms")
+            If LoadCostTime > 3000 Then Hint($"主页加载过于缓慢(花费了 {Math.Round(LoadCostTime / 1000, 1)} 秒),请向主页作者反馈此问题,或暂时停止使用该主页")
         End SyncLock
         End SyncLock
         Return
         Return
 Refresh:
 Refresh:

+ 1 - 2
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginAuthSkin.xaml.vb

@@ -49,11 +49,10 @@
             Log("[Launch] 要求更换角色,但登录加载器繁忙", LogLevel.Debug)
             Log("[Launch] 要求更换角色,但登录加载器繁忙", LogLevel.Debug)
             If CType(McLoginLoader.Input, McLoginServer).ForceReselectProfile Then
             If CType(McLoginLoader.Input, McLoginServer).ForceReselectProfile Then
                 Hint("正在尝试更换,请稍候!")
                 Hint("正在尝试更换,请稍候!")
-                Exit Sub
             Else
             Else
                 Hint("正在登录中,请稍后再更换角色!", HintType.Critical)
                 Hint("正在登录中,请稍后再更换角色!", HintType.Critical)
-                Exit Sub
             End If
             End If
+            Return
         End If
         End If
         Hint("正在尝试更换,请稍候!")
         Hint("正在尝试更换,请稍候!")
         Setup.Set("CacheAuthUuid", "") '清空选择缓存
         Setup.Set("CacheAuthUuid", "") '清空选择缓存

+ 1 - 1
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml

@@ -6,7 +6,7 @@
       xmlns:local="clr-namespace:PCL"
       xmlns:local="clr-namespace:PCL"
       mc:Ignorable="d" d:DesignWidth="297.6">
       mc:Ignorable="d" d:DesignWidth="297.6">
     <StackPanel Margin="0,0,0,5">
     <StackPanel Margin="0,0,0,5">
-        <local:MyHint x:Name="HintChinese" Text="玩家名如果包含英文、数字、下划线以外的内容,可能会无法进入 Minecraft 1.18 以后的世界!" Margin="0,0,0,15" Visibility="Collapsed" />
+        <local:MyHint x:Name="HintChinese" Theme="Red" Text="玩家名如果包含英文、数字、下划线以外的内容,可能会无法进入 Minecraft 1.18 以后的世界!" Margin="0,0,0,15" Visibility="Collapsed" />
         <local:MySkin HorizontalAlignment="Center" x:Name="Skin" HasCape="False" Margin="0,0,0,15" />
         <local:MySkin HorizontalAlignment="Center" x:Name="Skin" HasCape="False" Margin="0,0,0,15" />
         <local:MyComboBox IsEditable="True" x:Name="ComboName" Height="28" IsTextSearchEnabled="False" HintText="游戏用户名" />
         <local:MyComboBox IsEditable="True" x:Name="ComboName" Height="28" IsTextSearchEnabled="False" HintText="游戏用户名" />
     </StackPanel>
     </StackPanel>

+ 1 - 1
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb

@@ -25,7 +25,7 @@
         ComboAccounts.SelectedIndex = If(KeepInput, Math.Max(0, IndexBefore), 0)
         ComboAccounts.SelectedIndex = If(KeepInput, Math.Max(0, IndexBefore), 0)
     End Sub
     End Sub
     Private Sub ComboAccounts_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboAccounts.SelectionChanged
     Private Sub ComboAccounts_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboAccounts.SelectionChanged
-        If AniControlEnabled <> 0 OrElse ComboAccounts.SelectedItem Is Nothing OrElse ComboAccounts.ContentPresenter Is Nothing Then Exit Sub
+        If AniControlEnabled <> 0 OrElse ComboAccounts.SelectedItem Is Nothing OrElse ComboAccounts.ContentPresenter Is Nothing Then Return
         If TypeOf ComboAccounts.SelectedItem Is MyListItem Then
         If TypeOf ComboAccounts.SelectedItem Is MyListItem Then
             ComboAccounts.ContentPresenter.Content = CType(ComboAccounts.SelectedItem, MyListItem).Title
             ComboAccounts.ContentPresenter.Content = CType(ComboAccounts.SelectedItem, MyListItem).Title
         ElseIf TypeOf ComboAccounts.SelectedItem Is MyComboBoxItem Then
         ElseIf TypeOf ComboAccounts.SelectedItem Is MyComboBoxItem Then

+ 6 - 6
Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb

@@ -33,7 +33,7 @@
         AniStart(AaOpacity(PanButtons, 1 - PanButtons.Opacity, 120), "PageLoginMsSkin Button")
         AniStart(AaOpacity(PanButtons, 1 - PanButtons.Opacity, 120), "PageLoginMsSkin Button")
     End Sub
     End Sub
     Public Sub HidePanel() Handles PanData.MouseLeave
     Public Sub HidePanel() Handles PanData.MouseLeave
-        If BtnEdit.ContextMenu.IsOpen OrElse BtnSkin.ContextMenu.IsOpen OrElse PanData.IsMouseOver Then Exit Sub
+        If BtnEdit.ContextMenu.IsOpen OrElse BtnSkin.ContextMenu.IsOpen OrElse PanData.IsMouseOver Then Return
         AniStart(AaOpacity(PanButtons, -PanButtons.Opacity, 120), "PageLoginMsSkin Button")
         AniStart(AaOpacity(PanButtons, -PanButtons.Opacity, 120), "PageLoginMsSkin Button")
     End Sub
     End Sub
 
 
@@ -74,14 +74,14 @@
         '检查条件,获取新皮肤
         '检查条件,获取新皮肤
         If IsChanging Then
         If IsChanging Then
             Hint("正在更改皮肤中,请稍候!")
             Hint("正在更改皮肤中,请稍候!")
-            Exit Sub
+            Return
         End If
         End If
         If McLoginLoader.State = LoadState.Failed Then
         If McLoginLoader.State = LoadState.Failed Then
             Hint("登录失败,无法更改皮肤!", HintType.Critical)
             Hint("登录失败,无法更改皮肤!", HintType.Critical)
-            Exit Sub
+            Return
         End If
         End If
         Dim SkinInfo As McSkinInfo = McSkinSelect()
         Dim SkinInfo As McSkinInfo = McSkinSelect()
-        If Not SkinInfo.IsVaild Then Exit Sub
+        If Not SkinInfo.IsVaild Then Return
         Hint("正在更改皮肤……")
         Hint("正在更改皮肤……")
         IsChanging = True
         IsChanging = True
         '开始实际获取
         '开始实际获取
@@ -108,7 +108,7 @@ Retry:
                     GoTo Retry
                     GoTo Retry
                 ElseIf Result.Contains("""error""") Then
                 ElseIf Result.Contains("""error""") Then
                     Hint("更改皮肤失败:" & GetJson(Result)("error"), HintType.Critical)
                     Hint("更改皮肤失败:" & GetJson(Result)("error"), HintType.Critical)
-                    Exit Sub
+                    Return
                 End If
                 End If
                 '获取新皮肤地址
                 '获取新皮肤地址
                 Log("[Skin] 皮肤修改返回值:" & vbCrLf & Result)
                 Log("[Skin] 皮肤修改返回值:" & vbCrLf & Result)
@@ -117,7 +117,7 @@ Retry:
                 For Each Skin As JObject In ResultJson("skins")
                 For Each Skin As JObject In ResultJson("skins")
                     If Skin("state").ToString = "ACTIVE" Then
                     If Skin("state").ToString = "ACTIVE" Then
                         MySkin.ReloadCache(Skin("url"))
                         MySkin.ReloadCache(Skin("url"))
-                        Exit Sub
+                        Return
                     End If
                     End If
                 Next
                 Next
                 Throw New Exception("未知错误(" & Result & ")")
                 Throw New Exception("未知错误(" & Result & ")")

+ 0 - 1
Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml

@@ -103,7 +103,6 @@
                     <RowDefinition Height="Auto" />
                     <RowDefinition Height="Auto" />
                     <RowDefinition Height="1*" />
                     <RowDefinition Height="1*" />
                 </Grid.RowDefinitions>
                 </Grid.RowDefinitions>
-                <!--<local:MyHint IsWarn="True" Text="这是错误文本。" x:Name="HintTypeError" Visibility="Collapsed" Grid.ColumnSpan="5" Grid.RowSpan="5" Margin="15,15,15,0" VerticalAlignment="Top" />-->
                 <local:MyCard x:Name="BtnSelectCreate" Grid.Column="1" Grid.Row="1">
                 <local:MyCard x:Name="BtnSelectCreate" Grid.Column="1" Grid.Row="1">
                     <Grid Margin="35,0,25,0" IsHitTestVisible="False">
                     <Grid Margin="35,0,25,0" IsHitTestVisible="False">
                         <Grid.RowDefinitions>
                         <Grid.RowDefinitions>

+ 10 - 10
Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml.vb

@@ -18,7 +18,7 @@
     Private IsLoad As Boolean = False
     Private IsLoad As Boolean = False
     Private Sub OnLoaded() Handles Me.Loaded
     Private Sub OnLoaded() Handles Me.Loaded
         FormMain.EndProgramForce(ProcessReturnValues.Aborted)
         FormMain.EndProgramForce(ProcessReturnValues.Aborted)
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
         '启动监视线程
         '启动监视线程
         If Not IsWatcherStarted Then RunInNewThread(AddressOf WatcherThread, "Hiper Watcher")
         If Not IsWatcherStarted Then RunInNewThread(AddressOf WatcherThread, "Hiper Watcher")
@@ -149,7 +149,7 @@
 
 
     '每 1 秒执行的 Timer
     '每 1 秒执行的 Timer
     Private Sub WatcherTimer1()
     Private Sub WatcherTimer1()
-        If HiperState <> LoadState.Finished Then Exit Sub
+        If HiperState <> LoadState.Finished Then Return
         RunInUi(Sub()
         RunInUi(Sub()
                     '索引码剩余时间
                     '索引码剩余时间
                     Dim Span As TimeSpan = HiperCertTime - Date.Now
                     Dim Span As TimeSpan = HiperCertTime - Date.Now
@@ -178,7 +178,7 @@
                         HiperExit(True)
                         HiperExit(True)
                         ShowWindowToTop(Handle)
                         ShowWindowToTop(Handle)
                         Beep()
                         Beep()
-                        Exit Sub
+                        Return
                     End If
                     End If
                     '网络质量
                     '网络质量
                     Dim QualityScore As Integer = If(IpIsInChina, 0, -2)
                     Dim QualityScore As Integer = If(IpIsInChina, 0, -2)
@@ -272,7 +272,7 @@
         Log("[Hiper] 连接步骤:" & Intro)
         Log("[Hiper] 连接步骤:" & Intro)
         LoadStep = [Step]
         LoadStep = [Step]
         RunInUiWait(Sub()
         RunInUiWait(Sub()
-                        If FrmLinkHiper Is Nothing OrElse Not FrmLinkHiper.LabLoadDesc.IsLoaded Then Exit Sub
+                        If FrmLinkHiper Is Nothing OrElse Not FrmLinkHiper.LabLoadDesc.IsLoaded Then Return
                         FrmLinkHiper.LabLoadDesc.Text = Intro
                         FrmLinkHiper.LabLoadDesc.Text = Intro
                         FrmLinkHiper.UpdateProgress()
                         FrmLinkHiper.UpdateProgress()
                     End Sub)
                     End Sub)
@@ -280,7 +280,7 @@
 
 
     '承接重试
     '承接重试
     Private Sub CardLoad_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles CardLoad.MouseLeftButtonUp
     Private Sub CardLoad_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles CardLoad.MouseLeftButtonUp
-        If Not InitLoader.State = LoadState.Failed Then Exit Sub
+        If Not InitLoader.State = LoadState.Failed Then Return
         InitLoader.Start(IsForceRestart:=True)
         InitLoader.Start(IsForceRestart:=True)
     End Sub
     End Sub
 
 
@@ -299,7 +299,7 @@
     Private Sub UpdateProgress(Optional Value As Double = -1)
     Private Sub UpdateProgress(Optional Value As Double = -1)
         If Value = -1 Then Value = InitLoader.Progress
         If Value = -1 Then Value = InitLoader.Progress
         Dim DisplayingProgress As Double = ColumnProgressA.Width.Value
         Dim DisplayingProgress As Double = ColumnProgressA.Width.Value
-        If Math.Round(Value - DisplayingProgress, 3) = 0 Then Exit Sub
+        If Math.Round(Value - DisplayingProgress, 3) = 0 Then Return
         If DisplayingProgress > Value Then
         If DisplayingProgress > Value Then
             ColumnProgressA.Width = New GridLength(Value, GridUnitType.Star)
             ColumnProgressA.Width = New GridLength(Value, GridUnitType.Star)
             ColumnProgressB.Width = New GridLength(1 - Value, GridUnitType.Star)
             ColumnProgressB.Width = New GridLength(1 - Value, GridUnitType.Star)
@@ -327,7 +327,7 @@
 
 
     '退出
     '退出
     Private Sub BtnFinishExit_Click(sender As Object, e As EventArgs) Handles BtnFinishExit.Click
     Private Sub BtnFinishExit_Click(sender As Object, e As EventArgs) Handles BtnFinishExit.Click
-        If IsServerSide AndAlso MyMsgBox("你确定要关闭联机房间吗?", "确认退出", "确定", "取消", IsWarn:=True) = 2 Then Exit Sub
+        If IsServerSide AndAlso MyMsgBox("你确定要关闭联机房间吗?", "确认退出", "确定", "取消", IsWarn:=True) = 2 Then Return
         HiperExit(False)
         HiperExit(False)
     End Sub
     End Sub
 
 
@@ -338,7 +338,7 @@
     'Ping 房主
     'Ping 房主
     Private Sub BtnFinishPing_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnFinishPing.MouseLeftButtonUp
     Private Sub BtnFinishPing_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnFinishPing.MouseLeftButtonUp
         LabFinishPing.Text = "检测中"
         LabFinishPing.Text = "检测中"
-        If TaskPingHost.State = LoadState.Loading Then Exit Sub
+        If TaskPingHost.State = LoadState.Loading Then Return
         TaskPingHost.Start(True, IsForceRestart:=True)
         TaskPingHost.Start(True, IsForceRestart:=True)
     End Sub
     End Sub
     Private Shared TaskPingHost As New LoaderTask(Of Boolean, Integer)("HiPer Ping Host",
     Private Shared TaskPingHost As New LoaderTask(Of Boolean, Integer)("HiPer Ping Host",
@@ -362,7 +362,7 @@
             Return _CurrentSubpage
             Return _CurrentSubpage
         End Get
         End Get
         Set(value As Subpages)
         Set(value As Subpages)
-            If _CurrentSubpage = value Then Exit Property
+            If _CurrentSubpage = value Then Return
             _CurrentSubpage = value
             _CurrentSubpage = value
             Log("[Hiper] 子页面更改为 " & GetStringFromEnum(value))
             Log("[Hiper] 子页面更改为 " & GetStringFromEnum(value))
             PageOnContentExit()
             PageOnContentExit()
@@ -384,7 +384,7 @@
         If InitLoader.State = LoadState.Loading Then InitLoader.Abort()
         If InitLoader.State = LoadState.Loading Then InitLoader.Abort()
         If InitLoader.State = LoadState.Failed Then InitLoader.State = LoadState.Waiting
         If InitLoader.State = LoadState.Failed Then InitLoader.State = LoadState.Waiting
         RunInUi(Sub()
         RunInUi(Sub()
-                    If FrmLinkHiper Is Nothing OrElse Not FrmLinkHiper.IsLoaded Then Exit Sub
+                    If FrmLinkHiper Is Nothing OrElse Not FrmLinkHiper.IsLoaded Then Return
                     FrmLinkHiper.CurrentSubpage = If(ExitToCertPage, Subpages.PanCert, Subpages.PanSelect)
                     FrmLinkHiper.CurrentSubpage = If(ExitToCertPage, Subpages.PanCert, Subpages.PanSelect)
                     FrmLinkHiper.PageOnContentExit()
                     FrmLinkHiper.PageOnContentExit()
                 End Sub)
                 End Sub)

+ 1 - 1
Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml

@@ -10,7 +10,7 @@
             <StackPanel Orientation="Vertical" Margin="25,10">
             <StackPanel Orientation="Vertical" Margin="25,10">
                 <local:MyCard Margin="0,15,0,0" x:Name="CardUser" Title="已连接的玩家 (0)">
                 <local:MyCard Margin="0,15,0,0" x:Name="CardUser" Title="已连接的玩家 (0)">
                     <StackPanel Margin="20,37,20,15">
                     <StackPanel Margin="20,37,20,15">
-                        <local:MyHint Margin="5,2,5,8" x:Name="LabHint" IsWarn="False" />
+                        <local:MyHint Margin="5,2,5,8" x:Name="LabHint" />
                         <StackPanel x:Name="PanUserList" />
                         <StackPanel x:Name="PanUserList" />
                         <Grid Height="35" Margin="5,8,5,5">
                         <Grid Height="35" Margin="5,8,5,5">
                             <Grid.ColumnDefinitions>
                             <Grid.ColumnDefinitions>

+ 3 - 3
Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb

@@ -3,10 +3,10 @@
     Private IsLoad As Boolean = False
     Private IsLoad As Boolean = False
     Private IsPageSwitched As Boolean = False '如果在 Loaded 前切换到其他页面,会导致触发 Loaded 时再次切换一次
     Private IsPageSwitched As Boolean = False '如果在 Loaded 前切换到其他页面,会导致触发 Loaded 时再次切换一次
     Private Sub PageLinkLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
     Private Sub PageLinkLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
         '切换默认页面
         '切换默认页面
-        If IsPageSwitched Then Exit Sub
+        If IsPageSwitched Then Return
         ItemHiper.SetChecked(True, False, False)
         ItemHiper.SetChecked(True, False, False)
     End Sub
     End Sub
     Private Sub PageOtherLeft_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
     Private Sub PageOtherLeft_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
@@ -56,7 +56,7 @@
     ''' 切换现有页面。
     ''' 切换现有页面。
     ''' </summary>
     ''' </summary>
     Public Sub PageChange(ID As FormMain.PageSubType)
     Public Sub PageChange(ID As FormMain.PageSubType)
-        If PageID = ID Then Exit Sub
+        If PageID = ID Then Return
         AniControlEnabled += 1
         AniControlEnabled += 1
         IsPageSwitched = True
         IsPageSwitched = True
         Try
         Try

+ 286 - 188
Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml

@@ -104,197 +104,295 @@
             </local:MyCard>
             </local:MyCard>
             <local:MyCard Margin="0,0,0,15" Title="赞助者">
             <local:MyCard Margin="0,0,0,15" Title="赞助者">
                 <StackPanel Margin="25,40,10,20">
                 <StackPanel Margin="25,40,10,20">
-                    <TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 3 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
-                    <WrapPanel Margin="0,0,0,10">
                        <TextBlock Width="120" Margin="0,1.5" Text="micheal276" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="吃面不加葱" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="想去看那倒悬山" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="隳之狐" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="QY熹微" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="LZL" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="老卡费" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="散." />
-                        <TextBlock Width="120" Margin="0,1.5" Text="续笙_xusheng" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="HappyGhast0123" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Tong" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="15158206433" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="一抹蓝色和粉色" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="UcFB" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="哦" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="T2222" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Toudesu" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="苏利" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="DW." />
+                    <TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 4 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
+                    <WrapPanel Margin="0,0,0,10">
                        <TextBlock Width="120" Margin="0,1.5" Text="秦屎皇" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Hyacinth" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="hjk" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="JiechuAik" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="ls" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Alleyne" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="泠羽洛" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="user0527" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="zxgcugdyb" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Night_Fall" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="冷酷们" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="迅卩" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="WTFdog" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="NID" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="LexSar" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="巡洋舰7179" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="不允许使用的昵称" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="DLINX" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="仄仄仄" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="abc" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="胖虎贼懒" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="次月" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="芝士绒散" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="桂月兔子" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="TT" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Wah" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="卅载风雪满故园" />
+                        <TextBlock Width="240" Margin="0,1.5" Text="左手肘击,右手元神" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="幸运星" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="SphereBall" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="doubi_sir" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Tencelll" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="bigby" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Musire" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="YouMi" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="冉棠" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="白噪音" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="恶俗狗" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="空濛是只大笨狐狸" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="KSGDBCA" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="ALYESY" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="火花狐" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="LovePGKD" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Ls00w" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小洋和小昊" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="五月" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="绝沓" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="辻渃" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="又想玉玉了QWQ" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="雨沫云汐" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="回青观落日" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="猫七七" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="泉东居士" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="猫猫念余年" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="yoseya" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="雨" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="MRCA_MLU" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="不要太狗血" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="zhaoesaf" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="月球领航员" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="IsolatedLam" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="1818" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="ghjklbnm144" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Good night" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="盖着被子就跑" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="shabbyunicorn3" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="LEMON TEA" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="冰激凌天尊" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="向东114514" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Wangderful555" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="JDS123" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Nalyne" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="uglyduckling" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小孩" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="长宁QAQ" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="WYXiLYH" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="蔡徐坤" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="风清_GuDER" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="nananatuki" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="绯星" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="非牛非马先生小姐" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="......" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="MaTTer" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="grizzly" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="樱井落花" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="那个谁" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Hiang224855" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Mingze Du" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="yuuio" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Flowing_Shadow" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="buluo" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Gannet09" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="惠子呀惠子" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="PMapleLP" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="p_p" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="冉皓Kamiya" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="陈陈陈陈最" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="纳兰叶秋" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="++0" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Duskbean" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="mc_宣羽" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="八两大西瓜" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Madam企鹅" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="PMm" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="无敌钢筋大玉" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="诸葛千绝" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="风华一指流砂" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小阿君" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="桃乐志" />
+                        <TextBlock Width="240" Margin="0,1.5" Text="把你switch借我玩玩" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="林宇" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="星辰星空" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="幽寂" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="BasaltSlrtean" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="智子10086号" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="op" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="seasonlog" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="guxuyuming" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Marshmallow" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="孤单" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="甘李子" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="xaslat-渊" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Sweecol" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="木瓜牛奶布丁" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="午夜里的猫爱睡觉" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="超级番薯Pro" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="宝盖木" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="守着那个它" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="橙子dc" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="FY_dusty" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Mr." />
+                        <TextBlock Width="120" Margin="0,1.5" Text="星辰" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="ko8888ko" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Rutriste" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="坐轮椅的猫师傅" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="洛圣都劲夫" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="hyh" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="无刃幻越" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="JRgril" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="西宫硝子" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Loneliness" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="青青草" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="童璃" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="北极光" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="玲妹儿" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="SuLiHuaSong" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="多米" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="PigTheCreeper" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Finext652" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="秋禾_Hikari" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="steven" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="akergo" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="锦菌" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="阿銓" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="茉莉花茶少糖" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="凯" />
+                        <TextBlock Width="240" Margin="0,1.5" Text="广寒宫中金蟾炖兔子" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="BUBU" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="yzt" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Eyedazzler" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="空白" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="薛十一" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="胡克霍霍" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="S1767" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="沐雪于梦" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="门一多" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="dy2022" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="幽谷响" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="我的世界" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Bobsteve" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="EthanCAi" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="老鼠大" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="公孙月" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="nayo" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="白夜与黑昼" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="J-10" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="jade_lin" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="马不露肉" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="PANDA" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="子夜" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="墨霜二十一" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="August" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="CarrotMan_CD" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="yuguya" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="瞳鱼" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小妤情绪零碎" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="777" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="林海珠" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Mikey" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="君莫笑" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="梦璃素弦" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="一只果粒" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="我裂开啊" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="半个景煦子" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="售票员发通报??" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="蓝莓呢" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Golfl." />
+                        <TextBlock Width="120" Margin="0,1.5" Text="彧隳" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="吃灰的浅影" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="222" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="雅书" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="成长中的羽翼" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="伊仔今天也很非" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="DARTS_STUDIOS." />
+                        <TextBlock Width="120" Margin="0,1.5" Text="。" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="redblock" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="白上林" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="炒面炒面林" />
+                        <TextBlock Width="120" Margin="0,1.5" Text=": D" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="聆世音" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="量籽嘉素" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Watanuki" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="HUGO37211" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="忍小建" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="朝夕" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="lazier" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="忧化中" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="子八年" />
+                        <TextBlock Width="240" Margin="0,1.5" Text="A decadent person" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Rrzttc" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="FancyBitz" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="chihaya anon" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Mc__XiaoYao" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="诺伊" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小生饭盒" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="伊之心" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Kelvin_0" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="林小鸭" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="松鼠" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="亦似花落亦如霞" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="掺了牛奶的水" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="河里的螃蟹" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="BesidU" />
                         <TextBlock Width="120" Margin="0,1.5" Text="抛抛不是泡泡" />
                         <TextBlock Width="120" Margin="0,1.5" Text="抛抛不是泡泡" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="无名小卒" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="lgl" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="mk" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="鲨鱼不是鱼" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Momizi_Azusa" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="oseki" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="精?华?夏?" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="术士的黑猫" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="theagin" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="狗杞わ枸子" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="别凶不二啦" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="枫叶落江" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Tianwai来物" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="如风FC" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="fan" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="雨恋芳歌" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="neko" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="陌上云暮迟迟归" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="121" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="SGYH" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Lelouch" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="tisky" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="禹餘" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="MoYou" />
-                        <TextBlock Width="240" Margin="0,1.5" Text="?HONEY HONEY BOOM?" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="流雪无痕" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="yourenA" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="当归与蜜糖" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="提瓦特太保" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="weidao-云天" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Yangxl" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="zero" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="guoomg" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="孤念鬱海" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="李晨曦" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="dyh" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="didibubu" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="way_" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="浅冥" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="LightTeaHear" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="kiki" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="洛山阳" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="月下独酌" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="阿晴" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="论猫的液体可能性" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="微尔丶白折" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="超凡大谱系" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="麻圣" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="八宝饭" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="张不易" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="1" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="望Wang" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="alrin" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="无心态" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="MelonEater88" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="白日梦" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="FEssyyzplane" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="札卜铎徳勒" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="星河" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="老王1233" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="王等等等" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="橘子233" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="wyhll" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="SiMen_774" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Klcos" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="pepsi" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="FORGE" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="李青团" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Zmr2333" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="CWKF" />
-                        <TextBlock Width="240" Margin="0,1.5" Text="兜帽人evei622130" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="毒奶神探女" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="赤诚之心" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="藏白" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="某零子" />
                         <TextBlock Width="120" Margin="0,1.5" Text="WJMAS" />
                         <TextBlock Width="120" Margin="0,1.5" Text="WJMAS" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="骨头" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Starying" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="钱小穷" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="casper" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Summer丿皓月" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="小促" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="御坂美琴" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="闲的没事干啥呢" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="aiyu" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="shuaitiao" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="小真寻" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="清离风" />
-                        <TextBlock Width="240" Margin="0,1.5" Text="FateIsYetUncertain" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Olympia" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="橘如望九" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="木涵" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="2147483647" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="YJ-StarBlock" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="欲予卿" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="haolanne" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="浅夏" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="MCxiaobai" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="未知数x酱" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="有事打钱" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Setsuna" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="电脑" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="mpty" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="小兔噗噗" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="超级白羊大王" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="奈奈" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="12345" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="fshj" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Langfeige" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="聆风岱岳" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Fier" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="张怀民" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="minecraftmc22" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="爱蹈琯子" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="何心慈" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="睏欤" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="熙里糊涂" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="落叶" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="阿坎尔德" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="杜野凛世" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="呆呆" />
-                        <TextBlock Width="240" Margin="0,1.5" Text="我和琳妮特有个孩子" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Fishking_qwe" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="惠惠" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="黑暗风暴" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Oxsheep" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Clove_Cloud" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="今は最高" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="YuiuY" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="George0307" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="游子桀" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="玄之" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="海绵宝宝低顺钠" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="杜先生" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="黑火c" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="落日余音" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="mojanng_" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="聿丏" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="ClarkeTAT" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="东方浅浅" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="王ZEAN" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="ayu" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="无所畏惧冷圈人" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="馨軟" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="白加黑" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="梦境之中" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="青枝望月" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="m1nato__" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="18858019934" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="钩子Goou_Zi" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="开心快乐每一天" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="财阀" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小小小柴" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="晓游明" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="吃不饱的小云云" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="RandomQAQ" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Ahhhh" />
                         <TextBlock Width="120" Margin="0,1.5" Text="dingwenbo" />
                         <TextBlock Width="120" Margin="0,1.5" Text="dingwenbo" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="法老" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="和十奕" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="give" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="我是只面包猫" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="柒安" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="YUU" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="月下初拥" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="白叶夕秋" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="酸奶炸鱼" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="灵喻" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="_暮霭" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="TylerDeng" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="我不在线" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Hugh" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Qiyue" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="CHAKKS" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="Silver_1572" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="WIFTAB" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="hmal" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="通大小学弟" />
-                        <TextBlock Width="120" Margin="0,1.5" Text="htenet" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="逆行若羽" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Cloud5321" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="ETERNALpause" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="小怕" />
+                        <TextBlock Width="240" Margin="0,1.5" Text="mycraftgod2014111" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="xueling" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="拉的一坨" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="典急蚌孝豹" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="MENGXI_梦惜" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="baicai1339" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="xvp1563" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="库洛米" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="空心清风" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="素年锦时" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="浅色" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="绪方田月" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="bootspuss" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="万万大喜" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="FORxiaomo" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="躺床上发霉" />
+                        <TextBlock Width="240" Margin="0,1.5" Text="wuuuuuuuuuuud" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="xinyue_game" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="天灵雪" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="笙默语℡" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="QQGG" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="暮色极夜" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="陆舫" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="以炙面包" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Craig" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Hamider" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="狂仙儿" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="ggg" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="原色龙" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="江黎洛" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="大花曼陀罗" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="弎十五" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="肆意" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="phoximity" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="Saga_Xuan" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="噜啦啦啦" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="cicada" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="星索" />
+                        <TextBlock Width="120" Margin="0,1.5" Text="泠LINg" />
                     </WrapPanel>
                     </WrapPanel>
                     <Grid Height="35">
                     <Grid Height="35">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>

+ 1 - 1
Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml.vb

@@ -7,7 +7,7 @@
         PanBack.ScrollToHome()
         PanBack.ScrollToHome()
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoaded Then Exit Sub
+        If IsLoaded Then Return
         IsLoaded = True
         IsLoaded = True
 
 
         ItemAboutPcl.Info = ItemAboutPcl.Info.Replace("%VERSION%", VersionDisplayName).Replace("%VERSIONCODE%", VersionCode).Replace("%BRANCH%", VersionBranchCode)
         ItemAboutPcl.Info = ItemAboutPcl.Info.Replace("%VERSION%", VersionDisplayName).Replace("%VERSIONCODE%", VersionCode).Replace("%BRANCH%", VersionBranchCode)

+ 9 - 9
Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb

@@ -10,12 +10,12 @@
         If ItemTest.Checked AndAlso Setup.Get("UiHiddenOtherTest") Then IsHiddenPage = True
         If ItemTest.Checked AndAlso Setup.Get("UiHiddenOtherTest") Then IsHiddenPage = True
         If PageSetupUI.HiddenForceShow Then IsHiddenPage = False
         If PageSetupUI.HiddenForceShow Then IsHiddenPage = False
         '若页面错误,或尚未加载,则继续
         '若页面错误,或尚未加载,则继续
-        If IsLoad AndAlso Not IsHiddenPage Then Exit Sub
+        If IsLoad AndAlso Not IsHiddenPage Then Return
         IsLoad = True
         IsLoad = True
         '刷新子页面隐藏情况
         '刷新子页面隐藏情况
         PageSetupUI.HiddenRefresh()
         PageSetupUI.HiddenRefresh()
         '选择第一个未被禁用的子页面
         '选择第一个未被禁用的子页面
-        If IsPageSwitched Then Exit Sub
+        If IsPageSwitched Then Return
         If Not Setup.Get("UiHiddenOtherHelp") Then
         If Not Setup.Get("UiHiddenOtherHelp") Then
             ItemHelp.SetChecked(True, False, False)
             ItemHelp.SetChecked(True, False, False)
         ElseIf Not Setup.Get("UiHiddenOtherAbout") Then
         ElseIf Not Setup.Get("UiHiddenOtherAbout") Then
@@ -76,7 +76,7 @@
     ''' 切换现有页面。
     ''' 切换现有页面。
     ''' </summary>
     ''' </summary>
     Public Sub PageChange(ID As FormMain.PageSubType)
     Public Sub PageChange(ID As FormMain.PageSubType)
-        If PageID = ID Then Exit Sub
+        If PageID = ID Then Return
         AniControlEnabled += 1
         AniControlEnabled += 1
         IsPageSwitched = True
         IsPageSwitched = True
         Try
         Try
@@ -126,13 +126,13 @@
 
 
     '打开网页
     '打开网页
     Private Sub TryFeedback(sender As Object, e As RouteEventArgs) Handles ItemFeedback.Changed
     Private Sub TryFeedback(sender As Object, e As RouteEventArgs) Handles ItemFeedback.Changed
-        If Not ItemFeedback.Checked Then Exit Sub
+        If Not ItemFeedback.Checked Then Return
         TryFeedback()
         TryFeedback()
         e.Handled = True
         e.Handled = True
     End Sub
     End Sub
     Public Shared Sub TryFeedback()
     Public Shared Sub TryFeedback()
-        If Not CanFeedback(True) Then Exit Sub
-        Select Case MyMsgBox("在提交新反馈前,建议先搜索反馈列表,以避免重复提交。" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
+        If Not CanFeedback(True) Then Return
+        Select Case MyMsgBox("在提交新反馈前,建议先搜索反馈列表,以避免重复提交。" & vbCrLf & "如果无法打开该网页,请使用 VPN 以改善网络环境。",
                     "反馈", "提交新反馈", "查看反馈列表", "取消")
                     "反馈", "提交新反馈", "查看反馈列表", "取消")
             Case 1
             Case 1
                 Feedback(True, False)
                 Feedback(True, False)
@@ -141,13 +141,13 @@
         End Select
         End Select
     End Sub
     End Sub
     Private Sub TryVote(sender As Object, e As RouteEventArgs) Handles ItemVote.Changed
     Private Sub TryVote(sender As Object, e As RouteEventArgs) Handles ItemVote.Changed
-        If Not ItemVote.Checked Then Exit Sub
+        If Not ItemVote.Checked Then Return
         TryVote()
         TryVote()
         e.Handled = True
         e.Handled = True
     End Sub
     End Sub
     Public Shared Sub TryVote()
     Public Shared Sub TryVote()
-        If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
-                    "新功能投票", "打开", "取消") = 2 Then Exit Sub
+        If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请使用 VPN 以改善网络环境。",
+                    "新功能投票", "打开", "取消") = 2 Then Return
         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")
         OpenWebsite("https://github.com/Hex-Dragon/PCL2/discussions/categories/%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8?discussions_q=category%3A%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8+sort%3Adate_created")
     End Sub
     End Sub
 
 

+ 20 - 20
Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb

@@ -21,7 +21,7 @@
                         Exit For
                         Exit For
                     End If
                     End If
                 Next
                 Next
-                If IsEqual Then Exit Sub
+                If IsEqual Then Return
             End If
             End If
             McFolderListLast = McFolderList
             McFolderListLast = McFolderList
 
 
@@ -127,7 +127,7 @@
             For i = 0 To McFolderList.Count - 1
             For i = 0 To McFolderList.Count - 1
                 If McFolderList(i).Path = PathMcFolder Then
                 If McFolderList(i).Path = PathMcFolder Then
                     CType(FrmSelectLeft.PanList.Children(i + 1), MyListItem).Checked = True '去掉第一个标题
                     CType(FrmSelectLeft.PanList.Children(i + 1), MyListItem).Checked = True '去掉第一个标题
-                    Exit Sub
+                    Return
                 End If
                 End If
             Next
             Next
             If Not McFolderList.Any() Then
             If Not McFolderList.Any() Then
@@ -151,20 +151,20 @@
         '检查是否有下载任务
         '检查是否有下载任务
         If HasDownloadingTask() Then
         If HasDownloadingTask() Then
             Hint("在下载任务进行时,无法添加游戏文件夹!", HintType.Critical)
             Hint("在下载任务进行时,无法添加游戏文件夹!", HintType.Critical)
-            Exit Sub
+            Return
         End If
         End If
         Try
         Try
             '获取输入
             '获取输入
             NewFolder = SelectFolder()
             NewFolder = SelectFolder()
-            If NewFolder = "" Then Exit Sub
-            If NewFolder.Contains("!") OrElse NewFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Critical) : Exit Sub
+            If NewFolder = "" Then Return
+            If NewFolder.Contains("!") OrElse NewFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Critical) : Return
             '要求输入显示名称
             '要求输入显示名称
             Dim SplitedNames As String() = NewFolder.TrimEnd("\").Split("\")
             Dim SplitedNames As String() = NewFolder.TrimEnd("\").Split("\")
             Dim DefaultName As String = If(SplitedNames.Last = ".minecraft", If(SplitedNames.Count >= 3, SplitedNames(SplitedNames.Count - 2), ""), SplitedNames.Last)
             Dim DefaultName As String = If(SplitedNames.Last = ".minecraft", If(SplitedNames.Count >= 3, SplitedNames(SplitedNames.Count - 2), ""), SplitedNames.Last)
             If DefaultName.Length > 40 Then DefaultName = DefaultName.Substring(0, 39)
             If DefaultName.Length > 40 Then DefaultName = DefaultName.Substring(0, 39)
             Dim NewName As String = MyMsgBoxInput("输入显示名称", "输入该文件夹在左边栏列表中显示的名称。", DefaultName,
             Dim NewName As String = MyMsgBoxInput("输入显示名称", "输入该文件夹在左边栏列表中显示的名称。", DefaultName,
                                               New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
                                               New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
-            If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
+            If String.IsNullOrWhiteSpace(NewName) Then Return
             '添加文件夹
             '添加文件夹
             AddFolder(NewFolder, NewName, True)
             AddFolder(NewFolder, NewName, True)
         Catch ex As Exception
         Catch ex As Exception
@@ -183,7 +183,7 @@
                 If Not CheckPermission(FolderPath) Then
                 If Not CheckPermission(FolderPath) Then
                     If ShowHint Then
                     If ShowHint Then
                         Hint("添加文件夹失败:PCL 没有访问该文件夹的权限!", HintType.Critical)
                         Hint("添加文件夹失败:PCL 没有访问该文件夹的权限!", HintType.Critical)
-                        Exit Sub
+                        Return
                     Else
                     Else
                         Throw New Exception("PCL 没有访问文件夹的权限:" & FolderPath)
                         Throw New Exception("PCL 没有访问文件夹的权限:" & FolderPath)
                     End If
                     End If
@@ -208,7 +208,7 @@
                         IsAdded = True
                         IsAdded = True
                         If Folder.Split(">")(0) = DisplayName Then
                         If Folder.Split(">")(0) = DisplayName Then
                             If ShowHint Then Hint("此文件夹已在列表中!", HintType.Info)
                             If ShowHint Then Hint("此文件夹已在列表中!", HintType.Info)
-                            Exit Sub
+                            Return
                         Else
                         Else
                             Folders(i) = DisplayName & ">" & FolderPath
                             Folders(i) = DisplayName & ">" & FolderPath
                             IsReplace = True
                             IsReplace = True
@@ -225,15 +225,15 @@
                 Setup.Set("LaunchFolderSelect", FolderPath.Replace(Path, "$"))
                 Setup.Set("LaunchFolderSelect", FolderPath.Replace(Path, "$"))
                 McFolderListLoader.Start(IsForceRestart:=True)
                 McFolderListLoader.Start(IsForceRestart:=True)
                 '提示
                 '提示
-                If IsReplace Then Exit Sub
+                If IsReplace Then Return
                 If ShowHint Then Hint("文件夹 " & DisplayName & " 已添加!", HintType.Finish)
                 If ShowHint Then Hint("文件夹 " & DisplayName & " 已添加!", HintType.Finish)
                 '检查是否为根目录整合包,自动关闭版本隔离
                 '检查是否为根目录整合包,自动关闭版本隔离
                 '1. 根目录中存在数个 Mod
                 '1. 根目录中存在数个 Mod
                 Dim ModFolder As New DirectoryInfo(FolderPath & "mods\")
                 Dim ModFolder As New DirectoryInfo(FolderPath & "mods\")
-                If Not (ModFolder.Exists AndAlso ModFolder.EnumerateFiles.Count >= 3) Then Exit Sub
+                If Not (ModFolder.Exists AndAlso ModFolder.EnumerateFiles.Count >= 3) Then Return
                 '2. 版本数较少,可能为整合包
                 '2. 版本数较少,可能为整合包
                 Dim VersionFolder As New DirectoryInfo(FolderPath & "versions\")
                 Dim VersionFolder As New DirectoryInfo(FolderPath & "versions\")
-                If Not (VersionFolder.Exists AndAlso VersionFolder.EnumerateDirectories.Count <= 3) Then Exit Sub
+                If Not (VersionFolder.Exists AndAlso VersionFolder.EnumerateDirectories.Count <= 3) Then Return
                 '3. 能够找到可安装 Mod 的版本
                 '3. 能够找到可安装 Mod 的版本
                 For Each VersionPath In VersionFolder.EnumerateDirectories
                 For Each VersionPath In VersionFolder.EnumerateDirectories
                     Dim Version As New McVersion(VersionPath.FullName)
                     Dim Version As New McVersion(VersionPath.FullName)
@@ -241,7 +241,7 @@
                     If Not Version.Modable Then Continue For
                     If Not Version.Modable Then Continue For
                     '4. 该版本的隔离文件夹下不存在 mods
                     '4. 该版本的隔离文件夹下不存在 mods
                     Dim ModIndieFolder As New DirectoryInfo(Version.Path & "mods\")
                     Dim ModIndieFolder As New DirectoryInfo(Version.Path & "mods\")
-                    If ModIndieFolder.Exists AndAlso ModIndieFolder.EnumerateFiles.Any Then Exit Sub
+                    If ModIndieFolder.Exists AndAlso ModIndieFolder.EnumerateFiles.Any Then Return
                     '满足以上全部条件则视为根目录整合包
                     '满足以上全部条件则视为根目录整合包
                     Setup.Set("VersionArgumentIndie", 2, Version:=Version)
                     Setup.Set("VersionArgumentIndie", 2, Version:=Version)
                     Setup.Set("VersionArgumentIndieV2", False, Version:=Version)
                     Setup.Set("VersionArgumentIndieV2", False, Version:=Version)
@@ -258,7 +258,7 @@
         '检查是否有下载任务
         '检查是否有下载任务
         If HasDownloadingTask() Then
         If HasDownloadingTask() Then
             Hint("在下载任务进行时,无法创建游戏文件夹!", HintType.Critical)
             Hint("在下载任务进行时,无法创建游戏文件夹!", HintType.Critical)
-            Exit Sub
+            Return
         End If
         End If
         If Not Directory.Exists(Path & ".minecraft\") Then
         If Not Directory.Exists(Path & ".minecraft\") Then
             Directory.CreateDirectory(Path & ".minecraft\")
             Directory.CreateDirectory(Path & ".minecraft\")
@@ -290,7 +290,7 @@
                     '不删除
                     '不删除
                     Case 3
                     Case 3
                         '取消
                         '取消
-                        Exit Sub
+                        Return
                 End Select
                 End Select
             End If
             End If
             '若修改了本部分代码,应对应修改 Delete_Click 中的代码
             '若修改了本部分代码,应对应修改 Delete_Click 中的代码
@@ -317,8 +317,8 @@
     Public Sub Delete_Click(sender As Object, e As RoutedEventArgs)
     Public Sub Delete_Click(sender As Object, e As RoutedEventArgs)
         Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
         Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
         Dim DeleteText As String = If((Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1, "清空", "删除")
         Dim DeleteText As String = If((Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1, "清空", "删除")
-        If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久丢失,且不可恢复!", "删除警告", "取消", "确认", "取消") <> 2 Then Exit Sub
-        If MyMsgBox("如果你在该文件夹中存放了除 MC 以外的其他文件,这些文件也会被一同删除!" & vbCrLf & "继续删除会导致该文件夹中的所有文件永久丢失,请在仔细确认后再继续!" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这是最后一次警告!", "删除警告", "确认" & DeleteText, "取消", IsWarn:=True) <> 1 Then Exit Sub
+        If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久丢失,且不可恢复!", "删除警告", "取消", "确认", "取消") <> 2 Then Return
+        If MyMsgBox("如果你在该文件夹中存放了除 MC 以外的其他文件,这些文件也会被一同删除!" & vbCrLf & "继续删除会导致该文件夹中的所有文件永久丢失,请在仔细确认后再继续!" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这是最后一次警告!", "删除警告", "确认" & DeleteText, "取消", IsWarn:=True) <> 1 Then Return
         '移出列表
         '移出列表
         If Folder.Type = McFolderType.Custom Then
         If Folder.Type = McFolderType.Custom Then
             Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
             Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
@@ -369,7 +369,7 @@
             Dim NewName As String =
             Dim NewName As String =
                 MyMsgBoxInput("输入新名称", "", Folder.Name,
                 MyMsgBoxInput("输入新名称", "", Folder.Name,
                               New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
                               New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
-            If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
+            If String.IsNullOrWhiteSpace(NewName) Then Return
             '修改自定义名
             '修改自定义名
             Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
             Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
             Dim IsAdded As Boolean = False
             Dim IsAdded As Boolean = False
@@ -380,7 +380,7 @@
                     IsAdded = True
                     IsAdded = True
                     If FolderCurrent.Split(">")(0) = NewName Then
                     If FolderCurrent.Split(">")(0) = NewName Then
                         '名称未修改
                         '名称未修改
-                        Exit Sub
+                        Return
                     Else
                     Else
                         Folders(i) = NewName & ">" & Folder.Path
                         Folders(i) = NewName & ">" & Folder.Path
                     End If
                     End If
@@ -400,12 +400,12 @@
 
 
     '点击选项
     '点击选项
     Public Sub Folder_Change(sender As MyListItem, e As RouteEventArgs)
     Public Sub Folder_Change(sender As MyListItem, e As RouteEventArgs)
-        If Not e.RaiseByMouse OrElse Not sender.Checked Then Exit Sub
+        If Not e.RaiseByMouse OrElse Not sender.Checked Then Return
         '检查是否有下载任务
         '检查是否有下载任务
         If HasDownloadingTask(True) Then
         If HasDownloadingTask(True) Then
             Hint("在下载任务进行时,无法切换游戏文件夹!", HintType.Critical)
             Hint("在下载任务进行时,无法切换游戏文件夹!", HintType.Critical)
             e.Handled = True
             e.Handled = True
-            Exit Sub
+            Return
         End If
         End If
         '更换
         '更换
         Setup.Set("LaunchFolderSelect", CType(sender.Tag, McFolder).Path.Replace(Path, "$"))
         Setup.Set("LaunchFolderSelect", CType(sender.Tag, McFolder).Path.Replace(Path, "$"))

+ 1 - 1
Plain Craft Launcher 2/Pages/PageSelectRight.xaml.vb

@@ -231,7 +231,7 @@
                         Hint("版本 " & Version.Name & " 已删除到回收站!", HintType.Finish)
                         Hint("版本 " & Version.Name & " 已删除到回收站!", HintType.Finish)
                     End If
                     End If
                 Case 2
                 Case 2
-                    Exit Sub
+                    Return
             End Select
             End Select
             '从 UI 中移除
             '从 UI 中移除
             If Version.DisplayType = McVersionCardType.Hidden OrElse Not Version.IsStar Then
             If Version.DisplayType = McVersionCardType.Hidden OrElse Not Version.IsStar Then

+ 8 - 10
Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb

@@ -246,7 +246,7 @@
             Value = CTypeDynamic(Value, E.Type)
             Value = CTypeDynamic(Value, E.Type)
             If E.State = 2 Then
             If E.State = 2 Then
                 '如果已应用,且值相同,则无需再次更改
                 '如果已应用,且值相同,则无需再次更改
-                If E.Value = Value AndAlso Not ForceReload Then Exit Sub
+                If E.Value = Value AndAlso Not ForceReload Then Return
             Else
             Else
                 '如果未应用,则直接更改并应用
                 '如果未应用,则直接更改并应用
                 If E.Source <> SetupSource.Version Then E.State = 2
                 If E.Source <> SetupSource.Version Then E.State = 2
@@ -363,7 +363,7 @@
     ''' </summary>
     ''' </summary>
     Private Sub Read(Key As String, ByRef E As SetupEntry, Version As McVersion)
     Private Sub Read(Key As String, ByRef E As SetupEntry, Version As McVersion)
         Try
         Try
-            If Not E.State = 0 Then Exit Sub
+            If Not E.State = 0 Then Return
             Dim SourceValue As String = Nothing '先用 String 储存,避免类型转换
             Dim SourceValue As String = Nothing '先用 String 储存,避免类型转换
             Select Case E.Source
             Select Case E.Source
                 Case SetupSource.Normal
                 Case SetupSource.Normal
@@ -423,7 +423,7 @@
 
 
     '游戏内存
     '游戏内存
     Public Sub LaunchRamType(Type As Integer)
     Public Sub LaunchRamType(Type As Integer)
-        If FrmSetupLaunch Is Nothing Then Exit Sub
+        If FrmSetupLaunch Is Nothing Then Return
         FrmSetupLaunch.RamType(Type)
         FrmSetupLaunch.RamType(Type)
     End Sub
     End Sub
 
 
@@ -494,11 +494,9 @@
     Public Sub UiLauncherTransparent(Value As Integer)
     Public Sub UiLauncherTransparent(Value As Integer)
         FrmMain.Opacity = Value / 1000 + 0.4
         FrmMain.Opacity = Value / 1000 + 0.4
     End Sub
     End Sub
-#If Not BETA Then
     Public Sub UiLauncherTheme(Value As Integer)
     Public Sub UiLauncherTheme(Value As Integer)
         ThemeRefresh(Value)
         ThemeRefresh(Value)
     End Sub
     End Sub
-#End If
     Public Sub UiBackgroundColorful(Value As Boolean)
     Public Sub UiBackgroundColorful(Value As Boolean)
         ThemeRefresh()
         ThemeRefresh()
     End Sub
     End Sub
@@ -516,7 +514,7 @@
         FrmMain.ImgBack.Margin = New Thickness(-(Value + 1) / 1.8)
         FrmMain.ImgBack.Margin = New Thickness(-(Value + 1) / 1.8)
     End Sub
     End Sub
     Public Sub UiBackgroundSuit(Value As Integer)
     Public Sub UiBackgroundSuit(Value As Integer)
-        If IsNothing(FrmMain.ImgBack.Background) Then Exit Sub
+        If IsNothing(FrmMain.ImgBack.Background) Then Return
         Dim Width As Double = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
         Dim Width As Double = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
         Dim Height As Double = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
         Dim Height As Double = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
         If Value = 0 Then
         If Value = 0 Then
@@ -587,7 +585,7 @@
 
 
     '主页
     '主页
     Public Sub UiCustomType(Value As Integer)
     Public Sub UiCustomType(Value As Integer)
-        If FrmSetupUI Is Nothing Then Exit Sub
+        If FrmSetupUI Is Nothing Then Return
         Select Case Value
         Select Case Value
             Case 0 '无
             Case 0 '无
                 FrmSetupUI.PanCustomPreset.Visibility = Visibility.Collapsed
                 FrmSetupUI.PanCustomPreset.Visibility = Visibility.Collapsed
@@ -749,16 +747,16 @@
 
 
     '游戏内存
     '游戏内存
     Public Sub VersionRamType(Type As Integer)
     Public Sub VersionRamType(Type As Integer)
-        If FrmVersionSetup Is Nothing Then Exit Sub
+        If FrmVersionSetup Is Nothing Then Return
         FrmVersionSetup.RamType(Type)
         FrmVersionSetup.RamType(Type)
     End Sub
     End Sub
 
 
     '服务器
     '服务器
     Public Sub VersionServerLogin(Type As Integer)
     Public Sub VersionServerLogin(Type As Integer)
-        If FrmVersionSetup Is Nothing Then Exit Sub
+        If FrmVersionSetup Is Nothing Then Return
         '为第三方登录清空缓存以更新描述
         '为第三方登录清空缓存以更新描述
         WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "")
         WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "")
-        If PageVersionLeft.Version Is Nothing Then Exit Sub
+        If PageVersionLeft.Version Is Nothing Then Return
         PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
         PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
         LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
         LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
     End Sub
     End Sub

+ 13 - 13
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml

@@ -118,7 +118,7 @@
             </local:MyCard>
             </local:MyCard>
             <local:MyCard Margin="0,0,0,15" Title="游戏内存">
             <local:MyCard Margin="0,0,0,15" Title="游戏内存">
                 <StackPanel Margin="25,40,25,15">
                 <StackPanel Margin="25,40,25,15">
-                    <local:MyHint x:Name="LabRamWarn" Text="32 位 Java 最多只能分配 1 GB 内存,建议安装 64 位 Java!" IsWarn="True" Margin="0,0,0,12" />
+                    <local:MyHint x:Name="LabRamWarn" Visibility="Visible" Text="32 位 Java 只能分配最多 1 GB 的内存。强烈建议换用 64 位的 Java!" Theme="Yellow" Margin="0,0,0,12" />
                     <Grid Margin="0,0,0,3">
                     <Grid Margin="0,0,0,3">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="Auto" />
                             <ColumnDefinition Width="Auto" />
@@ -173,7 +173,7 @@
             </local:MyCard>
             </local:MyCard>
             <local:MyCard x:Name="CardSkin" Margin="0,0,0,15" Title="离线皮肤" CanSwap="True" IsSwaped="True">
             <local:MyCard x:Name="CardSkin" Margin="0,0,0,15" Title="离线皮肤" CanSwap="True" IsSwaped="True">
                 <StackPanel Margin="25,40,25,15">
                 <StackPanel Margin="25,40,25,15">
-                    <local:MyHint Text="由于技术问题,此功能只保证对 1.19.2 以前的版本有效!" IsWarn="True" Margin="0,0,0,10" />
+                    <local:MyHint Text="由于技术问题,此功能只保证对 1.19.2 以前的版本有效!" Theme="Yellow" Margin="0,0,0,10" />
                     <Grid Margin="-1,0,0,0">
                     <Grid Margin="-1,0,0,0">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition />
                             <ColumnDefinition />
@@ -225,7 +225,6 @@
                         <ColumnDefinition Width="1*" />
                         <ColumnDefinition Width="1*" />
                     </Grid.ColumnDefinitions>
                     </Grid.ColumnDefinitions>
                     <Grid.RowDefinitions>
                     <Grid.RowDefinitions>
-                        <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="9" />
                         <RowDefinition Height="9" />
                         <RowDefinition Height="28" />
                         <RowDefinition Height="28" />
@@ -233,30 +232,31 @@
                         <RowDefinition Height="28" />
                         <RowDefinition Height="28" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
+                        <RowDefinition Height="Auto" />
                     </Grid.RowDefinitions>
                     </Grid.RowDefinitions>
-                    <local:MyHint Text="你可以在版本独立设置中找到更多高级启动选项。" Margin="0,2,0,12" IsWarn="False" Grid.ColumnSpan="2"
-                                  CanClose="True" RelativeSetup="HintMoreAdvancedSetup" />
-                    <StackPanel Grid.Row="1" VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,0,25,0">
+                    <StackPanel VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,0,25,0">
                         <TextBlock Text="JVM 参数头部" VerticalAlignment="Center" />
                         <TextBlock Text="JVM 参数头部" VerticalAlignment="Center" />
                         <local:MyIconButton Height="23" Margin="0,1,0,0" x:Name="BtnAdvanceJvmReset" VerticalAlignment="Center" 
                         <local:MyIconButton Height="23" Margin="0,1,0,0" x:Name="BtnAdvanceJvmReset" VerticalAlignment="Center" 
                                         ToolTip="还原" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1"
                                         ToolTip="还原" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1"
                                         Logo="M530 0c287 0 521 229 521 511s-233 511-521 511c-233 0-436-151-500-368a63 63 0 0 1 44-79 65 65 0 0 1 80 43c48 162 200 276 375 276 215 0 390-171 390-383s-174-383-390-383c-103 0-199 39-270 106l21-5a63 63 0 0 1 33 123l-157 42a65 65 0 0 1-90-42l-49-183a65 65 0 1 1 126-33l6 26A524 524 0 0 1 530 0z" LogoScale="0.9" />
                                         Logo="M530 0c287 0 521 229 521 511s-233 511-521 511c-233 0-436-151-500-368a63 63 0 0 1 44-79 65 65 0 0 1 80 43c48 162 200 276 375 276 215 0 390-171 390-383s-174-383-390-383c-103 0-199 39-270 106l21-5a63 63 0 0 1 33 123l-157 42a65 65 0 0 1-90-42l-49-183a65 65 0 1 1 126-33l6 26A524 524 0 0 1 530 0z" LogoScale="0.9" />
                     </StackPanel>
                     </StackPanel>
-                    <local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="1" Grid.ColumnSpan="2" Tag="LaunchAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,除非有确定把握,否则请不要修改" MaxLength="4000"
+                    <local:MyTextBox x:Name="TextAdvanceJvm" Grid.ColumnSpan="2" Tag="LaunchAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,除非有确定把握,否则请不要修改" MaxLength="4000"
                                  Height="100" AcceptsReturn="True" TextWrapping="Wrap" VerticalContentAlignment="Top" Padding="0,5" VerticalScrollBarVisibility="Auto" />
                                  Height="100" AcceptsReturn="True" TextWrapping="Wrap" VerticalContentAlignment="Top" Padding="0,5" VerticalScrollBarVisibility="Auto" />
-                    <TextBlock Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" Text="游戏参数尾部" Margin="0,0,25,0" />
-                    <local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="3" Grid.ColumnSpan="2" Tag="LaunchAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xa;例如输入 --demo 则会以试玩模式启动游戏。" />
-                    <TextBlock Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Text="启动前执行命令" Margin="0,0,25,0" />
-                    <local:MyTextBox x:Name="TextAdvanceRun" Grid.Row="5" Grid.ColumnSpan="2" Tag="LaunchAdvanceRun" Grid.Column="1" HintText=""
+                    <TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="游戏参数尾部" Margin="0,0,25,0" />
+                    <local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xa;例如输入 --demo 则会以试玩模式启动游戏。" />
+                    <TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="启动前执行命令" Margin="0,0,25,0" />
+                    <local:MyTextBox x:Name="TextAdvanceRun" Grid.Row="4" Grid.ColumnSpan="2" Tag="LaunchAdvanceRun" Grid.Column="1" HintText=""
                                  ToolTip="在 MC 启动前执行特定命令或程序,语法与 Windows 的命令提示符一致。&#xa;&#xa;可以使用以下替换标记实现相对路径(路径均以 \ 结尾):&#xa; · {path}:PCL 的 exe 文件所在的文件夹&#xa; · {minecraft}:.minecraft 文件夹&#xa; · {verpath}:版本文件夹(.minecraft\versions\版本名\)&#xa; · {verindie}:开启版本隔离时等同版本文件夹,未开启时等同 .minecraft 文件夹&#xa; · {java}:游戏运行时的 Java 文件夹&#xa;&#xa;除此之外,也支持以下替换标记:&#xa; · {user}:玩家名字&#xa; · {login}:玩家的登录方式&#xa; · {uuid}:玩家的 UUID&#xa; · {name}:游戏版本名&#xa; · {date}、{time}:当前的系统时间&#xa; · {version}:游戏对应的原版版本号&#xa;&#xa;例如:&#xa; · &quot;{verpath}test.exe&quot; :运行版本文件夹下的 test.exe 程序&#xa; · &quot;{java}java.exe&quot; -jar &quot;{verpath}test.jar&quot; :用 Java 运行版本文件夹下的 test.jar&#xa; · notepad &quot;{verindie}options.txt&quot; :使用记事本打开该版本的设置文件&#xa;&#xa;涉及路径的操作最好都打上双引号,以避免路径中的空格导致运行失败。&#xa;执行命令时,命令行所在的目录是当前的 .minecraft 文件夹。" />
                                  ToolTip="在 MC 启动前执行特定命令或程序,语法与 Windows 的命令提示符一致。&#xa;&#xa;可以使用以下替换标记实现相对路径(路径均以 \ 结尾):&#xa; · {path}:PCL 的 exe 文件所在的文件夹&#xa; · {minecraft}:.minecraft 文件夹&#xa; · {verpath}:版本文件夹(.minecraft\versions\版本名\)&#xa; · {verindie}:开启版本隔离时等同版本文件夹,未开启时等同 .minecraft 文件夹&#xa; · {java}:游戏运行时的 Java 文件夹&#xa;&#xa;除此之外,也支持以下替换标记:&#xa; · {user}:玩家名字&#xa; · {login}:玩家的登录方式&#xa; · {uuid}:玩家的 UUID&#xa; · {name}:游戏版本名&#xa; · {date}、{time}:当前的系统时间&#xa; · {version}:游戏对应的原版版本号&#xa;&#xa;例如:&#xa; · &quot;{verpath}test.exe&quot; :运行版本文件夹下的 test.exe 程序&#xa; · &quot;{java}java.exe&quot; -jar &quot;{verpath}test.jar&quot; :用 Java 运行版本文件夹下的 test.jar&#xa; · notepad &quot;{verindie}options.txt&quot; :使用记事本打开该版本的设置文件&#xa;&#xa;涉及路径的操作最好都打上双引号,以避免路径中的空格导致运行失败。&#xa;执行命令时,命令行所在的目录是当前的 .minecraft 文件夹。" />
-                    <local:MyCheckBox Grid.Row="6" Grid.Column="1" x:Name="CheckAdvanceRunWait" Tag="LaunchAdvanceRunWait" Visibility="Collapsed"
+                    <local:MyCheckBox Grid.Row="5" Grid.Column="1" x:Name="CheckAdvanceRunWait" Tag="LaunchAdvanceRunWait" Visibility="Collapsed"
                                   Text="等待命令执行完成后再继续启动" Margin="0,8,0,7" />
                                   Text="等待命令执行完成后再继续启动" Margin="0,8,0,7" />
-                    <StackPanel Margin="0,12,0,4" Grid.Row="7" Grid.ColumnSpan="2" HorizontalAlignment="Left">
+                    <StackPanel Margin="0,12,0,4" Grid.Row="6" Grid.ColumnSpan="2" HorizontalAlignment="Left">
                         <local:MyCheckBox Height="28" Text="禁用 Java Launch Wrapper" x:Name="CheckAdvanceDisableJLW" Tag="LaunchAdvanceDisableJLW"
                         <local:MyCheckBox Height="28" Text="禁用 Java Launch Wrapper" x:Name="CheckAdvanceDisableJLW" Tag="LaunchAdvanceDisableJLW"
                             ToolTipService.Placement="Right" ToolTip="PCL 会使用 Java Launch Wrapper 来修复老版本 Java 在中文路径下无法启动的问题。&#xa;如果这被反作弊拦截,或遇到其他问题,也可以将其关闭。" />
                             ToolTipService.Placement="Right" ToolTip="PCL 会使用 Java Launch Wrapper 来修复老版本 Java 在中文路径下无法启动的问题。&#xa;如果这被反作弊拦截,或遇到其他问题,也可以将其关闭。" />
                         <local:MyCheckBox Height="28" Text="要求 Java 使用高性能显卡" x:Name="CheckAdvanceGraphicCard" Tag="LaunchAdvanceGraphicCard"
                         <local:MyCheckBox Height="28" Text="要求 Java 使用高性能显卡" x:Name="CheckAdvanceGraphicCard" Tag="LaunchAdvanceGraphicCard"
                             ToolTipService.Placement="Right" ToolTip="自动在 Windows 设置 → 系统 → 屏幕 → 显示卡 中将 Java 改为使用高性能显卡。&#xa;如果电脑同时有集显和独显,这能确保 MC 使用独显进行渲染,以大幅提高性能。" />
                             ToolTipService.Placement="Right" ToolTip="自动在 Windows 设置 → 系统 → 屏幕 → 显示卡 中将 Java 改为使用高性能显卡。&#xa;如果电脑同时有集显和独显,这能确保 MC 使用独显进行渲染,以大幅提高性能。" />
                     </StackPanel>
                     </StackPanel>
+                    <local:MyHint Text="你还可以在版本独立设置中找到更多高级启动选项。" Margin="0,5,0,10" Theme="Blue" Grid.Row="7" Grid.ColumnSpan="2"
+                                  CanClose="True" RelativeSetup="HintMoreAdvancedSetup" />
                 </Grid>
                 </Grid>
             </local:MyCard>
             </local:MyCard>
             <local:MyExtraTextButton HorizontalAlignment="Center" Margin="0,-5,0,15"
             <local:MyExtraTextButton HorizontalAlignment="Center" Margin="0,-5,0,15"

+ 19 - 19
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb

@@ -14,7 +14,7 @@
         End If
         End If
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
 
 
         AniControlEnabled += 1
         AniControlEnabled += 1
@@ -122,18 +122,18 @@
 
 
     Private Sub BtnSkinChange_Click(sender As Object, e As EventArgs) Handles BtnSkinChange.Click
     Private Sub BtnSkinChange_Click(sender As Object, e As EventArgs) Handles BtnSkinChange.Click
         Dim SkinInfo As McSkinInfo = McSkinSelect()
         Dim SkinInfo As McSkinInfo = McSkinSelect()
-        If Not SkinInfo.IsVaild Then Exit Sub
+        If Not SkinInfo.IsVaild Then Return
         ChangeSkin(SkinInfo)
         ChangeSkin(SkinInfo)
     End Sub
     End Sub
     Private Sub RadioSkinType3_Check(sender As Object, e As RouteEventArgs) Handles RadioSkinType4.PreviewCheck
     Private Sub RadioSkinType3_Check(sender As Object, e As RouteEventArgs) Handles RadioSkinType4.PreviewCheck
-        If Not (AniControlEnabled = 0 AndAlso e.RaiseByMouse) Then Exit Sub
+        If Not (AniControlEnabled = 0 AndAlso e.RaiseByMouse) Then Return
         '已有图片则不再选择
         '已有图片则不再选择
-        If File.Exists(PathAppdata & "CustomSkin.png") Then Exit Sub
+        If File.Exists(PathAppdata & "CustomSkin.png") Then Return
         '没有图片则要求选择
         '没有图片则要求选择
         Dim SkinInfo As McSkinInfo = McSkinSelect()
         Dim SkinInfo As McSkinInfo = McSkinSelect()
         If Not SkinInfo.IsVaild Then
         If Not SkinInfo.IsVaild Then
             e.Handled = True
             e.Handled = True
-            Exit Sub
+            Return
         End If
         End If
         '正式改变
         '正式改变
         If Not ChangeSkin(SkinInfo) Then e.Handled = True
         If Not ChangeSkin(SkinInfo) Then e.Handled = True
@@ -187,7 +187,7 @@
 #Region "游戏内存"
 #Region "游戏内存"
 
 
     Public Sub RamType(Type As Integer)
     Public Sub RamType(Type As Integer)
-        If SliderRamCustom Is Nothing Then Exit Sub
+        If SliderRamCustom Is Nothing Then Return
         SliderRamCustom.IsEnabled = (Type = 1)
         SliderRamCustom.IsEnabled = (Type = 1)
     End Sub
     End Sub
 
 
@@ -195,7 +195,7 @@
     ''' 刷新 UI 上的 RAM 显示。
     ''' 刷新 UI 上的 RAM 显示。
     ''' </summary>
     ''' </summary>
     Public Sub RefreshRam(ShowAnim As Boolean)
     Public Sub RefreshRam(ShowAnim As Boolean)
-        If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.Setup OrElse FrmSetupLeft.PageID <> FormMain.PageSubType.SetupLaunch Then Exit Sub
+        If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.Setup OrElse FrmSetupLeft.PageID <> FormMain.PageSubType.SetupLaunch Then Return
         '获取内存情况
         '获取内存情况
         Dim RamGame As Double = Math.Round(GetRam(McVersionCurrent, False), 5)
         Dim RamGame As Double = Math.Round(GetRam(McVersionCurrent, False), 5)
         Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024, 1)
         Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024, 1)
@@ -409,7 +409,7 @@ PreFin:
 
 
     '刷新 Java 下拉框显示
     '刷新 Java 下拉框显示
     Public Sub RefreshJavaComboBox()
     Public Sub RefreshJavaComboBox()
-        If ComboArgumentJava Is Nothing Then Exit Sub
+        If ComboArgumentJava Is Nothing Then Return
         '初始化列表
         '初始化列表
         ComboArgumentJava.Items.Clear()
         ComboArgumentJava.Items.Clear()
         ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "自动选择合适的 Java", .Tag = "自动选择"})
         ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "自动选择合适的 Java", .Tag = "自动选择"})
@@ -448,9 +448,9 @@ PreFin:
 
 
     '下拉框选择更改
     '下拉框选择更改
     Private Sub JavaSelectionUpdate() Handles ComboArgumentJava.SelectionChanged
     Private Sub JavaSelectionUpdate() Handles ComboArgumentJava.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         'Java 不可用时也不清空,会导致刷新时找不到对象
         'Java 不可用时也不清空,会导致刷新时找不到对象
-        If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.SelectedItem.Tag Is Nothing Then Exit Sub
+        If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.SelectedItem.Tag Is Nothing Then Return
         '设置新的 Java
         '设置新的 Java
         Dim SelectedJava = ComboArgumentJava.SelectedItem.Tag
         Dim SelectedJava = ComboArgumentJava.SelectedItem.Tag
         If "自动选择".Equals(SelectedJava) Then
         If "自动选择".Equals(SelectedJava) Then
@@ -469,11 +469,11 @@ PreFin:
     Private Sub BtnArgumentJavaSelect_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSelect.Click
     Private Sub BtnArgumentJavaSelect_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSelect.Click
         If JavaSearchLoader.State = LoadState.Loading Then
         If JavaSearchLoader.State = LoadState.Loading Then
             Hint("正在搜索 Java,请稍候!", HintType.Critical)
             Hint("正在搜索 Java,请稍候!", HintType.Critical)
-            Exit Sub
+            Return
         End If
         End If
         '选择 Java
         '选择 Java
         Dim JavaSelected As String = SelectFile("javaw.exe|javaw.exe", "选择 bin 文件夹中的 javaw.exe 文件")
         Dim JavaSelected As String = SelectFile("javaw.exe|javaw.exe", "选择 bin 文件夹中的 javaw.exe 文件")
-        If JavaSelected = "" Then Exit Sub
+        If JavaSelected = "" Then Return
         JavaSelected = GetPathFromFullPath(JavaSelected)
         JavaSelected = GetPathFromFullPath(JavaSelected)
         Try
         Try
             '验证 Java 可用
             '验证 Java 可用
@@ -492,14 +492,14 @@ PreFin:
             Hint("已将该 Java 加入 Java 列表!", HintType.Finish)
             Hint("已将该 Java 加入 Java 列表!", HintType.Finish)
         Catch ex As Exception
         Catch ex As Exception
             Log(ex, "该 Java 存在异常,无法使用", LogLevel.Msgbox, "异常的 Java")
             Log(ex, "该 Java 存在异常,无法使用", LogLevel.Msgbox, "异常的 Java")
-            Exit Sub
+            Return
         End Try
         End Try
     End Sub
     End Sub
     '自动查找
     '自动查找
     Private Sub BtnArgumentJavaSearch_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSearch.Click
     Private Sub BtnArgumentJavaSearch_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSearch.Click
         If JavaSearchLoader.State = LoadState.Loading Then
         If JavaSearchLoader.State = LoadState.Loading Then
             Hint("正在搜索 Java,请稍候!", HintType.Critical)
             Hint("正在搜索 Java,请稍候!", HintType.Critical)
-            Exit Sub
+            Return
         End If
         End If
         RunInThread(
         RunInThread(
         Sub()
         Sub()
@@ -518,7 +518,7 @@ PreFin:
 #Region "其他选项"
 #Region "其他选项"
 
 
     Private Sub WindowTypeUIRefresh() Handles ComboArgumentWindowType.SelectionChanged
     Private Sub WindowTypeUIRefresh() Handles ComboArgumentWindowType.SelectionChanged
-        If ComboArgumentWindowType Is Nothing Then Exit Sub
+        If ComboArgumentWindowType Is Nothing Then Return
         If ComboArgumentWindowType.SelectedIndex = 3 AndAlso LabArgumentWindowMiddle IsNot Nothing AndAlso LabArgumentWindowMiddle.Visibility = Visibility.Collapsed Then
         If ComboArgumentWindowType.SelectedIndex = 3 AndAlso LabArgumentWindowMiddle IsNot Nothing AndAlso LabArgumentWindowMiddle.Visibility = Visibility.Collapsed Then
             LabArgumentWindowMiddle.Visibility = Visibility.Visible
             LabArgumentWindowMiddle.Visibility = Visibility.Visible
             TextArgumentWindowHeight.Visibility = Visibility.Visible
             TextArgumentWindowHeight.Visibility = Visibility.Visible
@@ -532,7 +532,7 @@ PreFin:
 
 
     '可见性选择直接关闭的警告
     '可见性选择直接关闭的警告
     Private Sub ComboArgumentVisibie_SizeChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentVisibie.SelectionChanged
     Private Sub ComboArgumentVisibie_SizeChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentVisibie.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         If ComboArgumentVisibie.SelectedIndex = 0 Then
         If ComboArgumentVisibie.SelectedIndex = 0 Then
             If MyMsgBox("若在游戏启动后立即关闭启动器,崩溃检测、更改游戏标题等功能将失效。" & vbCrLf &
             If MyMsgBox("若在游戏启动后立即关闭启动器,崩溃检测、更改游戏标题等功能将失效。" & vbCrLf &
                         "如果想保留这些功能,可以选择让启动器在游戏启动后隐藏,游戏退出后自动关闭。", "提醒", "继续", "取消") = 2 Then
                         "如果想保留这些功能,可以选择让启动器在游戏启动后隐藏,游戏退出后自动关闭。", "提醒", "继续", "取消") = 2 Then
@@ -543,7 +543,7 @@ PreFin:
 
 
     '开启自动内存优化的警告
     '开启自动内存优化的警告
     Private Sub CheckArgumentRam_Change() Handles CheckArgumentRam.Change
     Private Sub CheckArgumentRam_Change() Handles CheckArgumentRam.Change
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         If Not CheckArgumentRam.Checked Then Return
         If Not CheckArgumentRam.Checked Then Return
         If MyMsgBox("内存优化会显著延长启动耗时,建议仅在内存不足时开启。" & vbCrLf &
         If MyMsgBox("内存优化会显著延长启动耗时,建议仅在内存不足时开启。" & vbCrLf &
                     "如果你在使用机械硬盘,这还可能导致一小段时间的严重卡顿。" &
                     "如果你在使用机械硬盘,这还可能导致一小段时间的严重卡顿。" &
@@ -555,8 +555,8 @@ PreFin:
 
 
     '版本隔离提示
     '版本隔离提示
     Private Sub ComboArgumentIndie_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentIndieV2.SelectionChanged
     Private Sub ComboArgumentIndie_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentIndieV2.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
-        MyMsgBox("默认策略只会对今后新安装的版本生效。" & vbCrLf & "已有版本的隔离策略需要在它的版本设置中调整。")
+        If AniControlEnabled <> 0 Then Return
+        MyMsgBox("本设置仅会对之后新安装的版本生效。" & vbCrLf & "如果要修改已安装的版本的隔离方式,请在它的版本独立设置中调整。")
     End Sub
     End Sub
 
 
 #End Region
 #End Region

+ 3 - 3
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLeft.xaml.vb

@@ -11,12 +11,12 @@
         If ItemLink.Checked AndAlso Setup.Get("UiHiddenSetupLink") Then IsHiddenPage = True
         If ItemLink.Checked AndAlso Setup.Get("UiHiddenSetupLink") Then IsHiddenPage = True
         If PageSetupUI.HiddenForceShow Then IsHiddenPage = False
         If PageSetupUI.HiddenForceShow Then IsHiddenPage = False
         '若页面错误,或尚未加载,则继续
         '若页面错误,或尚未加载,则继续
-        If IsLoad AndAlso Not IsHiddenPage Then Exit Sub
+        If IsLoad AndAlso Not IsHiddenPage Then Return
         IsLoad = True
         IsLoad = True
         '刷新子页面隐藏情况
         '刷新子页面隐藏情况
         PageSetupUI.HiddenRefresh()
         PageSetupUI.HiddenRefresh()
         '选择第一个未被禁用的子页面
         '选择第一个未被禁用的子页面
-        If IsPageSwitched Then Exit Sub
+        If IsPageSwitched Then Return
         If Not Setup.Get("UiHiddenSetupLaunch") Then
         If Not Setup.Get("UiHiddenSetupLaunch") Then
             ItemLaunch.SetChecked(True, False, False)
             ItemLaunch.SetChecked(True, False, False)
         ElseIf Not Setup.Get("UiHiddenSetupUi") Then
         ElseIf Not Setup.Get("UiHiddenSetupUi") Then
@@ -91,7 +91,7 @@
     ''' 切换现有页面。
     ''' 切换现有页面。
     ''' </summary>
     ''' </summary>
     Public Sub PageChange(ID As FormMain.PageSubType)
     Public Sub PageChange(ID As FormMain.PageSubType)
-        If PageID = ID Then Exit Sub
+        If PageID = ID Then Return
         AniControlEnabled += 1
         AniControlEnabled += 1
         IsPageSwitched = True
         IsPageSwitched = True
         Try
         Try

+ 1 - 1
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb

@@ -8,7 +8,7 @@
         PanBack.ScrollToHome()
         PanBack.ScrollToHome()
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoaded Then Exit Sub
+        If IsLoaded Then Return
         IsLoaded = True
         IsLoaded = True
 
 
         AniControlEnabled += 1
         AniControlEnabled += 1

+ 6 - 6
Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb

@@ -15,7 +15,7 @@
 #End If
 #End If
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoaded Then Exit Sub
+        If IsLoaded Then Return
         IsLoaded = True
         IsLoaded = True
 
 
         AniControlEnabled += 1
         AniControlEnabled += 1
@@ -124,7 +124,7 @@
         SliderDebugAnim.GetHintText = Function(v) If(v > 29, "关闭", (v / 10 + 0.1) & "x")
         SliderDebugAnim.GetHintText = Function(v) If(v > 29, "关闭", (v / 10 + 0.1) & "x")
     End Sub
     End Sub
     Private Sub SliderDownloadThread_PreviewChange(sender As Object, e As RouteEventArgs) Handles SliderDownloadThread.PreviewChange
     Private Sub SliderDownloadThread_PreviewChange(sender As Object, e As RouteEventArgs) Handles SliderDownloadThread.PreviewChange
-        If SliderDownloadThread.Value < 100 Then Exit Sub
+        If SliderDownloadThread.Value < 100 Then Return
         If Not Setup.Get("HintDownloadThread") Then
         If Not Setup.Get("HintDownloadThread") Then
             Setup.Set("HintDownloadThread", True)
             Setup.Set("HintDownloadThread", True)
             MyMsgBox("如果设置过多的下载线程,可能会导致下载时出现非常严重的卡顿。" & vbCrLf &
             MyMsgBox("如果设置过多的下载线程,可能会导致下载时出现非常严重的卡顿。" & vbCrLf &
@@ -147,8 +147,8 @@
 
 
     '自动更新
     '自动更新
     Private Sub ComboSystemActivity_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemActivity.SelectionChanged
     Private Sub ComboSystemActivity_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemActivity.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
-        If ComboSystemActivity.SelectedIndex <> 2 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
+        If ComboSystemActivity.SelectedIndex <> 2 Then Return
         If MyMsgBox("若选择此项,即使在将来出现严重问题时,你也无法获取相关通知。" & vbCrLf &
         If MyMsgBox("若选择此项,即使在将来出现严重问题时,你也无法获取相关通知。" & vbCrLf &
                     "例如,如果发现某个版本游戏存在严重 Bug,你可能就会因为无法得到通知而导致无法预知的后果。" & vbCrLf & vbCrLf &
                     "例如,如果发现某个版本游戏存在严重 Bug,你可能就会因为无法得到通知而导致无法预知的后果。" & vbCrLf & vbCrLf &
                     "一般选择 仅在有重要通知时显示公告 就可以让你尽量不受打扰了。" & vbCrLf &
                     "一般选择 仅在有重要通知时显示公告 就可以让你尽量不受打扰了。" & vbCrLf &
@@ -157,8 +157,8 @@
         End If
         End If
     End Sub
     End Sub
     Private Sub ComboSystemUpdate_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemUpdate.SelectionChanged
     Private Sub ComboSystemUpdate_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemUpdate.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
-        If ComboSystemUpdate.SelectedIndex <> 3 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
+        If ComboSystemUpdate.SelectedIndex <> 3 Then Return
         If MyMsgBox("若选择此项,即使在启动器将来出现严重问题时,你也无法获取更新并获得修复。" & vbCrLf &
         If MyMsgBox("若选择此项,即使在启动器将来出现严重问题时,你也无法获取更新并获得修复。" & vbCrLf &
                     "例如,如果官方修改了登录方式,从而导致现有启动器无法登录,你可能就会因为无法更新而无法开始游戏。" & vbCrLf & vbCrLf &
                     "例如,如果官方修改了登录方式,从而导致现有启动器无法登录,你可能就会因为无法更新而无法开始游戏。" & vbCrLf & vbCrLf &
                     "一般选择 仅在有重大漏洞更新时显示提示 就可以让你尽量不受打扰了。" & vbCrLf &
                     "一般选择 仅在有重大漏洞更新时显示提示 就可以让你尽量不受打扰了。" & vbCrLf &

+ 5 - 5
Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml

@@ -116,7 +116,7 @@
                         <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="背景模糊" Margin="0,0,25,0" />
                         <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="背景模糊" Margin="0,0,25,0" />
                         <local:MySlider x:Name="SliderBackgroundBlur" Tag="UiBackgroundBlur" MaxValue="40" Grid.Column="1" ToolTip="较强的模糊会导致启动器严重掉帧,请谨慎使用。&#13;不建议在制作整合包时开启模糊,以确保 PCL 在低性能电脑上可以流畅运行。" />
                         <local:MySlider x:Name="SliderBackgroundBlur" Tag="UiBackgroundBlur" MaxValue="40" Grid.Column="1" ToolTip="较强的模糊会导致启动器严重掉帧,请谨慎使用。&#13;不建议在制作整合包时开启模糊,以确保 PCL 在低性能电脑上可以流畅运行。" />
                     </Grid>
                     </Grid>
-                    <local:MyCheckBox Text="使用彩色背景" Margin="-1,0,0,8" Height="22" x:Name="CheckBackgroundColorful" Tag="UiBackgroundColorful" />
+                    <local:MyCheckBox Text="叠加彩色背景" Margin="-1,0,0,8" Height="22" x:Name="CheckBackgroundColorful" Tag="UiBackgroundColorful" />
                     <Grid Height="35" Margin="0,2,0,0">
                     <Grid Height="35" Margin="0,2,0,0">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
                             <ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
@@ -206,9 +206,9 @@
                         <local:MyRadioBox Text="读取本地文件" x:Name="RadioCustomType1" Height="22" Tag="UiCustomType/1" Grid.Column="2" />
                         <local:MyRadioBox Text="读取本地文件" x:Name="RadioCustomType1" Height="22" Tag="UiCustomType/1" Grid.Column="2" />
                         <local:MyRadioBox Text="联网更新" x:Name="RadioCustomType2" Height="22" Tag="UiCustomType/2" Grid.Column="3" />
                         <local:MyRadioBox Text="联网更新" x:Name="RadioCustomType2" Height="22" Tag="UiCustomType/2" Grid.Column="3" />
                     </Grid>
                     </Grid>
-                    <local:MyHint Margin="0,15,0,-9" Text="在使用陌生人提供的主页前请务必谨慎,恶意的主页可能会造成损害!" IsWarn="True" x:Name="HintCustomWarn" 
+                    <local:MyHint Margin="0,15,0,-4" Text="内容见 ModSetup" Theme="Blue" x:Name="HintCustom" />
+                    <local:MyHint Margin="0,15,0,6" Text="请谨慎使用陌生人提供的主页,恶意代码可能会造成损害!" Theme="Yellow" x:Name="HintCustomWarn" 
                                   CanClose="True" RelativeSetup="HintCustomWarn" />
                                   CanClose="True" RelativeSetup="HintCustomWarn" />
-                    <local:MyHint Margin="0,15,0,1" Text="内容见 ModSetup" IsWarn="False" x:Name="HintCustom" />
                     <Grid Height="35" x:Name="PanCustomLocal" Visibility="Collapsed" Margin="0,10,0,5">
                     <Grid Height="35" x:Name="PanCustomLocal" Visibility="Collapsed" Margin="0,10,0,5">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
                             <ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
@@ -282,7 +282,7 @@
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="3" Text="设置" x:Name="CheckHiddenPageSetup" Tag="UiHiddenPageSetup" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="3" Text="设置" x:Name="CheckHiddenPageSetup" Tag="UiHiddenPageSetup" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="4" Text="更多" x:Name="CheckHiddenPageOther" Tag="UiHiddenPageOther" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="4" Text="更多" x:Name="CheckHiddenPageOther" Tag="UiHiddenPageOther" />
                         <TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="设置 子页面" />
                         <TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="设置 子页面" />
-                        <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="2" Text="游戏" x:Name="CheckHiddenSetupLaunch" Tag="UiHiddenSetupLaunch" />
+                        <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="2" Text="启动" x:Name="CheckHiddenSetupLaunch" Tag="UiHiddenSetupLaunch" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" Text="个性化" x:Name="CheckHiddenSetupUI" Tag="UiHiddenSetupUi" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" Text="个性化" x:Name="CheckHiddenSetupUI" Tag="UiHiddenSetupUi" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="4" Text="其他" x:Name="CheckHiddenSetupSystem" Tag="UiHiddenSetupSystem" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="4" Text="其他" x:Name="CheckHiddenSetupSystem" Tag="UiHiddenSetupSystem" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="5" Text="联机" x:Name="CheckHiddenSetupLink" Tag="UiHiddenSetupLink" Visibility="Collapsed" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="5" Text="联机" x:Name="CheckHiddenSetupLink" Tag="UiHiddenSetupLink" Visibility="Collapsed" />
@@ -293,7 +293,7 @@
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="3" Grid.Column="5" Text="反馈" x:Name="CheckHiddenOtherFeedback" Tag="UiHiddenOtherFeedback" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="3" Grid.Column="5" Text="反馈" x:Name="CheckHiddenOtherFeedback" Tag="UiHiddenOtherFeedback" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="3" Grid.Column="6" Text="新功能投票" x:Name="CheckHiddenOtherVote" Tag="UiHiddenOtherVote" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="3" Grid.Column="6" Text="新功能投票" x:Name="CheckHiddenOtherVote" Tag="UiHiddenOtherVote" />
                         <TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="特定功能" />
                         <TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="特定功能" />
-                        <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="2" Text="邮箱隐藏" x:Name="CheckLauncherEmail" Tag="UiLauncherEmail" ToolTip="隐藏第三方登录的账号邮箱显示,并尽量将邮箱打码,以避免隐私泄露。&#xa;此选项的更改将在重启启动器后生效。" />
+                        <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="2" Text="邮箱隐藏" x:Name="CheckLauncherEmail" Tag="UiLauncherEmail" ToolTip="隐藏第三方登录的账号邮箱显示,以避免隐私泄露。&#xa;此选项的更改将在重启启动器后生效。" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="3" Text="版本管理" x:Name="CheckHiddenFunctionSelect" Tag="UiHiddenFunctionSelect" ToolTip="隐藏启动按钮下方的版本选择与版本设置入口。" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="3" Text="版本管理" x:Name="CheckHiddenFunctionSelect" Tag="UiHiddenFunctionSelect" ToolTip="隐藏启动按钮下方的版本选择与版本设置入口。" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="4" Text="Mod 更新" x:Name="CheckHiddenFunctionModUpdate" Tag="UiHiddenFunctionModUpdate" ToolTip="禁止在 Mod 管理页面更新 Mod。" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="4" Text="Mod 更新" x:Name="CheckHiddenFunctionModUpdate" Tag="UiHiddenFunctionModUpdate" ToolTip="禁止在 Mod 管理页面更新 Mod。" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="5" Text="功能隐藏" x:Name="CheckHiddenFunctionHidden" Tag="UiHiddenFunctionHidden" ToolTip="仅隐藏本选项卡,设置的禁用内容依然有效。&#xa;可以在保留个性化设置页面的情况下避免隐藏设置被修改。" />
                         <local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="4" Grid.Column="5" Text="功能隐藏" x:Name="CheckHiddenFunctionHidden" Tag="UiHiddenFunctionHidden" ToolTip="仅隐藏本选项卡,设置的禁用内容依然有效。&#xa;可以在保留个性化设置页面的情况下避免隐藏设置被修改。" />

+ 18 - 16
Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb

@@ -30,7 +30,7 @@
         AniControlEnabled -= 1
         AniControlEnabled -= 1
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoaded Then Exit Sub
+        If IsLoaded Then Return
         IsLoaded = True
         IsLoaded = True
 
 
         SliderLoad()
         SliderLoad()
@@ -89,7 +89,7 @@
             Catch
             Catch
                 Setup.Reset("UiCustomPreset")
                 Setup.Reset("UiCustomPreset")
             End Try
             End Try
-            CType(FindName("RadioCustomType" & Setup.Load("UiCustomType")), MyRadioBox).Checked = True
+            CType(FindName("RadioCustomType" & Setup.Load("UiCustomType", ForceReload:=True)), MyRadioBox).Checked = True
             TextCustomNet.Text = Setup.Get("UiCustomNet")
             TextCustomNet.Text = Setup.Get("UiCustomNet")
 
 
             '功能隐藏
             '功能隐藏
@@ -195,7 +195,7 @@
         BackgroundRefresh(True, True)
         BackgroundRefresh(True, True)
     End Sub
     End Sub
     Public Sub BackgroundRefreshUI(Show As Boolean, Count As Integer)
     Public Sub BackgroundRefreshUI(Show As Boolean, Count As Integer)
-        If IsNothing(PanBackgroundOpacity) Then Exit Sub
+        If IsNothing(PanBackgroundOpacity) Then Return
         If Show Then
         If Show Then
             PanBackgroundOpacity.Visibility = Visibility.Visible
             PanBackgroundOpacity.Visibility = Visibility.Visible
             PanBackgroundBlur.Visibility = Visibility.Visible
             PanBackgroundBlur.Visibility = Visibility.Visible
@@ -275,12 +275,13 @@
     '顶部栏
     '顶部栏
     Private Sub BtnLogoChange_Click(sender As Object, e As EventArgs) Handles BtnLogoChange.Click
     Private Sub BtnLogoChange_Click(sender As Object, e As EventArgs) Handles BtnLogoChange.Click
         Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片")
         Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片")
-        If FileName = "" Then Exit Sub
+        If FileName = "" Then Return
         Try
         Try
             '拷贝文件
             '拷贝文件
             File.Delete(Path & "PCL\Logo.png")
             File.Delete(Path & "PCL\Logo.png")
             CopyFile(FileName, Path & "PCL\Logo.png")
             CopyFile(FileName, Path & "PCL\Logo.png")
             '设置当前显示
             '设置当前显示
+            FrmMain.ImageTitleLogo.Source = Nothing '防止因为 Source 属性前后的值相同而不更新 (#5628)
             FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
             FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
         Catch ex As Exception
         Catch ex As Exception
             If ex.Message.Contains("参数无效") Then
             If ex.Message.Contains("参数无效") Then
@@ -293,11 +294,12 @@
         End Try
         End Try
     End Sub
     End Sub
     Private Sub RadioLogoType3_Check(sender As Object, e As RouteEventArgs) Handles RadioLogoType3.PreviewCheck
     Private Sub RadioLogoType3_Check(sender As Object, e As RouteEventArgs) Handles RadioLogoType3.PreviewCheck
-        If Not (AniControlEnabled = 0 AndAlso e.RaiseByMouse) Then Exit Sub
+        If Not (AniControlEnabled = 0 AndAlso e.RaiseByMouse) Then Return
 Refresh:
 Refresh:
         '已有图片则不再选择
         '已有图片则不再选择
         If File.Exists(Path & "PCL\Logo.png") Then
         If File.Exists(Path & "PCL\Logo.png") Then
             Try
             Try
+                FrmMain.ImageTitleLogo.Source = Nothing '防止因为 Source 属性前后的值相同而不更新 (#5628)
                 FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
                 FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
             Catch ex As Exception
             Catch ex As Exception
                 If ex.Message.Contains("参数无效") Then
                 If ex.Message.Contains("参数无效") Then
@@ -314,7 +316,7 @@ Refresh:
                     Log(exx, "清理错误的标题栏图片失败", LogLevel.Msgbox)
                     Log(exx, "清理错误的标题栏图片失败", LogLevel.Msgbox)
                 End Try
                 End Try
             End Try
             End Try
-            Exit Sub
+            Return
         End If
         End If
         '没有图片则要求选择
         '没有图片则要求选择
         Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片")
         Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片")
@@ -350,7 +352,7 @@ Refresh:
         MusicRefreshPlay(True)
         MusicRefreshPlay(True)
     End Sub
     End Sub
     Public Sub MusicRefreshUI()
     Public Sub MusicRefreshUI()
-        If PanBackgroundOpacity Is Nothing Then Exit Sub
+        If PanBackgroundOpacity Is Nothing Then Return
         If MusicAllList.Any Then
         If MusicAllList.Any Then
             PanMusicVolume.Visibility = Visibility.Visible
             PanMusicVolume.Visibility = Visibility.Visible
             PanMusicDetail.Visibility = Visibility.Visible
             PanMusicDetail.Visibility = Visibility.Visible
@@ -391,11 +393,11 @@ Refresh:
         End If
         End If
     End Sub
     End Sub
     Private Sub CheckMusicStart_Change() Handles CheckMusicStart.Change
     Private Sub CheckMusicStart_Change() Handles CheckMusicStart.Change
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         If CheckMusicStart.Checked Then CheckMusicStop.Checked = False
         If CheckMusicStart.Checked Then CheckMusicStop.Checked = False
     End Sub
     End Sub
     Private Sub CheckMusicStop_Change() Handles CheckMusicStop.Change
     Private Sub CheckMusicStop_Change() Handles CheckMusicStop.Change
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         If CheckMusicStop.Checked Then CheckMusicStart.Checked = False
         If CheckMusicStop.Checked Then CheckMusicStart.Checked = False
     End Sub
     End Sub
 
 
@@ -403,7 +405,7 @@ Refresh:
     Private Sub BtnCustomFile_Click(sender As Object, e As EventArgs) Handles BtnCustomFile.Click
     Private Sub BtnCustomFile_Click(sender As Object, e As EventArgs) Handles BtnCustomFile.Click
         Try
         Try
             If File.Exists(Path & "PCL\Custom.xaml") Then
             If File.Exists(Path & "PCL\Custom.xaml") Then
-                If MyMsgBox("当前已存在布局文件,继续生成教学文件将会覆盖现有布局文件!", "覆盖确认", "继续", "取消", IsWarn:=True) = 2 Then Exit Sub
+                If MyMsgBox("当前已存在布局文件,继续生成教学文件将会覆盖现有布局文件!", "覆盖确认", "继续", "取消", IsWarn:=True) = 2 Then Return
             End If
             End If
             WriteFile(Path & "PCL\Custom.xaml", GetResources("Custom"))
             WriteFile(Path & "PCL\Custom.xaml", GetResources("Custom"))
             Hint("教学文件已生成!", HintType.Finish)
             Hint("教学文件已生成!", HintType.Finish)
@@ -462,7 +464,7 @@ Refresh:
     '主题自定义
     '主题自定义
     Private Sub RadioLauncherTheme14_Change(sender As Object, e As RouteEventArgs) Handles RadioLauncherTheme14.Changed
     Private Sub RadioLauncherTheme14_Change(sender As Object, e As RouteEventArgs) Handles RadioLauncherTheme14.Changed
         If RadioLauncherTheme14.Checked Then
         If RadioLauncherTheme14.Checked Then
-            If LabLauncherHue.Visibility = Visibility.Visible Then Exit Sub
+            If LabLauncherHue.Visibility = Visibility.Visible Then Return
             LabLauncherHue.Visibility = Visibility.Visible
             LabLauncherHue.Visibility = Visibility.Visible
             SliderLauncherHue.Visibility = Visibility.Visible
             SliderLauncherHue.Visibility = Visibility.Visible
             LabLauncherSat.Visibility = Visibility.Visible
             LabLauncherSat.Visibility = Visibility.Visible
@@ -472,7 +474,7 @@ Refresh:
             LabLauncherLight.Visibility = Visibility.Visible
             LabLauncherLight.Visibility = Visibility.Visible
             SliderLauncherLight.Visibility = Visibility.Visible
             SliderLauncherLight.Visibility = Visibility.Visible
         Else
         Else
-            If LabLauncherHue.Visibility = Visibility.Collapsed Then Exit Sub
+            If LabLauncherHue.Visibility = Visibility.Collapsed Then Return
             LabLauncherHue.Visibility = Visibility.Collapsed
             LabLauncherHue.Visibility = Visibility.Collapsed
             SliderLauncherHue.Visibility = Visibility.Collapsed
             SliderLauncherHue.Visibility = Visibility.Collapsed
             LabLauncherSat.Visibility = Visibility.Collapsed
             LabLauncherSat.Visibility = Visibility.Collapsed
@@ -485,7 +487,7 @@ Refresh:
         CardLauncher.TriggerForceResize()
         CardLauncher.TriggerForceResize()
     End Sub
     End Sub
     Private Sub HSL_Change() Handles SliderLauncherHue.Change, SliderLauncherLight.Change, SliderLauncherSat.Change, SliderLauncherDelta.Change
     Private Sub HSL_Change() Handles SliderLauncherHue.Change, SliderLauncherLight.Change, SliderLauncherSat.Change, SliderLauncherDelta.Change
-        If AniControlEnabled <> 0 OrElse SliderLauncherSat Is Nothing OrElse Not SliderLauncherSat.IsLoaded Then Exit Sub
+        If AniControlEnabled <> 0 OrElse SliderLauncherSat Is Nothing OrElse Not SliderLauncherSat.IsLoaded Then Return
         ThemeRefresh()
         ThemeRefresh()
     End Sub
     End Sub
 
 
@@ -509,7 +511,7 @@ Refresh:
     ''' 更新功能隐藏带来的显示变化。
     ''' 更新功能隐藏带来的显示变化。
     ''' </summary>
     ''' </summary>
     Public Shared Sub HiddenRefresh() Handles Me.Loaded
     Public Shared Sub HiddenRefresh() Handles Me.Loaded
-        If FrmMain.PanTitleSelect Is Nothing OrElse Not FrmMain.PanTitleSelect.IsLoaded Then Exit Sub
+        If FrmMain.PanTitleSelect Is Nothing OrElse Not FrmMain.PanTitleSelect.IsLoaded Then Return
         Try
         Try
             '顶部栏
             '顶部栏
             If Not HiddenForceShow AndAlso Setup.Get("UiHiddenPageDownload") AndAlso Setup.Get("UiHiddenPageLink") AndAlso Setup.Get("UiHiddenPageSetup") AndAlso Setup.Get("UiHiddenPageOther") Then
             If Not HiddenForceShow AndAlso Setup.Get("UiHiddenPageDownload") AndAlso Setup.Get("UiHiddenPageLink") AndAlso Setup.Get("UiHiddenPageSetup") AndAlso Setup.Get("UiHiddenPageOther") Then
@@ -640,7 +642,7 @@ Refresh:
             CheckHiddenPageOther.Checked = False
             CheckHiddenPageOther.Checked = False
         End If
         End If
         '修改无具体内容的项
         '修改无具体内容的项
-        If Not user Then Exit Sub
+        If Not user Then Return
         If Setup.Get("UiHiddenOtherHelp") AndAlso Setup.Get("UiHiddenOtherAbout") AndAlso Setup.Get("UiHiddenOtherTest") Then
         If Setup.Get("UiHiddenOtherHelp") AndAlso Setup.Get("UiHiddenOtherAbout") AndAlso Setup.Get("UiHiddenOtherTest") Then
             CheckHiddenOtherFeedback.Checked = True
             CheckHiddenOtherFeedback.Checked = True
             CheckHiddenOtherVote.Checked = True
             CheckHiddenOtherVote.Checked = True
@@ -648,7 +650,7 @@ Refresh:
     End Sub
     End Sub
     Private Sub HiddenOtherNet(sender As Object, user As Boolean) Handles CheckHiddenOtherFeedback.Change, CheckHiddenOtherVote.Change
     Private Sub HiddenOtherNet(sender As Object, user As Boolean) Handles CheckHiddenOtherFeedback.Change, CheckHiddenOtherVote.Change
         '更多子页面(无具体内容的)
         '更多子页面(无具体内容的)
-        If Not user Then Exit Sub
+        If Not user Then Return
         If Setup.Get("UiHiddenOtherHelp") AndAlso Setup.Get("UiHiddenOtherAbout") AndAlso Setup.Get("UiHiddenOtherTest") AndAlso
         If Setup.Get("UiHiddenOtherHelp") AndAlso Setup.Get("UiHiddenOtherAbout") AndAlso Setup.Get("UiHiddenOtherTest") AndAlso
             (Not Setup.Get("UiHiddenOtherFeedback") OrElse Not Setup.Get("UiHiddenOtherVote")) Then
             (Not Setup.Get("UiHiddenOtherFeedback") OrElse Not Setup.Get("UiHiddenOtherVote")) Then
             CheckHiddenOtherAbout.Checked = False
             CheckHiddenOtherAbout.Checked = False

+ 8 - 7
Plain Craft Launcher 2/Pages/PageSpeedLeft.xaml.vb

@@ -13,7 +13,7 @@ Public Class PageSpeedLeft
         '如果在页面切换动画的 “上一页消失” 部分已经完成了下载,就直接尝试返回
         '如果在页面切换动画的 “上一页消失” 部分已经完成了下载,就直接尝试返回
         TryReturnToHome()
         TryReturnToHome()
 
 
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
 
 
         '监控定时器
         '监控定时器
@@ -34,7 +34,7 @@ Public Class PageSpeedLeft
     '定时器任务
     '定时器任务
     Private ReadOnly RightCards As New Dictionary(Of String, MyCard)
     Private ReadOnly RightCards As New Dictionary(Of String, MyCard)
     Private Sub Watcher()
     Private Sub Watcher()
-        If Not FrmMain.PageCurrent = FormMain.PageType.DownloadManager Then Exit Sub
+        If Not FrmMain.PageCurrent = FormMain.PageType.DownloadManager Then Return
         Try
         Try
 
 
 #Region "更新左边栏"
 #Region "更新左边栏"
@@ -46,7 +46,8 @@ Public Class PageSpeedLeft
                 LabThread.Text = "0 / " & NetTaskThreadLimit
                 LabThread.Text = "0 / " & NetTaskThreadLimit
             Else
             Else
                 '有任务,输出基本信息
                 '有任务,输出基本信息
-                Dim RawPercent As Double = LoaderTaskbarProgress
+                Dim Tasks = LoaderTaskbar.Where(Function(l) l.Show).ToList() '筛选掉启动 MC 的任务(#6270)
+                Dim RawPercent As Double = If(Tasks.Any, MathClamp(Tasks.Select(Function(l) l.Progress).Average(), 0, 1), 1)
                 Dim PredictText As String = Math.Floor(RawPercent * 100) & "." & StrFill(Math.Floor((RawPercent * 100 - Math.Floor(RawPercent * 100)) * 100), "0", 2) & " %"
                 Dim PredictText As String = Math.Floor(RawPercent * 100) & "." & StrFill(Math.Floor((RawPercent * 100 - Math.Floor(RawPercent * 100)) * 100), "0", 2) & " %"
                 LabProgress.Text = If(RawPercent > 0.999999, "100 %", PredictText)
                 LabProgress.Text = If(RawPercent > 0.999999, "100 %", PredictText)
                 LabSpeed.Text = GetString(NetManager.Speed) & "/s"
                 LabSpeed.Text = GetString(NetManager.Speed) & "/s"
@@ -58,7 +59,7 @@ Public Class PageSpeedLeft
         Catch ex As Exception
         Catch ex As Exception
             Log(ex, "下载管理左栏监视出错", LogLevel.Feedback)
             Log(ex, "下载管理左栏监视出错", LogLevel.Feedback)
         End Try
         End Try
-        If FrmSpeedRight Is Nothing OrElse FrmSpeedRight.PanMain Is Nothing Then Exit Sub
+        If FrmSpeedRight Is Nothing OrElse FrmSpeedRight.PanMain Is Nothing Then Return
         Try
         Try
             For Each Loader In LoaderTaskbar.ToList
             For Each Loader In LoaderTaskbar.ToList
                 TaskRefresh(Loader)
                 TaskRefresh(Loader)
@@ -68,7 +69,7 @@ Public Class PageSpeedLeft
         End Try
         End Try
     End Sub
     End Sub
     Public Sub TaskRefresh(Loader As LoaderBase)
     Public Sub TaskRefresh(Loader As LoaderBase)
-        If Loader Is Nothing OrElse Not Loader.Show Then Exit Sub
+        If Loader Is Nothing OrElse Not Loader.Show Then Return
         Try
         Try
             '获取实际加载器列表
             '获取实际加载器列表
             Dim LoaderList As List(Of LoaderBase) = CType(Loader, Object).GetLoaderList()
             Dim LoaderList As List(Of LoaderBase) = CType(Loader, Object).GetLoaderList()
@@ -76,11 +77,11 @@ Public Class PageSpeedLeft
                 '已有此卡片
                 '已有此卡片
                 Dim Card As Grid = RightCards(Loader.Name)
                 Dim Card As Grid = RightCards(Loader.Name)
                 Dim NewValue As Double = Loader.Progress + Loader.State
                 Dim NewValue As Double = Loader.Progress + Loader.State
-                If Val(Card.Tag) = NewValue Then Exit Sub
+                If Val(Card.Tag) = NewValue Then Return
                 Card.Tag = NewValue
                 Card.Tag = NewValue
                 If Card.Children.Count <= 3 Then
                 If Card.Children.Count <= 3 Then
                     Log("[Watcher] 元素不足的卡片:" & Loader.Name, LogLevel.Debug)
                     Log("[Watcher] 元素不足的卡片:" & Loader.Name, LogLevel.Debug)
-                    Exit Sub
+                    Return
                 End If
                 End If
                 Card = Card.Children(3)
                 Card = Card.Children(3)
                 Try
                 Try

+ 25 - 17
Plain Craft Launcher 2/Pages/PageVersion/MyLocalModItem.xaml.vb

@@ -32,7 +32,7 @@ Public Class MyLocalModItem
                     LabTitle.TextDecorations = TextDecorations.Strikethrough
                     LabTitle.TextDecorations = TextDecorations.Strikethrough
                     value &= " [错误]"
                     value &= " [错误]"
             End Select
             End Select
-            If LabTitle.Text = value Then Exit Property
+            If LabTitle.Text = value Then Return
             LabTitle.Text = value
             LabTitle.Text = value
             _Title = RawValue
             _Title = RawValue
         End Set
         End Set
@@ -44,7 +44,7 @@ Public Class MyLocalModItem
             Return If(LabSubtitle?.Text, "")
             Return If(LabSubtitle?.Text, "")
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If LabSubtitle.Text = value Then Exit Property
+            If LabSubtitle.Text = value Then Return
             LabSubtitle.Text = value
             LabSubtitle.Text = value
             LabSubtitle.Visibility = If(value = "", Visibility.Collapsed, Visibility.Visible)
             LabSubtitle.Visibility = If(value = "", Visibility.Collapsed, Visibility.Visible)
         End Set
         End Set
@@ -56,7 +56,7 @@ Public Class MyLocalModItem
             Return LabInfo.Text
             Return LabInfo.Text
         End Get
         End Get
         Set(value As String)
         Set(value As String)
-            If LabInfo.Text = value Then Exit Property
+            If LabInfo.Text = value Then Return
             LabInfo.Text = value
             LabInfo.Text = value
         End Set
         End Set
     End Property
     End Property
@@ -97,7 +97,7 @@ Public Class MyLocalModItem
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
     Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
         If IsMouseDown Then
         If IsMouseDown Then
             RaiseEvent Click(sender, e)
             RaiseEvent Click(sender, e)
-            If e.Handled Then Exit Sub
+            If e.Handled Then Return
             Log("[Control] 按下本地 Mod 列表项:" & LabTitle.Text)
             Log("[Control] 按下本地 Mod 列表项:" & LabTitle.Text)
         End If
         End If
     End Sub
     End Sub
@@ -105,7 +105,7 @@ Public Class MyLocalModItem
     '鼠标点击判定
     '鼠标点击判定
     Private IsMouseDown As Boolean = False
     Private IsMouseDown As Boolean = False
     Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
     Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
-        If Not IsMouseDirectlyOver Then Exit Sub
+        If Not IsMouseDirectlyOver Then Return
         IsMouseDown = True
         IsMouseDown = True
         If ButtonStack IsNot Nothing Then ButtonStack.IsHitTestVisible = False
         If ButtonStack IsNot Nothing Then ButtonStack.IsHitTestVisible = False
     End Sub
     End Sub
@@ -116,25 +116,33 @@ Public Class MyLocalModItem
 
 
     '滑动选中
     '滑动选中
     Private Shared SwipeStart As Integer, SwipeEnd As Integer
     Private Shared SwipeStart As Integer, SwipeEnd As Integer
-    Private Shared Swiping As Boolean = False
+    Private Shared _Swiping As Boolean = False
+    Private Shared Property Swiping As Boolean
+        Get
+            Return _Swiping
+        End Get
+        Set(value As Boolean)
+            _Swiping = value
+            FrmVersionMod.CardSelect.IsHitTestVisible = Not value
+        End Set
+    End Property
     Private Shared SwipToState As Boolean '被滑动到的目标应将 Checked 改为此值
     Private Shared SwipToState As Boolean '被滑动到的目标应将 Checked 改为此值
     Private Sub Button_MouseSwipeStart(sender As Object, e As Object) Handles Me.MouseLeftButtonDown
     Private Sub Button_MouseSwipeStart(sender As Object, e As Object) Handles Me.MouseLeftButtonDown
-        If Parent Is Nothing Then Exit Sub 'Mod 可能已被删除(#3824)
+        If Parent Is Nothing Then Return 'Mod 可能已被删除(#3824)
         '开始滑动
         '开始滑动
         Dim Index = CType(Parent, StackPanel).Children.IndexOf(Me)
         Dim Index = CType(Parent, StackPanel).Children.IndexOf(Me)
         SwipeStart = Index
         SwipeStart = Index
         SwipeEnd = Index
         SwipeEnd = Index
         Swiping = True
         Swiping = True
         SwipToState = Not Checked
         SwipToState = Not Checked
-        FrmVersionMod.CardSelect.IsHitTestVisible = False '暂时禁用下边栏
     End Sub
     End Sub
     Private Sub Button_MouseSwipe(sender As Object, e As Object) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonUp
     Private Sub Button_MouseSwipe(sender As Object, e As Object) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonUp
-        If Parent Is Nothing Then Exit Sub 'Mod 可能已被删除(#3824)
+        If Parent Is Nothing Then Return 'Mod 可能已被删除(#3824)
         '结束滑动
         '结束滑动
-        If Mouse.LeftButton <> MouseButtonState.Pressed OrElse Not Swiping Then
+        If Mouse.LeftButton <> MouseButtonState.Pressed OrElse
+           TypeOf Mouse.DirectlyOver IsNot MyLocalModItem Then '#5771
             Swiping = False
             Swiping = False
-            FrmVersionMod.CardSelect.IsHitTestVisible = True
-            Exit Sub
+            Return
         End If
         End If
         '计算滑动范围
         '计算滑动范围
         Dim Elements = CType(Parent, StackPanel).Children
         Dim Elements = CType(Parent, StackPanel).Children
@@ -142,7 +150,7 @@ Public Class MyLocalModItem
         SwipeStart = MathClamp(Math.Min(SwipeStart, Index), 0, Elements.Count - 1)
         SwipeStart = MathClamp(Math.Min(SwipeStart, Index), 0, Elements.Count - 1)
         SwipeEnd = MathClamp(Math.Max(SwipeEnd, Index), 0, Elements.Count - 1)
         SwipeEnd = MathClamp(Math.Max(SwipeEnd, Index), 0, Elements.Count - 1)
         '勾选所有范围中的项
         '勾选所有范围中的项
-        If SwipeStart = SwipeEnd Then Exit Sub
+        If SwipeStart = SwipeEnd Then Return
         For i = SwipeStart To SwipeEnd
         For i = SwipeStart To SwipeEnd
             Dim Item As MyLocalModItem = Elements(i)
             Dim Item As MyLocalModItem = Elements(i)
             Item.InitLate(Item, e)
             Item.InitLate(Item, e)
@@ -162,20 +170,20 @@ Public Class MyLocalModItem
             Try
             Try
                 '触发属性值修改
                 '触发属性值修改
                 Dim RawValue = _Checked
                 Dim RawValue = _Checked
-                If value = _Checked Then Exit Property
+                If value = _Checked Then Return
                 _Checked = value
                 _Checked = value
                 Dim ChangedEventArgs As New RouteEventArgs(False)
                 Dim ChangedEventArgs As New RouteEventArgs(False)
                 If IsInitialized Then
                 If IsInitialized Then
                     RaiseEvent Changed(Me, ChangedEventArgs)
                     RaiseEvent Changed(Me, ChangedEventArgs)
                     If ChangedEventArgs.Handled Then
                     If ChangedEventArgs.Handled Then
                         _Checked = RawValue
                         _Checked = RawValue
-                        Exit Property
+                        Return
                     End If
                     End If
                 End If
                 End If
                 If value Then
                 If value Then
                     Dim CheckEventArgs As New RouteEventArgs(False)
                     Dim CheckEventArgs As New RouteEventArgs(False)
                     RaiseEvent Check(Me, CheckEventArgs)
                     RaiseEvent Check(Me, CheckEventArgs)
-                    If CheckEventArgs.Handled Then Exit Property
+                    If CheckEventArgs.Handled Then Return
                 End If
                 End If
                 '更改动画
                 '更改动画
                 If IsVisibleInForm() Then
                 If IsVisibleInForm() Then
@@ -270,7 +278,7 @@ Public Class MyLocalModItem
                 Children.Remove(ButtonStack)
                 Children.Remove(ButtonStack)
                 ButtonStack = Nothing
                 ButtonStack = Nothing
             End If
             End If
-            If Not value.Any() Then Exit Property
+            If Not value.Any() Then Return
             '添加新 Stack
             '添加新 Stack
             ButtonStack = New StackPanel With {.Opacity = 0, .Margin = New Thickness(0, 0, 5, 0), .SnapsToDevicePixels = False, .Orientation = Orientation.Horizontal,
             ButtonStack = New StackPanel With {.Opacity = 0, .Margin = New Thickness(0, 0, 5, 0), .SnapsToDevicePixels = False, .Orientation = Orientation.Horizontal,
                 .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Center, .UseLayoutRounding = False}
                 .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Center, .UseLayoutRounding = False}

+ 5 - 5
Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml

@@ -13,7 +13,7 @@
         </Grid.Resources>
         </Grid.Resources>
         <local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
         <local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
             <StackPanel Margin="25,10,25,65">
             <StackPanel Margin="25,10,25,65">
-                <local:MyHint Margin="0,15,0,0" Text="受 Modrinth 整合包规范限制,导出的整合包中暂不包含 OptiFine。" IsWarn="False" x:Name="HintOptiFine" />
+                <local:MyHint Margin="0,15,0,0" Text="受 Modrinth 整合包规范限制,导出的整合包中不会包含 OptiFine。" Theme="Yellow" x:Name="HintOptiFine" />
                 <local:MyCard Margin="0,15">
                 <local:MyCard Margin="0,15">
                     <Grid Margin="22,15,25,15">
                     <Grid Margin="22,15,25,15">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>
@@ -237,14 +237,14 @@
                 </local:MyCard>
                 </local:MyCard>
                 <local:MyCard Title="高级选项" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
                 <local:MyCard Title="高级选项" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
                     <StackPanel Margin="25,37,23,20">
                     <StackPanel Margin="25,37,23,20">
-                        <local:MyHint Text="建议仅在无法稳定连接 CurseForge 或 Modrinth 时才打包资源文件。&#xa;二次分发可能违反使用协议,请尽量不要公开发布包含资源文件的整合包!"
-                                      IsWarn="False" Margin="0,0,0,4" Visibility="{Binding Checked, ElementName=CheckAdvancedInclude, Converter={StaticResource BooleanToVisibilityConverter}}" />
+                        <local:MyHint Text="建议仅在无法稳定连接 CurseForge 或 Modrinth 时才打包资源文件。&#xa;请不要公开发布含资源文件的整合包,这会违反部分 Mod 的使用协议!"
+                                      Theme="Yellow" Margin="0,2,0,8" Visibility="{Binding Checked, ElementName=CheckAdvancedInclude, Converter={StaticResource BooleanToVisibilityConverter}}" />
                         <local:MyCheckBox Text="打包资源文件,以避免在导入时下载" x:Name="CheckAdvancedInclude"
                         <local:MyCheckBox Text="打包资源文件,以避免在导入时下载" x:Name="CheckAdvancedInclude"
                                           ToolTip="将 Mod、资源包、光影包的文件直接放入整合包中,这样在导入时就无需联网下载它们。&#xa;建议仅在无法稳定连接 CurseForge 或 Modrinth 时才考虑勾选。" />
                                           ToolTip="将 Mod、资源包、光影包的文件直接放入整合包中,这样在导入时就无需联网下载它们。&#xa;建议仅在无法稳定连接 CurseForge 或 Modrinth 时才考虑勾选。" />
                         <local:MyCheckBox Text="Modrinth 上传模式" x:Name="CheckAdvancedModrinth"
                         <local:MyCheckBox Text="Modrinth 上传模式" x:Name="CheckAdvancedModrinth"
                                           ToolTip="如果你想要打包上传到 Modrinth,勾选此项会生成完全符合 Modrinth 要求的整合包文件。&#xa;由于 Modrinth 要求,只能从 CurseForge 下载的资源将无法联网下载,会被直接放入整合包中。&#xa;此外,勾选后也不能在整合包中包含 PCL 启动器文件。" />
                                           ToolTip="如果你想要打包上传到 Modrinth,勾选此项会生成完全符合 Modrinth 要求的整合包文件。&#xa;由于 Modrinth 要求,只能从 CurseForge 下载的资源将无法联网下载,会被直接放入整合包中。&#xa;此外,勾选后也不能在整合包中包含 PCL 启动器文件。" />
-                        <local:MyHint IsWarn="False" RelativeSetup="HintExportConfig" CanClose="True" Margin="0,20,0,0"
-                                      Text="配置文件中含有未在此处列出的选项,例如精准控制导出的文件、设置整合包存放位置等。&#xa;请先选择 “保存配置”,然后编辑保存的配置文件。" />
+                        <local:MyHint Theme="Blue" RelativeSetup="HintExportConfig" CanClose="True" Margin="0,20,0,2"
+                                      Text="配置文件中含有更多高级选项,例如精准控制导出的文件、设置整合包存放位置等。&#xa;要修改这些选项,请先点击 “保存配置”,在编辑配置文件后再导入。" />
                         <Grid Height="35" Margin="0,12,0,0">
                         <Grid Height="35" Margin="0,12,0,0">
                             <Grid.ColumnDefinitions>
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
                                 <ColumnDefinition Width="Auto" SharedSizeGroup="Button" />

+ 7 - 4
Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb

@@ -256,6 +256,8 @@ Public Class PageVersionExport
             Yield "!*.log"
             Yield "!*.log"
             Yield "!*.dat_old"
             Yield "!*.dat_old"
             Yield "!*.BakaCoreInfo"
             Yield "!*.BakaCoreInfo"
+            Yield "!hmclversion.cfg"
+            Yield "!log4j2.xml"
             Yield ""
             Yield ""
         End If
         End If
     End Function
     End Function
@@ -407,7 +409,6 @@ Public Class PageVersionExport
         Next
         Next
 
 
         '确认导出位置
         '确认导出位置
-        Dim Extension As String = If(CheckOptionsPcl.Checked, ".zip", ".mrpack")
         Dim PackPath As String = Nothing
         Dim PackPath As String = Nothing
         If Not String.IsNullOrWhiteSpace(ConfigPackPath) AndAlso
         If Not String.IsNullOrWhiteSpace(ConfigPackPath) AndAlso
            (Not ConfigPackPath.EndsWithF("\") AndAlso Not ConfigPackPath.EndsWithF("/")) Then
            (Not ConfigPackPath.EndsWithF("\") AndAlso Not ConfigPackPath.EndsWithF("/")) Then
@@ -421,9 +422,11 @@ Public Class PageVersionExport
             End Try
             End Try
         End If
         End If
         If PackPath Is Nothing Then
         If PackPath Is Nothing Then
+            Dim Extensions As New List(Of String)
+            If Not CheckAdvancedModrinth.Checked Then Extensions.Add("压缩文件(*.zip)|*.zip")
+            If Not CheckOptionsPcl.Checked Then Extensions.Add("Modrinth 整合包文件(*.mrpack)|*.mrpack")
             PackPath = SelectSaveFile("选择导出位置",
             PackPath = SelectSaveFile("选择导出位置",
-                PackName & If(String.IsNullOrEmpty(TextExportVersion.Text), "", " " & TextExportVersion.Text),
-                $"整合包文件(*{Extension})|*{Extension}")
+                PackName & If(String.IsNullOrEmpty(TextExportVersion.Text), "", " " & TextExportVersion.Text), Extensions.Join("|"))
             Log($"[Export] 手动指定的导出路径:{PackPath}")
             Log($"[Export] 手动指定的导出路径:{PackPath}")
         End If
         End If
         If String.IsNullOrEmpty(PackPath) Then Return
         If String.IsNullOrEmpty(PackPath) Then Return
@@ -612,7 +615,7 @@ Public Class PageVersionExport
 
 
             '等待线程结束
             '等待线程结束
             Do Until EndedThreadCount = 2
             Do Until EndedThreadCount = 2
-                If Loader.IsAborted Then Exit Sub
+                If Loader.IsAborted Then Return
                 Thread.Sleep(10)
                 Thread.Sleep(10)
             Loop
             Loop
 
 

+ 1 - 1
Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb

@@ -59,7 +59,7 @@
     ''' 切换现有页面。
     ''' 切换现有页面。
     ''' </summary>
     ''' </summary>
     Public Sub PageChange(ID As FormMain.PageSubType)
     Public Sub PageChange(ID As FormMain.PageSubType)
-        If PageID = ID Then Exit Sub
+        If PageID = ID Then Return
         AniControlEnabled += 1
         AniControlEnabled += 1
         Try
         Try
             PageChangeRun(PageGet(ID))
             PageChangeRun(PageGet(ID))

+ 1 - 1
Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml

@@ -59,7 +59,7 @@
             <local:MyLoading Text="正在加载 Mod 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
             <local:MyLoading Text="正在加载 Mod 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
         </local:MyCard>
         </local:MyCard>
         <local:MyCard x:Name="CardSelect" Visibility="Collapsed" Opacity="0"
         <local:MyCard x:Name="CardSelect" Visibility="Collapsed" Opacity="0"
-                      HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="25,25,25,0" UseAnimation="False" HasMouseAnimation="False">
+                      HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="25,25,25,0" UseAnimation="False">
             <local:MyCard.RenderTransform>
             <local:MyCard.RenderTransform>
                 <TranslateTransform x:Name="TransSelect" Y="-10" />
                 <TranslateTransform x:Name="TransSelect" Y="-10" />
             </local:MyCard.RenderTransform>
             </local:MyCard.RenderTransform>

+ 6 - 6
Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb

@@ -14,7 +14,7 @@
         AniControlEnabled -= 1
         AniControlEnabled -= 1
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
 
 
         '调整按钮边距(这玩意儿没法从 XAML 改)
         '调整按钮边距(这玩意儿没法从 XAML 改)
@@ -89,7 +89,7 @@
             Else
             Else
                 PanEmpty.Visibility = Visibility.Visible
                 PanEmpty.Visibility = Visibility.Visible
                 PanBack.Visibility = Visibility.Collapsed
                 PanBack.Visibility = Visibility.Collapsed
-                Exit Sub
+                Return
             End If
             End If
             '修改缓存
             '修改缓存
             ModItems.Clear()
             ModItems.Clear()
@@ -154,7 +154,7 @@
     ''' 刷新整个 UI。
     ''' 刷新整个 UI。
     ''' </summary>
     ''' </summary>
     Public Sub RefreshUI()
     Public Sub RefreshUI()
-        If PanList Is Nothing Then Exit Sub
+        If PanList Is Nothing Then Return
         Dim ShowingMods = If(IsSearching, SearchResult, If(McModLoader.Output, New List(Of McMod))).Where(Function(m) CanPassFilter(m)).ToList
         Dim ShowingMods = If(IsSearching, SearchResult, If(McModLoader.Output, New List(Of McMod))).Where(Function(m) CanPassFilter(m)).ToList
         '重新列出列表
         '重新列出列表
         AniControlEnabled += 1
         AniControlEnabled += 1
@@ -584,7 +584,7 @@ Install:
             If MyMsgBox($"新版本 Mod 可能不兼容旧存档或者其他 Mod,这可能导致游戏崩溃,甚至永久损坏存档!{vbCrLf}如果你在游玩整合包,请千万不要自行更新 Mod!{vbCrLf}{vbCrLf}在更新前,请先备份存档,并检查 Mod 的更新日志。{vbCrLf}如果更新后出现问题,你也可以在回收站找回更新前的 Mod。", "Mod 更新警告", "我已了解风险,继续更新", "取消", IsWarn:=True) = 1 Then
             If MyMsgBox($"新版本 Mod 可能不兼容旧存档或者其他 Mod,这可能导致游戏崩溃,甚至永久损坏存档!{vbCrLf}如果你在游玩整合包,请千万不要自行更新 Mod!{vbCrLf}{vbCrLf}在更新前,请先备份存档,并检查 Mod 的更新日志。{vbCrLf}如果更新后出现问题,你也可以在回收站找回更新前的 Mod。", "Mod 更新警告", "我已了解风险,继续更新", "取消", IsWarn:=True) = 1 Then
                 Setup.Set("HintUpdateMod", True)
                 Setup.Set("HintUpdateMod", True)
             Else
             Else
-                Exit Sub
+                Return
             End If
             End If
         End If
         End If
         Try
         Try
@@ -676,7 +676,7 @@ Install:
                     Case LoadState.Aborted
                     Case LoadState.Aborted
                         Hint("Mod 更新已中止!", HintType.Info)
                         Hint("Mod 更新已中止!", HintType.Info)
                     Case Else
                     Case Else
-                        Exit Sub
+                        Return
                 End Select
                 End Select
                 Log($"[Mod] 已从正在进行 Mod 更新的文件夹列表移除:{PathMods}")
                 Log($"[Mod] 已从正在进行 Mod 更新的文件夹列表移除:{PathMods}")
                 UpdatingVersions.Remove(PathMods)
                 UpdatingVersions.Remove(PathMods)
@@ -759,7 +759,7 @@ Install:
                 RefreshBars()
                 RefreshBars()
             End If
             End If
             '显示结果提示
             '显示结果提示
-            If Not IsSuccessful Then Exit Sub
+            If Not IsSuccessful Then Return
             If IsShiftPressed Then
             If IsShiftPressed Then
                 If ModList.Count = 1 Then
                 If ModList.Count = 1 Then
                     Hint($"已彻底删除 {ModList.Single.FileName}!", HintType.Finish)
                     Hint($"已彻底删除 {ModList.Single.FileName}!", HintType.Finish)

+ 13 - 13
Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb

@@ -11,7 +11,7 @@
         Reload()
         Reload()
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoad Then Exit Sub
+        If IsLoad Then Return
         IsLoad = True
         IsLoad = True
         PanDisplay.TriggerForceResize()
         PanDisplay.TriggerForceResize()
 
 
@@ -54,7 +54,7 @@
 
 
     '版本分类
     '版本分类
     Private Sub ComboDisplayType_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayType.SelectionChanged
     Private Sub ComboDisplayType_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayType.SelectionChanged
-        If Not (IsLoad AndAlso AniControlEnabled = 0) Then Exit Sub
+        If Not (IsLoad AndAlso AniControlEnabled = 0) Then Return
         If ComboDisplayType.SelectedIndex <> 1 Then
         If ComboDisplayType.SelectedIndex <> 1 Then
             '改为不隐藏
             '改为不隐藏
             Try
             Try
@@ -75,7 +75,7 @@
                 If Not Setup.Get("HintHide") Then
                 If Not Setup.Get("HintHide") Then
                     If MyMsgBox("确认要从版本列表中隐藏该版本吗?隐藏该版本后,它将不再出现于 PCL 显示的版本列表中。" & vbCrLf & "此后,在版本列表页面按下 F11 才可以查看被隐藏的版本。", "隐藏版本提示",, "取消") <> 1 Then
                     If MyMsgBox("确认要从版本列表中隐藏该版本吗?隐藏该版本后,它将不再出现于 PCL 显示的版本列表中。" & vbCrLf & "此后,在版本列表页面按下 F11 才可以查看被隐藏的版本。", "隐藏版本提示",, "取消") <> 1 Then
                         ComboDisplayType.SelectedIndex = 0
                         ComboDisplayType.SelectedIndex = 0
-                        Exit Sub
+                        Return
                     End If
                     End If
                     Setup.Set("HintHide", True)
                     Setup.Set("HintHide", True)
                 End If
                 End If
@@ -110,7 +110,7 @@
             Dim OldPath As String = PageVersionLeft.Version.Path
             Dim OldPath As String = PageVersionLeft.Version.Path
             '修改此部分的同时修改快速安装的版本名检测*
             '修改此部分的同时修改快速安装的版本名检测*
             Dim NewName As String = MyMsgBoxInput("重命名版本", "", OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)})
             Dim NewName As String = MyMsgBoxInput("重命名版本", "", OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)})
-            If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
+            If String.IsNullOrWhiteSpace(NewName) Then Return
             Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
             Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
             '获取临时中间名,以防止仅修改大小写的重命名失败
             '获取临时中间名,以防止仅修改大小写的重命名失败
             Dim TempName As String = NewName & "_temp"
             Dim TempName As String = NewName & "_temp"
@@ -128,6 +128,7 @@
             My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
             My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
             My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
             My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
             '清理 ini 缓存
             '清理 ini 缓存
+            IniClearCache(PageVersionLeft.Version.PathIndie & "options.txt")
             IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
             IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
             '遍历重命名所有文件与文件夹
             '遍历重命名所有文件与文件夹
             For Each Entry As DirectoryInfo In New DirectoryInfo(NewPath).EnumerateDirectories
             For Each Entry As DirectoryInfo In New DirectoryInfo(NewPath).EnumerateDirectories
@@ -180,17 +181,15 @@
 
 
     '版本图标
     '版本图标
     Private Sub ComboDisplayLogo_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
     Private Sub ComboDisplayLogo_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
-        If Not (IsLoad AndAlso AniControlEnabled = 0) Then Exit Sub
+        If Not (IsLoad AndAlso AniControlEnabled = 0) Then Return
         '选择 自定义 时修改图片
         '选择 自定义 时修改图片
         Try
         Try
             If ComboDisplayLogo.SelectedItem Is ItemDisplayLogoCustom Then
             If ComboDisplayLogo.SelectedItem Is ItemDisplayLogoCustom Then
                 Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
                 Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
                 If FileName = "" Then
                 If FileName = "" Then
                     Reload() '还原选项
                     Reload() '还原选项
-                    Exit Sub
+                    Return
                 End If
                 End If
-                File.Delete(PageVersionLeft.Version.Path & "PCL\Logo.png")
-                Directory.CreateDirectory(PageVersionLeft.Version.Path & "PCL") '虽然不知道为啥,有时候真没这文件夹
                 CopyFile(FileName, PageVersionLeft.Version.Path & "PCL\Logo.png")
                 CopyFile(FileName, PageVersionLeft.Version.Path & "PCL\Logo.png")
             Else
             Else
                 File.Delete(PageVersionLeft.Version.Path & "PCL\Logo.png")
                 File.Delete(PageVersionLeft.Version.Path & "PCL\Logo.png")
@@ -261,11 +260,11 @@
         Try
         Try
             '弹窗要求指定脚本的保存位置
             '弹窗要求指定脚本的保存位置
             Dim SavePath As String = SelectSaveFile("选择脚本保存位置", "启动 " & PageVersionLeft.Version.Name & ".bat", "批处理文件(*.bat)|*.bat")
             Dim SavePath As String = SelectSaveFile("选择脚本保存位置", "启动 " & PageVersionLeft.Version.Name & ".bat", "批处理文件(*.bat)|*.bat")
-            If SavePath = "" Then Exit Sub
+            If SavePath = "" Then Return
             '检查中断(等玩家选完弹窗指不定任务就结束了呢……)
             '检查中断(等玩家选完弹窗指不定任务就结束了呢……)
             If McLaunchLoader.State = LoadState.Loading Then
             If McLaunchLoader.State = LoadState.Loading Then
                 Hint("请在当前启动任务结束后再试!", HintType.Critical)
                 Hint("请在当前启动任务结束后再试!", HintType.Critical)
-                Exit Sub
+                Return
             End If
             End If
             '生成脚本
             '生成脚本
             If McLaunchStart(New McLaunchOptions With {.SaveBatch = SavePath, .Version = PageVersionLeft.Version}) Then
             If McLaunchStart(New McLaunchOptions With {.SaveBatch = SavePath, .Version = PageVersionLeft.Version}) Then
@@ -286,13 +285,13 @@
             '忽略文件检查提示
             '忽略文件检查提示
             If ShouldIgnoreFileCheck(PageVersionLeft.Version) Then
             If ShouldIgnoreFileCheck(PageVersionLeft.Version) Then
                 Hint("请先关闭 [版本设置 → 设置 → 高级启动选项 → 关闭文件校验],然后再尝试补全文件!", HintType.Info)
                 Hint("请先关闭 [版本设置 → 设置 → 高级启动选项 → 关闭文件校验],然后再尝试补全文件!", HintType.Info)
-                Exit Sub
+                Return
             End If
             End If
             '重复任务检查
             '重复任务检查
             For Each OngoingLoader In LoaderTaskbar
             For Each OngoingLoader In LoaderTaskbar
                 If OngoingLoader.Name <> PageVersionLeft.Version.Name & " 文件补全" Then Continue For
                 If OngoingLoader.Name <> PageVersionLeft.Version.Name & " 文件补全" Then Continue For
                 Hint("正在处理中,请稍候!", HintType.Critical)
                 Hint("正在处理中,请稍候!", HintType.Critical)
-                Exit Sub
+                Return
             Next
             Next
             '启动
             '启动
             Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload))
             Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload))
@@ -326,6 +325,7 @@
                         If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
                         If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
                         "版本删除确认", , "取消",, IsHintIndie OrElse IsShiftPressed)
                         "版本删除确认", , "取消",, IsHintIndie OrElse IsShiftPressed)
                 Case 1
                 Case 1
+                    IniClearCache(PageVersionLeft.Version.PathIndie & "options.txt")
                     IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
                     IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
                     If IsShiftPressed Then
                     If IsShiftPressed Then
                         DeleteDirectory(PageVersionLeft.Version.Path)
                         DeleteDirectory(PageVersionLeft.Version.Path)
@@ -335,7 +335,7 @@
                         Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
                         Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
                     End If
                     End If
                 Case 2
                 Case 2
-                    Exit Sub
+                    Return
             End Select
             End Select
             LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
             LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
             FrmMain.PageBack()
             FrmMain.PageBack()

+ 2 - 2
Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml

@@ -7,7 +7,7 @@
     PanScroll="{Binding ElementName=PanBack}">
     PanScroll="{Binding ElementName=PanBack}">
     <local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
     <local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
         <StackPanel x:Name="PanMain" Margin="25,25,25,25">
         <StackPanel x:Name="PanMain" Margin="25,25,25,25">
-            <local:MyHint Text="这些设置只对该游戏版本生效,不影响其他版本。" IsWarn="False" Margin="0,0,0,15"
+            <local:MyHint Text="这些设置只对该游戏版本生效,不影响其他版本。" Theme="Blue" Margin="0,0,0,15"
                           CanClose="True" RelativeSetup="HintIndieSetup"  />
                           CanClose="True" RelativeSetup="HintIndieSetup"  />
             <local:MyCard x:Name="CardArgument" Margin="0,0,0,15" Title="启动选项">
             <local:MyCard x:Name="CardArgument" Margin="0,0,0,15" Title="启动选项">
                 <StackPanel Margin="25,40,25,21">
                 <StackPanel Margin="25,40,25,21">
@@ -58,7 +58,7 @@
             </local:MyCard>
             </local:MyCard>
             <local:MyCard Margin="0,0,0,15" Title="游戏内存">
             <local:MyCard Margin="0,0,0,15" Title="游戏内存">
                 <StackPanel Margin="25,40,25,15">
                 <StackPanel Margin="25,40,25,15">
-                    <local:MyHint x:Name="LabRamWarn" Text="32 位 Java 最多只能分配 1 GB 内存,建议安装 64 位 Java!" IsWarn="True" Margin="0,0,0,12" />
+                    <local:MyHint x:Name="LabRamWarn" Text="32 位 Java 只能分配最多 1 GB 的内存。强烈建议换用 64 位的 Java!" Theme="Yellow" Margin="0,0,0,12" />
                     <Grid Margin="0,0,0,3">
                     <Grid Margin="0,0,0,3">
                         <Grid.ColumnDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="Auto" />
                             <ColumnDefinition Width="Auto" />

+ 14 - 14
Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb

@@ -14,7 +14,7 @@
         AniControlEnabled -= 1
         AniControlEnabled -= 1
 
 
         '非重复加载部分
         '非重复加载部分
-        If IsLoaded Then Exit Sub
+        If IsLoaded Then Return
         IsLoaded = True
         IsLoaded = True
 
 
         '内存自动刷新
         '内存自动刷新
@@ -132,7 +132,7 @@
 #Region "游戏内存"
 #Region "游戏内存"
 
 
     Public Sub RamType(Type As Integer)
     Public Sub RamType(Type As Integer)
-        If SliderRamCustom Is Nothing Then Exit Sub
+        If SliderRamCustom Is Nothing Then Return
         SliderRamCustom.IsEnabled = (Type = 1)
         SliderRamCustom.IsEnabled = (Type = 1)
     End Sub
     End Sub
 
 
@@ -140,7 +140,7 @@
     ''' 刷新 UI 上的 RAM 显示。
     ''' 刷新 UI 上的 RAM 显示。
     ''' </summary>
     ''' </summary>
     Public Sub RefreshRam(ShowAnim As Boolean)
     Public Sub RefreshRam(ShowAnim As Boolean)
-        If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.VersionSetup OrElse FrmVersionLeft.PageID <> FormMain.PageSubType.VersionSetup Then Exit Sub
+        If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.VersionSetup OrElse FrmVersionLeft.PageID <> FormMain.PageSubType.VersionSetup Then Return
         '获取内存情况
         '获取内存情况
         Dim RamGame As Double = Math.Round(GetRam(PageVersionLeft.Version), 5)
         Dim RamGame As Double = Math.Round(GetRam(PageVersionLeft.Version), 5)
         Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024, 1)
         Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024, 1)
@@ -358,19 +358,19 @@ PreFin:
     '全局
     '全局
     Private ComboServerLoginLast As Integer
     Private ComboServerLoginLast As Integer
     Private Sub ComboServerLogin_Changed() Handles ComboServerLogin.SelectionChanged, TextServerNide.ValidatedTextChanged, TextServerAuthServer.ValidatedTextChanged, TextServerAuthRegister.ValidatedTextChanged
     Private Sub ComboServerLogin_Changed() Handles ComboServerLogin.SelectionChanged, TextServerNide.ValidatedTextChanged, TextServerAuthServer.ValidatedTextChanged, TextServerAuthRegister.ValidatedTextChanged
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         ServerLogin(ComboServerLogin.SelectedIndex)
         ServerLogin(ComboServerLogin.SelectedIndex)
         '检查是否输入正确,正确才触发设置改变
         '检查是否输入正确,正确才触发设置改变
-        If ComboServerLogin.SelectedIndex = 3 AndAlso Not TextServerNide.IsValidated Then Exit Sub
-        If ComboServerLogin.SelectedIndex = 4 AndAlso Not TextServerAuthServer.IsValidated Then Exit Sub
+        If ComboServerLogin.SelectedIndex = 3 AndAlso Not TextServerNide.IsValidated Then Return
+        If ComboServerLogin.SelectedIndex = 4 AndAlso Not TextServerAuthServer.IsValidated Then Return
         '检查结果是否发生改变,未改变则不触发设置改变
         '检查结果是否发生改变,未改变则不触发设置改变
-        If ComboServerLoginLast = ComboServerLogin.SelectedIndex Then Exit Sub
+        If ComboServerLoginLast = ComboServerLogin.SelectedIndex Then Return
         '触发
         '触发
         ComboServerLoginLast = ComboServerLogin.SelectedIndex
         ComboServerLoginLast = ComboServerLogin.SelectedIndex
         ComboChange(ComboServerLogin, Nothing)
         ComboChange(ComboServerLogin, Nothing)
     End Sub
     End Sub
     Public Sub ServerLogin(Type As Integer)
     Public Sub ServerLogin(Type As Integer)
-        If LabServerNide Is Nothing Then Exit Sub
+        If LabServerNide Is Nothing Then Return
         LabServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
         LabServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
         TextServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
         TextServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
         PanServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
         PanServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
@@ -393,7 +393,7 @@ PreFin:
     Private Sub BtnServerAuthLittle_Click(sender As Object, e As EventArgs) Handles BtnServerAuthLittle.Click
     Private Sub BtnServerAuthLittle_Click(sender As Object, e As EventArgs) Handles BtnServerAuthLittle.Click
         If TextServerAuthServer.Text <> "" AndAlso TextServerAuthServer.Text <> "https://littleskin.cn/api/yggdrasil" AndAlso
         If TextServerAuthServer.Text <> "" AndAlso TextServerAuthServer.Text <> "https://littleskin.cn/api/yggdrasil" AndAlso
             MyMsgBox("即将把第三方登录设置覆盖为 LittleSkin 登录。" & vbCrLf & "除非你是服主,或者服主要求你这样做,否则请不要继续。" & vbCrLf & vbCrLf & "是否确实需要覆盖当前设置?",
             MyMsgBox("即将把第三方登录设置覆盖为 LittleSkin 登录。" & vbCrLf & "除非你是服主,或者服主要求你这样做,否则请不要继续。" & vbCrLf & vbCrLf & "是否确实需要覆盖当前设置?",
-                     "设置覆盖确认", "继续", "取消") = 2 Then Exit Sub
+                     "设置覆盖确认", "继续", "取消") = 2 Then Return
         TextServerAuthServer.Text = "https://littleskin.cn/api/yggdrasil"
         TextServerAuthServer.Text = "https://littleskin.cn/api/yggdrasil"
         TextServerAuthRegister.Text = "https://littleskin.cn/auth/register"
         TextServerAuthRegister.Text = "https://littleskin.cn/auth/register"
         TextServerAuthName.Text = "LittleSkin 登录"
         TextServerAuthName.Text = "LittleSkin 登录"
@@ -405,7 +405,7 @@ PreFin:
 
 
     '刷新 Java 下拉框显示
     '刷新 Java 下拉框显示
     Public Sub RefreshJavaComboBox()
     Public Sub RefreshJavaComboBox()
-        If ComboArgumentJava Is Nothing Then Exit Sub
+        If ComboArgumentJava Is Nothing Then Return
         '初始化列表
         '初始化列表
         ComboArgumentJava.Items.Clear()
         ComboArgumentJava.Items.Clear()
         ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "跟随全局设置", .Tag = "使用全局设置"})
         ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "跟随全局设置", .Tag = "使用全局设置"})
@@ -451,9 +451,9 @@ PreFin:
 
 
     '下拉框选择更改
     '下拉框选择更改
     Private Sub JavaSelectionUpdate() Handles ComboArgumentJava.SelectionChanged
     Private Sub JavaSelectionUpdate() Handles ComboArgumentJava.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
         'Java 不可用时也不清空,会导致刷新时找不到对象
         'Java 不可用时也不清空,会导致刷新时找不到对象
-        If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.SelectedItem.Tag Is Nothing Then Exit Sub
+        If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.SelectedItem.Tag Is Nothing Then Return
         '设置新的 Java
         '设置新的 Java
         Dim SelectedJava = ComboArgumentJava.SelectedItem.Tag
         Dim SelectedJava = ComboArgumentJava.SelectedItem.Tag
         If "使用全局设置".Equals(SelectedJava) Then
         If "使用全局设置".Equals(SelectedJava) Then
@@ -479,8 +479,8 @@ PreFin:
     '版本隔离警告
     '版本隔离警告
     Private IsReverting As Boolean = False
     Private IsReverting As Boolean = False
     Private Sub ComboArgumentIndieV2_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentIndieV2.SelectionChanged
     Private Sub ComboArgumentIndieV2_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentIndieV2.SelectionChanged
-        If AniControlEnabled <> 0 Then Exit Sub
-        If IsReverting Then Exit Sub
+        If AniControlEnabled <> 0 Then Return
+        If IsReverting Then Return
         If MyMsgBox("调整版本隔离后,你可能得把游戏存档、Mod 等文件手动迁移到新的游戏文件夹中。" & vbCrLf &
         If MyMsgBox("调整版本隔离后,你可能得把游戏存档、Mod 等文件手动迁移到新的游戏文件夹中。" & vbCrLf &
                     "如果修改后发现存档消失,把这项设置改回来就能恢复。" & vbCrLf &
                     "如果修改后发现存档消失,把这项设置改回来就能恢复。" & vbCrLf &
                     "如果你不会迁移存档,不建议修改这项设置!",
                     "如果你不会迁移存档,不建议修改这项设置!",

+ 1 - 9
Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj

@@ -323,7 +323,7 @@
     <Compile Include="Pages\PageVersion\PageVersionSetup.xaml.vb">
     <Compile Include="Pages\PageVersion\PageVersionSetup.xaml.vb">
       <DependentUpon>PageVersionSetup.xaml</DependentUpon>
       <DependentUpon>PageVersionSetup.xaml</DependentUpon>
     </Compile>
     </Compile>
-    <Compile Include="Modules\Reference\SystemDropShadowChrome.vb" />
+    <Compile Include="Controls\MyDropShadow.vb" />
     <Compile Include="Modules\Base\ModLoader.vb" />
     <Compile Include="Modules\Base\ModLoader.vb" />
     <Compile Include="Modules\Base\ModNet.vb" />
     <Compile Include="Modules\Base\ModNet.vb" />
     <Compile Include="Modules\Base\ModValidate.vb" />
     <Compile Include="Modules\Base\ModValidate.vb" />
@@ -603,14 +603,6 @@
       <SubType>Designer</SubType>
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
       <Generator>MSBuild:Compile</Generator>
     </Page>
     </Page>
-    <Page Include="Resources\Language\en_US.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
-    <Page Include="Resources\Language\zh_CN.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
     <Page Include="Pages\PageDownload\PageDownloadForge.xaml">
     <Page Include="Pages\PageDownload\PageDownloadForge.xaml">
       <SubType>Designer</SubType>
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
       <Generator>MSBuild:Compile</Generator>

+ 4 - 7
Plain Craft Launcher 2/Resources/Custom.xaml

@@ -16,9 +16,9 @@
 
 
 <local:MyCard Title="卡片、提示条" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
 <local:MyCard Title="卡片、提示条" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
     <StackPanel Margin="25,40,23,15">
     <StackPanel Margin="25,40,23,15">
-        <local:MyHint Text="local:MyHint 代表提示条,它默认是警告样式。" />
-        <local:MyHint Margin="0,8,0,2" IsWarn="False"
-                    Text="将提示条的 IsWarn 属性改为 False 即可改为提示样式。&#xA;使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
+        <local:MyHint Text="local:MyHint 代表提示条。" />
+        <local:MyHint Margin="0,8,0,2" Theme="Blue"
+                    Text="将提示条的 Theme 属性改为 Blue、Yellow 或 Red 即可修改配色。&#xA;使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
         <TextBlock TextWrapping="Wrap" Margin="0,6,0,0"
         <TextBlock TextWrapping="Wrap" Margin="0,6,0,0"
                     Text="卡片(local:MyCard)的 Title 属性决定了它的标题。&#xA;为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
                     Text="卡片(local:MyCard)的 Title 属性决定了它的标题。&#xA;为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
     </StackPanel>
     </StackPanel>
@@ -242,7 +242,6 @@
     <StackPanel Margin="25,40,23,15">
     <StackPanel Margin="25,40,23,15">
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
                     Text="在花括号 {} 中写入特定内容,PCL 会在加载时对其进行替换。&#xa;例如,path 会被替换为 PCL 可执行文件所在文件夹({path}),用于在 EventData 中指定特定文件,或是加载图片。" />
                     Text="在花括号 {} 中写入特定内容,PCL 会在加载时对其进行替换。&#xa;例如,path 会被替换为 PCL 可执行文件所在文件夹({path}),用于在 EventData 中指定特定文件,或是加载图片。" />
-        <local:MyHint Margin="0,6,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
                     Text="你也可以使用替换标记来获取随机内容:cave 会被替换为一条随机的回声洞内容,hint 则是 “你知道吗” 的内容。" />
                     Text="你也可以使用替换标记来获取随机内容:cave 会被替换为一条随机的回声洞内容,hint 则是 “你知道吗” 的内容。" />
         <TextBlock TextWrapping="Wrap" Margin="10,6,0,5" Foreground="{DynamicResource ColorBrush3}"
         <TextBlock TextWrapping="Wrap" Margin="10,6,0,5" Foreground="{DynamicResource ColorBrush3}"
@@ -275,7 +274,6 @@
 
 
 <local:MyCard Title="进阶:图标按钮" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
 <local:MyCard Title="进阶:图标按钮" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
     <StackPanel Margin="25,40,23,15">
     <StackPanel Margin="25,40,23,15">
-        <local:MyHint Margin="0,0,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
                     Text="MyIconTextButton 是一种带有自定义矢量图标的按钮变体,它同样支持 EventType 与 EventData 属性。&#xa;通过设置 Logo 属性来控制它的图标,设置 LogoScale 属性还可以调整图标的缩放比例。" />
                     Text="MyIconTextButton 是一种带有自定义矢量图标的按钮变体,它同样支持 EventType 与 EventData 属性。&#xa;通过设置 Logo 属性来控制它的图标,设置 LogoScale 属性还可以调整图标的缩放比例。" />
         <local:MyIconTextButton Margin="0,4,0,8" Height="35" HorizontalAlignment="Center"
         <local:MyIconTextButton Margin="0,4,0,8" Height="35" HorizontalAlignment="Center"
@@ -301,7 +299,6 @@
 
 
 <local:MyCard Title="进阶:联网主页" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
 <local:MyCard Title="进阶:联网主页" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
     <StackPanel Margin="25,40,23,15">
     <StackPanel Margin="25,40,23,15">
-        <local:MyHint Margin="0,0,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
         <TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
                     Text="如果你在尝试制作联网更新的主页,可以查看下方的 GitHub 讨论页。&#xa;你可以根据其中的介绍为主页添加版本号检查以节省流量,也可以通过检查 Referer 和 User Agent 来确定对方的 PCL 版本。" />
                     Text="如果你在尝试制作联网更新的主页,可以查看下方的 GitHub 讨论页。&#xa;你可以根据其中的介绍为主页添加版本号检查以节省流量,也可以通过检查 Referer 和 User Agent 来确定对方的 PCL 版本。" />
         <local:MyButton Margin="0,0,0,8" Height="35" HorizontalAlignment="Center" Padding="20,0,20,0"
         <local:MyButton Margin="0,0,0,8" Height="35" HorizontalAlignment="Center" Padding="20,0,20,0"
@@ -343,7 +340,7 @@ local:MyCard(卡片):
 
 
 local:MyHint(提示条):
 local:MyHint(提示条):
  - Text:设置显示的文本(&#xA; 代表换行)
  - Text:设置显示的文本(&#xA; 代表换行)
- - IsWarn:设置为 True 代表警告样式,False 代表提示样式
+ - Theme:设置颜色主题(Blue、Yellow 或 Red)
 
 
 local:MyButton(按钮):
 local:MyButton(按钮):
  - Text:设置显示的文本
  - Text:设置显示的文本

BIN
Plain Craft Launcher 2/Resources/Help.zip


+ 0 - 10
Plain Craft Launcher 2/Resources/Language/en_US.xaml

@@ -1,10 +0,0 @@
-<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:s="clr-namespace:System;assembly=mscorlib">
-
-    <s:String x:Key="LangTitleOther">More</s:String>
-    <s:String x:Key="LangTitleDownload">Download</s:String>
-    <s:String x:Key="LangTitleHome">Launch</s:String>
-    <s:String x:Key="LangTitleSetup">Setting</s:String>
-
-</ResourceDictionary>

+ 0 - 10
Plain Craft Launcher 2/Resources/Language/zh_CN.xaml

@@ -1,10 +0,0 @@
-<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:s="clr-namespace:System;assembly=mscorlib">
-
-    <s:String x:Key="LangTitleOther">更多</s:String>
-    <s:String x:Key="LangTitleDownload">下载</s:String>
-    <s:String x:Key="LangTitleHome"> 启动</s:String>
-    <s:String x:Key="LangTitleSetup">设置</s:String>
-
-</ResourceDictionary>

Fichier diff supprimé car celui-ci est trop grand
+ 129 - 129
Plain Craft Launcher 2/Resources/ModData.txt


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff