diff --git a/Plain Craft Launcher 2/Application.xaml.vb b/Plain Craft Launcher 2/Application.xaml.vb
index db86a37..cdde3cd 100644
--- a/Plain Craft Launcher 2/Application.xaml.vb
+++ b/Plain Craft Launcher 2/Application.xaml.vb
@@ -78,7 +78,6 @@ Public Class Application
End If
End Try
Directory.CreateDirectory(PathTemp & "Cache")
- Directory.CreateDirectory(PathTemp & "Download")
Directory.CreateDirectory(PathAppdata)
'检测单例
#If Not DEBUG Then
@@ -124,9 +123,9 @@ WaitRetry:
'添加日志
Log($"[Start] 程序版本:{VersionDisplayName} ({VersionCode}{If(CommitHash = "", "", $",#{CommitHash}")})")
#If RELEASE Then
- Log($"[Start] 识别码:{UniqueAddress}{If(ThemeCheckOne(9), ",正式版", "")}")
+ Log($"[Start] 识别码:{Identify}{If(ThemeCheckOne(9), ",正式版", "")}")
#Else
- Log($"[Start] 识别码:{UniqueAddress}{If(ThemeCheckOne(9), ",已解锁反馈主题", "")}")
+ Log($"[Start] 识别码:{Identify}{If(ThemeCheckOne(9), ",已解锁反馈主题", "")}")
#End If
Log($"[Start] 程序路径:{PathWithName}")
Log($"[Start] 系统编码:{Encoding.Default.HeaderName} ({Encoding.Default.CodePage}, GBK={IsGBKEncoding})")
diff --git a/Plain Craft Launcher 2/Controls/IMyRadio.vb b/Plain Craft Launcher 2/Controls/Behaviors/IMyRadio.vb
similarity index 100%
rename from Plain Craft Launcher 2/Controls/IMyRadio.vb
rename to Plain Craft Launcher 2/Controls/Behaviors/IMyRadio.vb
diff --git a/Plain Craft Launcher 2/Controls/Interfaces.vb b/Plain Craft Launcher 2/Controls/Behaviors/Interfaces.vb
similarity index 100%
rename from Plain Craft Launcher 2/Controls/Interfaces.vb
rename to Plain Craft Launcher 2/Controls/Behaviors/Interfaces.vb
diff --git a/Plain Craft Launcher 2/Controls/MyButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyButton.xaml.vb
index 2eeaa05..992673e 100644
--- a/Plain Craft Launcher 2/Controls/MyButton.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyButton.xaml.vb
@@ -140,51 +140,14 @@ Public Class MyButton
End Try
End Sub
- '实现自定义事件
+ '鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
+ Private IsMouseDown As Boolean = False
Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
If Not IsMouseDown Then Return
Log("[Control] 按下按钮:" & Text)
RaiseEvent Click(sender, e)
- If Not String.IsNullOrEmpty(Tag) Then
- If Tag.ToString.StartsWithF("链接-") OrElse Tag.ToString.StartsWithF("启动-") Then
- Hint("主页自定义按钮语法已更新,且不再兼容老版本语法,请查看新的自定义示例!")
- End If
- End If
- ModEvent.ProcessCustomEvents(EventType, EventData, _CustomEvents)
+ RaiseCustomEvent() '自定义事件
End Sub
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyButton), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyButton), New PropertyMetadata(Nothing))
- Public Property CustomEvents As CustomEventCollection
- Get
- If _CustomEvents Is Nothing Then
- _CustomEvents = New CustomEventCollection
- End If
- Return _CustomEvents
- End Get
- Set(value As CustomEventCollection)
- _CustomEvents = value
- End Set
- End Property
- Private _CustomEvents As CustomEventCollection = Nothing
-
- '鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
- Private IsMouseDown As Boolean = False
Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
IsMouseDown = True
Focus()
diff --git a/Plain Craft Launcher 2/Controls/MyCard.vb b/Plain Craft Launcher 2/Controls/MyCard.vb
index 0274be0..b84cae2 100644
--- a/Plain Craft Launcher 2/Controls/MyCard.vb
+++ b/Plain Craft Launcher 2/Controls/MyCard.vb
@@ -132,7 +132,9 @@
For Each Data As Object In Stack.Tag
Select Case Type
Case 0
- Stack.Children.Add(PageSelectRight.McVersionListItem(Data))
+ Dim VersionItem As MyListItem = CType(Data, McVersion).ToListItem
+ VersionItem.ContentHandler = AddressOf PageSelectRight.McVersionListContent
+ Stack.Children.Add(VersionItem)
Case 2
Stack.Children.Add(McDownloadListItem(Data, AddressOf McDownloadMenuSave, True))
Case 3
@@ -309,9 +311,6 @@
End Set
End Property
Private _IsSwapped As Boolean = False
- '''
- ''' 是否已被折叠。(已过时,请使用 IsSwapped)
- '''
Public Property IsSwaped As Boolean
Get
@@ -325,37 +324,45 @@
Sub(sender, e) If sender IsNot Nothing AndAlso TypeOf sender Is MyCard Then CType(sender, MyCard).IsSwapped = CType(e.NewValue, Boolean)))
Public Property SwapLogoRight As Boolean = False
- Private IsMouseDown As Boolean = False
+ Private IsSwapMouseDown As Boolean = False '用于触发卡片展开/折叠的 MouseDown
+ Private IsCustomMouseDown As Boolean = False '用于触发自定义事件的 MouseDown
Public Event PreviewSwap(sender As Object, e As RouteEventArgs)
Public Event Swap(sender As Object, e As RouteEventArgs)
Public Const SwapedHeight As Integer = 40
Private Sub MyCard_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
Dim Pos As Double = Mouse.GetPosition(Me).Y
+ If Not IsSwapped AndAlso
+ (Pos > If(IsSwapped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Return
+ IsCustomMouseDown = True
If Not IsSwapped AndAlso
(SwapControl Is Nothing OrElse Pos > If(IsSwapped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Return '检测点击位置;或已经不在可视树上的误判
- IsMouseDown = True
+ IsSwapMouseDown = True
End Sub
- Private Sub MyCard_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
- If Not IsMouseDown Then Return
- IsMouseDown = False
+ Private Sub MyCard_MouseLeftButtonUp() Handles Me.MouseLeftButtonUp
+ If Not IsCustomMouseDown Then Return
+ IsCustomMouseDown = False
+ RaiseCustomEvent() '触发自定义事件
+
+ If Not IsSwapMouseDown Then Return
+ IsSwapMouseDown = False
Dim Pos As Double = Mouse.GetPosition(Me).Y
If Not IsSwapped AndAlso
(SwapControl Is Nothing OrElse Pos > If(IsSwapped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Return '检测点击位置;或已经不在可视树上的误判
- Dim ee = New RouteEventArgs(True)
- RaiseEvent PreviewSwap(Me, ee)
- If ee.Handled Then
- IsMouseDown = False
+ Dim e = New RouteEventArgs(True)
+ RaiseEvent PreviewSwap(Me, e)
+ If e.Handled Then
+ IsSwapMouseDown = False
Return
End If
IsSwapped = Not IsSwapped
Log("[Control] " & If(IsSwapped, "折叠卡片", "展开卡片") & If(Title Is Nothing, "", ":" & Title))
- RaiseEvent Swap(Me, ee)
+ RaiseEvent Swap(Me, e)
End Sub
Private Sub MyCard_MouseLeave_Swap(sender As Object, e As MouseEventArgs) Handles Me.MouseLeave
- IsMouseDown = False
+ IsSwapMouseDown = False
End Sub
#End Region
diff --git a/Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb b/Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb
index a0e8c9c..3703419 100644
--- a/Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb
@@ -12,9 +12,6 @@ Public Class MyCheckBox
''' 是否为用户手动改变的勾选状态。
Public Event Change(sender As Object, user As Boolean)
Public Event PreviewChange(sender As Object, e As RouteEventArgs)
- Public Sub RaiseChange()
- RaiseEvent Change(Me, False)
- End Sub '使外部程序引发本控件的 Change 事件
'自定义属性
Public Property Checked As Boolean
@@ -59,6 +56,7 @@ Public Class MyCheckBox
'更改动画
SyncUI()
+ RaiseCustomEvent()
Catch ex As Exception
Log(ex, "设置 Checked 失败")
End Try
diff --git a/Plain Craft Launcher 2/Controls/MyComboBox.vb b/Plain Craft Launcher 2/Controls/MyComboBox.vb
index 874b48a..69f7ae2 100644
--- a/Plain Craft Launcher 2/Controls/MyComboBox.vb
+++ b/Plain Craft Launcher 2/Controls/MyComboBox.vb
@@ -117,15 +117,14 @@
Private IsTextChanging As Boolean = False
Private Sub MyComboBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
If IsTextChanging OrElse Not IsEditable Then Return
- If SelectedItem IsNot Nothing AndAlso Text <> SelectedItem.ToString Then
- Dim RawText As String = Text
- Dim RawSelectionStart As Integer = TextBox.SelectionStart
- IsTextChanging = True
- SelectedItem = Nothing
- Text = RawText
- TextBox.SelectionStart = RawSelectionStart
- IsTextChanging = False
- End If
+ If SelectedItem Is Nothing OrElse Text = SelectedItem.ToString Then Return
+ Dim RawText As String = Text
+ Dim RawSelectionStart As Integer = TextBox.SelectionStart
+ IsTextChanging = True
+ SelectedItem = Nothing
+ Text = RawText
+ TextBox.SelectionStart = RawSelectionStart
+ IsTextChanging = False
End Sub
Public ReadOnly Property ContentPresenter As ContentPresenter
@@ -134,4 +133,8 @@
End Get
End Property
+ Private Sub MyComboBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles Me.SelectionChanged
+ If IsLoaded AndAlso AniControlEnabled = 0 Then RaiseCustomEvent()
+ End Sub
+
End Class
diff --git a/Plain Craft Launcher 2/Controls/MyExtraButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyExtraButton.xaml.vb
index 0bb1b3a..6f90827 100644
--- a/Plain Craft Launcher 2/Controls/MyExtraButton.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyExtraButton.xaml.vb
@@ -53,25 +53,26 @@
Set(value As Boolean)
If _Show = value Then Return
_Show = value
- RunInUi(Sub()
- If value Then
- '有了
- Visibility = Visibility.Visible
- AniStart({
- AaScaleTransform(Me, 0.3 - CType(RenderTransform, ScaleTransform).ScaleX, 500, 60, New AniEaseOutFluent(AniEasePower.Weak)),
- AaScaleTransform(Me, 0.7, 500, 60, New AniEaseOutBack(AniEasePower.Weak)),
- AaHeight(Me, 50 - Height, 200,, New AniEaseOutFluent(AniEasePower.Weak))
- }, "MyExtraButton MainScale " & Uuid)
- Else
- '没了
- AniStart({
- AaScaleTransform(Me, -CType(RenderTransform, ScaleTransform).ScaleX, 100,, New AniEaseInFluent(AniEasePower.Weak)),
- AaHeight(Me, -Height, 400, 100, New AniEaseOutFluent()),
- AaCode(Sub() Visibility = Visibility.Collapsed,, True)
- }, "MyExtraButton MainScale " & Uuid)
- End If
- IsHitTestVisible = value '防止缩放动画中依然可以点进去
- End Sub)
+ RunInUi(
+ Sub()
+ If value Then
+ '有了
+ Visibility = Visibility.Visible
+ AniStart({
+ AaScaleTransform(Me, 0.3 - CType(RenderTransform, ScaleTransform).ScaleX, 500, 60, New AniEaseOutFluent(AniEasePower.Weak)),
+ AaScaleTransform(Me, 0.7, 500, 60, New AniEaseOutBack(AniEasePower.Weak)),
+ AaHeight(Me, 50 - Height, 200,, New AniEaseOutFluent(AniEasePower.Weak))
+ }, "MyExtraButton MainScale " & Uuid)
+ Else
+ '没了
+ AniStart({
+ AaScaleTransform(Me, -CType(RenderTransform, ScaleTransform).ScaleX, 100,, New AniEaseInFluent(AniEasePower.Weak)),
+ AaHeight(Me, -Height, 400, 100, New AniEaseOutFluent()),
+ AaCode(Sub() Visibility = Visibility.Collapsed,, True)
+ }, "MyExtraButton MainScale " & Uuid)
+ End If
+ IsHitTestVisible = value '防止缩放动画中依然可以点进去
+ End Sub)
End Set
End Property
Public Delegate Function ShowCheckDelegate() As Boolean
@@ -137,6 +138,7 @@
AaScaleTransform(PanScale, 1 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 300,, New AniEaseOutBack)
}, "MyExtraButton Scale " & Uuid)
End If
+ If IsLeftMouseHeld Then RaiseCustomEvent()
IsLeftMouseHeld = False
RefreshColor() '直接刷新颜色以判断是否已触发 MouseLeave
End Sub
@@ -199,16 +201,17 @@
''' 发出一圈波浪效果提示。
'''
Public Sub Ribble()
- RunInUi(Sub()
- Dim Shape As New Border With {.CornerRadius = New CornerRadius(1000), .BorderThickness = New Thickness(0.001), .Opacity = 0.5, .RenderTransformOrigin = New Point(0.5, 0.5), .RenderTransform = New ScaleTransform()}
- Shape.SetResourceReference(Border.BackgroundProperty, "ColorBrush5")
- PanScale.Children.Insert(0, Shape)
- AniStart({
- AaScaleTransform(Shape, 13, 1000, Ease:=New AniEaseInoutFluent(AniEasePower.Strong, 0.3)),
- AaOpacity(Shape, -Shape.Opacity, 1000),
- AaCode(Sub() PanScale.Children.Remove(Shape), After:=True)
- }, "ExtraButton Ribble " & GetUuid())
- End Sub)
+ RunInUi(
+ Sub()
+ Dim Shape As New Border With {.CornerRadius = New CornerRadius(1000), .BorderThickness = New Thickness(0.001), .Opacity = 0.5, .RenderTransformOrigin = New Point(0.5, 0.5), .RenderTransform = New ScaleTransform()}
+ Shape.SetResourceReference(Border.BackgroundProperty, "ColorBrush5")
+ PanScale.Children.Insert(0, Shape)
+ AniStart({
+ AaScaleTransform(Shape, 13, 1000, Ease:=New AniEaseInoutFluent(AniEasePower.Strong, 0.3)),
+ AaOpacity(Shape, -Shape.Opacity, 1000),
+ AaCode(Sub() PanScale.Children.Remove(Shape), After:=True)
+ }, "ExtraButton Ribble " & GetUuid())
+ End Sub)
End Sub
End Class
diff --git a/Plain Craft Launcher 2/Controls/MyExtraTextButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyExtraTextButton.xaml.vb
index 9784cd0..266ba47 100644
--- a/Plain Craft Launcher 2/Controls/MyExtraTextButton.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyExtraTextButton.xaml.vb
@@ -81,12 +81,12 @@ Public Class MyExtraTextButton
'触发点击事件
Private Sub Button_LeftMouseUp(sender As Object, e As MouseButtonEventArgs) Handles PanClick.MouseLeftButtonUp
- If IsLeftMouseHeld Then
- Log("[Control] 按下附加图标按钮:" & Text)
- RaiseEvent Click(sender, e)
- e.Handled = True
- Button_LeftMouseUp()
- End If
+ If Not IsLeftMouseHeld Then Return
+ Log("[Control] 按下附加图标按钮:" & Text)
+ RaiseEvent Click(sender, e)
+ e.Handled = True
+ RaiseCustomEvent()
+ Button_LeftMouseUp()
End Sub
'鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
diff --git a/Plain Craft Launcher 2/Controls/MyHint.xaml.vb b/Plain Craft Launcher 2/Controls/MyHint.xaml.vb
index dba944a..9498b37 100644
--- a/Plain Craft Launcher 2/Controls/MyHint.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyHint.xaml.vb
@@ -113,7 +113,7 @@ Public Class MyHint
IsMouseDown = False
Log("[Control] 按下提示条" & If(String.IsNullOrEmpty(Name), "", ":" & Name))
e.Handled = True
- ModEvent.ProcessCustomEvents(EventType, EventData, _CustomEvents)
+ RaiseCustomEvent() '自定义事件
End Sub
Private Sub MyHint_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
IsMouseDown = True
@@ -121,36 +121,6 @@ Public Class MyHint
Private Sub MyHint_MouseLeave() Handles Me.MouseLeave
IsMouseDown = False
End Sub
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyHint), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyHint), New PropertyMetadata(Nothing))
- Public Property CustomEvents As CustomEventCollection
- Get
- If _CustomEvents Is Nothing Then
- _CustomEvents = New CustomEventCollection
- End If
- Return _CustomEvents
- End Get
- Set(value As CustomEventCollection)
- _CustomEvents = value
- End Set
- End Property
- Private _CustomEvents As CustomEventCollection = Nothing
End Class
Partial Public Module ModAnimation
diff --git a/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb
index d060e88..5da1eaf 100644
--- a/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyIconButton.xaml.vb
@@ -48,48 +48,16 @@
End Set
End Property
- '触发点击事件
+ '鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
+ Private IsMouseDown As Boolean = False
Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
If Not IsMouseDown Then Return
Log("[Control] 按下图标按钮" & If(String.IsNullOrEmpty(Name), "", ":" & Name))
RaiseEvent Click(sender, e)
e.Handled = True
Button_MouseUp()
- ModEvent.ProcessCustomEvents(EventType, EventData, _CustomEvents)
+ RaiseCustomEvent() '自定义事件
End Sub
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyIconButton), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyIconButton), New PropertyMetadata(Nothing))
- Public Property CustomEvents As CustomEventCollection
- Get
- If _CustomEvents Is Nothing Then
- _CustomEvents = New CustomEventCollection
- End If
- Return _CustomEvents
- End Get
- Set(value As CustomEventCollection)
- _CustomEvents = value
- End Set
- End Property
- Private _CustomEvents As CustomEventCollection = Nothing
-
- '鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
- Private IsMouseDown As Boolean = False
Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
IsMouseDown = True
Focus()
@@ -114,7 +82,6 @@
RefreshAnim() '直接刷新颜色以判断是否已触发 MouseLeave
End Sub
- '自定义事件
'务必放在 IsMouseDown 更新之后
Private Const AnimationColorIn As Integer = 120
Private Const AnimationColorOut As Integer = 150
diff --git a/Plain Craft Launcher 2/Controls/MyIconTextButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyIconTextButton.xaml.vb
index 1fe5557..dd5ed21 100644
--- a/Plain Craft Launcher 2/Controls/MyIconTextButton.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyIconTextButton.xaml.vb
@@ -8,9 +8,6 @@ Public Class MyIconTextButton
Public Uuid As Integer = GetUuid()
Public Event Check(sender As Object, raiseByMouse As Boolean)
Public Event Change(sender As Object, raiseByMouse As Boolean)
- Public Sub RaiseChange()
- RaiseEvent Change(Me, False)
- End Sub '使外部程序可以引发本控件的 Change 事件
'自定义属性
@@ -76,7 +73,7 @@ Public Class MyIconTextButton
Log("[Control] 按下带图标按钮:" & Text)
IsMouseDown = False
RaiseEvent Click(Me, New RouteEventArgs(True))
- ModEvent.ProcessCustomEvents(EventType, EventData, _CustomEvents)
+ RaiseCustomEvent() '自定义事件
RefreshColor()
End Sub
Private Sub MyIconTextButton_MouseDown() Handles Me.MouseLeftButtonDown
@@ -87,36 +84,6 @@ Public Class MyIconTextButton
IsMouseDown = False
RefreshColor()
End Sub
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyIconTextButton), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyIconTextButton), New PropertyMetadata(Nothing))
- Public Property CustomEvents As CustomEventCollection
- Get
- If _CustomEvents Is Nothing Then
- _CustomEvents = New CustomEventCollection
- End If
- Return _CustomEvents
- End Get
- Set(value As CustomEventCollection)
- _CustomEvents = value
- End Set
- End Property
- Private _CustomEvents As CustomEventCollection = Nothing
'动画
diff --git a/Plain Craft Launcher 2/Controls/MyImage.vb b/Plain Craft Launcher 2/Controls/MyImage.vb
index 8f6de5b..d4c5cf1 100644
--- a/Plain Craft Launcher 2/Controls/MyImage.vb
+++ b/Plain Craft Launcher 2/Controls/MyImage.vb
@@ -46,7 +46,7 @@
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString())))
'''
- ''' 若 Source 是一个网络图片,该地址将作为第二下载源。
+ ''' 若 Source 是一个网络图片,该地址将作为第二图片源。
'''
Public Property FallbackSource As String
Get
@@ -120,11 +120,12 @@
End If
RunInNewThread(
Sub()
+ Dim IsLocalFallback As Boolean = FallbackSource IsNot Nothing AndAlso Not FallbackSource.StartsWithF("http")
Try
'下载
ActualSource = LoadingSource '显示加载中的占位图片
NetDownloadByLoader(
- If(String.IsNullOrEmpty(FallbackSource), {Source}, {Source, FallbackSource}),
+ If(String.IsNullOrEmpty(FallbackSource) OrElse IsLocalFallback, {Source}, {Source, FallbackSource}),
TempPath, SimulateBrowserHeaders:=True)
If EnableCache Then
'保存缓存并显示
@@ -139,7 +140,19 @@
If TempPath IsNot Nothing Then File.Delete(TempPath)
Catch
End Try
- Log(ex, $"下载图片失败", LogLevel.Hint)
+ '加载本地备用图片
+ If IsLocalFallback Then
+ Try
+ RunInUiWait(Sub() ActualSource = FallbackSource)
+ Log(ex, $"下载图片失败,使用本地备用图片({Source})")
+ Return
+ Catch exx As Exception
+ Log(ex, $"下载图片失败({Source})", LogLevel.Hint)
+ Log(exx, $"加载备用图片失败({FallbackSource})", LogLevel.Hint)
+ End Try
+ Else
+ Log(ex, $"下载图片失败({Source},备用:{FallbackSource})", LogLevel.Hint)
+ End If
End Try
End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal)
End Sub
diff --git a/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb b/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb
index 48c5d8e..cf462ec 100644
--- a/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb
@@ -506,8 +506,8 @@ Public Class MyListItem
RaiseEvent Click(sender, e)
If e.Handled Then Return
'触发自定义事件
- If Not String.IsNullOrEmpty(EventType) Then
- ModEvent.ProcessCustomEvents(EventType, EventData, _CustomEvents)
+ If CustomEventService.GetEventType(sender) <> CustomEvent.EventType.None Then
+ RaiseCustomEvent()
e.Handled = True
End If
If e.Handled Then Return
@@ -537,38 +537,6 @@ Public Class MyListItem
If ButtonStack IsNot Nothing Then ButtonStack.IsHitTestVisible = True
End Sub
- '实现自定义事件
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyListItem), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyListItem), New PropertyMetadata(Nothing))
- Public Property CustomEvents As CustomEventCollection
- Get
- If _CustomEvents Is Nothing Then
- _CustomEvents = New CustomEventCollection
- End If
- Return _CustomEvents
- End Get
- Set(value As CustomEventCollection)
- _CustomEvents = value
- End Set
- End Property
- Private _CustomEvents As CustomEventCollection = Nothing
-
#End Region
Private StateLast As String
@@ -669,13 +637,14 @@ Public Class MyListItem
SetResourceReference(ForegroundProperty, "ColorBrush1")
End If
ColumnPaddingRight.Width = New GridLength(MinPaddingRight)
- If EventType = "打开帮助" AndAlso Not (Title <> "" AndAlso Info <> "") Then '#3266
+ If CustomEventService.GetEventType(Me) = CustomEvent.EventType.打开帮助 AndAlso Not (Title <> "" AndAlso Info <> "") Then '#3266
Try
- Dim Unused = New HelpEntry(GetEventAbsoluteUrls(EventData, EventType)(0)).SetToListItem(Me)
+ Dim Entry As New HelpEntry(CustomEvent.GetAbsoluteUrls(CustomEventService.GetEventData(Me), CustomEventService.GetEventType(Me))(0))
+ Entry.SetToListItem(Me)
Catch ex As Exception
Log(ex, "设置帮助 MyListItem 失败", LogLevel.Msgbox)
- EventType = Nothing
- EventData = Nothing
+ CustomEventService.SetEventType(Me, CustomEvent.EventType.None)
+ CustomEventService.SetEventData(Me, "")
End Try
End If
End Sub
diff --git a/Plain Craft Launcher 2/Controls/MyMenuItem.vb b/Plain Craft Launcher 2/Controls/MyMenuItem.vb
index cc70ee6..4c22da3 100644
--- a/Plain Craft Launcher 2/Controls/MyMenuItem.vb
+++ b/Plain Craft Launcher 2/Controls/MyMenuItem.vb
@@ -54,4 +54,7 @@
End If
End Sub
+ Private Sub MyMenuItem_Click(sender As Object, e As RoutedEventArgs) Handles Me.Click
+ RaiseCustomEvent()
+ End Sub
End Class
diff --git a/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb b/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb
index 5dd839f..ba77d6f 100644
--- a/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb
@@ -93,6 +93,7 @@ Public Class MyRadioBox
If IsChanged Then
If Checked Then RaiseEvent Check(Me, New RouteEventArgs(user))
RaiseEvent Changed(Me, New RouteEventArgs(user))
+ RaiseCustomEvent()
End If
'更改动画
diff --git a/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb
index 4be05b8..2753034 100644
--- a/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb
@@ -7,10 +7,6 @@ Public Class MyRadioButton
Public Uuid As Integer = GetUuid()
Public Event Check(sender As Object, raiseByMouse As Boolean)
- Public Event Change(sender As Object, raiseByMouse As Boolean)
- Public Sub RaiseChange()
- RaiseEvent Change(Me, False)
- End Sub '使外部程序可以引发本控件的 Change 事件
'自定义属性
@@ -46,23 +42,22 @@ Public Class MyRadioButton
''' 手动设置 Checked 属性。
'''
''' 新的 Checked 属性。
- ''' 是否由用户引发。
+ ''' 是否由用户引发。
''' 是否执行动画。
- Public Sub SetChecked(value As Boolean, user As Boolean, anime As Boolean)
+ Public Sub SetChecked(value As Boolean, raiseByMouse As Boolean, anime As Boolean)
Try
'自定义属性基础
Dim IsChanged As Boolean = False
- If IsLoaded AndAlso Not value = _Checked Then RaiseEvent Change(Me, user)
- If Not value = _Checked Then
+ If _Checked <> value Then
_Checked = value
IsChanged = True
End If
'保证只有一个单选框选中
- If IsNothing(Parent) Then Return
+ If Parent Is Nothing Then Return
Dim RadioboxList As New List(Of MyRadioButton)
Dim CheckedCount As Integer = 0
'收集控件列表与选中个数
@@ -105,7 +100,8 @@ Public Class MyRadioButton
RefreshColor(Nothing, anime)
'触发事件
- If Checked Then RaiseEvent Check(Me, user)
+ If Checked Then RaiseEvent Check(Me, raiseByMouse)
+ RaiseCustomEvent()
Catch ex As Exception
Log(ex, "单选按钮勾选改变错误", LogLevel.Hint)
diff --git a/Plain Craft Launcher 2/Controls/MySearchBox.xaml.vb b/Plain Craft Launcher 2/Controls/MySearchBox.xaml.vb
index ee3bb15..a8fde05 100644
--- a/Plain Craft Launcher 2/Controls/MySearchBox.xaml.vb
+++ b/Plain Craft Launcher 2/Controls/MySearchBox.xaml.vb
@@ -39,4 +39,7 @@
TextBox.Focus()
End Sub
+ Private Sub MySearchBox_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
+ If e.Key = Key.Enter Then RaiseCustomEvent()
+ End Sub
End Class
diff --git a/Plain Craft Launcher 2/Controls/MyTextBox.vb b/Plain Craft Launcher 2/Controls/MyTextBox.vb
index e847a58..55a00b3 100644
--- a/Plain Craft Launcher 2/Controls/MyTextBox.vb
+++ b/Plain Craft Launcher 2/Controls/MyTextBox.vb
@@ -291,4 +291,8 @@
End If
End Sub
+ '在按下回车时触发自定义事件
+ Private Sub MyTextBox_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
+ If e.Key = Key.Enter Then RaiseCustomEvent()
+ End Sub
End Class
diff --git a/Plain Craft Launcher 2/Controls/MyTextButton.vb b/Plain Craft Launcher 2/Controls/MyTextButton.vb
index bea7021..4bde410 100644
--- a/Plain Craft Launcher 2/Controls/MyTextButton.vb
+++ b/Plain Craft Launcher 2/Controls/MyTextButton.vb
@@ -22,15 +22,15 @@
End Set
End Property
Public Shared ReadOnly TextProperty As DependencyProperty =
- DependencyProperty.Register("Text", GetType(String), GetType(MyTextButton), New PropertyMetadata("", Sub(sender As MyTextButton, e As DependencyPropertyChangedEventArgs)
- If Not e.OldValue = e.NewValue Then
- AniStart({
- AaOpacity(sender, -sender.Opacity, 50),
- AaCode(Sub() sender.Content = e.NewValue,, True),
- AaOpacity(sender, 1, 170)
- }, "MyTextButton Text " & sender.Uuid)
- End If
- End Sub))
+ DependencyProperty.Register("Text", GetType(String), GetType(MyTextButton), New PropertyMetadata("",
+ Sub(sender As MyTextButton, e As DependencyPropertyChangedEventArgs)
+ If e.OldValue = e.NewValue Then Return
+ AniStart({
+ AaOpacity(sender, -sender.Opacity, 50),
+ AaCode(Sub() sender.Content = e.NewValue,, True),
+ AaOpacity(sender, 1, 170)
+ }, "MyTextButton Text " & sender.Uuid)
+ End Sub))
'鼠标事件
@@ -43,13 +43,12 @@
IsMouseDown = False
End Sub
Private Sub MyTextButton_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
- If IsMouseDown Then
- IsMouseDown = False
- Log("[Control] 按下文本按钮:" & Text)
- RaiseEvent Click(Me, Nothing)
- ModEvent.ProcessCustomEvents(EventType, EventData, _CustomEvents)
- e.Handled = True
- End If
+ If Not IsMouseDown Then Return
+ IsMouseDown = False
+ Log("[Control] 按下文本按钮:" & Text)
+ RaiseEvent Click(Me, Nothing)
+ RaiseCustomEvent()
+ e.Handled = True
End Sub
'指向动画
@@ -85,38 +84,4 @@
End If
End Sub
- '实现自定义事件
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register(
- "EventType", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register(
- "EventData", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing))
- Public Property CustomEvents As CustomEventCollection
- Get
- If _CustomEvents Is Nothing Then
- _CustomEvents = New CustomEventCollection
- End If
- Return _CustomEvents
- End Get
- Set(value As CustomEventCollection)
- _CustomEvents = value
- End Set
- End Property
- Private _CustomEvents As CustomEventCollection = Nothing
-
End Class
diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb
index 7799e8f..7f1c0b1 100644
--- a/Plain Craft Launcher 2/FormMain.xaml.vb
+++ b/Plain Craft Launcher 2/FormMain.xaml.vb
@@ -104,6 +104,15 @@ Public Class FormMain
'3:BUG+ IMP* FEAT-
'2:BUG* IMP-
'1:BUG-
+ If LastVersion < 371 Then 'Snapshot 2.10.9
+ FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:如果版本设置了自定义描述,会在标题后面以淡灰色显示其版本号"))
+ FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "新增:支持为一个控件设置多个自定义事件"))
+ FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "新增:修改变量、弹出提示自定义事件"))
+ FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "新增:添加大量替换标记,允许在更多设置和 XAML 中使用更多替换标记"))
+ FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法安装 MMC 整合包"))
+ FeatureCount += 33
+ BugCount += 11
+ End If
If LastVersion < 370 Then 'Snapshot 2.10.8
If LastVersion >= 368 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:网络与下载稳定性优化"))
FeatureCount += 3
@@ -318,7 +327,7 @@ Public Class FormMain
FrmLaunchRight.PageState = MyPageRight.PageStates.ContentStay
'模式提醒
#If DEBUG Then
- Hint("[开发者模式] PCL 正以开发者模式运行,这可能会造成严重的性能下降,请务必立即向开发者反馈此问题!", HintType.Critical)
+ Hint("[开发者模式] PCL 正以开发者模式运行,这可能会造成严重的性能下降,请务必立即向开发者反馈此问题!", HintType.Red)
#End If
If ModeDebug Then Hint("[调试模式] PCL 正以调试模式运行,这可能会导致性能下降,若无必要请不要开启!")
'尽早执行的加载池
@@ -687,9 +696,9 @@ Public Class FormMain
If e.Key = Key.F12 Then
PageSetupUI.HiddenForceShow = Not PageSetupUI.HiddenForceShow
If PageSetupUI.HiddenForceShow Then
- Hint("功能隐藏设置已暂时关闭!", HintType.Finish)
+ Hint("功能隐藏设置已暂时关闭!", HintType.Green)
Else
- Hint("功能隐藏设置已重新开启!", HintType.Finish)
+ Hint("功能隐藏设置已重新开启!", HintType.Green)
End If
PageSetupUI.HiddenRefresh()
Return
@@ -785,12 +794,12 @@ Public Class FormMain
Dim AuthlibServer As String = Net.WebUtility.UrlDecode(Str.Substring("authlib-injector:yggdrasil-server:".Length))
Log("[System] Authlib 拖拽:" & AuthlibServer)
If Not String.IsNullOrEmpty(New ValidateHttp().Validate(AuthlibServer)) Then
- Hint($"输入的 Authlib 验证服务器不符合网址格式({AuthlibServer})!", HintType.Critical)
+ Hint($"输入的 Authlib 验证服务器不符合网址格式({AuthlibServer})!", HintType.Red)
Return
End If
Dim TargetVersion = If(PageCurrent = PageType.VersionSetup, PageVersionLeft.Version, McVersionCurrent)
If TargetVersion Is Nothing Then
- Hint("请先下载游戏,再设置第三方登录!", HintType.Critical)
+ Hint("请先下载游戏,再设置第三方登录!", HintType.Red)
Return
End If
If AuthlibServer = "https://littleskin.cn/api/yggdrasil" Then
@@ -837,7 +846,7 @@ Public Class FormMain
'获取文件并检查
Dim FilePathRaw = e.Data.GetData(DataFormats.FileDrop)
If FilePathRaw Is Nothing Then '#2690
- Hint("请将文件解压后再拖入!", HintType.Critical)
+ Hint("请将文件解压后再拖入!", HintType.Red)
Return
End If
e.Handled = True
@@ -855,10 +864,10 @@ Public Class FormMain
Log("[System] 接受文件拖拽:" & FilePath & If(FilePathList.Any, $" 等 {FilePathList.Count} 个文件", ""), LogLevel.Developer)
'基础检查
If Directory.Exists(FilePathList.First) AndAlso Not File.Exists(FilePathList.First) Then
- Hint("请拖入一个文件,而非文件夹!", HintType.Critical)
+ Hint("请拖入一个文件,而非文件夹!", HintType.Red)
Return
ElseIf Not File.Exists(FilePathList.First) Then
- Hint("拖入的文件不存在:" & FilePathList.First, HintType.Critical)
+ Hint("拖入的文件不存在:" & FilePathList.First, HintType.Red)
Return
End If
'多文件拖拽
@@ -866,7 +875,7 @@ Public Class FormMain
'必须要求全部为 jar 文件
For Each File In FilePathList
If Not {"jar", "litemod", "disabled", "old"}.Contains(File.AfterLast(".").ToLower) Then
- Hint("一次请只拖入一个文件!", HintType.Critical)
+ Hint("一次请只拖入一个文件!", HintType.Red)
Return
End If
Next
@@ -885,7 +894,7 @@ Public Class FormMain
Sub()
Setup.Set("UiCustomType", 1)
FrmLaunchRight.ForceRefresh()
- Hint("已加载主页自定义文件!", HintType.Finish)
+ Hint("已加载主页自定义文件!", HintType.Green)
End Sub)
Return
End If
@@ -995,9 +1004,9 @@ Public Class FormMain
#Region "切换页面"
'页面种类与属性
- '注意,这一枚举在 “切换页面” EventType 中调用,应视作公开 API 的一部分
'''
''' 页面种类。
+ ''' 该枚举在自定义事件中使用,是公开 API 的一部分。
'''
Public Enum PageType
'''
@@ -1043,6 +1052,7 @@ Public Class FormMain
End Enum
'''
''' 次要页面种类。其数值必须与 StackPanel 中的下标一致。
+ ''' 该枚举在自定义事件中使用,是公开 API 的一部分。
'''
Public Enum PageSubType
[Default] = 0
@@ -1485,7 +1495,7 @@ Public Class FormMain
'投降
Public Sub AprilGiveup() Handles BtnExtraApril.Click
If IsAprilEnabled AndAlso Not IsAprilGiveup Then
- Hint("=D", HintType.Finish)
+ Hint("=D", HintType.Green)
IsAprilGiveup = True
FrmLaunchLeft.AprilScaleTrans.ScaleX = 1
FrmLaunchLeft.AprilScaleTrans.ScaleY = 1
@@ -1503,7 +1513,7 @@ Public Class FormMain
For Each Watcher In McWatcherList
Watcher.Kill()
Next
- Hint("已关闭运行中的 Minecraft!", HintType.Finish)
+ Hint("已关闭运行中的 Minecraft!", HintType.Green)
Catch ex As Exception
Log(ex, "强制关闭所有 Minecraft 失败", LogLevel.Feedback)
End Try
diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb
index 8d026e1..3ad35f4 100644
--- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb
+++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb
@@ -13,13 +13,13 @@ Public Module ModBase
#Region "声明"
'下列版本信息由更新器自动修改
- Public Const VersionBaseName As String = "2.10.8" '不含分支前缀的显示用版本名
- Public Const VersionStandardCode As String = "2.10.8." & VersionBranchCode '标准格式的四段式版本号
+ Public Const VersionBaseName As String = "2.10.9" '不含分支前缀的显示用版本名
+ Public Const VersionStandardCode As String = "2.10.9." & VersionBranchCode '标准格式的四段式版本号
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
#If BETA Then
- Public Const VersionCode As Integer = 367 'Release
+ Public Const VersionCode As Integer = 369 'Release
#Else
- Public Const VersionCode As Integer = 370 'Snapshot
+ Public Const VersionCode As Integer = 371 'Snapshot
#End If
'自动生成的版本信息
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -69,7 +69,7 @@ Public Module ModBase
'''
''' 识别码。
'''
- Public UniqueAddress As String = SecretGetUniqueAddress()
+ Public Identify As String = SecretGetIdentify()
'''
''' 程序是否已结束。
'''
@@ -761,7 +761,6 @@ Public Module ModBase
If FilePath.Contains("\") Then FilePath = FilePath.Substring(FilePath.LastIndexOfF("\") + 1)
Dim length As Integer = FilePath.Length
If length = 0 Then Throw New Exception("不包含文件名:" & FilePath)
- If length > 250 Then Throw New PathTooLongException("文件名过长:" & FilePath)
Return FilePath
End Function
'''
@@ -1400,12 +1399,13 @@ RetryDir:
'''
''' 若路径长度大于指定值,则将长路径转换为短路径。
+ ''' 如果路径不存在,则返回原始路径。
'''
Public Function ShortenPath(LongPath As String) As String
If LongPath.Length <= 200 OrElse LongPath.StartsWithF("http", True) Then Return LongPath
If Not Directory.Exists(LongPath) AndAlso Not File.Exists(LongPath) Then Return LongPath
Dim ShortPath As New StringBuilder(260)
- GetShortPathName(LongPath, ShortPath, 260)
+ GetShortPathName(LongPath.Replace("/", "\"), ShortPath, 260) '第一个参数也会在调用后被修改,使用 Replace 后不会影响原始字符串
ShortenPath = ShortPath.ToString
If String.IsNullOrEmpty(ShortenPath) Then Return LongPath
End Function
@@ -1511,6 +1511,19 @@ RetryDir:
Return [Enum].GetName(EnumData.GetType, EnumData)
End Function
'''
+ ''' 将字符串转换为枚举类型,支持数字或原文两种格式,若为空字符串则返回 0。
+ ''' 若转换失败会抛出异常。
+ '''
+ Public Function ParseToEnum(Of T)(Str As String) As T
+ If String.IsNullOrEmpty(Str) Then
+ Return CType(0, Object)
+ ElseIf IsNumeric(Str) Then
+ Return CType(CInt(Str), Object)
+ Else
+ Return [Enum].Parse(GetType(T), Str, True)
+ End If
+ End Function
+ '''
''' 将文件大小转化为适合的文本形式,如“1.28 M”。
'''
''' 以字节为单位的大小表示。
@@ -2579,7 +2592,7 @@ Retry:
Log(ex, "可能由于剪贴板被其他程序占用,文本复制失败", LogLevel.Hint)
End If
End Try
- If ShowSuccessHint Then Hint("已成功复制!", HintType.Finish)
+ If ShowSuccessHint Then Hint("已成功复制!", HintType.Green)
End Sub)
End Sub
@@ -2716,6 +2729,11 @@ Retry:
''' 将 XML 转换为对应 UI 对象。
'''
Public Function GetObjectFromXML(Str As String) As Object
+ Str = Str. '兼容旧版自定义事件写法
+ Replace("EventType=""", "local:CustomEventService.EventType=""").
+ Replace("EventData=""", "local:CustomEventService.EventData=""").
+ Replace("Property=""EventType""", "Property=""local:CustomEventService.EventType""").
+ Replace("Property=""EventData""", "Property=""local:CustomEventService.EventData""")
Using Stream As New MemoryStream(Encoding.UTF8.GetBytes(Str))
'类型检查
Using Reader As New XamlXmlReader(Stream)
@@ -2831,7 +2849,7 @@ Retry:
File.Create(Path & "PCL\Log1.txt").Dispose()
Catch ex As IOException
IsInitSuccess = False
- Hint("可能同时开启了多个 PCL,程序可能会出现未知问题!", HintType.Critical)
+ Hint("可能同时开启了多个 PCL,程序可能会出现未知问题!", HintType.Red)
Log(ex, "日志初始化失败(疑似文件占用问题)")
Catch ex As Exception
IsInitSuccess = False
@@ -2884,6 +2902,7 @@ Retry:
'输出日志
Dim AppendText As String = $"[{GetTimeNow()}] <{If(Thread.CurrentThread.Name = "", "主线程", Thread.CurrentThread.Name)}> {Text}{vbCrLf}" '减轻同步锁占用
+ AppendText = FilterUserName(FilterAccessToken(AppendText, "*"), "*")
If ModeDebug Then
SyncLock LogListLock
LogList.Append(AppendText)
@@ -2903,16 +2922,16 @@ Retry:
Select Case Level
#If DEBUG Then
Case LogLevel.Developer
- Hint("[开发者模式] " & Text, HintType.Info, False)
+ Hint("[开发者模式] " & Text, HintType.Blue, False)
Case LogLevel.Debug
- Hint("[调试模式] " & Text, HintType.Info, False)
+ Hint("[调试模式] " & Text, HintType.Blue, False)
#Else
Case LogLevel.Developer
Case LogLevel.Debug
- If ModeDebug Then Hint("[调试模式] " & Text, HintType.Info, False)
+ If ModeDebug Then Hint("[调试模式] " & Text, HintType.Blue, False)
#End If
Case LogLevel.Hint
- Hint(Text, HintType.Critical, False)
+ Hint(Text, HintType.Red, False)
Case LogLevel.Msgbox
MyMsgBox(Text, Title, IsWarn:=True)
Case LogLevel.Feedback
@@ -2955,6 +2974,7 @@ Retry:
'输出日志
Dim AppendText As String = $"[{GetTimeNow()}] <{If(Thread.CurrentThread.Name = "", "主线程", Thread.CurrentThread.Name)}> {Desc}:{Ex.GetDetail(True)}{vbCrLf}" '减轻同步锁占用
+ AppendText = FilterUserName(FilterAccessToken(AppendText, "*"), "*")
If ModeDebug Then
SyncLock LogListLock
LogList.Append(AppendText)
@@ -2973,19 +2993,19 @@ Retry:
#If DEBUG Then
Case LogLevel.Developer
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
- Hint("[开发者模式] " & ExLine, HintType.Info, False)
+ Hint("[开发者模式] " & ExLine, HintType.Blue, False)
Case LogLevel.Debug
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
- Hint("[调试模式] " & ExLine, HintType.Info, False)
+ Hint("[调试模式] " & ExLine, HintType.Blue, False)
#Else
Case LogLevel.Developer
Case LogLevel.Debug
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
- If ModeDebug Then Hint("[调试模式] " & ExLine, HintType.Info, False)
+ If ModeDebug Then Hint("[调试模式] " & ExLine, HintType.Blue, False)
#End If
Case LogLevel.Hint
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
- Hint(ExLine, HintType.Critical, False)
+ Hint(ExLine, HintType.Red, False)
Case LogLevel.Msgbox
MyMsgBox(ExFull, Title, IsWarn:=True)
Case LogLevel.Feedback
diff --git a/Plain Craft Launcher 2/Modules/Base/ModNet.vb b/Plain Craft Launcher 2/Modules/Base/ModNet.vb
index 806da0b..e19c8b9 100644
--- a/Plain Craft Launcher 2/Modules/Base/ModNet.vb
+++ b/Plain Craft Launcher 2/Modules/Base/ModNet.vb
@@ -998,20 +998,18 @@ StartThread:
If ModeDebug AndAlso Response.RequestMessage.RequestUri.ToString <> Th.Source.Url Then Log($"[Download] {LocalName}:重定向至 {Response.RequestMessage.RequestUri}")
'文件大小校验
ContentLength = Response.Content.Headers.ContentLength.GetValueOrDefault(-1)
- If ContentLength = -1 Then
+ If ContentLength < 0 Then
If FileSize > 1 Then
If Th.DownloadStart = 0 Then
Log($"[Download] {LocalName}:文件大小未知,但已从其他下载源获取,不作处理")
Else
- Log($"[Download] {LocalName}:ContentLength 返回了 -1,无法确定是否支持分段下载,视作不支持")
+ Log($"[Download] {LocalName}:ContentLength 返回了 {ContentLength},无法确定是否支持分段下载,视作不支持")
GoTo NotSupportRange
End If
Else
FileSize = -1 : IsUnknownSize = True
Log($"[Download] {LocalName}:文件大小未知")
End If
- ElseIf ContentLength < 0 Then
- Throw New Exception("获取片大小失败,结果为 " & ContentLength & "。")
ElseIf Th.IsFirstThread Then
If Check IsNot Nothing Then
If ContentLength < Check.MinSize AndAlso Check.MinSize > 0 Then
@@ -1040,15 +1038,11 @@ StartThread:
ElseIf Th.DownloadStart > 0 AndAlso ContentLength = FileSize Then
NotSupportRange:
SyncLock LockSource
- If SourcesOnce.Contains(Th.Source) Then
- GoTo SourceBreak
- Else
- SourcesOnce.Add(Th.Source)
- End If
+ If SourcesOnce.Contains(Th.Source) Then GoTo SourceBreak
End SyncLock
- Throw New WebException($"该下载源不支持分段下载:Range 起始于 {Th.DownloadStart},预期 ContentLength 为 {FileSize - Th.DownloadStart},返回 ContentLength 为 {ContentLength},总文件大小 {FileSize}")
+ Throw New RangeNotSupportedException($"该下载源不支持分段下载:Range 起始于 {Th.DownloadStart},预期 ContentLength 为 {FileSize - Th.DownloadStart},返回 ContentLength 为 {ContentLength},总文件大小 {FileSize}")
ElseIf Not FileSize - Th.DownloadStart = ContentLength Then
- Throw New WebException($"获取到的分段大小不一致:Range 起始于 {Th.DownloadStart},预期 ContentLength 为 {FileSize - Th.DownloadStart},返回 ContentLength 为 {ContentLength},总文件大小 {FileSize}")
+ Throw New RangeNotSupportedException($"获取到的分段大小不一致:Range 起始于 {Th.DownloadStart},预期 ContentLength 为 {FileSize - Th.DownloadStart},返回 ContentLength 为 {ContentLength},总文件大小 {FileSize}")
End If
'Log($"[Download] {LocalName} {Info.Uuid}#:通过大小检查,文件大小 {FileSize},起始点 {Info.DownloadStart},ContentLength {ContentLength}")
Th.State = NetState.Get
@@ -1061,6 +1055,7 @@ NotSupportRange:
Cache = New MemoryStream
ResultStream = Cache
Else
+ Directory.CreateDirectory(PathTemp & "Download")
Th.Temp = $"{PathTemp}Download\{Uuid}_{Th.Uuid}_{RandomInteger(0, 999999)}.tmp"
ResultStream = New FileStream(Th.Temp, FileMode.Create, FileAccess.Write, FileShare.Read)
End If
@@ -1165,9 +1160,10 @@ SourceBreak:
Th.State = NetState.Error
Th.Source.Ex = ex
'根据情况判断,是否在多线程下禁用下载源(连续错误过多,或不支持断点续传)
- If IsMergeFailure OrElse
- ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse
- ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse ex.Message.Contains("获取到的分段大小不一致") OrElse
+ Dim IsRangeNotSupported As Boolean = TypeOf ex Is RangeNotSupportedException OrElse ex.Message.Contains("(416)")
+ If IsMergeFailure OrElse IsRangeNotSupported OrElse
+ ex.Message.Contains("(502)") OrElse ex.Message.Contains("(404)") OrElse
+ ex.Message.Contains("未能解析") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse
((ex.Message.Contains("(403)") OrElse ex.Message.Contains("(429)")) AndAlso Not Th.Source.Url.ContainsF("bmclapi")) OrElse 'BMCLAPI 的部分源在高频率请求下会返回 403/429,所以不应因此禁用下载源
(Th.Source.FailCount >= MathClamp(NetTaskThreadLimit, 5, 30) AndAlso DownloadDone < 1) OrElse Th.Source.FailCount > NetTaskThreadLimit + 2 Then
'当一个下载源有多个线程在下载时,只选择其中一个线程进行后续处理
@@ -1180,9 +1176,9 @@ SourceBreak:
End SyncLock
'……后续处理
If IsThisFail Then
- Log($"[Download] {LocalName}:下载源被禁用({Th.Source.Id}):{Th.Source.Url}")
+ Log($"[Download] {LocalName}:下载源被禁用({Th.Source.Id},Range 问题:{IsRangeNotSupported}):{Th.Source.Url}")
Log(ex, $"{If(SourcesOnce.FirstOrDefault?.SingleThread Is Nothing, "", "单线程")}下载源 {Th.Source.Id} 已被禁用",
- If(ex.Message.Contains("不支持分段下载") OrElse ex.Message.Contains("(404)") OrElse ex.Message.Contains("(416)"), LogLevel.Developer, LogLevel.Debug))
+ If(IsRangeNotSupported OrElse ex.Message.Contains("(404)"), LogLevel.Developer, LogLevel.Debug))
SyncLock LockSource
SourcesOnce.Remove(Th.Source)
End SyncLock
@@ -1191,9 +1187,10 @@ SourceBreak:
Fail(ex)
ElseIf HasAvailableSource() AndAlso Not IsMergeFailure Then
'当前源失败,但还有下载源:正常地继续执行
- ElseIf Not Retried AndAlso Sources.Count > 1 Then
+ ElseIf Not Retried Then
'合并失败或首次下载失败,未重试:将所有下载源重新标记为不允许断点续传的下载源,逐个重新尝试下载
- Hint($"{LocalName}:文件下载失败,正在自动重试……", If(ModeDebug, HintType.Critical, HintType.Info)) '在调试模式下给出红色提示
+ '若所有源均不支持 Range,也会走到这里重试
+ If Not IsRangeNotSupported Then Hint($"{LocalName}:文件下载失败,正在自动重试……", If(ModeDebug, HintType.Red, HintType.Blue)) '在调试模式下给出红色提示
Retried = True
SyncLock LockSource
SourcesOnce.Clear()
@@ -1388,6 +1385,12 @@ Retry:
End Sub
End Class
+ Private Class RangeNotSupportedException
+ Inherits WebException
+ Public Sub New(Message As String)
+ MyBase.New(Message)
+ End Sub
+ End Class
'''
''' 下载一系列文件的加载器。
'''
@@ -1890,7 +1893,6 @@ Retry:
Catch ex As Exception
Log(ex, "清理下载缓存失败")
End Try
- Directory.CreateDirectory(PathTemp & "Download")
End If
IsDownloadCacheCleared = True
End SyncLock
diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb
index bc11865..8b97b0f 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb
@@ -908,8 +908,7 @@ NextStack:
If File.Exists(OutputFile) Then
If FileEncoding Is Nothing Then FileEncoding = GetEncoding(ReadFileBytes(OutputFile))
Dim FileContent As String = ReadFile(OutputFile, FileEncoding)
- FileContent = FilterAccessToken(FileContent, If(FileName = "启动脚本.bat", "F", "*"))
- FileContent = FilterUserName(FileContent, "*")
+ FileContent = FilterUserName(FilterAccessToken(FileContent, If(FileName = "启动脚本.bat", "F", "*")), "*")
WriteFile(TempFolder & "Report\" & FileName, FileContent, Encoding:=FileEncoding)
Log($"[Crash] 导出文件:{FileName},编码:{FileEncoding.HeaderName}")
End If
@@ -917,7 +916,7 @@ NextStack:
'导出报告
Compression.ZipFile.CreateFromDirectory(TempFolder & "Report\", FileAddress)
DeleteDirectory(TempFolder & "Report\")
- Hint("错误报告已导出!", HintType.Finish)
+ Hint("错误报告已导出!", HintType.Green)
Catch ex As Exception
Log(ex, "导出错误报告失败", LogLevel.Feedback)
Return
diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb
index ccaddd1..c4c8fdb 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb
@@ -35,7 +35,7 @@ Public Module ModLaunch
'预检查
If Not RunInUi() Then Throw New Exception("McLaunchStart 必须在 UI 线程调用!")
If McLaunchLoader.State = LoadState.Loading Then
- Hint("已有游戏正在启动中!", HintType.Critical)
+ Hint("已有游戏正在启动中!", HintType.Red)
Return False
End If
'强制切换需要启动的版本
@@ -44,7 +44,7 @@ Public Module ModLaunch
'检查版本
CurrentLaunchOptions.Version.Load()
If CurrentLaunchOptions.Version.State = McVersionState.Error Then
- Hint("无法启动 Minecraft:" & CurrentLaunchOptions.Version.Info, HintType.Critical)
+ Hint("无法启动 Minecraft:" & CurrentLaunchOptions.Version.Info, HintType.Red)
Return False
End If
'切换版本
@@ -98,7 +98,7 @@ Public Module ModLaunch
McLaunchPrecheck()
McLaunchLog("预检测已通过")
Catch ex As Exception
- If Not ex.Message.StartsWithF("$$") Then Hint(ex.Message, HintType.Critical)
+ If Not ex.Message.StartsWithF("$$") Then Hint(ex.Message, HintType.Red)
Throw
End Try
Dim IsSavingBatch As Boolean = CurrentLaunchOptions?.SaveBatch IsNot Nothing
@@ -146,7 +146,7 @@ Public Module ModLaunch
'成功与失败处理
Select Case LaunchLoader.State
Case LoadState.Finished
- Hint(McVersionCurrent.Name & " 启动成功!", HintType.Finish)
+ Hint(McVersionCurrent.Name & " 启动成功!", HintType.Green)
'上报
If Not IsSavingBatch Then
Telemetry("Minecraft 启动成功",
@@ -155,9 +155,9 @@ Public Module ModLaunch
End If
Case LoadState.Aborted
If AbortHint Is Nothing Then
- Hint(If(IsSavingBatch, "已取消导出启动脚本!", "已取消启动!"), HintType.Info)
+ Hint(If(IsSavingBatch, "已取消导出启动脚本!", "已取消启动!"), HintType.Blue)
Else
- Hint(AbortHint, HintType.Finish)
+ Hint(AbortHint, HintType.Green)
End If
Case LoadState.Failed
Throw LaunchLoader.Error
@@ -270,7 +270,7 @@ NextInner:
Select Case MyMsgBox("你必须先登录正版账号,才能进行离线登录!", "正版验证", "购买正版", "试玩", "返回",
Button1Action:=Sub() OpenWebsite("https://www.xbox.com/zh-cn/games/store/minecraft-java-bedrock-edition-for-pc/9nxp44l49shj"))
Case 2
- Hint("游戏将以试玩模式启动!", HintType.Critical)
+ Hint("游戏将以试玩模式启动!", HintType.Red)
CurrentLaunchOptions.ExtraArgs.Add("--demo")
Case 3
Throw New Exception("$$")
@@ -755,10 +755,10 @@ LoginFinish:
ContentType:="application/json; charset=utf-8", RequireJson:=True))
'检查登录结果
If LoginJson("availableProfiles").Count = 0 Then
- If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色,无法更换!", HintType.Critical)
+ If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色,无法更换!", HintType.Red)
Throw New Exception("$你还没有创建角色,请在创建角色后再试!")
ElseIf Data.Input.ForceReselectProfile AndAlso LoginJson("availableProfiles").Count = 1 Then
- Hint("你的账户中只有一个角色,无法更换!", HintType.Critical)
+ Hint("你的账户中只有一个角色,无法更换!", HintType.Red)
End If
Dim SelectedName As String = Nothing
Dim SelectedId As String = Nothing
@@ -1304,7 +1304,7 @@ Retry:
If McLaunchJavaSelected IsNot Nothing Then
McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
Else
- Hint("没有可用的 Java,已取消启动!", HintType.Critical)
+ Hint("没有可用的 Java,已取消启动!", HintType.Red)
Throw New Exception("$$")
End If
@@ -1395,7 +1395,7 @@ Retry:
Next
'自定义
Dim ArgumentGame As String = Setup.Get("VersionAdvanceGame", Version:=McVersionCurrent)
- Arguments += " " & If(ArgumentGame = "", Setup.Get("LaunchAdvanceGame"), ArgumentGame)
+ Arguments += " " & ArgumentReplace(If(ArgumentGame = "", Setup.Get("LaunchAdvanceGame"), ArgumentGame))
'进行参数替换
Dim ReplaceArguments = McLaunchArgumentsReplace(McVersionCurrent, Loader)
If String.IsNullOrWhiteSpace(ReplaceArguments("${version_type}")) Then
@@ -1412,6 +1412,9 @@ Retry:
FinalArguments += Argument & " "
Next
FinalArguments = FinalArguments.TrimEnd
+ '替换 Module Path 为短路径(Forge 会在版本 JSON 硬编码这些路径)
+ FinalArguments = FinalArguments.RegexReplaceEach("(?<= (-p|--module-path) "")[^""]+(?="" )",
+ Function(ModulePath) ModulePath.Value.RegexReplaceEach("[A-Z]{1}:\\[^;]+", Function(m) ShortenPath(m.Value)))
'进服
Dim Server As String = If(String.IsNullOrEmpty(CurrentLaunchOptions.ServerIp), Setup.Get("VersionServerEnter", McVersionCurrent), CurrentLaunchOptions.ServerIp)
If Server.Length > 0 Then
@@ -1427,7 +1430,7 @@ Retry:
'不包含端口号
FinalArguments += $" --server {Server} --port 25565"
End If
- If McVersionCurrent.Version.HasOptiFine Then Hint("OptiFine 与自动进入服务器可能不兼容,有概率导致材质丢失甚至游戏崩溃!", HintType.Critical)
+ If McVersionCurrent.Version.HasOptiFine Then Hint("OptiFine 与自动进入服务器可能不兼容,有概率导致材质丢失甚至游戏崩溃!", HintType.Red)
End If
End If
'输出
@@ -1447,7 +1450,7 @@ Retry:
If ArgumentJvm = "" Then ArgumentJvm = Setup.Get("LaunchAdvanceJvm")
If Not ArgumentJvm.Contains("-Dlog4j2.formatMsgNoLookups=true") Then ArgumentJvm += " -Dlog4j2.formatMsgNoLookups=true"
ArgumentJvm = ArgumentJvm.Replace(" -XX:MaxDirectMemorySize=256M", "") '#3511 的清理
- DataList.Insert(0, ArgumentJvm) '可变 JVM 参数
+ DataList.Insert(0, ArgumentReplace(ArgumentJvm)) '可变 JVM 参数
DataList.Add("-Xmn" & Math.Floor(PageVersionSetup.GetRam(McVersionCurrent, Not McLaunchJavaSelected.Is64Bit) * 1024 * 0.15) & "m")
DataList.Add("-Xmx" & Math.Floor(PageVersionSetup.GetRam(McVersionCurrent, Not McLaunchJavaSelected.Is64Bit) * 1024) & "m")
DataList.Add("""-Djava.library.path=" & GetNativesFolder() & """")
@@ -1571,7 +1574,7 @@ NextVersion:
'去重
DeDuplicateDataList.Remove("-XX:MaxDirectMemorySize=256M") '#3511 的清理
- Dim Result As String = Join(DeDuplicateDataList.Distinct.ToList, " ")
+ Dim Result As String = DeDuplicateDataList.Distinct.Join(" ")
'添加 MainClass
If Version.JsonObject("mainClass") Is Nothing Then
@@ -1592,7 +1595,7 @@ NextVersion:
If Not BasicString.Contains("--height") Then BasicString += " --height ${resolution_height} --width ${resolution_width}"
DataList.Add(BasicString)
- Dim Result As String = Join(DataList, " ")
+ Dim Result As String = DataList.Join(" ")
'特别改变 OptiFineTweaker
If (Version.Version.HasForge OrElse Version.Version.HasLiteLoader) AndAlso Version.Version.HasOptiFine Then
@@ -1697,7 +1700,7 @@ NextVersion:
GameArguments.Add("${launcher_version}", VersionCode)
GameArguments.Add("${version_name}", Version.Name)
Dim ArgumentInfo As String = Setup.Get("VersionArgumentInfo", Version:=McVersionCurrent)
- GameArguments.Add("${version_type}", If(ArgumentInfo = "", Setup.Get("LaunchArgumentInfo"), ArgumentInfo))
+ GameArguments.Add("${version_type}", ArgumentReplace(If(ArgumentInfo = "", Setup.Get("LaunchArgumentInfo"), ArgumentInfo)))
GameArguments.Add("${game_directory}", ShortenPath(Left(McVersionCurrent.PathIndie, McVersionCurrent.PathIndie.Count - 1)))
GameArguments.Add("${assets_root}", ShortenPath(PathMcFolder & "assets"))
GameArguments.Add("${user_properties}", "{}")
@@ -1707,7 +1710,7 @@ NextVersion:
GameArguments.Add("${access_token}", McLoginLoader.Output.AccessToken)
GameArguments.Add("${auth_session}", McLoginLoader.Output.AccessToken)
GameArguments.Add("${user_type}", "msa") '#1221
- GameArguments.Add("${primary_jar}", Version.Path & Version.Name & ".jar") '#6942
+ GameArguments.Add("${primary_jar}", ShortenPath(Version.Path & Version.Name & ".jar")) '#6942
'窗口尺寸参数
Dim GameSize As Size
@@ -1827,10 +1830,14 @@ NextVersion:
'''
Private Function GetNativesFolder() As String
Dim Result As String = McVersionCurrent.Path & McVersionCurrent.Name & "-natives"
- If IsGBKEncoding OrElse Result.IsASCII() Then Return ShortenPath(Result)
- Result = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\bin\natives"
- If Result.IsASCII() Then Return ShortenPath(Result)
- Return OsDrive & "ProgramData\PCL\natives"
+ If Not (IsGBKEncoding OrElse Result.IsASCII()) Then
+ Result = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\bin\natives"
+ If Not Result.IsASCII() Then
+ Result = OsDrive & "ProgramData\PCL\natives"
+ End If
+ End If
+ Directory.CreateDirectory(Result) '提前创建,这样 ShortenPath 才有结果(否则在长路径下首次启动 Forge 会崩溃)
+ Return ShortenPath(Result)
End Function
#End Region
@@ -1981,7 +1988,7 @@ NextVersion:
McLoginLoader.Input.Type = McLoginType.Legacy AndAlso '离线登录
(Setup.Get("LaunchSkinType") = 2 OrElse '强制 Alex
(Setup.Get("LaunchSkinType") = 4 AndAlso Setup.Get("LaunchSkinSlim"))) Then '或选用 Alex 皮肤
- Hint("此 Minecraft 版本尚不支持 Alex 皮肤,你的皮肤可能会显示为 Steve!", HintType.Critical)
+ Hint("此 Minecraft 版本尚不支持 Alex 皮肤,你的皮肤可能会显示为 Steve!", HintType.Red)
End If
'离线皮肤资源包
@@ -2125,9 +2132,9 @@ IgnoreCustomSkin:
'获取自定义命令
Dim CustomCommandGlobal As String = Setup.Get("LaunchAdvanceRun")
- If CustomCommandGlobal <> "" Then CustomCommandGlobal = ArgumentReplace(CustomCommandGlobal, True)
+ If CustomCommandGlobal <> "" Then CustomCommandGlobal = ArgumentReplace(CustomCommandGlobal)
Dim CustomCommandVersion As String = Setup.Get("VersionAdvanceRun", Version:=McVersionCurrent)
- If CustomCommandVersion <> "" Then CustomCommandVersion = ArgumentReplace(CustomCommandVersion, True)
+ If CustomCommandVersion <> "" Then CustomCommandVersion = ArgumentReplace(CustomCommandVersion)
'输出 bat
Try
@@ -2283,7 +2290,7 @@ IgnoreCustomSkin:
'获取窗口标题
Dim WindowTitle As String = Setup.Get("VersionArgumentTitle", Version:=McVersionCurrent)
If WindowTitle = "" Then WindowTitle = Setup.Get("LaunchArgumentTitle")
- WindowTitle = ArgumentReplace(WindowTitle, False)
+ WindowTitle = ArgumentReplace(WindowTitle, ReplaceTime:=False)
'初始化等待
Dim Watcher As New Watcher(Loader, McVersionCurrent, WindowTitle)
@@ -2332,47 +2339,6 @@ IgnoreCustomSkin:
End Sub
- '''
- ''' 在启动结束时,对 PCL 约定的替换标记进行处理。
- '''
- Private Function ArgumentReplace(Raw As String, ReplaceTimeAndDate As Boolean) As String
- If Raw Is Nothing Then Return Nothing
- '路径替换
- Raw = Raw.Replace("{minecraft}", PathMcFolder)
- Raw = Raw.Replace("{verpath}", McVersionCurrent.Path)
- Raw = Raw.Replace("{verindie}", McVersionCurrent.PathIndie)
- Raw = Raw.Replace("{java}", McLaunchJavaSelected.PathFolder)
- '普通替换
- Raw = Raw.Replace("{user}", McLoginLoader.Output.Name)
- Raw = Raw.Replace("{uuid}", McLoginLoader.Output.Uuid)
- If ReplaceTimeAndDate Then '设置窗口标题时需要动态替换日期和时间
- Raw = Raw.Replace("{date}", Date.Now.ToString("yyyy/M/d"))
- Raw = Raw.Replace("{time}", Date.Now.ToString("HH:mm:ss"))
- End If
- Select Case McLoginLoader.Input.Type
- Case McLoginType.Legacy
- If PageLinkHiper.HiperState = LoadState.Finished Then
- Raw = Raw.Replace("{login}", "联机离线")
- Else
- Raw = Raw.Replace("{login}", "离线")
- End If
- Case McLoginType.Ms
- Raw = Raw.Replace("{login}", "正版")
- Case McLoginType.Nide
- Raw = Raw.Replace("{login}", "统一通行证")
- Case McLoginType.Auth
- Raw = Raw.Replace("{login}", "Authlib-Injector")
- End Select
- Raw = Raw.Replace("{name}", McVersionCurrent.Name)
- If {"unknown", "old", "pending"}.Contains(McVersionCurrent.Version.McName.ToLower) Then
- Raw = Raw.Replace("{version}", McVersionCurrent.Name)
- Else
- Raw = Raw.Replace("{version}", McVersionCurrent.Version.McName)
- End If
- Raw = Raw.Replace("{path}", Path)
- Return Raw
- End Function
-
#End Region
End Module
diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb
index 6a3a527..2382a0b 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb
@@ -68,7 +68,7 @@ Public Module ModMinecraft
For Each Folder As String In Setup.Get("LaunchFolders").Split("|")
If Folder = "" Then Continue For
If Not Folder.Contains(">") OrElse Not Folder.EndsWithF("\") Then
- Hint("无效的 Minecraft 文件夹:" & Folder, HintType.Critical)
+ Hint("无效的 Minecraft 文件夹:" & Folder, HintType.Red)
Continue For
End If
Dim Name As String = Folder.Split(">")(0)
@@ -261,6 +261,12 @@ Public Module ModMinecraft
''' 显示的描述文本。
'''
Public Info As String = "该版本未被加载,请向作者反馈此问题"
+ Public ReadOnly Property HasCustomInfo As Boolean
+ Get
+ Return ReadIni(Path & "PCL\Setup.ini", "CustomInfo") <> ""
+ End Get
+ End Property
+
'''
''' 该版本的列表检查原始结果,不受自定义影响。
'''
@@ -784,7 +790,17 @@ ExitDataLoad:
End If
'确定版本描述
Dim CustomInfo As String = ReadIni(Path & "PCL\Setup.ini", "CustomInfo")
- Info = If(CustomInfo <> "", CustomInfo, GetDefaultDescription())
+ If CustomInfo <> "" Then
+ Info = CustomInfo
+ Else
+ Info = GetVersionDescription()
+ If State = McVersionState.Fool Then
+ Info = GetMcFoolName(Version.McName)
+ ElseIf State <> McVersionState.Error Then
+ If Setup.Get("VersionServerLogin", Version:=Me) = 3 Then Info += ", 统一通行证验证"
+ If Setup.Get("VersionServerLogin", Version:=Me) = 4 Then Info += ", Authlib 验证"
+ End If
+ End If
'确定版本收藏状态
IsStar = ReadIni(Path & "PCL\Setup.ini", "IsStar", False)
'确定版本显示种类
@@ -817,11 +833,13 @@ ExitDataLoad:
End Try
Return Me
End Function
+ Public IsLoaded As Boolean = False
'''
- ''' 获取版本的默认描述。
+ ''' 获取对该版本的简短描述。
+ ''' 例如 “快照 16w01a”、“原版 1.12.2”、“愚人节版本 2.0”。
'''
- Public Function GetDefaultDescription() As String
- Dim Info As String = ""
+ Public Function GetVersionDescription() As String
+ Dim Info As String
Select Case State
Case McVersionState.Snapshot
If Version.McName.ContainsF("pre", True) Then
@@ -838,21 +856,38 @@ ExitDataLoad:
Case McVersionState.Original, McVersionState.Forge, McVersionState.NeoForge, McVersionState.Fabric, McVersionState.OptiFine, McVersionState.LiteLoader
Info = Version.ToString
Case McVersionState.Fool
- Info = GetMcFoolName(Version.McName)
+ Info = "愚人节版本 " & Version.McName
Case McVersionState.Error
Return Me.Info '已有错误信息
Case Else
Info = "发生了未知错误,请向作者反馈此问题"
End Select
- If Not State = McVersionState.Error Then
- If Setup.Get("VersionServerLogin", Version:=Me) = 3 Then Info += ", 统一通行证验证"
- If Setup.Get("VersionServerLogin", Version:=Me) = 4 Then Info += ", Authlib 验证"
- End If
Return Info
End Function
- Public IsLoaded As Boolean = False
+ Public Function ToListItem() As MyListItem
+ Dim NewItem As New MyListItem With {.Info = Info, .Height = 42, .Tag = Me, .SnapsToDevicePixels = True, .Type = MyListItem.CheckType.Clickable}
+ '标题
+ NewItem.Inlines.Clear()
+ NewItem.Inlines.Add(New Run(Name))
+ If HasCustomInfo Then '如果版本设置了自定义描述,在标题后面以淡灰色显示其版本号
+ NewItem.Inlines.Add(New Run(" | " & GetVersionDescription()) With {.Foreground = New MyColor(215, 215, 215), .FontSize = 12})
+ End If
+ 'Logo
+ Try
+ If Logo.EndsWith("PCL\Logo.png") Then
+ NewItem.Logo = Path & "PCL\Logo.png" '修复老版本中,存储的自定义 Logo 使用完整路径,导致移动后无法加载的 Bug
+ Else
+ NewItem.Logo = Logo
+ End If
+ Catch ex As Exception
+ Log(ex, "加载版本图标失败", LogLevel.Hint)
+ NewItem.Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png"
+ End Try
+ Return NewItem
+ End Function
+ '运算符支持
Public Overrides Function Equals(obj As Object) As Boolean
Dim version = TryCast(obj, McVersion)
Return version IsNot Nothing AndAlso Path = version.Path
@@ -865,7 +900,6 @@ ExitDataLoad:
Public Shared Operator <>(a As McVersion, b As McVersion) As Boolean
Return Not (a = b)
End Operator
-
End Class
Public Enum McVersionState
[Error]
@@ -1567,12 +1601,12 @@ OnLoaded:
Try
Dim Image As New MyBitmap(FileName)
If Image.Pic.Width <> 64 OrElse Not (Image.Pic.Height = 32 OrElse Image.Pic.Height = 64) Then
- Hint("皮肤图片大小应为 64x32 像素或 64x64 像素!", HintType.Critical)
+ Hint("皮肤图片大小应为 64x32 像素或 64x64 像素!", HintType.Red)
Return New McSkinInfo With {.IsVaild = False}
End If
Dim FileInfo As New FileInfo(FileName)
If FileInfo.Length > 24 * 1024 Then
- Hint("皮肤文件大小需小于 24 KB,而所选文件大小为 " & Math.Round(FileInfo.Length / 1024, 2) & " KB", HintType.Critical)
+ Hint("皮肤文件大小需小于 24 KB,而所选文件大小为 " & Math.Round(FileInfo.Length / 1024, 2) & " KB", HintType.Red)
Return New McSkinInfo With {.IsVaild = False}
End If
Catch ex As Exception
diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
index a2d7783..5769826 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
@@ -31,7 +31,7 @@ Public Module ModModpack
Try
'字符校验
Dim TargetFolder As String = $"{PathMcFolder}versions\{VersionName}\"
- If TargetFolder.Contains("!") OrElse TargetFolder.Contains(";") Then Hint("游戏路径中不能含有感叹号或分号:" & TargetFolder, HintType.Critical) : Throw New CancelledException
+ If TargetFolder.Contains("!") OrElse TargetFolder.Contains(";") Then Hint("游戏路径中不能含有感叹号或分号:" & TargetFolder, HintType.Red) : Throw New CancelledException
'获取整合包种类与关键 Json
Dim PackType As Integer = -1
Try
@@ -344,7 +344,7 @@ Retry:
'重复任务检查
Dim LoaderName As String = "CurseForge 整合包安装:" & VersionName & " "
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
- Hint("该整合包正在安装中!", HintType.Critical)
+ Hint("该整合包正在安装中!", HintType.Red)
Throw New CancelledException
End If
@@ -485,7 +485,7 @@ Retry:
'重复任务检查
Dim LoaderName As String = $"Modrinth 整合包安装:{VersionName} "
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
- Hint("该整合包正在安装中!", HintType.Critical)
+ Hint("该整合包正在安装中!", HintType.Red)
Throw New CancelledException
End If
@@ -540,7 +540,7 @@ Retry:
'重复任务检查
Dim LoaderName As String = "HMCL 整合包安装:" & VersionName & " "
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
- Hint("该整合包正在安装中!", HintType.Critical)
+ Hint("该整合包正在安装中!", HintType.Red)
Throw New CancelledException
End If
'启动
@@ -639,8 +639,8 @@ Retry:
'构造版本安装请求
If PackJson("components") Is Nothing Then Throw New Exception("该 MMC 整合包未提供游戏版本信息,无法安装!")
Dim Request As New McInstallRequest With {.TargetVersionName = VersionName, .TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\"}
- For Each Component In PackJson("components")
- If Not Component.Contains("uid") Then Continue For
+ For Each Component As JObject In PackJson("components")
+ If Not Component.ContainsKey("uid") Then Continue For
Select Case Component("uid").ToString
Case "org.lwjgl"
Log("[ModPack] 已跳过 LWJGL 项")
@@ -667,7 +667,7 @@ Retry:
'重复任务检查
Dim LoaderName As String = "MMC 整合包安装:" & VersionName & " "
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
- Hint("该整合包正在安装中!", HintType.Critical)
+ Hint("该整合包正在安装中!", HintType.Red)
Throw New CancelledException
End If
@@ -725,7 +725,7 @@ Retry:
Next
If Not Addons.ContainsKey("game") Then Throw New Exception("该 MCBBS 整合包未提供游戏版本信息,无法安装!")
If Addons.ContainsKey("quilt") Then
- Hint("PCL 暂不支持安装需要 Quilt 的整合包!", HintType.Critical)
+ Hint("PCL 暂不支持安装需要 Quilt 的整合包!", HintType.Red)
Throw New CancelledException
End If
Dim Request As New McInstallRequest With {
@@ -746,7 +746,7 @@ Retry:
'重复任务检查
Dim LoaderName As String = "MCBBS 整合包安装:" & VersionName & " "
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
- Hint("该整合包正在安装中!", HintType.Critical)
+ Hint("该整合包正在安装中!", HintType.Red)
Throw New CancelledException
End If
@@ -766,7 +766,7 @@ Retry:
MyMsgBox("接下来请选择一个空文件夹,它会被安装到这个文件夹里。", "安装", "继续", ForceWait:=True)
Dim TargetFolder As String = SelectFolder("选择安装目标(必须是一个空文件夹)")
If String.IsNullOrEmpty(TargetFolder) Then Throw New CancelledException
- If Directory.GetFileSystemEntries(TargetFolder).Length > 0 Then Hint("请选择一个空文件夹作为安装目标!", HintType.Critical) : Throw New CancelledException
+ If Directory.GetFileSystemEntries(TargetFolder).Length > 0 Then Hint("请选择一个空文件夹作为安装目标!", HintType.Red) : Throw New CancelledException
'解压
Dim Loader As New LoaderCombo(Of String)("解压压缩包", {
New LoaderTask(Of String, Integer)("解压压缩包",
@@ -843,8 +843,8 @@ Retry:
MyMsgBox("接下来请选择一个空文件夹,它会被安装到这个文件夹里。", "安装", "继续", ForceWait:=True)
Dim TargetFolder As String = SelectFolder("选择安装目标(必须是一个空文件夹)")
If String.IsNullOrEmpty(TargetFolder) Then Throw New CancelledException
- If TargetFolder.Contains("!") OrElse TargetFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Critical) : Throw New CancelledException
- If Directory.GetFileSystemEntries(TargetFolder).Length > 0 Then Hint("请选择一个空文件夹作为安装目标!", HintType.Critical) : Throw New CancelledException
+ If TargetFolder.Contains("!") OrElse TargetFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Red) : Throw New CancelledException
+ If Directory.GetFileSystemEntries(TargetFolder).Length > 0 Then Hint("请选择一个空文件夹作为安装目标!", HintType.Red) : Throw New CancelledException
'解压
Dim Loader As New LoaderCombo(Of String)("解压压缩包", {
New LoaderTask(Of String, Integer)("解压压缩包",
diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb
index c4f08a4..d6259a0 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb
@@ -349,7 +349,7 @@
State = MinecraftState.Crashed
'崩溃分析
WatcherLog("Minecraft 已崩溃,将在 2 秒后开始崩溃分析")
- Hint("检测到 Minecraft 出现错误,错误分析已开始……", HintType.Critical)
+ Hint("检测到 Minecraft 出现错误,错误分析已开始……", HintType.Red)
FeedbackInfo()
RunInNewThread(
Sub()
diff --git a/Plain Craft Launcher 2/Modules/ModEvent.vb b/Plain Craft Launcher 2/Modules/ModEvent.vb
index 615fcf7..02849de 100644
--- a/Plain Craft Launcher 2/Modules/ModEvent.vb
+++ b/Plain Craft Launcher 2/Modules/ModEvent.vb
@@ -1,181 +1,291 @@
-Imports System.Collections.ObjectModel
+
+#Region "附加属性"
+
+'''
+''' 用于在 XAML 中初始化列表对象。
+''' 附加属性无法在 XAML 中为每个对象初始化独立的列表对象,因此需要一个包装类,然后在 XAML 中显式初始化。
+'''
+
+Public Class CustomEventCollection
+ Implements IEnumerable(Of CustomEvent)
+ Dim _Events As New List(Of CustomEvent)
+ Public ReadOnly Property Events As List(Of CustomEvent)
+ Get
+ Return _Events
+ End Get
+ End Property
+ Public Function GetEnumerator() As IEnumerator(Of CustomEvent) Implements IEnumerable(Of CustomEvent).GetEnumerator
+ Return DirectCast(Events, IEnumerable(Of CustomEvent)).GetEnumerator()
+ End Function
+ Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
+ Return DirectCast(Events, IEnumerable).GetEnumerator()
+ End Function
+End Class
+
+'''
+''' 提供自定义事件的附加属性。
+'''
+Public Class CustomEventService
+
+ 'Events
+ Public Shared ReadOnly EventsProperty As DependencyProperty =
+ DependencyProperty.RegisterAttached("Events", GetType(CustomEventCollection), GetType(CustomEventService), New PropertyMetadata(Nothing))
+
+ Public Shared Sub SetEvents(d As DependencyObject, value As CustomEventCollection)
+ d.SetValue(EventsProperty, value)
+ End Sub
+
+ Public Shared Function GetEvents(d As DependencyObject) As CustomEventCollection
+ If d.GetValue(EventsProperty) Is Nothing Then d.SetValue(EventsProperty, New CustomEventCollection)
+ Return d.GetValue(EventsProperty)
+ End Function
+
+ 'EventType
+ Public Shared ReadOnly EventTypeProperty As DependencyProperty =
+ DependencyProperty.RegisterAttached("EventType", GetType(CustomEvent.EventType), GetType(CustomEventService), New PropertyMetadata(Nothing))
+
+ Public Shared Sub SetEventType(d As DependencyObject, value As CustomEvent.EventType)
+ d.SetValue(EventTypeProperty, value)
+ End Sub
+
+ Public Shared Function GetEventType(d As DependencyObject) As CustomEvent.EventType
+ Return d.GetValue(EventTypeProperty)
+ End Function
+
+ 'EventData
+ Public Shared ReadOnly EventDataProperty As DependencyProperty =
+ DependencyProperty.RegisterAttached("EventData", GetType(String), GetType(CustomEventService), New PropertyMetadata(Nothing))
+
+ Public Shared Sub SetEventData(d As DependencyObject, value As String)
+ d.SetValue(EventDataProperty, value)
+ End Sub
+
+ Public Shared Function GetEventData(d As DependencyObject) As String
+ Return d.GetValue(EventDataProperty)
+ End Function
+
+End Class
+
+Partial Public Module ModMain
-Public Module ModEvent
-#Region "事件执行方法"
'''
- ''' 供外部调用的自定义事件执行接口,会在新建工作线程中运行逻辑。
+ ''' 触发该控件上的自定义事件。
+ ''' 事件会在新线程中执行。
'''
- ''' xaml中的EventType
- ''' xaml中的EventData
- ''' xaml中的CustomEvents
- Public Sub ProcessCustomEvents(SingleEventType As String, SingleEventData As String, EventCollection As CustomEventCollection)
+
+ Public Sub RaiseCustomEvent(Control As DependencyObject)
+ '收集事件列表
+ Dim Events = CustomEventService.GetEvents(Control).ToList
+ Dim EventType = CustomEventService.GetEventType(Control)
+ If EventType <> CustomEvent.EventType.None Then Events.Add(New CustomEvent(EventType, CustomEventService.GetEventData(Control)))
+ '执行事件
+ If Not Events.Any Then Return
RunInNewThread(
- Sub()
- Try
- '先执行单个事件
- StartCustomEvent(SingleEventType, SingleEventData)
- '再挨个执行事件集合中的事件
- If EventCollection IsNot Nothing Then
- For Each AnEvent In RunInUiWait(Function() EventCollection.DeepCloneToStructureList())
- StartCustomEvent(AnEvent.EventType, AnEvent.EventData)
- Next
- End If
- Catch ex As Exception
- Log(ex, "自定义事件执行器发生异常", LogLevel.Feedback)
- End Try
- End Sub, "CustomEventProcessor " & GetUuid())
- End Sub
- '''
- ''' 对当前线程阻塞地调用自定义事件处理器,接受来自 xaml 原始输入作为参数。
- '''
- Private Sub StartCustomEvent(Type As String, DataRaw As String)
- If String.IsNullOrEmpty(Type) Then Exit Sub
- Dim Data = If(DataRaw Is Nothing, {""}, DataRaw.Split("|"))
- Log("[Control] 执行自定义事件:" & Type & ", " & Join(Data, ", "))
- '检测是否存在对应事件
- If Not CustomEventProcessorsDict.ContainsKey(Type) Then
- MyMsgBox($"未知的事件类型:'{Type}'{vbCrLf}请检查事件类型填写是否正确,或者 PCL 是否为最新版本。", "事件执行失败", ForceWait:=True)
- Exit Sub
- End If
- '调用事件处理器
- Try
- CustomEventProcessorsDict(Type)(Data)
- Catch ex As Exception
- Log(ex, $"自定义事件执行失败:{Type}", LogLevel.Msgbox, "自定义主页事件执行失败")
- End Try
+ Sub()
+ For Each e In Events
+ e.Raise()
+ Next
+ End Sub, "执行自定义事件 " & GetUuid())
End Sub
- '''
- ''' 存储各个自定义事件处理器的字典,以 EventType 为键,执行自定义事件时在工作线程中调用 Action 并传入分割后的 EventData 。
- ''' Action 应当在事件逻辑结束后,即可以开始下一个事件时再结束;以便于挨个调用事件不打架。
- '''
- Private ReadOnly CustomEventProcessorsDict As New Dictionary(Of String, Action(Of String())) From {
- {"打开网页",
- Sub(Data As String())
- Data(0) = Data(0).Replace("\", "/")
- If Not Data(0).Contains("://") OrElse Data(0).StartsWithF("file", True) Then '为了支持更多协议(#2200)
- MyMsgBox("打开网页事件中,EventData 必须为一个网址。" & vbCrLf & "如果想要启动程序,请将 EventType 改为 打开文件。", "事件执行失败")
- Exit Sub
- End If
- Hint("网页正在开启中,请稍候……")
- OpenWebsite(Data(0))
- End Sub},
- {"打开文件",
- Sub(Data As String())
- Dim ActualPaths = GetEventAbsoluteUrls(Data(0), "打开文件")
- Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1)
- Log($"[Control] 打开文件:路径:{Location},工作目录:{WorkingDir}")
- If Not CommandRunUserConfirm(If(Data.Length < 2, Location, $"{Location} {Data(1)}")) Then Exit Sub
- Dim Info As New ProcessStartInfo With {
- .Arguments = If(Data.Length < 2, "", Data(1)),
- .FileName = Location,
- .WorkingDirectory = ShortenPath(WorkingDir)
- }
- Process.Start(Info)
- End Sub},
- {"打开帮助",
- Sub(Data As String())
- Dim ActualPaths = GetEventAbsoluteUrls(Data(0), "打开帮助")
- Dim Location = ActualPaths(0)
- Log($"[Control] 打开帮助:{Location}")
- PageOtherHelp.EnterHelpPage(Location)
- End Sub},
- {"执行命令",
- Sub(Data As String())
- Dim ActualPaths = GetEventAbsoluteUrls(Data(0), "执行命令")
- Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1)
- Log($"[Control] 执行命令:路径:{Location},工作目录:{WorkingDir}")
- If Not CommandRunUserConfirm(If(Data.Length < 2, Location, $"{Location} {Data(1)}")) Then Exit Sub
- Dim Info As New ProcessStartInfo With {
- .Arguments = If(Data.Length < 2, "", Data(1)),
- .FileName = Location,
- .WorkingDirectory = ShortenPath(WorkingDir)
- }
- Process.Start(Info)
- End Sub},
- {"启动游戏",
- Sub(Data As String())
- If Data(0) = "\current" Then
- If McVersionCurrent Is Nothing Then
- Hint("请先选择一个 Minecraft 版本!", HintType.Critical)
- Exit Sub
- Else
- Data(0) = McVersionCurrent.Name
- End If
- End If
- RunInUiWait(
- Sub()
- If McLaunchStart(New McLaunchOptions With {.Version = New McVersion(Data(0)), .ServerIp = If(Data.Length >= 2, Data(1), Nothing)}) Then
- Hint("正在启动 " & Data(0) & "……")
- End If
- End Sub)
- End Sub},
- {"复制文本", Sub(Data As String()) ClipboardSet(Join(Data, "|"))},
- {"刷新主页",
- Sub(Data As String())
- RunInUiWait(Sub() FrmLaunchRight.ForceRefresh())
- If Data(0) = "" Then Hint("已刷新主页!", HintType.Finish)
- End Sub},
- {"刷新帮助", Sub() RunInUi(Sub() PageOtherLeft.RefreshHelp())},
- {"今日人品", Sub() PageOtherTest.Jrrp()},
- {"内存优化",
- Sub(Data As String())
- If Data.Length >= 1 AndAlso Data(0) = "前台运行" Then
- PageOtherTest.MemoryOptimize(Data.Length >= 2 AndAlso Data(1) = "显示提示")
- Else
- RunInNewThread(Sub() PageOtherTest.MemoryOptimize(True))
- End If
- End Sub},
- {"弹出窗口", Sub(Data As String()) MyMsgBox(Data(1).Replace("\n", vbCrLf), Data(0).Replace("\n", vbCrLf), ForceWait:=True)},
- {"切换页面", Sub(Data As String()) RunInUiWait(Sub() FrmMain.PageChange(Val(Data(0)), Val(Data(1))))},
- {"安装整合包", Sub() RunInUiWait(Sub() ModpackInstall())},
- {"导入整合包", Sub() RunInUiWait(Sub() ModpackInstall())},
- {"下载文件",
- Sub(Data As String())
- Data(0) = Data(0).Replace("\", "/")
- If Not (Data(0).StartsWithF("http://", True) OrElse Data(0).StartsWithF("https://", True)) Then
- MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败")
- Exit Sub
- End If
- Try
- Select Case Data.Length
- Case 1
- PageOtherTest.StartCustomDownload(Data(0), GetFileNameFromPath(Data(0)))
- Case 2
- PageOtherTest.StartCustomDownload(Data(0), Data(1))
- Case Else
- PageOtherTest.StartCustomDownload(Data(0), Data(1), Data(2))
- End Select
- Catch
- PageOtherTest.StartCustomDownload(Data(0), "未知")
- End Try
- End Sub}
- }
+End Module
#End Region
-#Region "工具方法"
+
+'''
+''' 自定义事件。
+'''
+Public Class CustomEvent
+
+#Region "属性与触发"
+
+ Public Property Type As EventType = EventType.None
+ Public Property Data As String = Nothing
+ Public Sub New()
+ End Sub
+ Public Sub New(Type As EventType, Data As String)
+ Me.Type = Type
+ Me.Data = Data
+ End Sub
+
'''
- ''' 弹窗询问用户是否同意继续执行打开类事件。
+ ''' 在当前线程中触发该自定义事件。
'''
- Private Function CommandRunUserConfirm(TextShowToUser As String) As Boolean
- If Setup.Get("HintCustomCommand") Then Return True
- Select Case MyMsgBox("即将执行:" & TextShowToUser & vbCrLf & "请在确认该操作没有安全隐患后继续。", "执行确认", "继续", "继续且今后不再要求确认", "取消")
- Case 1
- Return True
- Case 2
- Setup.Set("HintCustomCommand", True)
- Return True
- Case Else '3
- Log("[Control] 用户取消了打开类事件")
- Return False
- End Select
- End Function
+ Public Sub Raise()
+ Raise(Type, Data)
+ End Sub
+
+#End Region
+
+ Public Enum EventType
+ None = 0
+ 打开网页
+ 打开文件
+ 打开帮助
+ 执行命令
+ 启动游戏
+ 复制文本
+ 刷新主页
+ 刷新页面
+ 刷新帮助
+ 今日人品
+ 内存优化
+ 清理垃圾
+ 弹出窗口
+ 弹出提示
+ 切换页面
+ 导入整合包
+ 安装整合包
+ 下载文件
+ 修改设置
+ 写入设置
+ 修改变量
+ 写入变量
+ End Enum
+
+ '''
+ ''' 在当前线程中触发一个自定义事件。
+ '''
+ Public Shared Sub Raise(Type As EventType, Arg As String)
+ If Type = EventType.None Then Return
+ Log($"[Control] 执行自定义事件:{Type}, {Arg}")
+ Try
+ Dim Args As String() = If(Arg?.Split("|"), {""})
+ Select Case Type
+
+ Case EventType.打开网页
+ Arg = Arg.Replace("\", "/")
+ If Not Arg.Contains("://") OrElse Arg.StartsWithF("file", True) Then '为了支持更多协议(#2200)
+ MyMsgBox("EventData 必须为一个网址。" & vbCrLf & "如果想要启动程序,请将 EventType 改为 打开文件。", "事件执行失败")
+ Return
+ End If
+ Hint("正在开启中,请稍候:" & Arg)
+ RunInThread(Sub() OpenWebsite(Arg))
+
+ Case EventType.打开文件, EventType.打开帮助, EventType.执行命令
+ RunInThread(
+ Sub()
+ Try
+ '确认实际路径
+ Dim ActualPaths = GetAbsoluteUrls(Args(0), Type)
+ Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1)
+ Log($"[Control] 打开类自定义事件实际路径:{Location},工作目录:{WorkingDir}")
+ '执行
+ If Type = EventType.打开帮助 Then
+ PageOtherHelp.EnterHelpPage(Location)
+ Else
+ If Not EventSafetyConfirm("即将执行:" & Location & If(Args.Length >= 2, " " & Args(1), "")) Then Return
+ Dim Info As New ProcessStartInfo With {
+ .Arguments = If(Args.Length >= 2, Args(1), ""),
+ .FileName = Location,
+ .WorkingDirectory = WorkingDir
+ }
+ StartProcess(Info)
+ End If
+ Catch ex As Exception
+ Log(ex, "执行打开类自定义事件失败", LogLevel.Msgbox)
+ End Try
+ End Sub)
+
+ Case EventType.启动游戏
+ If Args(0) = "\current" Then
+ If McVersionCurrent Is Nothing Then
+ Hint("请先选择一个 Minecraft 版本!", HintType.Red)
+ Return
+ Else
+ Args(0) = McVersionCurrent.Name
+ End If
+ End If
+ RunInUi(
+ Sub()
+ If McLaunchStart(New McLaunchOptions With
+ {.ServerIp = If(Args.Length >= 2, Args(1), Nothing), .Version = New McVersion(Args(0))}) Then
+ Hint($"正在启动 {Args(0)}……")
+ End If
+ End Sub)
+
+ Case EventType.复制文本
+ ClipboardSet(Arg)
+
+ Case EventType.刷新主页, EventType.刷新页面
+ If TypeOf FrmMain.PageRight Is IRefreshable Then
+ RunInUiWait(Sub() CType(FrmMain.PageRight, IRefreshable).Refresh())
+ If String.IsNullOrEmpty(Arg) Then Hint("已刷新!", HintType.Green)
+ Else
+ Hint("当前页面不支持刷新操作!", HintType.Red)
+ End If
+
+ Case EventType.刷新帮助
+ RunInUiWait(Sub() PageOtherLeft.RefreshHelp())
+ If String.IsNullOrEmpty(Arg) Then Hint("已刷新!", HintType.Green)
+
+ Case EventType.今日人品
+ PageOtherTest.Jrrp()
+
+ Case EventType.内存优化
+ RunInThread(Sub() PageOtherTest.MemoryOptimize(True))
+
+ Case EventType.清理垃圾
+ RunInThread(Sub() PageOtherTest.RubbishClear())
+
+ Case EventType.弹出窗口
+ If Args.Length = 1 Then Throw New Exception($"EventType {Type} 需要至少 2 个以 | 分割的参数,例如 弹窗标题|弹窗内容")
+ MyMsgBox(Args(1).Replace("\n", vbCrLf), Args(0).Replace("\n", vbCrLf), If(Args.Length > 2, Args(2), "确定"))
+
+ Case EventType.弹出提示
+ Hint(Args(0).Replace("\n", vbCrLf), If(Args.Length = 1, HintType.Blue, Args(1).ParseToEnum(Of HintType)))
+
+ Case EventType.切换页面
+ RunInUi(Sub() FrmMain.PageChange(
+ Args(0).ParseToEnum(Of FormMain.PageType),
+ If(Args.Length = 1, FormMain.PageSubType.Default, Args(1).ParseToEnum(Of FormMain.PageSubType))))
+
+ Case EventType.导入整合包, EventType.安装整合包
+ RunInUi(Sub() ModpackInstall())
+
+ Case EventType.下载文件
+ Args(0) = Args(0).Replace("\", "/")
+ If Not (Args(0).StartsWithF("http://", True) OrElse Args(0).StartsWithF("https://", True)) Then
+ MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败")
+ Return
+ End If
+ If Not EventSafetyConfirm("即将从该网址下载文件:" & vbCrLf & Args(0)) Then Return
+ Try
+ Select Case Args.Length
+ Case 1
+ PageOtherTest.StartCustomDownload(Args(0), GetFileNameFromPath(Args(0)))
+ Case 2
+ PageOtherTest.StartCustomDownload(Args(0), Args(1))
+ Case Else
+ PageOtherTest.StartCustomDownload(Args(0), Args(1), Args(2))
+ End Select
+ Catch
+ PageOtherTest.StartCustomDownload(Args(0), "未知")
+ End Try
+
+ Case EventType.修改设置, EventType.写入设置
+ If Args.Length = 1 Then Throw New Exception($"EventType {Type} 需要至少 2 个以 | 分割的参数,例如 UiLauncherTransparent|400")
+ Setup.SetSafe(Args(0), Args(1), Version:=McVersionCurrent)
+ If Args.Length = 2 Then Hint($"已写入设置:{Args(0)} → {Args(1)}", HintType.Green)
+
+ Case EventType.修改变量, EventType.写入变量
+ If Args.Length = 1 Then Throw New Exception($"EventType {Type} 需要至少 2 个以 | 分割的参数,例如 VariableName|SomeValue")
+ WriteReg("CustomEvent" & Args(0), Args(1))
+ If Args.Length = 2 Then Hint($"已写入变量:{Args(0)} → {Args(1)}", HintType.Green)
+
+ Case Else
+ MyMsgBox("未知的事件类型:" & Type & vbCrLf & "请检查事件类型填写是否正确,或者 PCL 是否为最新版本。", "事件执行失败")
+ End Select
+ Catch ex As Exception
+ Log(ex, $"事件执行失败({Type}, {Arg})", LogLevel.Msgbox)
+ End Try
+ End Sub
'''
''' 返回自定义事件的绝对 Url。实际返回 {绝对 Url, WorkingDir}。
''' 失败会抛出异常。
'''
- Public Function GetEventAbsoluteUrls(RelativeUrl As String, EventType As String) As String()
+ Public Shared Function GetAbsoluteUrls(RelativeUrl As String, Type As EventType) As String()
'网页确认
If RelativeUrl.StartsWithF("http", True) Then
@@ -216,25 +326,25 @@ Public Module ModEvent
If RelativeUrl.Contains(":\") Then
'绝对路径
Location = RelativeUrl
- Log("[Control] 自定义事件中由绝对路径" & EventType & ":" & Location)
+ Log("[Control] 自定义事件中由绝对路径" & Type & ":" & Location)
ElseIf File.Exists(Path & "PCL\" & RelativeUrl) Then
'相对 PCL 文件夹的路径
Location = Path & "PCL\" & RelativeUrl
- Log("[Control] 自定义事件中由相对 PCL 文件夹的路径" & EventType & ":" & Location)
+ Log("[Control] 自定义事件中由相对 PCL 文件夹的路径" & Type & ":" & Location)
ElseIf File.Exists(Path & "PCL\Help\" & RelativeUrl) Then
'相对 PCL 本地帮助文件夹的路径
Location = Path & "PCL\Help\" & RelativeUrl
WorkingDir = Path & "PCL\Help\"
- Log("[Control] 自定义事件中由相对 PCL 本地帮助文件夹的路径" & EventType & ":" & Location)
- ElseIf EventType = "打开帮助" AndAlso File.Exists(PathTemp & "Help\" & RelativeUrl) Then
+ Log("[Control] 自定义事件中由相对 PCL 本地帮助文件夹的路径" & Type & ":" & Location)
+ ElseIf Type = EventType.打开帮助 AndAlso File.Exists(PathTemp & "Help\" & RelativeUrl) Then
'相对 PCL 自带帮助文件夹的路径
Location = PathTemp & "Help\" & RelativeUrl
WorkingDir = PathTemp & "Help\"
- Log("[Control] 自定义事件中由相对 PCL 自带帮助文件夹的路径" & EventType & ":" & Location)
- ElseIf EventType = "打开文件" OrElse EventType = "执行命令" Then
+ Log("[Control] 自定义事件中由相对 PCL 自带帮助文件夹的路径" & Type & ":" & Location)
+ ElseIf Type = EventType.打开文件 OrElse Type = EventType.执行命令 Then
'直接使用原有路径启动程序
Location = RelativeUrl
- Log("[Control] 自定义事件中直接" & EventType & ":" & Location)
+ Log("[Control] 自定义事件中直接" & Type & ":" & Location)
Else
'打开帮助,但是格式不对劲
Throw New FileNotFoundException("未找到 EventData 指向的本地 xaml 文件:" & RelativeUrl, RelativeUrl)
@@ -243,42 +353,20 @@ Public Module ModEvent
Return {Location, WorkingDir}
End Function
-#End Region
-End Module
-#Region "数据结构类声明"
-Public Class CustomEventCollection
- Inherits ObservableCollection(Of CustomEvent)
- Public Function DeepCloneToStructureList() As IList(Of CustomEventStructure)
- DeepCloneToStructureList = New List(Of CustomEventStructure)
- For Each AnEvent In Me
- DeepCloneToStructureList.Add(New CustomEventStructure With {.EventType = AnEvent.EventType, .EventData = AnEvent.EventData})
- Next
+ '''
+ ''' 弹出安全确认弹窗。返回是否继续执行。
+ '''
+ Private Shared Function EventSafetyConfirm(Message As String) As Boolean
+ If Setup.Get("HintCustomCommand") Then Return True
+ Select Case MyMsgBox(Message & vbCrLf & "请在确认没有安全隐患后再继续。", "执行确认", "继续", "继续且今后不再要求确认", "取消")
+ Case 1
+ Return True
+ Case 2
+ Setup.Set("HintCustomCommand", True)
+ Return True
+ Case Else
+ Return False
+ End Select
End Function
-End Class
-Public Class CustomEvent
- Inherits DependencyObject
- Public Property EventType As String
- Get
- Return GetValue(EventTypeProperty)
- End Get
- Set(value As String)
- SetValue(EventTypeProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(CustomEvent), New PropertyMetadata(Nothing))
- Public Property EventData As String
- Get
- Return GetValue(EventDataProperty)
- End Get
- Set(value As String)
- SetValue(EventDataProperty, value)
- End Set
- End Property
- Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(CustomEvent), New PropertyMetadata(Nothing))
-End Class
-Public Structure CustomEventStructure
- Public EventType As String
- Public EventData As String
-End Structure
-#End Region
\ No newline at end of file
+End Class
diff --git a/Plain Craft Launcher 2/Modules/ModMain.vb b/Plain Craft Launcher 2/Modules/ModMain.vb
index 68aaebb..c7eb4c5 100644
--- a/Plain Craft Launcher 2/Modules/ModMain.vb
+++ b/Plain Craft Launcher 2/Modules/ModMain.vb
@@ -7,23 +7,12 @@ Public Module ModMain
'''
''' 提示信息的种类。
+ ''' 该枚举在自定义事件中使用,是公开 API 的一部分。
'''
Public Enum HintType
- '''
- ''' 信息,通常是蓝色的“i”。
- '''
- '''
- Info
- '''
- ''' 已完成,通常是绿色的“√”。
- '''
- '''
- Finish
- '''
- ''' 错误,通常是红色的“×”。
- '''
- '''
- Critical
+ Blue
+ Green
+ Red
End Enum
Private Structure HintMessage
Public Text As String
@@ -38,7 +27,7 @@ Public Module ModMain
'''
''' 在窗口左下角弹出提示文本。
'''
- 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.Blue, Optional Log As Boolean = True)
If HintWaiting Is Nothing Then HintWaiting = New SafeList(Of HintMessage)
HintWaiting.Add(New HintMessage With {.Text = If(Text, ""), .Type = Type, .Log = Log})
End Sub
@@ -68,13 +57,13 @@ Public Module ModMain
Dim TargetColor0, TargetColor1 As MyColor
Dim Percent As Double = 0.3
Select Case CurrentHint.Type
- Case HintType.Info
+ Case HintType.Blue
TargetColor0 = New MyColor(215, 37, 155, 252)
TargetColor1 = New MyColor(215, 10, 142, 252)
- Case HintType.Finish
+ Case HintType.Green
TargetColor0 = New MyColor(215, 33, 177, 33)
TargetColor1 = New MyColor(215, 29, 160, 29)
- Case Else 'HintType.Critical
+ Case Else 'HintType.Red
TargetColor0 = New MyColor(215, 255, 53, 11)
TargetColor1 = New MyColor(215, 255, 43, 0)
End Select
@@ -490,7 +479,7 @@ EndHint:
''' 是否为 “执行事件”。
'''
Public IsEvent As Boolean
- Public EventType As String
+ Public EventType As CustomEvent.EventType
Public EventData As String
'''
''' 若非执行事件,其对应的 .xaml 本地文件内容。
@@ -504,7 +493,7 @@ EndHint:
'''
Public Sub New(FilePath As String)
RawPath = FilePath
- Dim JsonData As JObject = GetJson(HelpArgumentReplace(ReadFile(FilePath)))
+ Dim JsonData As JObject = GetJson(ArgumentReplace(ReadFile(FilePath), AddressOf EscapeXML))
If JsonData Is Nothing Then Throw New FileNotFoundException("未找到帮助文件:" & FilePath, FilePath)
'加载常规信息
If JsonData("Title") IsNot Nothing Then
@@ -524,8 +513,7 @@ EndHint:
Next
'加载事件信息
If If(JsonData("IsEvent"), False) Then
- EventType = JsonData("EventType")
- If EventType Is Nothing Then Throw New ArgumentException("未找到 EventType 项")
+ EventType = [Enum].Parse(GetType(CustomEvent.EventType), JsonData("EventType").ToString)
EventData = If(JsonData("EventData"), "")
IsEvent = True
Else
@@ -550,7 +538,7 @@ EndHint:
Public Function SetToListItem(Item As MyListItem) As MyListItem
Dim Logo As String
If IsEvent Then
- If EventType = "弹出窗口" Then
+ If EventType = CustomEvent.EventType.弹出窗口 Then
Logo = PathImage & "Blocks/GrassPath.png"
Else
Logo = PathImage & "Blocks/CommandBlock.png"
@@ -567,9 +555,9 @@ EndHint:
.Height = 42
.Type = MyListItem.CheckType.Clickable
.Tag = Me
- .EventType = Nothing
- .EventData = Nothing
End With
+ CustomEventService.SetEventType(Item, CustomEvent.EventType.None) '清空自定义事件属性,它们会被下面的点击事件处理
+ CustomEventService.SetEventData(Item, Nothing)
'项目的点击事件
AddHandler Item.Click, Sub(sender, e) PageOtherHelp.OnItemClick(sender.Tag)
Return Item
@@ -669,15 +657,6 @@ NextFile:
Log("[Help] 已解压内置帮助文件,目前状态:" & File.Exists(PathTemp & "Help\启动器\备份设置.xaml"), LogLevel.Debug)
End If
End Sub
- '''
- ''' 对帮助文件约定的替换标记进行处理,如果遇到需要转义的字符会进行转义。
- '''
- Public Function HelpArgumentReplace(Xaml As String) As String
- Dim Result = Xaml.Replace("{path}", EscapeXML(Path))
- Result = Result.RegexReplaceEach("\{hint\}", Function() EscapeXML(PageOtherTest.GetRandomHint()))
- Result = Result.RegexReplaceEach("\{cave\}", Function() EscapeXML(PageOtherTest.GetRandomCave()))
- Return Result
- End Function
#End Region
@@ -836,6 +815,78 @@ NextFile:
End Using
End Sub
+ '''
+ ''' 对替换标记进行处理。会对替换内容使用 EscapeHandler 进行转义。
+ '''
+ Public Function ArgumentReplace(Text As String, Optional EscapeHandler As Func(Of String, String) = Nothing, Optional ReplaceTime As Boolean = True) As String
+ '预处理
+ If Text Is Nothing Then Return Nothing
+ Dim Replacer =
+ Function(s As String) As String
+ If s Is Nothing Then Return ""
+ If EscapeHandler Is Nothing Then Return s
+ If s.Contains(":\") Then s = ShortenPath(s)
+ Return EscapeHandler(s)
+ End Function
+ '基础
+ Text = Text.Replace("{pcl_version}", Replacer(VersionBaseName))
+ Text = Text.Replace("{pcl_version_code}", Replacer(VersionCode))
+ Text = Text.Replace("{pcl_version_branch}", Replacer(VersionBranchName))
+ Text = Text.Replace("{pcl_branch}", Replacer(VersionBranchMain))
+ Text = Text.Replace("{identify}", Replacer(Identify))
+ Text = Text.Replace("{path}", Replacer(Path))
+ Text = Text.Replace("{path_with_name}", Replacer(PathWithName))
+ Text = Text.Replace("{path_temp}", Replacer(PathTemp))
+ '时间
+ If ReplaceTime Then '在窗口标题中,时间会被后续动态替换,所以此时不应该替换
+ Text = Text.Replace("{date}", Replacer(Date.Now.ToString("yyyy/M/d")))
+ Text = Text.Replace("{time}", Replacer(Date.Now.ToString("HH:mm:ss")))
+ End If
+ 'Minecraft
+ Text = Text.Replace("{java}", Replacer(McLaunchJavaSelected?.PathFolder))
+ Text = Text.Replace("{minecraft}", Replacer(PathMcFolder))
+ If McVersionCurrent IsNot Nothing Then
+ Text = Text.Replace("{version_path}", Replacer(McVersionCurrent.Path)) : Text = Text.Replace("{verpath}", Replacer(McVersionCurrent.Path))
+ Text = Text.Replace("{version_indie}", Replacer(McVersionCurrent.PathIndie)) : Text = Text.Replace("{verindie}", Replacer(McVersionCurrent.PathIndie))
+ Text = Text.Replace("{name}", Replacer(McVersionCurrent.Name))
+ If {"unknown", "old", "pending"}.Contains(McVersionCurrent.Version.McName.ToLower) Then
+ Text = Text.Replace("{version}", Replacer(McVersionCurrent.Name))
+ Else
+ Text = Text.Replace("{version}", Replacer(McVersionCurrent.Version.McName))
+ End If
+ Else
+ Text = Text.Replace("{version_path}", Replacer(Nothing)) : Text = Text.Replace("{verpath}", Replacer(Nothing))
+ Text = Text.Replace("{version_indie}", Replacer(Nothing)) : Text = Text.Replace("{verindie}", Replacer(Nothing))
+ Text = Text.Replace("{name}", Replacer(Nothing))
+ Text = Text.Replace("{version}", Replacer(Nothing))
+ End If
+ '登录信息
+ If McLoginLoader.State = LoadState.Finished Then
+ Text = Text.Replace("{user}", Replacer(McLoginLoader.Output.Name))
+ Text = Text.Replace("{uuid}", Replacer(McLoginLoader.Output.Uuid.ToLower))
+ Select Case McLoginLoader.Input.Type
+ Case McLoginType.Legacy
+ Text = Text.Replace("{login}", Replacer("离线"))
+ Case McLoginType.Ms
+ Text = Text.Replace("{login}", Replacer("正版"))
+ Case McLoginType.Nide
+ Text = Text.Replace("{login}", Replacer("统一通行证"))
+ Case McLoginType.Auth
+ Text = Text.Replace("{login}", Replacer("Authlib-Injector"))
+ End Select
+ Else
+ Text = Text.Replace("{user}", Replacer(Nothing))
+ Text = Text.Replace("{uuid}", Replacer(Nothing))
+ Text = Text.Replace("{login}", Replacer(Nothing))
+ End If
+ '高级
+ Text = Text.RegexReplaceEach("\{hint\}", Function() Replacer(PageOtherTest.GetRandomHint()))
+ Text = Text.RegexReplaceEach("\{cave\}", Function() Replacer(PageOtherTest.GetRandomCave()))
+ Text = Text.RegexReplaceEach("\{setup:([a-zA-Z0-9]+)\}", Function(m) Replacer(Setup.GetSafe(m.Groups(1).Value, McVersionCurrent)))
+ Text = Text.RegexReplaceEach("\{varible:([^\}]+)\}", Function(m) Replacer(ReadReg("CustomEvent" & m.Groups(1).Value, Nothing)))
+ Return Text
+ End Function
+
#End Region
#Region "任务缓存"
diff --git a/Plain Craft Launcher 2/Modules/ModMusic.vb b/Plain Craft Launcher 2/Modules/ModMusic.vb
index 0476e89..403ceee 100644
--- a/Plain Craft Launcher 2/Modules/ModMusic.vb
+++ b/Plain Craft Launcher 2/Modules/ModMusic.vb
@@ -111,7 +111,7 @@
'''
Public Sub MusicControlPause()
If MusicNAudio Is Nothing Then
- Hint("音乐播放尚未开始!", HintType.Critical)
+ Hint("音乐播放尚未开始!", HintType.Red)
Else
Select Case MusicState
Case MusicStates.Pause
@@ -131,14 +131,14 @@
Public Sub MusicControlNext()
If MusicAllList.Count = 1 Then
MusicStartPlay(MusicCurrent)
- Hint("重新播放:" & GetFileNameFromPath(MusicCurrent), HintType.Finish)
+ Hint("重新播放:" & GetFileNameFromPath(MusicCurrent), HintType.Green)
Else
Dim Address As String = DequeueNextMusicAddress()
If Address Is Nothing Then
- Hint("没有可以播放的音乐!", HintType.Critical)
+ Hint("没有可以播放的音乐!", HintType.Red)
Else
MusicStartPlay(Address)
- Hint("正在播放:" & GetFileNameFromPath(Address), HintType.Finish)
+ Hint("正在播放:" & GetFileNameFromPath(Address), HintType.Green)
End If
End If
MusicRefreshUI()
@@ -182,19 +182,19 @@
MusicListInit(True)
If Not MusicAllList.Any() Then
If MusicNAudio Is Nothing Then
- If ShowHint Then Hint("未检测到可用的背景音乐!", HintType.Critical)
+ If ShowHint Then Hint("未检测到可用的背景音乐!", HintType.Red)
Else
MusicNAudio = Nothing
- If ShowHint Then Hint("背景音乐已清除!", HintType.Finish)
+ If ShowHint Then Hint("背景音乐已清除!", HintType.Green)
End If
Else
Dim Address As String = DequeueNextMusicAddress()
If Address Is Nothing Then
- If ShowHint Then Hint("没有可以播放的音乐!", HintType.Critical)
+ If ShowHint Then Hint("没有可以播放的音乐!", HintType.Red)
Else
Try
MusicStartPlay(Address, IsFirstLoad)
- If ShowHint Then Hint("背景音乐已刷新:" & GetFileNameFromPath(Address), HintType.Finish, False)
+ If ShowHint Then Hint("背景音乐已刷新:" & GetFileNameFromPath(Address), HintType.Green, False)
Catch
End Try
End If
@@ -303,18 +303,18 @@
Catch ex As Exception
Log(ex, "播放音乐出现内部错误(" & MusicCurrent & ")", LogLevel.Developer)
If TypeOf ex Is NAudio.MmException AndAlso ex.Message.Contains("AlreadyAllocated") Then
- Hint("你的音频设备正被其他程序占用。请在关闭占用的程序后重启 PCL,才能恢复音乐播放功能!", HintType.Critical)
+ Hint("你的音频设备正被其他程序占用。请在关闭占用的程序后重启 PCL,才能恢复音乐播放功能!", HintType.Red)
Thread.Sleep(1000000000)
End If
If TypeOf ex Is NAudio.MmException AndAlso (ex.Message.Contains("NoDriver") OrElse ex.Message.Contains("BadDeviceId")) Then
- Hint("由于音频设备变更,音乐播放功能在重启 PCL 后才能恢复!", HintType.Critical)
+ Hint("由于音频设备变更,音乐播放功能在重启 PCL 后才能恢复!", HintType.Red)
Thread.Sleep(1000000000)
End If
If ex.Message.Contains("Got a frame at sample rate") OrElse ex.Message.Contains("does not support changes to") Then
- Hint("播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & "):PCL 不支持播放音频属性在中途发生变化的音乐", HintType.Critical)
+ Hint("播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & "):PCL 不支持播放音频属性在中途发生变化的音乐", HintType.Red)
ElseIf Not (MusicCurrent.EndsWithF(".wav", True) OrElse MusicCurrent.EndsWithF(".mp3", True) OrElse MusicCurrent.EndsWithF(".flac", True)) OrElse
ex.Message.Contains("0xC00D36C4") Then '#5096:不支持给定的 URL 的字节流类型。 (异常来自 HRESULT:0xC00D36C4)
- Hint("播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & "):PCL 可能不支持此音乐格式,请将格式转换为 .wav、.mp3 或 .flac 后再试", HintType.Critical)
+ Hint("播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & "):PCL 可能不支持此音乐格式,请将格式转换为 .wav、.mp3 或 .flac 后再试", HintType.Red)
Else
Log(ex, "播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & ")", LogLevel.Hint)
End If
diff --git a/Plain Craft Launcher 2/Modules/ModSecret.vb b/Plain Craft Launcher 2/Modules/ModSecret.vb
index 672ea2a..f4bd63c 100644
--- a/Plain Craft Launcher 2/Modules/ModSecret.vb
+++ b/Plain Craft Launcher 2/Modules/ModSecret.vb
@@ -6,6 +6,8 @@ Friend Module ModSecret
#Region "杂项"
+ '标注 PCL 的不同分支,仅用于替换标记
+ Public Const VersionBranchMain As String = "OpenSource"
'在开源版的注册表与常规版的注册表隔离,以防数据冲突
Public Const RegFolder As String = "PCLDebug"
'用于微软登录的 ClientId
@@ -56,13 +58,13 @@ Friend Module ModSecret
'''
''' 获取设备标识码。
'''
- Friend Function SecretGetUniqueAddress() As String
+ Friend Function SecretGetIdentify() As String
Return "0000-0000-0000-0000"
End Function
Friend Sub SecretLaunchJvmArgs(ByRef DataList As List(Of String))
Dim DataJvmCustom As String = Setup.Get("VersionAdvanceJvm", Version:=McVersionCurrent)
- DataList.Insert(0, If(DataJvmCustom = "", Setup.Get("LaunchAdvanceJvm"), DataJvmCustom)) '可变 JVM 参数
+ DataList.Insert(0, ArgumentReplace(If(DataJvmCustom = "", Setup.Get("LaunchAdvanceJvm"), DataJvmCustom))) '可变 JVM 参数
McLaunchLog("当前剩余内存:" & Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10 & "G")
DataList.Add("-Xmn" & Math.Floor(PageVersionSetup.GetRam(McVersionCurrent) * 1024 * 0.15) & "m")
DataList.Add("-Xmx" & Math.Floor(PageVersionSetup.GetRam(McVersionCurrent) * 1024) & "m")
diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb
index ac15996..5813168 100644
--- a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb
+++ b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
' 方法是按如下所示使用“*”
-
-
+
+
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.vb
index 9d2dae5..fda60b1 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.vb
@@ -290,9 +290,9 @@
Sub(MyLoader)
Select Case MyLoader.State
Case LoadState.Failed
- Hint(MyLoader.Name & "失败:" & MyLoader.Error.GetBrief(), HintType.Critical)
+ Hint(MyLoader.Name & "失败:" & MyLoader.Error.GetBrief(), HintType.Red)
Case LoadState.Aborted
- Hint(MyLoader.Name & "已取消!", HintType.Info)
+ Hint(MyLoader.Name & "已取消!", HintType.Blue)
Case LoadState.Loading
Return '不重新加载版本列表
End Select
@@ -326,7 +326,7 @@
Dim DefaultFolder As String = Nothing
If File.Type <> CompType.ModPack Then
Dim SubFolder As String = Nothing
- Select Case Project.Type
+ Select Case File.Type
Case CompType.Mod : SubFolder = "mods\"
Case CompType.ResourcePack : SubFolder = "resourcepacks\"
Case CompType.Shader : SubFolder = "shaderpacks\"
@@ -346,7 +346,7 @@
Function(Version)
If Not Version.IsLoaded Then Version.Load()
'只对 Mod 和数据包进行版本检测
- If Project.Type = CompType.Mod OrElse Project.Type = CompType.DataPack Then
+ If File.Type = CompType.Mod OrElse File.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
@@ -359,8 +359,8 @@
Return False
End Function
'获取常规资源默认下载位置
- If CachedFolder.ContainsKey(Project.Type) Then
- DefaultFolder = CachedFolder(Project.Type)
+ If CachedFolder.ContainsKey(File.Type) Then
+ DefaultFolder = CachedFolder(File.Type)
Log($"[Comp] 使用上次下载时的文件夹作为默认下载位置:{DefaultFolder}")
ElseIf McVersionCurrent IsNot Nothing AndAlso IsVersionSuitable(McVersionCurrent) Then
DefaultFolder = $"{McVersionCurrent.PathIndie}{SubFolder}"
@@ -425,7 +425,7 @@
If Not Target.Contains("\") Then Return
'构造步骤加载器
Dim LoaderName As String = Desc & "下载:" & IO.Path.GetFileNameWithoutExtension(Target) & " "
- If Target <> DefaultFolder Then CachedFolder(Project.Type) = GetPathFromFullPath(Target)
+ If Target <> DefaultFolder Then CachedFolder(File.Type) = GetPathFromFullPath(Target)
Dim Loaders As New List(Of LoaderBase)
Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.ToNetFile(Target)}) With {.ProgressWeight = 6, .Block = True})
'启动
diff --git a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb
index a19a93c..6e1d801 100644
--- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb
+++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb
@@ -32,7 +32,7 @@ Public Module ModDownloadLib
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For
If Behaviour = NetPreDownloadBehaviour.ExitWhileExistsOrDownloading Then Return OngoingLoader
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return OngoingLoader
Next
@@ -223,7 +223,7 @@ Public Module ModDownloadLib
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"Minecraft {Id} 服务端下载" Then Continue For
- Hint("该服务端正在下载中!", HintType.Critical)
+ Hint("该服务端正在下载中!", HintType.Red)
Return
Next
@@ -241,7 +241,7 @@ Public Module ModDownloadLib
File.Delete(VersionFolder & Id & ".json")
If Not New DirectoryInfo(VersionFolder).GetFileSystemInfos.Any() Then Directory.Delete(VersionFolder)
Task.Output = New List(Of NetFile)
- Hint($"Mojang 没有给 Minecraft {Id} 提供官方服务端下载,没法下,撤退!", HintType.Critical)
+ Hint($"Mojang 没有给 Minecraft {Id} 提供官方服务端下载,没法下,撤退!", HintType.Red)
Thread.Sleep(2000) '等玩家把上一个提示看完
Task.Abort()
Return
@@ -300,7 +300,7 @@ pause"
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return
Next
@@ -401,7 +401,7 @@ pause"
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"OptiFine {DownloadInfo.NameDisplay} 下载" Then Continue For
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return
Next
@@ -832,7 +832,7 @@ Retry:
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"LiteLoader {Id} 下载" Then Continue For
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return
Next
@@ -866,7 +866,7 @@ Retry:
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"LiteLoader {Id} 下载" Then Continue For
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return
Next
@@ -1048,7 +1048,7 @@ Retry:
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"{DisplayName} 下载" Then Continue For
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return
Next
@@ -1803,7 +1803,7 @@ Retry:
'重复任务检查
For Each OngoingLoader In LoaderTaskbar.ToList()
If OngoingLoader.Name <> $"Fabric {Version} 安装器下载" Then Continue For
- Hint("该版本正在下载中!", HintType.Critical)
+ Hint("该版本正在下载中!", HintType.Red)
Return
Next
@@ -1986,28 +1986,28 @@ Retry:
''' 在加载器状态改变后显示一条提示。
''' 不会进行任何其他操作。
'''
- Public Sub LoaderStateChangedHintOnly(Loader)
+ Public Sub LoaderStateChangedHintOnly(Loader As LoaderBase)
Select Case Loader.State
Case LoadState.Finished
- Hint(Loader.Name & "成功!", HintType.Finish)
+ Hint(Loader.Name & "成功!", HintType.Green)
Case LoadState.Failed
- Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Critical)
+ Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Red)
Case LoadState.Aborted
- Hint(Loader.Name & "已取消!", HintType.Info)
+ Hint(Loader.Name & "已取消!", HintType.Blue)
End Select
End Sub
'''
''' 安装加载器状态改变后进行提示和重载文件夹列表的方法。
'''
- Public Sub McInstallState(Loader)
+ Public Sub McInstallState(Loader As LoaderBase)
Select Case Loader.State
Case LoadState.Finished
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '清空缓存(合并安装会先生成文件夹,这会在刷新时误判为可以使用缓存)
- Hint(Loader.Name & "成功!", HintType.Finish)
+ Hint(Loader.Name & "成功!", HintType.Green)
Case LoadState.Failed
- Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Critical)
+ Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Red)
Case LoadState.Aborted
- Hint(Loader.Name & "已取消!", HintType.Info)
+ Hint(Loader.Name & "已取消!", HintType.Blue)
Case LoadState.Loading
Return '不重新加载版本列表
End Select
@@ -2108,7 +2108,7 @@ Retry:
'重复版本检查
If File.Exists($"{VersionFolder}{Request.TargetVersionName}.json") Then
- Hint("版本 " & Request.TargetVersionName & " 已经存在!", HintType.Critical)
+ Hint("版本 " & Request.TargetVersionName & " 已经存在!", HintType.Red)
Throw New CancelledException
End If
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml b/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml
index 1144f09..83f5368 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml
@@ -1,8 +1,8 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:PCL"
+ RenderTransformOrigin="0,0.5" UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="25">
@@ -23,17 +23,17 @@
-
-
+
-
-
-
+
+
+
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb
index dd48c06..576c6dc 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb
@@ -89,14 +89,14 @@
$"登录网页将自动开启,请在网页中输入 {UserCode}(已自动复制)。" & vbCrLf & vbCrLf &
$"如果网络环境不佳,网页可能一直加载不出来,届时请使用加速器或 VPN 改善网络环境。" & vbCrLf &
$"你也可以用其他设备打开 {Website} 并输入上述代码。"
- Btn1.EventData = Website
- Btn2.EventData = UserCode
+ CustomEventService.SetEventData(Btn1, Website)
+ CustomEventService.SetEventData(Btn2, UserCode)
'启动工作线程
RunInNewThread(AddressOf WorkThread, "MyMsgLogin")
End Sub
Private Sub WorkThread()
- Thread.Sleep(3000)
+ Thread.Sleep(2000)
If MyConverter.IsExited Then Return
OpenWebsite(Website)
ClipboardSet(UserCode)
@@ -118,7 +118,7 @@
'获取结果
Dim ResultJson As JObject = GetJson(Result)
McLaunchLog($"令牌过期时间:{ResultJson("expires_in")} 秒")
- Hint("网页登录成功!", HintType.Finish)
+ Hint("网页登录成功!", HintType.Green)
Finished({ResultJson("access_token").ToString, ResultJson("refresh_token").ToString})
Return
Catch ex As Exception
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb
index 352c69b..2715ec8 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb
@@ -47,7 +47,7 @@
Public Shared Sub Save(Loader As LoaderTask(Of EqualableList(Of String), String))
Dim Address = Loader.Output
If Not Loader.State = LoadState.Finished Then
- Hint("皮肤正在获取中,请稍候!", HintType.Critical)
+ Hint("皮肤正在获取中,请稍候!", HintType.Red)
If Not Loader.State = LoadState.Loading Then Loader.Start()
Return
End If
@@ -61,7 +61,7 @@
Else
CopyFile(Address, FileAddress)
End If
- Hint("皮肤保存成功!", HintType.Finish)
+ Hint("皮肤保存成功!", HintType.Green)
End If
Catch ex As Exception
Log(ex, "保存皮肤失败", LogLevel.Hint)
@@ -143,7 +143,7 @@
Next
If FrmLaunchLeft IsNot Nothing AndAlso HasLoaderRunning Then
'由于 Abort 不是实时的,暂时不会释放文件,会导致删除报错,故只能取消执行
- Hint("有正在获取中的皮肤,请稍后再试!", HintType.Info)
+ Hint("有正在获取中的皮肤,请稍后再试!", HintType.Blue)
Else
RunInThread(
Sub()
@@ -161,7 +161,7 @@
For Each SkinLoader In If(sender IsNot Nothing, {sender}, {PageLaunchLeft.SkinLegacy, PageLaunchLeft.SkinMs})
SkinLoader.WaitForExit(IsForceRestart:=True)
Next
- Hint("已刷新头像!", HintType.Finish)
+ Hint("已刷新头像!", HintType.Green)
Catch ex As Exception
Log(ex, "刷新皮肤缓存失败", LogLevel.Msgbox)
End Try
@@ -184,7 +184,7 @@
SkinLoader.WaitForExit(IsForceRestart:=True)
Next
'完成提示
- Hint("更改皮肤成功!", HintType.Finish)
+ Hint("更改皮肤成功!", HintType.Green)
Catch ex As Exception
Log(ex, "更改正版皮肤后刷新皮肤失败", LogLevel.Feedback)
End Try
@@ -212,7 +212,7 @@
Return
End If
If McLoginMsLoader.State = LoadState.Failed Then
- Hint("登录失败,无法更改披风!", HintType.Critical)
+ Hint("登录失败,无法更改披风!", HintType.Red)
Return
End If
Hint("正在获取披风列表,请稍候……")
@@ -225,7 +225,7 @@ Retry:
'获取登录信息
If McLoginMsLoader.State <> LoadState.Finished Then McLoginMsLoader.WaitForExit(PageLoginMsSkin.GetLoginData())
If McLoginMsLoader.State <> LoadState.Finished Then
- Hint("登录失败,无法更改披风!", HintType.Critical)
+ Hint("登录失败,无法更改披风!", HintType.Red)
Return
End If
Dim AccessToken As String = McLoginMsLoader.Output.AccessToken
@@ -265,10 +265,10 @@ Retry:
ContentType:="application/json",
Headers:={{"Authorization", "Bearer " & AccessToken}})
If Result.Contains("""errorMessage""") Then
- Hint("更改披风失败:" & GetJson(Result)("errorMessage").ToString, HintType.Critical)
+ Hint("更改披风失败:" & GetJson(Result)("errorMessage").ToString, HintType.Red)
Return
Else
- Hint("更改披风成功!", HintType.Finish)
+ Hint("更改披风成功!", HintType.Green)
End If
Catch ex As Exception
Log(ex, "更改披风失败", LogLevel.Hint)
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb
index 65b5086..260fed3 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb
@@ -134,6 +134,8 @@ Public Class PageLaunchRight
Private Sub OnlineLoaderSub(Task As LoaderTask(Of String, Integer))
Dim Address As String = Task.Input '#3721 中连续触发两次导致内容变化
Try
+ '替换自定义变量与设置
+ Address = ArgumentReplace(Address, AddressOf WebUtility.HtmlEncode)
'获取版本校验地址
Dim VersionAddress As String
If Address.Contains(".xaml") Then
@@ -146,29 +148,27 @@ Public Class PageLaunchRight
End If
'校验版本
Dim Version As String = ""
- Dim NeedDownload As Boolean = True
Try
Version = NetRequestByClientRetry(VersionAddress)
If Version.Length > 1000 Then Throw New Exception($"获取的主页版本过长({Version.Length} 字符)")
Dim CurrentVersion As String = Setup.Get("CacheSavedPageVersion")
If Version <> "" AndAlso CurrentVersion <> "" AndAlso Version = CurrentVersion Then
Log($"[Page] 当前缓存的主页已为最新,当前版本:{Version},检查源:{VersionAddress}")
- NeedDownload = False
- Else
- Log($"[Page] 需要下载联网主页,当前版本:{Version},检查源:{VersionAddress}")
+ Return
End If
+ Log($"[Page] 需要下载联网主页,当前版本:{Version},检查源:{VersionAddress}")
Catch exx As Exception
Log(exx, $"联网获取主页版本失败", LogLevel.Developer)
Log($"[Page] 无法检查联网主页版本,将直接下载,检查源:{VersionAddress}")
End Try
'实际下载
- If Not NeedDownload Then Return
Dim FileContent As String = NetRequestByClientRetry(Address)
Log($"[Page] 已联网下载主页,内容长度:{FileContent.Length},来源:{Address}")
Setup.Set("CacheSavedPageUrl", Address)
Setup.Set("CacheSavedPageVersion", Version)
WriteFile(PathTemp & "Cache\Custom.xaml", FileContent)
- Refresh() '要求刷新
+ '若内容变更则要求刷新
+ If LoadedContentHash <> FileContent.GetHashCode() Then Refresh()
Catch ex As Exception
Log(ex, $"下载主页失败({Address})", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
End Try
@@ -220,7 +220,7 @@ Public Class PageLaunchRight
End If
Dim LoadStartTime As Date = Date.Now
'修改时应同时修改 PageOtherHelpDetail.Init
- Content = HelpArgumentReplace(Content)
+ Content = ArgumentReplace(Content, AddressOf EscapeXML)
Do While Content.Contains("xmlns")
Content = Content.RegexReplace("xmlns[^""']*(""|')[^""']*(""|')", "").Replace("xmlns", "") '禁止声明命名空间
Loop
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginAuthSkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginAuthSkin.xaml.vb
index 56970a4..a339893 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginAuthSkin.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginAuthSkin.xaml.vb
@@ -50,7 +50,7 @@
If CType(McLoginLoader.Input, McLoginServer).ForceReselectProfile Then
Hint("正在尝试更换,请稍候!")
Else
- Hint("正在登录中,请稍后再更换角色!", HintType.Critical)
+ Hint("正在登录中,请稍后再更换角色!", HintType.Red)
End If
Return
End If
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb
index 33cafbb..780d8d6 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb
@@ -68,7 +68,7 @@ Public Class PageLoginLegacy
End Sub
Private Sub Skin_Click() Handles Skin.Click
If (Setup.Get("UiHiddenPageSetup") OrElse Setup.Get("UiHiddenSetupLaunch")) AndAlso Not PageSetupUI.HiddenForceShow Then
- Hint("启动设置已被禁用!", HintType.Critical)
+ Hint("启动设置已被禁用!", HintType.Red)
Else
FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupLaunch) '切换到皮肤设置页面
End If
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml
index cf470d4..8364edd 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml
@@ -27,9 +27,9 @@
-
-
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb
index ae823a7..0d5ed36 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb
@@ -90,7 +90,7 @@
Catch ex As Exception
If ex.Message = "$$" Then
ElseIf ex.Message.StartsWith("$") Then
- Hint(ex.Message.TrimStart("$"), HintType.Critical)
+ Hint(ex.Message.TrimStart("$"), HintType.Red)
ElseIf TypeOf ex Is Security.Authentication.AuthenticationException AndAlso ex.Message.ContainsF("SSL/TLS") Then
Log(ex, "正版登录验证失败,请考虑在 [设置 → 其他] 中关闭 [在正版登录时验证 SSL 证书],然后再试。" & vbCrLf & vbCrLf & "原始错误信息:", LogLevel.Msgbox)
Else
diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb
index 4b808f9..7199516 100644
--- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb
@@ -77,7 +77,7 @@
Return
End If
If McLoginLoader.State = LoadState.Failed Then
- Hint("登录失败,无法更改皮肤!", HintType.Critical)
+ Hint("登录失败,无法更改皮肤!", HintType.Red)
Return
End If
Dim SkinInfo As McSkinInfo = McSkinSelect()
@@ -106,7 +106,7 @@ Retry:
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
GoTo Retry
ElseIf Result.Contains("""error""") Then
- Hint("更改皮肤失败:" & GetJson(Result)("error").ToString, HintType.Critical)
+ Hint("更改皮肤失败:" & GetJson(Result)("error").ToString, HintType.Red)
Return
End If
'获取新皮肤地址
@@ -122,7 +122,7 @@ Retry:
Throw New Exception("未知错误(" & Result & ")")
Catch ex As Exception
If TypeOf ex Is OperationCanceledException Then
- Hint("更改皮肤失败:连接皮肤服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Critical)
+ Hint("更改皮肤失败:连接皮肤服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Red)
Else
Log(ex, "更改皮肤失败", LogLevel.Hint)
End If
diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml
index a64acc2..143d253 100644
--- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml
+++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml
@@ -8,29 +8,10 @@
-
-
-
-
-
-
-
diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml
index 9cf794e..fd4a3b0 100644
--- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml
+++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkHiper.xaml
@@ -83,7 +83,7 @@
-
+
@@ -229,7 +229,6 @@
-
diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml
index cc093ec..7a63bb3 100644
--- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml
+++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml
@@ -44,7 +44,7 @@
-
+
diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb
index f1e6312..b398ac3 100644
--- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb
@@ -121,26 +121,7 @@ Public Class PageLinkIoi
''' 获取当前的玩家名。
'''
Public Shared Function GetPlayerName() As String
- '自动生成玩家名
- If AutogenPlayerName Is Nothing Then
- If IsPlayerNameValid(McLoginName) Then
- AutogenPlayerName = McLoginName()
- Else
- AutogenPlayerName = "玩家 " & CType(GetHash(If(UniqueAddress, "")) Mod 1048576, Integer).ToString("x5").ToUpper
- End If
- End If
- '获取玩家自定义的名称
- Dim CustomName As String = Setup.Get("LinkName").ToString.Trim()
- If CustomName <> "" Then
- If IsPlayerNameValid(CustomName) Then
- Return CustomName.Trim
- Else
- Hint("你所设置的玩家名存在异常,已被重置!", HintType.Critical)
- Setup.Set("LinkName", "")
- End If
- End If
- '使用自动生成的玩家名
- Return AutogenPlayerName
+ Return ""
End Function
Private Shared AutogenPlayerName As String = Nothing '并非由玩家自定义,而是自动生成的玩家名
'''
diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml b/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml
index 0f8afa1..7e3bf33 100644
--- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml
+++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml
@@ -29,8 +29,10 @@
-
-
+
+
@@ -51,11 +53,11 @@
-
+
-
+
-
+
@@ -105,288 +107,217 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -395,7 +326,7 @@
-
+
@@ -410,8 +341,8 @@
-
-
+
+
@@ -443,49 +374,49 @@
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/00ll00/java_launch_wrapper" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/00ll00/java_launch_wrapper?tab=MIT-1-ov-file#readme" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://www.newtonsoft.com/json" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://opensource.org/licenses/MIT" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/naudio/NAudio" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/naudio/NAudio/blob/master/license.txt" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://www.ookii.org/Software/Dialogs/" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/caioproiete/ookii-dialogs-wpf/blob/master/LICENSE" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://iconmonstr.com/" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://iconmonstr.com/license/" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/imazen/libwebp-net" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://github.com/imazen/libwebp-net/blob/master/LICENSE.txt" />
+ local:CustomEventService.EventType="打开网页" local:CustomEventService.EventData="https://www.iconfont.cn/" />
diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml.vb b/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml.vb
index 13e7a3f..cbaec36 100644
--- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherAbout.xaml.vb
@@ -18,8 +18,8 @@
End Sub
- Public Shared Sub CopyUniqueAddress() Handles BtnDonateCopy.Click
- ClipboardSet(UniqueAddress)
+ Public Shared Sub CopyIdentify() Handles BtnDonateCopy.Click
+ ClipboardSet(Identify)
End Sub
Private Sub BtnDonateCodeInput_Click() Handles BtnDonateInput.Click
DonateCodeInput()
diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelp.xaml.vb b/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelp.xaml.vb
index 2802cd4..6fd927f 100644
--- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelp.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelp.xaml.vb
@@ -71,7 +71,7 @@
Public Shared Sub OnItemClick(Entry As HelpEntry)
Try
If Entry.IsEvent Then
- ModEvent.ProcessCustomEvents(Entry.EventType, Entry.EventData, Nothing)
+ CustomEvent.Raise(Entry.EventType, Entry.EventData)
Else
EnterHelpPage(Entry)
End If
diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelpDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelpDetail.xaml.vb
index dafcd2e..9d6b223 100644
--- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelpDetail.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherHelpDetail.xaml.vb
@@ -18,8 +18,10 @@
If Content = "" Then Throw New Exception("帮助 xaml 文件为空")
Try
'修改时应同时修改 PageLaunchRight.LoadContent
- Content = HelpArgumentReplace(Content)
- If Content.Contains("xmlns") Then Content = Content.RegexReplace("xmlns[^""']*(""|')[^""']*(""|')", "").Replace("xmlns", "") '禁止声明命名空间
+ Content = ArgumentReplace(Content, AddressOf EscapeXML)
+ Do While Content.Contains("xmlns")
+ Content = Content.RegexReplace("xmlns[^""']*(""|')[^""']*(""|')", "").Replace("xmlns", "") '禁止声明命名空间
+ Loop
Content = "" & Content & ""
Me.Entry = Entry
PanCustom.Children.Clear()
diff --git a/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb
index 7d8d927..4469cc2 100644
--- a/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSelectLeft.xaml.vb
@@ -150,14 +150,14 @@
Dim NewFolder As String = ""
'检查是否有下载任务
If HasDownloadingTask() Then
- Hint("在下载任务进行时,无法添加游戏文件夹!", HintType.Critical)
+ Hint("在下载任务进行时,无法添加游戏文件夹!", HintType.Red)
Return
End If
Try
'获取输入
NewFolder = SelectFolder()
If NewFolder = "" Then Return
- If NewFolder.Contains("!") OrElse NewFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Critical) : Return
+ If NewFolder.Contains("!") OrElse NewFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Red) : Return
'要求输入显示名称
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)
@@ -182,7 +182,7 @@
'检查文件夹权限
If Not CheckPermission(FolderPath) Then
If ShowHint Then
- Hint("添加文件夹失败:PCL 没有访问该文件夹的权限!", HintType.Critical)
+ Hint("添加文件夹失败:PCL 没有访问该文件夹的权限!", HintType.Red)
Return
Else
Throw New Exception("PCL 没有访问文件夹的权限:" & FolderPath)
@@ -207,12 +207,12 @@
If Folder.Split(">")(1) = FolderPath Then
IsAdded = True
If Folder.Split(">")(0) = DisplayName Then
- If ShowHint Then Hint("此文件夹已在列表中!", HintType.Info)
+ If ShowHint Then Hint("此文件夹已在列表中!", HintType.Blue)
Return
Else
Folders(i) = DisplayName & ">" & FolderPath
IsReplace = True
- If ShowHint Then Hint("文件夹名称已更新为 " & DisplayName & " !", HintType.Finish)
+ If ShowHint Then Hint("文件夹名称已更新为 " & DisplayName & " !", HintType.Green)
End If
Exit For
End If
@@ -226,7 +226,7 @@
McFolderListLoader.Start(IsForceRestart:=True)
'提示
If IsReplace Then Return
- If ShowHint Then Hint("文件夹 " & DisplayName & " 已添加!", HintType.Finish)
+ If ShowHint Then Hint("文件夹 " & DisplayName & " 已添加!", HintType.Green)
'检查是否为根目录整合包,自动关闭版本隔离
'1. 根目录中存在数个 Mod
Dim ModFolder As New DirectoryInfo(FolderPath & "mods\")
@@ -257,7 +257,7 @@
Public Sub Create_Click()
'检查是否有下载任务
If HasDownloadingTask() Then
- Hint("在下载任务进行时,无法创建游戏文件夹!", HintType.Critical)
+ Hint("在下载任务进行时,无法创建游戏文件夹!", HintType.Red)
Return
End If
If Not Directory.Exists(Path & ".minecraft\") Then
@@ -265,7 +265,7 @@
Directory.CreateDirectory(Path & ".minecraft\versions\")
Setup.Set("LaunchFolderSelect", "$.minecraft\")
McFolderLauncherProfilesJsonCreate(Path & ".minecraft\")
- Hint("新建 .minecraft 文件夹成功!", HintType.Finish)
+ Hint("新建 .minecraft 文件夹成功!", HintType.Green)
End If
McFolderListLoader.Start(IsForceRestart:=True)
End Sub
@@ -307,7 +307,7 @@
Next
'保存
Setup.Set("LaunchFolders", If(Not Folders.Any(), "", Join(Folders.ToArray, "|")))
- Hint(If(Folder.Type = McFolderType.Custom, "文件夹 " & Name & " 已从列表中移除!", "文件夹名称已复原!"), HintType.Finish)
+ Hint(If(Folder.Type = McFolderType.Custom, "文件夹 " & Name & " 已从列表中移除!", "文件夹名称已复原!"), HintType.Green)
McFolderListLoader.Start(IsForceRestart:=True)
Catch ex As Exception
@@ -336,10 +336,10 @@
Sub()
'删除文件夹
Try
- Hint("正在" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Info)
+ Hint("正在" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Blue)
DeleteDirectory(Folder.Path)
If DeleteText = "清空" Then Directory.CreateDirectory(Folder.Path)
- Hint("已" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Finish)
+ Hint("已" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Green)
Catch ex As Exception
Log(ex, DeleteText & "文件夹 " & Folder.Name & " 失败", LogLevel.Hint)
Finally
@@ -389,7 +389,7 @@
Next
'如果没有添加过,则添加进去(因为修改了默认项的名称)
If Not IsAdded Then Folders.Add(NewName & ">" & Folder.Path)
- Hint("文件夹名称已更新为 " & NewName & " !", HintType.Finish)
+ Hint("文件夹名称已更新为 " & NewName & " !", HintType.Green)
'保存
Setup.Set("LaunchFolders", Join(Folders.ToArray, "|"))
McFolderListLoader.Start(IsForceRestart:=True)
@@ -403,7 +403,7 @@
If Not e.RaiseByMouse OrElse Not sender.Checked Then Return
'检查是否有下载任务
If HasDownloadingTask(True) Then
- Hint("在下载任务进行时,无法切换游戏文件夹!", HintType.Critical)
+ Hint("在下载任务进行时,无法切换游戏文件夹!", HintType.Red)
e.Handled = True
Return
End If
diff --git a/Plain Craft Launcher 2/Pages/PageSelectRight.xaml.vb b/Plain Craft Launcher 2/Pages/PageSelectRight.xaml.vb
index e6e7d27..16bd2f8 100644
--- a/Plain Craft Launcher 2/Pages/PageSelectRight.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSelectRight.xaml.vb
@@ -114,22 +114,7 @@
Log(ex, "将版本列表转换显示时失败", LogLevel.Feedback)
End Try
End Sub
- Public Shared Function McVersionListItem(Version As McVersion) As MyListItem
- Dim NewItem As New MyListItem With {.Title = Version.Name, .Info = Version.Info, .Height = 42, .Tag = Version, .SnapsToDevicePixels = True, .Type = MyListItem.CheckType.Clickable}
- Try
- If Version.Logo.EndsWith("PCL\Logo.png") Then
- NewItem.Logo = Version.Path & "PCL\Logo.png" '修复老版本中,存储的自定义 Logo 使用完整路径,导致移动后无法加载的 Bug
- Else
- NewItem.Logo = Version.Logo
- End If
- Catch ex As Exception
- Log(ex, "加载版本图标失败", LogLevel.Hint)
- NewItem.Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png"
- End Try
- NewItem.ContentHandler = AddressOf McVersionListContent
- Return NewItem
- End Function
- Private Shared Sub McVersionListContent(sender As MyListItem, e As EventArgs)
+ Public Shared Sub McVersionListContent(sender As MyListItem, e As EventArgs)
Dim Version As McVersion = sender.Tag
'注册点击事件
AddHandler sender.Click, AddressOf Item_Click
@@ -225,10 +210,10 @@
IniClearCache(Version.Path & "PCL\Setup.ini")
If IsShiftPressed Then
DeleteDirectory(Version.Path)
- Hint("版本 " & Version.Name & " 已永久删除!", HintType.Finish)
+ Hint("版本 " & Version.Name & " 已永久删除!", HintType.Green)
Else
FileIO.FileSystem.DeleteDirectory(Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
- Hint("版本 " & Version.Name & " 已删除到回收站!", HintType.Finish)
+ Hint("版本 " & Version.Name & " 已删除!", HintType.Green)
End If
Case 2
Return
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb b/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb
index 38dca35..b18c083 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb
+++ b/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb
@@ -227,7 +227,7 @@
Me.Value = Value
Me.Source = Source
Me.Type = If(Value, New Object).GetType
- Me.DefaultValueEncoded = If(Encoded, SecretEncrypt(Value, "PCL" & UniqueAddress), Value)
+ Me.DefaultValueEncoded = If(Encoded, SecretEncrypt(Value, "PCL" & Identify), Value)
Catch ex As Exception
Log(ex, "初始化 SetupEntry 失败", LogLevel.Feedback) '#5095 的 fallback
End Try
@@ -241,6 +241,14 @@
Public Sub [Set](Key As String, Value As Object, Optional ForceReload As Boolean = False, Optional Version As McVersion = Nothing)
[Set](Key, Value, SetupDict(Key), ForceReload, Version)
End Sub
+ '''
+ ''' 写入某个未经加密的设置项。
+ ''' 若该设置项经过了加密,则会抛出异常。
+ '''
+ Public Sub SetSafe(Key As String, Value As Object, Optional ForceReload As Boolean = False, Optional Version As McVersion = Nothing)
+ If SetupDict(Key).Encoded Then Throw New InvalidOperationException("禁止写入加密设置项:" & Key)
+ [Set](Key, Version, ForceReload, Version)
+ End Sub
Private Sub [Set](Key As String, Value As Object, E As SetupEntry, ForceReload As Boolean, Version As McVersion)
Try
@@ -258,7 +266,7 @@
If E.Encoded Then
Try
If Value Is Nothing Then Value = ""
- Value = SecretEncrypt(Value, "PCL" & UniqueAddress)
+ Value = SecretEncrypt(Value, "PCL" & Identify)
Catch ex As Exception
Log(ex, "加密设置失败:" & Key, LogLevel.Developer)
End Try
@@ -303,9 +311,17 @@
''' 获取某个设置项的值。
'''
Public Function [Get](Key As String, Optional Version As McVersion = Nothing)
- If Not SetupDict.ContainsKey(Key) Then Throw New KeyNotFoundException("未找到设置项:" & Key) With {.Source = Key}
+ If Not SetupDict.ContainsKey(Key) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
Return [Get](Key, SetupDict(Key), Version)
End Function
+ '''
+ ''' 获取某个未经加密的设置项的值。
+ ''' 若该设置项经过了加密,则会抛出异常。
+ '''
+ Public Function GetSafe(Key As String, Optional Version As McVersion = Nothing)
+ If SetupDict(Key).Encoded Then Throw New InvalidOperationException("禁止读取加密设置项:" & Key)
+ Return [Get](Key, Version)
+ End Function
Private Function [Get](Key As String, E As SetupEntry, Version As McVersion)
'获取强制值
Dim Force As String = ForceValue(Key)
@@ -383,7 +399,7 @@
SourceValue = E.DefaultValue
Else
Try
- SourceValue = SecretDecrypt(SourceValue, "PCL" & UniqueAddress)
+ SourceValue = SecretDecrypt(SourceValue, "PCL" & Identify)
Catch ex As Exception
Log(ex, "解密设置失败:" & Key, LogLevel.Developer)
SourceValue = E.DefaultValue
@@ -601,8 +617,7 @@
FrmSetupUI.HintCustom.Visibility = Visibility.Visible
FrmSetupUI.HintCustomWarn.Visibility = If(Setup.Get("HintCustomWarn"), Visibility.Collapsed, Visibility.Visible)
FrmSetupUI.HintCustom.Text = $"从 PCL 文件夹下的 Custom.xaml 读取主页内容。{vbCrLf}你可以手动编辑该文件,向主页添加文本、图片、常用网站、快捷启动等功能。"
- FrmSetupUI.HintCustom.EventType = ""
- FrmSetupUI.HintCustom.EventData = ""
+ CustomEventService.SetEventType(FrmSetupUI.HintCustom, CustomEvent.EventType.None)
Case 2 '联网
FrmSetupUI.PanCustomPreset.Visibility = Visibility.Collapsed
FrmSetupUI.PanCustomLocal.Visibility = Visibility.Collapsed
@@ -610,8 +625,8 @@
FrmSetupUI.HintCustom.Visibility = Visibility.Visible
FrmSetupUI.HintCustomWarn.Visibility = If(Setup.Get("HintCustomWarn"), Visibility.Collapsed, Visibility.Visible)
FrmSetupUI.HintCustom.Text = $"从指定网址联网获取主页内容。服主也可以用于动态更新服务器公告。{vbCrLf}如果你制作了稳定运行的联网主页,可以点击这条提示投稿,若合格即可加入预设!"
- FrmSetupUI.HintCustom.EventType = "打开网页"
- FrmSetupUI.HintCustom.EventData = "https://github.com/Meloong-Git/PCL/discussions/2528"
+ CustomEventService.SetEventType(FrmSetupUI.HintCustom, CustomEvent.EventType.打开网页)
+ CustomEventService.SetEventData(FrmSetupUI.HintCustom, "https://github.com/Meloong-Git/PCL/discussions/2528")
Case 3 '预设
FrmSetupUI.PanCustomPreset.Visibility = Visibility.Visible
FrmSetupUI.PanCustomLocal.Visibility = Visibility.Collapsed
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml
index f207a1d..8adb4fa 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml
+++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml
@@ -41,9 +41,9 @@
-
+
-
+
@@ -240,13 +240,13 @@
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" />
-
-
+
+ ToolTip="在 MC 启动前执行特定命令或程序,语法与 Windows 的命令提示符一致。
你可以用替换标记来动态改变其内容或实现相对路径,在 更多 → 帮助 中搜索 “替换标记” 以了解用法。例如:
· "{verpath}test.exe" :运行版本文件夹下的 test.exe 程序
· "{java}java.exe" -jar "{verpath}test.jar" :用 Java 运行版本文件夹下的 test.jar
· notepad "{verindie}options.txt" :使用记事本打开该版本的设置文件
涉及路径的操作最好都打上双引号,以避免路径中的空格导致运行失败。
执行命令时,命令行所在的目录是当前的 .minecraft 文件夹。" />
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb
index d194840..cf5f028 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.vb
@@ -93,7 +93,7 @@
JavaSearchLoader.Start(IsForceRestart:=True)
Log("[Setup] 已初始化启动设置")
- Hint("已初始化启动设置!", HintType.Finish, False)
+ Hint("已初始化启动设置!", HintType.Green, False)
Catch ex As Exception
Log(ex, "初始化启动设置失败", LogLevel.Msgbox)
End Try
@@ -170,7 +170,7 @@
Try
File.Delete(PathAppdata & "CustomSkin.png")
RadioSkinType0.SetChecked(True, True)
- Hint("离线皮肤已清空!", HintType.Finish)
+ Hint("离线皮肤已清空!", HintType.Green)
Catch ex As Exception
Log(ex, "清空离线皮肤失败", LogLevel.Msgbox)
End Try
@@ -468,7 +468,7 @@ PreFin:
'手动选择
Private Sub BtnArgumentJavaSelect_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSelect.Click
If JavaSearchLoader.State = LoadState.Loading Then
- Hint("正在搜索 Java,请稍候!", HintType.Critical)
+ Hint("正在搜索 Java,请稍候!", HintType.Red)
Return
End If
'选择 Java
@@ -489,7 +489,7 @@ PreFin:
Setup.Set("LaunchArgumentJavaAll", JavaNewList.ToString(Newtonsoft.Json.Formatting.None))
'重新加载列表
JavaSearchLoader.Start(IsForceRestart:=True)
- Hint("已将该 Java 加入 Java 列表!", HintType.Finish)
+ Hint("已将该 Java 加入 Java 列表!", HintType.Green)
Catch ex As Exception
Log(ex, "该 Java 存在异常,无法使用", LogLevel.Msgbox, "异常的 Java")
Return
@@ -498,7 +498,7 @@ PreFin:
'自动查找
Private Sub BtnArgumentJavaSearch_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSearch.Click
If JavaSearchLoader.State = LoadState.Loading Then
- Hint("正在搜索 Java,请稍候!", HintType.Critical)
+ Hint("正在搜索 Java,请稍候!", HintType.Red)
Return
End If
RunInThread(
@@ -506,9 +506,9 @@ PreFin:
Hint("正在搜索 Java!")
JavaSearchLoader.WaitForExit(IsForceRestart:=True)
If Not JavaList.Any() Then
- Hint("未找到可用的 Java!", HintType.Critical)
+ Hint("未找到可用的 Java!", HintType.Red)
Else
- Hint("已找到 " & JavaList.Count & " 个 Java,请检查下拉框查看列表!", HintType.Finish)
+ Hint("已找到 " & JavaList.Count & " 个 Java,请检查下拉框查看列表!", HintType.Green)
End If
End Sub)
End Sub
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb
index 3069a96..c4cc82e 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLink.xaml.vb
@@ -28,7 +28,7 @@
Setup.Reset("LinkHiperCertWarn")
Log("[Setup] 已初始化联机页设置")
- Hint("已初始化联机页设置!", HintType.Finish, False)
+ Hint("已初始化联机页设置!", HintType.Green, False)
Catch ex As Exception
Log(ex, "初始化联机页设置失败", LogLevel.Msgbox)
End Try
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb
index 7ead8ef..766413a 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb
@@ -85,7 +85,7 @@
Setup.Reset("SystemSystemTelemetry")
Log("[Setup] 已初始化启动器页设置")
- Hint("已初始化启动器页设置!", HintType.Finish, False)
+ Hint("已初始化启动器页设置!", HintType.Green, False)
Catch ex As Exception
Log(ex, "初始化启动器页设置失败", LogLevel.Msgbox)
End Try
@@ -136,7 +136,7 @@
'识别码/解锁码替代入口
Private Sub BtnSystemIdentify_Click(sender As Object, e As MouseButtonEventArgs) Handles BtnSystemIdentify.Click
- PageOtherAbout.CopyUniqueAddress()
+ PageOtherAbout.CopyIdentify()
End Sub
Private Sub BtnSystemUnlock_Click(sender As Object, e As MouseButtonEventArgs) Handles BtnSystemUnlock.Click
DonateCodeInput()
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml
index b995ec8..06913f0 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml
+++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml
@@ -225,7 +225,8 @@
-
+
diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb
index 92fe4e1..a992749 100644
--- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb
@@ -162,7 +162,7 @@
Setup.Reset("UiHiddenOtherTest")
Log("[Setup] 已初始化个性化设置!")
- Hint("已初始化个性化设置", HintType.Finish, False)
+ Hint("已初始化个性化设置", HintType.Green, False)
Catch ex As Exception
Log(ex, "初始化个性化设置失败", LogLevel.Msgbox)
End Try
@@ -215,7 +215,7 @@
If MyMsgBox("即将删除背景图片文件夹中的所有文件。" & vbCrLf & "此操作不可撤销,是否确定?", "警告",, "取消", IsWarn:=True) = 1 Then
DeleteDirectory(Path & "PCL\Pictures")
BackgroundRefresh(False, True)
- Hint("背景图片已清空!", HintType.Finish)
+ Hint("背景图片已清空!", HintType.Green)
End If
End Sub
'''
@@ -238,10 +238,10 @@
If Not Pic.Any() Then
If Refresh Then
If FrmMain.ImgBack.Visibility = Visibility.Collapsed Then
- If IsHint Then Hint("未检测到可用背景图片!", HintType.Critical)
+ If IsHint Then Hint("未检测到可用背景图片!", HintType.Red)
Else
FrmMain.ImgBack.Visibility = Visibility.Collapsed
- If IsHint Then Hint("背景图片已清除!", HintType.Finish)
+ If IsHint Then Hint("背景图片已清除!", HintType.Green)
End If
End If
If Not IsNothing(FrmSetupUI) Then FrmSetupUI.BackgroundRefreshUI(False, 0)
@@ -253,7 +253,7 @@
FrmMain.ImgBack.Background = New MyBitmap(Address)
Setup.Load("UiBackgroundSuit", True)
FrmMain.ImgBack.Visibility = Visibility.Visible
- If IsHint Then Hint("背景图片已刷新:" & GetFileNameFromPath(Address), HintType.Finish, False)
+ If IsHint Then Hint("背景图片已刷新:" & GetFileNameFromPath(Address), HintType.Green, False)
Catch ex As Exception
If ex.Message.Contains("参数无效") Then
Log("刷新背景图片失败,该图片文件可能并非标准格式。" & vbCrLf &
@@ -338,7 +338,7 @@ Refresh:
Try
File.Delete(Path & "PCL\Logo.png")
RadioLogoType1.SetChecked(True, True)
- Hint("标题栏图片已清空!", HintType.Finish)
+ Hint("标题栏图片已清空!", HintType.Green)
Catch ex As Exception
Log(ex, "清空标题栏图片失败", LogLevel.Msgbox)
End Try
@@ -381,7 +381,7 @@ Refresh:
'删除文件
Try
DeleteDirectory(Path & "PCL\Musics")
- Hint("背景音乐已删除!", HintType.Finish)
+ Hint("背景音乐已删除!", HintType.Green)
Catch ex As Exception
Log(ex, "删除背景音乐失败", LogLevel.Msgbox)
End Try
@@ -410,7 +410,7 @@ Refresh:
If MyMsgBox("当前已存在布局文件,继续生成教学文件将会覆盖现有布局文件!", "覆盖确认", "继续", "取消", IsWarn:=True) = 2 Then Return
End If
WriteFile(Path & "PCL\Custom.xaml", GetResources("Custom"))
- Hint("教学文件已生成!", HintType.Finish)
+ Hint("教学文件已生成!", HintType.Green)
OpenExplorer(Path & "PCL\Custom.xaml")
Catch ex As Exception
Log(ex, "生成教学文件失败", LogLevel.Feedback)
@@ -418,7 +418,7 @@ Refresh:
End Sub
Private Sub BtnCustomRefresh_Click() Handles BtnCustomRefresh.Click
FrmLaunchRight.ForceRefresh()
- Hint("已刷新主页!", HintType.Finish)
+ Hint("已刷新主页!", HintType.Green)
End Sub
Private Sub BtnCustomTutorial_Click(sender As Object, e As EventArgs) Handles BtnCustomTutorial.Click
MyMsgBox("1. 点击 生成教学文件 按钮,这会在 PCL 文件夹下生成 Custom.xaml 布局文件。" & vbCrLf &
diff --git a/Plain Craft Launcher 2/Pages/PageSpeedLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageSpeedLeft.xaml.vb
index 3796d42..785b928 100644
--- a/Plain Craft Launcher 2/Pages/PageSpeedLeft.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageSpeedLeft.xaml.vb
@@ -96,7 +96,7 @@ Public Class PageSpeedLeft
AddHandler Tb.MouseLeftButtonDown,
Sub(sender As TextBlock, e As EventArgs)
ClipboardSet(sender.Text, False)
- Hint("已复制错误详情!", HintType.Finish)
+ Hint("已复制错误详情!", HintType.Green)
End Sub
Card.Children.Add(Tb)
#End Region
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
index 3574f12..4eee204 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
@@ -262,7 +262,7 @@
+ local:CustomEventService.EventType="打开帮助" />
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
index cdae17b..0ad29e3 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
@@ -22,7 +22,8 @@ Public Class PageVersionExport
Private Sub PageVersionExport_Loaded() Handles Me.Loaded
AniControlEnabled += 1
If CurrentVersion <> PageVersionLeft.Version.Path Then RefreshAll() '切换到了另一个版本,重置页面
- BtnAdvancedHelp.EventData = If(VersionBranchName = "Release", "指南/整合包制作 - Public.json", "指南/整合包制作 - Snapshot.json")
+ CustomEventService.SetEventData(BtnAdvancedHelp,
+ If(VersionBranchName = "Release", "指南/整合包制作 - Public.json", "指南/整合包制作 - Snapshot.json"))
AniControlEnabled -= 1
End Sub
Public Sub RefreshAll() Implements IRefreshable.Refresh
@@ -35,7 +36,7 @@ Public Class PageVersionExport
TextExportVersion.HintText = "1.0.0"
CheckAdvancedInclude.Checked = False
CheckAdvancedModrinth.Checked = False
- GetExportOption(CheckOptionsBasic).Description = PageVersionLeft.Version.GetDefaultDescription()
+ GetExportOption(CheckOptionsBasic).Description = PageVersionLeft.Version.GetVersionDescription()
ResetConfigOverrides()
ReloadAllSubOptions()
RefreshAllOptionsUI()
@@ -341,7 +342,7 @@ Public Class PageVersionExport
ConfigLines.AddRange(GetExtraFileLines())
'结束
WriteFile(ConfigPath, ConfigLines.Join(vbCrLf))
- Hint("已保存配置文件:" & ConfigPath, HintType.Finish)
+ Hint("已保存配置文件:" & ConfigPath, HintType.Green)
OpenExplorer(ConfigPath)
Catch ex As Exception
Log(ex, "保存配置失败", LogLevel.Msgbox)
@@ -378,7 +379,7 @@ Public Class PageVersionExport
ExtraFiles = Nothing
End If
'结束
- Hint("已读取配置文件:" & ConfigPath, HintType.Finish)
+ Hint("已读取配置文件:" & ConfigPath, HintType.Green)
Catch ex As Exception
Log(ex, "读取配置失败", LogLevel.Msgbox)
End Try
@@ -517,13 +518,13 @@ Public Class PageVersionExport
If Directory.Exists(Line) Then
CopyDirectory(Line, BaseFolder & GetFolderNameFromPath(Line) & "\")
Else
- Hint($"未找到配置文件中指定的文件夹:{Line}", HintType.Critical)
+ Hint($"未找到配置文件中指定的文件夹:{Line}", HintType.Red)
End If
Else
If File.Exists(Line) Then
CopyFile(Line, BaseFolder & GetFileNameFromPath(Line))
Else
- Hint($"未找到配置文件中指定的单个文件:{Line}", HintType.Critical)
+ Hint($"未找到配置文件中指定的单个文件:{Line}", HintType.Red)
End If
End If
Next
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb
index 73c280c..a844d23 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb
@@ -306,7 +306,7 @@
If Result.Any Then
MyMsgBox(Join(Result, vbCrLf & vbCrLf), "Mod 检查结果")
Else
- Hint("Mod 检查完成,未发现任何问题!", HintType.Finish)
+ Hint("Mod 检查完成,未发现任何问题!", HintType.Green)
End If
Catch ex As Exception
Log(ex, "进行 Mod 检查时出错", LogLevel.Feedback)
@@ -340,7 +340,7 @@
Log("[System] 文件为 jar/litemod 格式,尝试作为 Mod 安装")
'检查回收站:回收站中的文件有错误的文件名
If FilePathList.First.Contains(":\$RECYCLE.BIN\") Then
- Hint("请先将文件从回收站还原,再尝试安装!", HintType.Critical)
+ Hint("请先将文件从回收站还原,再尝试安装!", HintType.Red)
Return True
End If
'获取并检查目标版本
@@ -362,9 +362,9 @@ Install:
CopyFile(ModFile, TargetVersion.PathIndie & "mods\" & NewFileName)
Next
If FilePathList.Count = 1 Then
- Hint($"已安装 {GetFileNameFromPath(FilePathList.First).Replace(".disabled", "").Replace(".old", "")}!", HintType.Finish)
+ Hint($"已安装 {GetFileNameFromPath(FilePathList.First).Replace(".disabled", "").Replace(".old", "")}!", HintType.Green)
Else
- Hint($"已安装 {FilePathList.Count} 个 Mod!", HintType.Finish)
+ Hint($"已安装 {FilePathList.Count} 个 Mod!", HintType.Green)
End If
'刷新列表
If FrmMain.PageCurrent = FormMain.PageType.VersionSetup AndAlso FrmMain.PageCurrentSub = FormMain.PageSubType.VersionMod Then
@@ -570,7 +570,7 @@ Install:
If IsSuccessful Then
RefreshBars()
Else
- Hint("由于文件被占用,Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
+ Hint("由于文件被占用,Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Red)
ReloadModList(True)
End If
LoaderRun(LoaderFolderRunType.UpdateOnly)
@@ -643,14 +643,14 @@ Install:
Try
For Each Entry As McMod In ModList
If File.Exists(Entry.Path) Then
- My.Computer.FileSystem.DeleteFile(Entry.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
+ My.Computer.FileSystem.DeleteFile(Entry.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
Else
Log($"[Mod] 未找到更新前的 Mod 文件,跳过对它的删除:{Entry.Path}", LogLevel.Debug)
End If
Next
For Each Entry As KeyValuePair(Of String, String) In FileCopyList
If File.Exists(Entry.Value) Then
- My.Computer.FileSystem.DeleteFile(Entry.Value, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
+ My.Computer.FileSystem.DeleteFile(Entry.Value, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
Log($"[Mod] 更新后的 Mod 文件已存在,将会把它放入回收站:{Entry.Value}", LogLevel.Debug)
End If
If Directory.Exists(GetPathFromFullPath(Entry.Value)) Then
@@ -676,14 +676,14 @@ Install:
Case 0 '一般是由于 Mod 文件被占用,然后玩家主动取消
Log($"[Mod] 没有 Mod 被成功更新")
Case 1
- Hint($"已成功更新 {FinishedFileNames.Single}!", HintType.Finish)
+ Hint($"已成功更新 {FinishedFileNames.Single}!", HintType.Green)
Case Else
- Hint($"已成功更新 {FinishedFileNames.Count} 个 Mod!", HintType.Finish)
+ Hint($"已成功更新 {FinishedFileNames.Count} 个 Mod!", HintType.Green)
End Select
Case LoadState.Failed
- Hint("Mod 更新失败:" & Loader.Error.GetBrief(), HintType.Critical)
+ Hint("Mod 更新失败:" & Loader.Error.GetBrief(), HintType.Red)
Case LoadState.Aborted
- Hint("Mod 更新已中止!", HintType.Info)
+ Hint("Mod 更新已中止!", HintType.Blue)
Case Else
Return
End Select
@@ -739,7 +739,7 @@ Install:
If IsShiftPressed Then
File.Delete(ModEntity.Path)
Else
- My.Computer.FileSystem.DeleteFile(ModEntity.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
+ My.Computer.FileSystem.DeleteFile(ModEntity.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
End If
Catch ex As OperationCanceledException
Log(ex, "删除 Mod 被主动取消")
@@ -760,7 +760,7 @@ Install:
Next
RefreshBars()
If Not IsSuccessful Then
- Hint("由于文件被占用,Mod 删除失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
+ Hint("由于文件被占用,Mod 删除失败,请尝试关闭正在运行的游戏后再试!", HintType.Red)
ReloadModList(True)
ElseIf PanList.Children.Count = 0 Then
ReloadModList(True) '删除了全部文件
@@ -771,15 +771,15 @@ Install:
If Not IsSuccessful Then Return
If IsShiftPressed Then
If ModList.Count = 1 Then
- Hint($"已彻底删除 {ModList.Single.FileName}!", HintType.Finish)
+ Hint($"已彻底删除 {ModList.Single.FileName}!", HintType.Green)
Else
- Hint($"已彻底删除 {ModList.Count} 个文件!", HintType.Finish)
+ Hint($"已彻底删除 {ModList.Count} 个文件!", HintType.Green)
End If
Else
If ModList.Count = 1 Then
- Hint($"已将 {ModList.Single.FileName} 删除到回收站!", HintType.Finish)
+ Hint($"已将 {ModList.Single.FileName} 删除到回收站!", HintType.Green)
Else
- Hint($"已将 {ModList.Count} 个文件删除到回收站!", HintType.Finish)
+ Hint($"已将 {ModList.Count} 个文件删除到回收站!", HintType.Green)
End If
End If
Catch ex As OperationCanceledException
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb
index 294b486..3035e9f 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionOverall.xaml.vb
@@ -30,7 +30,7 @@
BtnFolderMods.Visibility = If(PageVersionLeft.Version.Modable, Visibility.Visible, Visibility.Collapsed)
'刷新版本显示
PanDisplayItem.Children.Clear()
- ItemVersion = PageSelectRight.McVersionListItem(PageVersionLeft.Version)
+ ItemVersion = PageVersionLeft.Version.ToListItem
ItemVersion.IsHitTestVisible = False
PanDisplayItem.Children.Add(ItemVersion)
FrmMain.PageNameRefresh()
@@ -169,7 +169,7 @@
Log(ex, "重命名版本 json 失败")
End Try
'刷新与提示
- Hint("重命名成功!", HintType.Finish)
+ Hint("重命名成功!", HintType.Green)
PageVersionLeft.Version = New McVersion(NewName).Load()
If Not IsNothing(McVersionCurrent) AndAlso McVersionCurrent.Equals(PageVersionLeft.Version) Then WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
Reload()
@@ -263,7 +263,7 @@
If SavePath = "" Then Return
'检查中断(等玩家选完弹窗指不定任务就结束了呢……)
If McLaunchLoader.State = LoadState.Loading Then
- Hint("请在当前启动任务结束后再试!", HintType.Critical)
+ Hint("请在当前启动任务结束后再试!", HintType.Red)
Return
End If
'生成脚本
@@ -284,13 +284,13 @@
Try
'忽略文件检查提示
If ShouldIgnoreFileCheck(PageVersionLeft.Version) Then
- Hint("请先关闭 [版本设置 → 设置 → 高级启动选项 → 关闭文件校验],然后再尝试补全文件!", HintType.Info)
+ Hint("请先关闭 [版本设置 → 设置 → 高级启动选项 → 关闭文件校验],然后再尝试补全文件!", HintType.Blue)
Return
End If
'重复任务检查
For Each OngoingLoader In LoaderTaskbar
If OngoingLoader.Name <> PageVersionLeft.Version.Name & " 文件补全" Then Continue For
- Hint("正在处理中,请稍候!", HintType.Critical)
+ Hint("正在处理中,请稍候!", HintType.Red)
Return
Next
'启动
@@ -299,11 +299,11 @@
Sub()
Select Case Loader.State
Case LoadState.Finished
- Hint(Loader.Name & "成功!", HintType.Finish)
+ Hint(Loader.Name & "成功!", HintType.Green)
Case LoadState.Failed
- Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Critical)
+ Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Red)
Case LoadState.Aborted
- Hint(Loader.Name & "已取消!", HintType.Info)
+ Hint(Loader.Name & "已取消!", HintType.Blue)
End Select
End Sub
Loader.Start(PageVersionLeft.Version.Name)
@@ -329,10 +329,10 @@
IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
If IsShiftPressed Then
DeleteDirectory(PageVersionLeft.Version.Path)
- Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish)
+ Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Green)
Else
- FileIO.FileSystem.DeleteDirectory(PageVersionLeft.Version.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
- Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
+ FileIO.FileSystem.DeleteDirectory(PageVersionLeft.Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
+ Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Green)
End If
Case 2
Return
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml
index b3a872c..7c1e11d 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml
@@ -34,9 +34,9 @@
ToolTip="与其余关闭隔离的版本共享存档、Mod 等文件。
若存在多个安装了 Mod 的版本,可能会由于 Mod 冲突而导致崩溃。" ToolTipService.HorizontalOffset="100"/>
-
+
-
+
@@ -209,13 +209,13 @@
-
-
+
+ ToolTip="该项不会覆盖全局设置:启动时会先执行全局设置的命令,再执行版本设置的命令。
在 MC 启动前执行特定命令或程序,语法与 Windows 的命令提示符一致。
你可以用替换标记来动态改变其内容或实现相对路径,在 更多 → 帮助 中搜索 “替换标记” 以了解用法。例如:
· "{verpath}test.exe" :运行版本文件夹下的 test.exe 程序
· "{java}java.exe" -jar "{verpath}test.jar" :用 Java 运行版本文件夹下的 test.jar
· notepad "{verindie}options.txt" :使用记事本打开该版本的设置文件
涉及路径的操作最好都打上双引号,以避免路径中的空格导致运行失败。
执行命令时,命令行所在的目录是当前的 .minecraft 文件夹。" />
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb
index 414d5f0..b22e277 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionSetup.xaml.vb
@@ -98,7 +98,7 @@
JavaSearchLoader.Start(IsForceRestart:=True)
Log("[Setup] 已初始化版本独立设置")
- Hint("已初始化版本独立设置!", HintType.Finish, False)
+ Hint("已初始化版本独立设置!", HintType.Green, False)
Catch ex As Exception
Log(ex, "初始化版本独立设置失败", LogLevel.Msgbox)
End Try
diff --git a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj
index b5eafff..e40bfb6 100644
--- a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj
+++ b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj
@@ -206,8 +206,8 @@
Designer
-
-
+
+
diff --git a/Plain Craft Launcher 2/Resources/Custom.xaml b/Plain Craft Launcher 2/Resources/Custom.xaml
index 07ed9a2..65c3675 100644
--- a/Plain Craft Launcher 2/Resources/Custom.xaml
+++ b/Plain Craft Launcher 2/Resources/Custom.xaml
@@ -53,114 +53,37 @@
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -198,7 +121,7 @@
Logo="pack://application:,,,/images/Blocks/Grass.png"
EventType="打开帮助" EventData="帮助/自定义帮助.json" Type="Clickable" />
+ Text="EventType、EventData 与按钮几乎一致。唯一不同的是,列表项不支持联网加载帮助文件。" />
@@ -261,17 +184,6 @@
-
-
-
-
-
-
-
-