2.9.1
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
<runtime>
|
<runtime>
|
||||||
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
|
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
|
||||||
<AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false"/> <!-- #5337 -->
|
<AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false"/> <!-- #5337 -->
|
||||||
|
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" /> <!-- 长路径支持 -->
|
||||||
<generatePublisherEvidence enabled="false"/>
|
<generatePublisherEvidence enabled="false"/>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
|
|||||||
@@ -14,6 +14,12 @@
|
|||||||
<ResourceDictionary Source="pack://application:,,,/Resources/Language/zh_CN.xaml" />
|
<ResourceDictionary Source="pack://application:,,,/Resources/Language/zh_CN.xaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<!-- Converter -->
|
||||||
|
<local:AdditionConverter x:Key="AdditionConverter"/>
|
||||||
|
<local:MultiplicationConverter x:Key="MultiplicationConverter"/>
|
||||||
|
<local:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
|
||||||
|
<local:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||||
|
|
||||||
<!-- 颜色表 -->
|
<!-- 颜色表 -->
|
||||||
<SolidColorBrush x:Key="ColorBrush1">#343d4a</SolidColorBrush>
|
<SolidColorBrush x:Key="ColorBrush1">#343d4a</SolidColorBrush>
|
||||||
<SolidColorBrush x:Key="ColorBrush2">#0b5bcb</SolidColorBrush>
|
<SolidColorBrush x:Key="ColorBrush2">#0b5bcb</SolidColorBrush>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<Border.RenderTransform>
|
<Border.RenderTransform>
|
||||||
<ScaleTransform />
|
<ScaleTransform />
|
||||||
</Border.RenderTransform>
|
</Border.RenderTransform>
|
||||||
<TextBlock TextOptions.TextFormattingMode="Display" SnapsToDevicePixels="True" TextTrimming="None" Text="Button" HorizontalAlignment="Center" x:Name="LabText" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Foreground="{Binding Parent.BorderBrush, RelativeSource={RelativeSource Self}}" FontSize="13" IsHitTestVisible="False">
|
<TextBlock TextOptions.TextFormattingMode="Display" SnapsToDevicePixels="True" TextTrimming="None" HorizontalAlignment="Center" x:Name="LabText" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Foreground="{Binding Parent.BorderBrush, RelativeSource={RelativeSource Self}}" FontSize="13" IsHitTestVisible="False">
|
||||||
<TextBlock.RenderTransform>
|
<TextBlock.RenderTransform>
|
||||||
<ScaleTransform />
|
<ScaleTransform />
|
||||||
</TextBlock.RenderTransform>
|
</TextBlock.RenderTransform>
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
Public Class MyButton
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyButton
|
||||||
|
|
||||||
'声明
|
'声明
|
||||||
Public Event Click(sender As Object, e As MouseButtonEventArgs) '自定义事件
|
Public Event Click(sender As Object, e As MouseButtonEventArgs) '自定义事件
|
||||||
|
|
||||||
'自定义属性
|
'自定义属性
|
||||||
Public Uuid As Integer = GetUuid()
|
Public Uuid As Integer = GetUuid()
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Text As String
|
Public Property Text As String
|
||||||
Get
|
Get
|
||||||
Return LabText.Text
|
Return GetValue(TextProperty)
|
||||||
End Get
|
End Get
|
||||||
Set(value As String)
|
Set(value As String)
|
||||||
LabText.Text = value
|
SetValue(TextProperty, value)
|
||||||
End Set
|
End Set
|
||||||
End Property '显示文本
|
End Property '显示文本
|
||||||
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyButton), New PropertyMetadata(New PropertyChangedCallback(
|
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyButton), New PropertyMetadata(New PropertyChangedCallback(
|
||||||
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
||||||
If Not IsNothing(sender) Then CType(sender, MyButton).LabText.Text = e.NewValue
|
If sender IsNot Nothing Then CType(sender, MyButton).LabText.Text = e.NewValue
|
||||||
End Sub)))
|
End Sub)))
|
||||||
Public Property TextPadding As Thickness
|
Public Property TextPadding As Thickness
|
||||||
Get
|
Get
|
||||||
|
|||||||
@@ -36,6 +36,11 @@
|
|||||||
|
|
||||||
'属性
|
'属性
|
||||||
Public Uuid As Integer = GetUuid()
|
Public Uuid As Integer = GetUuid()
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return MainTextBlock.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Title As String
|
Public Property Title As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(TitleProperty)
|
Return GetValue(TitleProperty)
|
||||||
@@ -62,7 +67,7 @@
|
|||||||
If IsLoad Then Exit Sub
|
If IsLoad Then Exit Sub
|
||||||
IsLoad = True
|
IsLoad = True
|
||||||
'初次加载限定
|
'初次加载限定
|
||||||
If Title <> "" AndAlso MainTextBlock Is Nothing Then
|
If MainTextBlock Is Nothing Then
|
||||||
MainTextBlock = New TextBlock With {.HorizontalAlignment = HorizontalAlignment.Left, .VerticalAlignment = VerticalAlignment.Top, .Margin = New Thickness(15, 12, 0, 0), .FontWeight = FontWeights.Bold, .FontSize = 13, .IsHitTestVisible = False}
|
MainTextBlock = New TextBlock With {.HorizontalAlignment = HorizontalAlignment.Left, .VerticalAlignment = VerticalAlignment.Top, .Margin = New Thickness(15, 12, 0, 0), .FontWeight = FontWeights.Bold, .FontSize = 13, .IsHitTestVisible = False}
|
||||||
MainTextBlock.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrush1")
|
MainTextBlock.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrush1")
|
||||||
MainTextBlock.SetBinding(TextBlock.TextProperty, New Binding("Title") With {.Source = Me, .Mode = BindingMode.OneWay})
|
MainTextBlock.SetBinding(TextBlock.TextProperty, New Binding("Title") With {.Source = Me, .Mode = BindingMode.OneWay})
|
||||||
@@ -231,7 +236,8 @@
|
|||||||
AaHeight(Me, DeltaHeight, MathClamp(Math.Abs(DeltaHeight) * 4, 150, 250),, New AniEaseOutFluent)
|
AaHeight(Me, DeltaHeight, MathClamp(Math.Abs(DeltaHeight) * 4, 150, 250),, New AniEaseOutFluent)
|
||||||
})
|
})
|
||||||
End If
|
End If
|
||||||
AnimList.Add(AaCode(Sub()
|
AnimList.Add(AaCode(
|
||||||
|
Sub()
|
||||||
IsHeightAnimating = False
|
IsHeightAnimating = False
|
||||||
Height = ActualUsedHeight
|
Height = ActualUsedHeight
|
||||||
If IsSwaped Then SwapControl.Visibility = Visibility.Collapsed
|
If IsSwaped Then SwapControl.Visibility = Visibility.Collapsed
|
||||||
@@ -253,7 +259,8 @@
|
|||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
'折叠
|
#Region "折叠"
|
||||||
|
|
||||||
'若设置了 CanSwap,或 SwapControl 不为空,则判定为会进行折叠
|
'若设置了 CanSwap,或 SwapControl 不为空,则判定为会进行折叠
|
||||||
'这是因为不能直接在 XAML 中设置 SwapControl
|
'这是因为不能直接在 XAML 中设置 SwapControl
|
||||||
Public SwapControl As Object
|
Public SwapControl As Object
|
||||||
@@ -294,7 +301,7 @@
|
|||||||
Private Sub MyCard_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
|
Private Sub MyCard_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
|
||||||
Dim Pos As Double = Mouse.GetPosition(Me).Y
|
Dim Pos As Double = Mouse.GetPosition(Me).Y
|
||||||
If Not IsSwaped AndAlso
|
If Not IsSwaped AndAlso
|
||||||
(SwapControl Is Nothing OrElse Pos > SwapedHeight OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Exit Sub '检测点击位置;或已经不在可视树上的误判
|
(SwapControl Is Nothing OrElse Pos > If(IsSwaped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Exit Sub '检测点击位置;或已经不在可视树上的误判
|
||||||
IsMouseDown = True
|
IsMouseDown = True
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub MyCard_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
|
Private Sub MyCard_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
|
||||||
@@ -303,7 +310,7 @@
|
|||||||
|
|
||||||
Dim Pos As Double = Mouse.GetPosition(Me).Y
|
Dim Pos As Double = Mouse.GetPosition(Me).Y
|
||||||
If Not IsSwaped AndAlso
|
If Not IsSwaped AndAlso
|
||||||
(SwapControl Is Nothing OrElse Pos > SwapedHeight OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Exit Sub '检测点击位置;或已经不在可视树上的误判
|
(SwapControl Is Nothing OrElse Pos > If(IsSwaped, SwapedHeight, SwapedHeight - 6) OrElse (Pos = 0 AndAlso Not IsMouseDirectlyOver)) Then Exit Sub '检测点击位置;或已经不在可视树上的误判
|
||||||
|
|
||||||
Dim ee = New RouteEventArgs(True)
|
Dim ee = New RouteEventArgs(True)
|
||||||
RaiseEvent PreviewSwap(Me, ee)
|
RaiseEvent PreviewSwap(Me, ee)
|
||||||
@@ -320,6 +327,8 @@
|
|||||||
IsMouseDown = False
|
IsMouseDown = False
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
Partial Public Module ModAnimation
|
Partial Public Module ModAnimation
|
||||||
Public Sub AniDispose(Control As MyCard, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
|
Public Sub AniDispose(Control As MyCard, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MyCheckBox"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MyCheckBox"
|
||||||
FocusVisualStyle="{x:Null}"
|
FocusVisualStyle="{x:Null}"
|
||||||
MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True" d:DesignWidth="126.4" d:DesignHeight="44.8">
|
MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True" d:DesignWidth="126.4" d:DesignHeight="44.8">
|
||||||
<TextBlock IsHitTestVisible="False" FontSize="13" x:Name="LabText" Padding="0" Margin="26,0,0,0" Text="Checkbox" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center" />
|
<TextBlock IsHitTestVisible="False" FontSize="13" x:FieldModifier="Public" x:Name="LabText" Padding="0" Margin="26,0,0,0" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center" />
|
||||||
<Border IsHitTestVisible="False" x:Name="ShapeBorder" BorderThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" BorderBrush="{DynamicResource ColorBrush1}" CornerRadius="3" Margin="1,0,0,0" Background="{StaticResource ColorBrushHalfWhite}" />
|
<Border IsHitTestVisible="False" x:Name="ShapeBorder" BorderThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" BorderBrush="{DynamicResource ColorBrush1}" CornerRadius="3" Margin="1,0,0,0" Background="{StaticResource ColorBrushHalfWhite}" />
|
||||||
<Path IsHitTestVisible="False" x:Name="ShapeCheck" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding BorderBrush, ElementName=ShapeBorder}" Width="12" Height="12" Margin="4,0,0,0" Data="M0,6L1.5,4.5 4.5,7.5 10.5,1.5 12,3 4.5,10.5 0,6z">
|
<Path IsHitTestVisible="False" x:Name="ShapeCheck" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding BorderBrush, ElementName=ShapeBorder}" Width="12" Height="12" Margin="4,0,0,0" Data="M0,6L1.5,4.5 4.5,7.5 10.5,1.5 12,3 4.5,10.5 0,6z">
|
||||||
<Path.RenderTransform>
|
<Path.RenderTransform>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Public Class MyCheckBox
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyCheckBox
|
||||||
|
|
||||||
'基础
|
'基础
|
||||||
|
|
||||||
@@ -14,29 +17,32 @@
|
|||||||
End Sub '使外部程序引发本控件的 Change 事件
|
End Sub '使外部程序引发本控件的 Change 事件
|
||||||
|
|
||||||
'自定义属性
|
'自定义属性
|
||||||
|
|
||||||
Private _Checked As Boolean = False '是否选中
|
|
||||||
Public Property Checked As Boolean
|
Public Property Checked As Boolean
|
||||||
Get
|
Get
|
||||||
Return _Checked
|
Return GetValue(CheckedProperty)
|
||||||
End Get
|
End Get
|
||||||
Set(value As Boolean)
|
Set(value As Boolean)
|
||||||
SetChecked(value, False, True)
|
SetChecked(value, False)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Public Shared ReadOnly CheckedProperty As DependencyProperty =
|
||||||
|
DependencyProperty.Register("Checked", GetType(Boolean), GetType(MyCheckBox), New PropertyMetadata(False,
|
||||||
|
Sub(d As MyCheckBox, e As DependencyPropertyChangedEventArgs)
|
||||||
|
'在使用 XAML 设置 Checked 属性时,不会触发 Checked_Set 方法,所以需要在这里手动触发 UI 改变
|
||||||
|
If Not d.IsLoaded Then d.SyncUI()
|
||||||
|
End Sub))
|
||||||
|
|
||||||
Private Const AnimationTimeOfCheck As Integer = 150 '勾选状态变更动画长度
|
Private Const AnimationTimeOfCheck As Integer = 150 '勾选状态变更动画长度
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 手动设置 Checked 属性。
|
''' 手动设置 Checked 属性。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="value">新的 Checked 属性。</param>
|
''' <param name="value">新的 Checked 属性。</param>
|
||||||
''' <param name="user">是否由用户引发。</param>
|
''' <param name="user">是否由用户引发。</param>
|
||||||
''' <param name="anime">是否执行动画。</param>
|
Public Sub SetChecked(value As Boolean, user As Boolean)
|
||||||
Public Sub SetChecked(value As Boolean, user As Boolean, anime As Boolean)
|
|
||||||
Try
|
Try
|
||||||
If value = _Checked Then Exit Sub
|
If value = Checked Then Exit Sub
|
||||||
|
|
||||||
'Preview 事件
|
'Preview 事件
|
||||||
|
|
||||||
If value AndAlso user Then
|
If value AndAlso user Then
|
||||||
Dim e = New RouteEventArgs(user)
|
Dim e = New RouteEventArgs(user)
|
||||||
RaiseEvent PreviewChange(Me, e)
|
RaiseEvent PreviewChange(Me, e)
|
||||||
@@ -48,12 +54,17 @@
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
_Checked = value
|
SetValue(CheckedProperty, value)
|
||||||
If IsLoaded Then RaiseEvent Change(Me, user)
|
If IsLoaded Then RaiseEvent Change(Me, user)
|
||||||
|
|
||||||
'更改动画
|
'更改动画
|
||||||
|
SyncUI()
|
||||||
If IsLoaded AndAlso AniControlEnabled = 0 AndAlso anime Then '防止默认属性变更触发动画
|
Catch ex As Exception
|
||||||
|
Log(ex, "设置 Checked 失败")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub SyncUI()
|
||||||
|
If AniControlEnabled = 0 AndAlso IsLoaded Then '防止默认属性变更触发动画
|
||||||
AllowMouseDown = False
|
AllowMouseDown = False
|
||||||
If Checked Then
|
If Checked Then
|
||||||
'由无变有
|
'由无变有
|
||||||
@@ -97,11 +108,13 @@
|
|||||||
ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"))
|
ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"))
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "设置 Checked 失败")
|
|
||||||
End Try
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Text As String
|
Public Property Text As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(TextProperty)
|
Return GetValue(TextProperty)
|
||||||
@@ -110,9 +123,9 @@
|
|||||||
SetValue(TextProperty, value)
|
SetValue(TextProperty, value)
|
||||||
End Set
|
End Set
|
||||||
End Property '内容
|
End Property '内容
|
||||||
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyCheckbox), New PropertyMetadata(New PropertyChangedCallback(
|
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyCheckBox), New PropertyMetadata(New PropertyChangedCallback(
|
||||||
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
||||||
If Not IsNothing(sender) Then CType(sender, MyCheckbox).LabText.Text = e.NewValue
|
If Not IsNothing(sender) Then CType(sender, MyCheckBox).LabText.Text = e.NewValue
|
||||||
End Sub)))
|
End Sub)))
|
||||||
|
|
||||||
'点击事件
|
'点击事件
|
||||||
@@ -123,7 +136,7 @@
|
|||||||
If Not MouseDowned Then Exit Sub
|
If Not MouseDowned Then Exit Sub
|
||||||
Log("[Control] 按下复选框(" & (Not Checked).ToString & "):" & Text)
|
Log("[Control] 按下复选框(" & (Not Checked).ToString & "):" & Text)
|
||||||
MouseDowned = False
|
MouseDowned = False
|
||||||
SetChecked(Not Checked, True, True)
|
SetChecked(Not Checked, True)
|
||||||
AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
|
AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub Checkbox_MouseDown() Handles Me.MouseLeftButtonDown
|
Private Sub Checkbox_MouseDown() Handles Me.MouseLeftButtonDown
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<Grid
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:PCL"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
x:Name="PanBack" mc:Ignorable="d" x:Class="MyExtraTextButton"
|
||||||
|
RenderTransformOrigin="0.5,0.5" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="16" ToolTipService.HorizontalOffset="-8" Height="52">
|
||||||
|
<Grid.RenderTransform>
|
||||||
|
<ScaleTransform ScaleX="0" ScaleY="0" />
|
||||||
|
</Grid.RenderTransform>
|
||||||
|
<Border x:Name="PanClick" BorderThickness="0.001" Background="{StaticResource ColorBrushSemiTransparent}"
|
||||||
|
CornerRadius="{Binding ActualHeight, ConverterParameter=0.4, Converter={StaticResource MultiplicationConverter}, ElementName=PanBack, Mode=OneWay}"/>
|
||||||
|
<Grid x:Name="PanScale" IsHitTestVisible="False" RenderTransformOrigin="0.5,0.5" Margin="0,10,0,0">
|
||||||
|
<Grid.RenderTransform>
|
||||||
|
<ScaleTransform />
|
||||||
|
</Grid.RenderTransform>
|
||||||
|
<Border x:Name="PanColor" BorderThickness="0.001" Background="{DynamicResource ColorBrush3}"
|
||||||
|
CornerRadius="{Binding ActualHeight, ConverterParameter=0.4, Converter={StaticResource MultiplicationConverter}, ElementName=PanBack, Mode=OneWay}">
|
||||||
|
<Border.Effect>
|
||||||
|
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.2" />
|
||||||
|
</Border.Effect>
|
||||||
|
</Border>
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="24,0" SnapsToDevicePixels="False" UseLayoutRounding="False">
|
||||||
|
<Path x:Name="Path" Stretch="Uniform" Margin="0,12" Fill="{DynamicResource ColorBrush8}" RenderTransformOrigin="0.5,0.5">
|
||||||
|
<Path.RenderTransform>
|
||||||
|
<ScaleTransform />
|
||||||
|
</Path.RenderTransform>
|
||||||
|
</Path>
|
||||||
|
<TextBlock x:Name="LabText" VerticalAlignment="Center" Foreground="{DynamicResource ColorBrush8}" FontSize="16"
|
||||||
|
Margin="11,0,-2,1.2" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyExtraTextButton
|
||||||
|
|
||||||
|
'声明
|
||||||
|
Public Event Click(sender As Object, e As MouseButtonEventArgs) '自定义事件
|
||||||
|
|
||||||
|
'自定义属性
|
||||||
|
Public Uuid As Integer = GetUuid()
|
||||||
|
Private _Logo As String = ""
|
||||||
|
Public Property Logo As String
|
||||||
|
Get
|
||||||
|
Return _Logo
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
If value = _Logo Then Exit Property
|
||||||
|
_Logo = value
|
||||||
|
Path.Data = (New GeometryConverter).ConvertFromString(value)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private _LogoScale As Double = 1
|
||||||
|
Public Property LogoScale() As Double
|
||||||
|
Get
|
||||||
|
Return _LogoScale
|
||||||
|
End Get
|
||||||
|
Set(value As Double)
|
||||||
|
_LogoScale = value
|
||||||
|
If Path IsNot Nothing Then Path.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale}
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
'显示文本
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Public Property Text As String
|
||||||
|
Get
|
||||||
|
Return GetValue(TextProperty)
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
SetValue(TextProperty, value)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyExtraTextButton), New PropertyMetadata(New PropertyChangedCallback(
|
||||||
|
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
||||||
|
If sender IsNot Nothing Then CType(sender, MyExtraTextButton).LabText.Text = e.NewValue
|
||||||
|
End Sub)))
|
||||||
|
|
||||||
|
'动画
|
||||||
|
Private _Show As Boolean = False
|
||||||
|
Public Property Show As Boolean
|
||||||
|
Get
|
||||||
|
Return _Show
|
||||||
|
End Get
|
||||||
|
Set(value As Boolean)
|
||||||
|
If _Show = value Then Exit Property
|
||||||
|
_Show = value
|
||||||
|
RunInUi(
|
||||||
|
Sub()
|
||||||
|
If value Then
|
||||||
|
'有了
|
||||||
|
Opacity = 0
|
||||||
|
AniStart({
|
||||||
|
AaOpacity(Me, 1 - Opacity, 80, 50),
|
||||||
|
AaScaleTransform(Me, 0.15 - CType(RenderTransform, ScaleTransform).ScaleX, 400, 50, New AniEaseOutBack),
|
||||||
|
AaScaleTransform(Me, 0.85, 160, 50, New AniEaseOutFluent(AniEasePower.Middle))
|
||||||
|
}, "MyExtraTextButton MainScale " & Uuid)
|
||||||
|
Else
|
||||||
|
'没了
|
||||||
|
AniStart({
|
||||||
|
AaOpacity(Me, -Opacity, 50, 50),
|
||||||
|
AaScaleTransform(Me, -CType(RenderTransform, ScaleTransform).ScaleX, 100,, New AniEaseInFluent(AniEasePower.Weak))
|
||||||
|
}, "MyExtraTextButton MainScale " & Uuid)
|
||||||
|
End If
|
||||||
|
IsHitTestVisible = value '防止缩放动画中依然可以点进去
|
||||||
|
End Sub)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'触发点击事件
|
||||||
|
Private Sub Button_LeftMouseUp(sender As Object, e As MouseButtonEventArgs) Handles PanClick.MouseLeftButtonUp
|
||||||
|
If IsLeftMouseHeld Then
|
||||||
|
Log("[Control] 按下附加按钮" & If(ToolTip = "", "", ":" & ToolTip.ToString))
|
||||||
|
RaiseEvent Click(sender, e)
|
||||||
|
e.Handled = True
|
||||||
|
Button_LeftMouseUp()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
|
||||||
|
Private IsLeftMouseHeld As Boolean = False
|
||||||
|
Private Sub Button_LeftMouseDown(sender As Object, e As MouseButtonEventArgs) Handles PanClick.MouseLeftButtonDown
|
||||||
|
If Not IsLeftMouseHeld Then
|
||||||
|
AniStart({
|
||||||
|
AaScaleTransform(PanScale, 0.85 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
|
||||||
|
AaScaleTransform(PanScale, -0.05, 60,, New AniEaseOutFluent)
|
||||||
|
}, "MyExtraTextButton Scale " & Uuid)
|
||||||
|
End If
|
||||||
|
IsLeftMouseHeld = True
|
||||||
|
Focus()
|
||||||
|
End Sub
|
||||||
|
Private Sub Button_LeftMouseUp() Handles PanClick.MouseLeftButtonUp
|
||||||
|
AniStart({
|
||||||
|
AaScaleTransform(PanScale, 1 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 300,, New AniEaseOutBack)
|
||||||
|
}, "MyExtraTextButton Scale " & Uuid)
|
||||||
|
IsLeftMouseHeld = False
|
||||||
|
RefreshColor() '直接刷新颜色以判断是否已触发 MouseLeave
|
||||||
|
End Sub
|
||||||
|
Private Sub Button_RightMouseUp() Handles PanClick.MouseRightButtonUp
|
||||||
|
If Not IsLeftMouseHeld Then
|
||||||
|
AniStart({
|
||||||
|
AaScaleTransform(PanScale, 1 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 300,, New AniEaseOutBack)
|
||||||
|
}, "MyExtraTextButton Scale " & Uuid)
|
||||||
|
End If
|
||||||
|
RefreshColor() '直接刷新颜色以判断是否已触发 MouseLeave
|
||||||
|
End Sub
|
||||||
|
Private Sub Button_MouseLeave() Handles PanClick.MouseLeave
|
||||||
|
IsLeftMouseHeld = False
|
||||||
|
AniStart({
|
||||||
|
AaScaleTransform(PanScale, 1 - CType(PanScale.RenderTransform, ScaleTransform).ScaleX, 500,, New AniEaseOutFluent)
|
||||||
|
}, "MyExtraTextButton Scale " & Uuid)
|
||||||
|
RefreshColor() '直接刷新颜色以判断是否已触发 MouseLeave
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'自定义事件
|
||||||
|
'务必放在 IsMouseDown 更新之后
|
||||||
|
Private Const AnimationColorIn As Integer = 120
|
||||||
|
Private Const AnimationColorOut As Integer = 150
|
||||||
|
Public Sub RefreshColor() Handles PanClick.MouseEnter, PanClick.MouseLeave, Me.Loaded
|
||||||
|
Try
|
||||||
|
If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
|
||||||
|
|
||||||
|
If IsMouseOver Then
|
||||||
|
'指向
|
||||||
|
AniStart(AaColor(PanColor, BackgroundProperty, "ColorBrush4", AnimationColorIn), "MyExtraTextButton Color " & Uuid)
|
||||||
|
Else
|
||||||
|
'普通
|
||||||
|
AniStart(AaColor(PanColor, BackgroundProperty, "ColorBrush3", AnimationColorOut), "MyExtraTextButton Color " & Uuid)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Else
|
||||||
|
|
||||||
|
AniStop("MyExtraTextButton Color " & Uuid)
|
||||||
|
If IsMouseOver Then
|
||||||
|
PanColor.SetResourceReference(BackgroundProperty, "ColorBrush4")
|
||||||
|
Else
|
||||||
|
PanColor.SetResourceReference(BackgroundProperty, "ColorBrush3")
|
||||||
|
End If
|
||||||
|
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
Log(ex, "刷新图标按钮颜色出错")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
End Class
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Path IsHitTestVisible="False" Grid.Column="0" x:Name="Path" VerticalAlignment="Center" Fill="#BF0000" Width="14" Stretch="Uniform" Margin="10,0,2,0" Data="F1 M 58.5832,55.4172L 17.4169,55.4171C 15.5619,53.5621 15.5619,50.5546 17.4168,48.6996L 35.201,15.8402C 37.056,13.9852 40.0635,13.9852 41.9185,15.8402L 58.5832,48.6997C 60.4382,50.5546 60.4382,53.5622 58.5832,55.4172 Z M 34.0417,25.7292L 36.0208,41.9584L 39.9791,41.9583L 41.9583,25.7292L 34.0417,25.7292 Z M 38,44.3333C 36.2511,44.3333 34.8333,45.7511 34.8333,47.5C 34.8333,49.2489 36.2511,50.6667 38,50.6667C 39.7489,50.6667 41.1666,49.2489 41.1666,47.5C 41.1666,45.7511 39.7489,44.3333 38,44.3333 Z " />
|
<Path IsHitTestVisible="False" Grid.Column="0" x:Name="Path" VerticalAlignment="Center" Fill="#BF0000" Width="14" Stretch="Uniform" Margin="10,0,2,0" Data="F1 M 58.5832,55.4172L 17.4169,55.4171C 15.5619,53.5621 15.5619,50.5546 17.4168,48.6996L 35.201,15.8402C 37.056,13.9852 40.0635,13.9852 41.9185,15.8402L 58.5832,48.6997C 60.4382,50.5546 60.4382,53.5622 58.5832,55.4172 Z M 34.0417,25.7292L 36.0208,41.9584L 39.9791,41.9583L 41.9583,25.7292L 34.0417,25.7292 Z M 38,44.3333C 36.2511,44.3333 34.8333,45.7511 34.8333,47.5C 34.8333,49.2489 36.2511,50.6667 38,50.6667C 39.7489,50.6667 41.1666,49.2489 41.1666,47.5C 41.1666,45.7511 39.7489,44.3333 38,44.3333 Z " />
|
||||||
<TextBlock IsHitTestVisible="False" Grid.Column="1" x:Name="LabText" Margin="0,0.5,0,0" Padding="6,6,8,6" Text="提示文本" VerticalAlignment="Center" Foreground="#BF0000" TextWrapping="Wrap" />
|
<TextBlock IsHitTestVisible="False" Grid.Column="1" x:Name="LabText" Margin="0,0.5,0,0" Padding="6,6,8,6" VerticalAlignment="Center" Foreground="#BF0000" TextWrapping="Wrap" />
|
||||||
<local:MyIconButton x:Name="BtnClose" SnapsToDevicePixels="True" Visibility="Collapsed" Foreground="#BF0000" Theme="Custom" Margin="0,0,6,0" Grid.Column="2" Height="20" Width="20" VerticalAlignment="Center" Logo="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z"
|
<local:MyIconButton x:Name="BtnClose" SnapsToDevicePixels="True" Visibility="Collapsed" Foreground="#BF0000" Theme="Custom" Margin="0,0,6,0" Grid.Column="2" Height="20" Width="20" VerticalAlignment="Center" Logo="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z"
|
||||||
ToolTip="不再显示" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="29" ToolTipService.HorizontalOffset="2" />
|
ToolTip="不再显示" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="29" ToolTipService.HorizontalOffset="2" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Public Class MyHint
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyHint
|
||||||
|
|
||||||
Public Uuid As Integer = GetUuid()
|
Public Uuid As Integer = GetUuid()
|
||||||
|
|
||||||
@@ -30,6 +33,11 @@
|
|||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Text As String
|
Public Property Text As String
|
||||||
Get
|
Get
|
||||||
Return LabText.Text
|
Return LabText.Text
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Public Class MyIconTextButton
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyIconTextButton
|
||||||
|
|
||||||
'基础
|
'基础
|
||||||
|
|
||||||
@@ -30,6 +33,11 @@
|
|||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Text As String
|
Public Property Text As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(TextProperty)
|
Return GetValue(TextProperty)
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ RetryStart:
|
|||||||
ElseIf EnableCache Then
|
ElseIf EnableCache Then
|
||||||
'保存缓存并显示
|
'保存缓存并显示
|
||||||
If File.Exists(TempPath) Then File.Delete(TempPath)
|
If File.Exists(TempPath) Then File.Delete(TempPath)
|
||||||
Rename(TempDownloadingPath, TempPath)
|
FileSystem.Rename(TempDownloadingPath, TempPath)
|
||||||
RunInUi(Sub() ActualSource = TempPath)
|
RunInUi(Sub() ActualSource = TempPath)
|
||||||
Else
|
Else
|
||||||
'直接显示
|
'直接显示
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Public Class MyListItem
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyListItem
|
||||||
Implements IMyRadio
|
Implements IMyRadio
|
||||||
|
|
||||||
Public Event Click(sender As Object, e As MouseButtonEventArgs)
|
Public Event Click(sender As Object, e As MouseButtonEventArgs)
|
||||||
@@ -161,6 +164,11 @@
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
'标题
|
'标题
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabTitle.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Title As String
|
Public Property Title As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(TitleProperty)
|
Return GetValue(TitleProperty)
|
||||||
@@ -337,16 +345,7 @@
|
|||||||
Return _Checked
|
Return _Checked
|
||||||
End Get
|
End Get
|
||||||
Set(value As Boolean)
|
Set(value As Boolean)
|
||||||
SetChecked(value, False, True, _Half)
|
SetChecked(value, False, True)
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private _Half As Boolean = False
|
|
||||||
Public Property Half As Boolean
|
|
||||||
Get
|
|
||||||
Return _Half
|
|
||||||
End Get
|
|
||||||
Set(value As Boolean)
|
|
||||||
SetChecked(_Checked, False, True, value)
|
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -355,8 +354,7 @@
|
|||||||
''' <param name="value">新的 Checked 属性。</param>
|
''' <param name="value">新的 Checked 属性。</param>
|
||||||
''' <param name="user">是否由用户引发。</param>
|
''' <param name="user">是否由用户引发。</param>
|
||||||
''' <param name="anime">是否执行动画。</param>
|
''' <param name="anime">是否执行动画。</param>
|
||||||
''' <param name="half">是否为部分选中。</param>
|
Public Sub SetChecked(value As Boolean, user As Boolean, anime As Boolean)
|
||||||
Public Sub SetChecked(value As Boolean, user As Boolean, anime As Boolean, Optional half As Boolean = False)
|
|
||||||
Try
|
Try
|
||||||
|
|
||||||
'自定义属性基础
|
'自定义属性基础
|
||||||
@@ -374,9 +372,8 @@
|
|||||||
End If
|
End If
|
||||||
_Checked = value
|
_Checked = value
|
||||||
Else
|
Else
|
||||||
If value = _Checked AndAlso half = _Half Then Exit Sub
|
If value = _Checked Then Exit Sub
|
||||||
_Checked = value
|
_Checked = value
|
||||||
_Half = half
|
|
||||||
If IsInitialized Then
|
If IsInitialized Then
|
||||||
RaiseEvent Changed(Me, ChangedEventArgs)
|
RaiseEvent Changed(Me, ChangedEventArgs)
|
||||||
If ChangedEventArgs.Handled Then
|
If ChangedEventArgs.Handled Then
|
||||||
@@ -440,9 +437,9 @@
|
|||||||
'由无变有
|
'由无变有
|
||||||
If Not IsNothing(RectCheck) Then
|
If Not IsNothing(RectCheck) Then
|
||||||
Dim Delta = ActualHeight - RectCheck.ActualHeight - 12
|
Dim Delta = ActualHeight - RectCheck.ActualHeight - 12
|
||||||
Anim.Add(AaHeight(RectCheck, Delta * If(half, 0.2, 0.4), 200,, New AniEaseOutFluent(AniEasePower.Weak)))
|
Anim.Add(AaHeight(RectCheck, Delta * 0.4, 200,, New AniEaseOutFluent(AniEasePower.Weak)))
|
||||||
Anim.Add(AaHeight(RectCheck, Delta * If(half, 0.3, 0.6), 300,, New AniEaseOutBack(AniEasePower.Weak)))
|
Anim.Add(AaHeight(RectCheck, Delta * 0.6, 300,, New AniEaseOutBack(AniEasePower.Weak)))
|
||||||
Anim.Add(AaOpacity(RectCheck, If(half, 0.5, 1) - RectCheck.Opacity, 30))
|
Anim.Add(AaOpacity(RectCheck, 1 - RectCheck.Opacity, 30))
|
||||||
RectCheck.VerticalAlignment = VerticalAlignment.Center
|
RectCheck.VerticalAlignment = VerticalAlignment.Center
|
||||||
RectCheck.Margin = New Thickness(-1, 0, 0, 0)
|
RectCheck.Margin = New Thickness(-1, 0, 0, 0)
|
||||||
End If
|
End If
|
||||||
@@ -461,17 +458,12 @@
|
|||||||
Else
|
Else
|
||||||
'不使用动画
|
'不使用动画
|
||||||
AniStop("MyListItem Checked " & Uuid)
|
AniStop("MyListItem Checked " & Uuid)
|
||||||
|
If Checked Then
|
||||||
If Checked OrElse half Then
|
|
||||||
If Not IsNothing(RectCheck) Then
|
If Not IsNothing(RectCheck) Then
|
||||||
RectCheck.Height = Double.NaN
|
RectCheck.Height = Double.NaN
|
||||||
RectCheck.Margin = New Thickness(-1, 6, 0, 6)
|
RectCheck.Margin = New Thickness(-1, 6, 0, 6)
|
||||||
RectCheck.Opacity = 1
|
RectCheck.Opacity = 1
|
||||||
RectCheck.VerticalAlignment = VerticalAlignment.Stretch
|
RectCheck.VerticalAlignment = VerticalAlignment.Stretch
|
||||||
If half Then
|
|
||||||
RectCheck.Height = Height * 0.4
|
|
||||||
RectCheck.Opacity = 0.5
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
SetResourceReference(ForegroundProperty, If(Height < 40, "ColorBrush3", "ColorBrush2"))
|
SetResourceReference(ForegroundProperty, If(Height < 40, "ColorBrush3", "ColorBrush2"))
|
||||||
Else
|
Else
|
||||||
|
|||||||
@@ -353,6 +353,10 @@
|
|||||||
If Control.RenderTransform IsNot Nothing AndAlso TypeOf Control.RenderTransform Is TranslateTransform Then Control.RenderTransform = Nothing
|
If Control.RenderTransform IsNot Nothing AndAlso TypeOf Control.RenderTransform Is TranslateTransform Then Control.RenderTransform = Nothing
|
||||||
Next
|
Next
|
||||||
For Each Control As FrameworkElement In GetAllAnimControls(Element)
|
For Each Control As FrameworkElement In GetAllAnimControls(Element)
|
||||||
|
If TypeOf Control Is MyExtraTextButton Then
|
||||||
|
CType(Control, MyExtraTextButton).Show = True
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
Control.Opacity = 0
|
Control.Opacity = 0
|
||||||
Control.RenderTransform = New TranslateTransform(0, -16)
|
Control.RenderTransform = New TranslateTransform(0, -16)
|
||||||
AniList.Add(AaOpacity(Control, 1, 150, Delay, New AniEaseOutFluent(AniEasePower.Weak)))
|
AniList.Add(AaOpacity(Control, 1, 150, Delay, New AniEaseOutFluent(AniEasePower.Weak)))
|
||||||
@@ -379,6 +383,10 @@
|
|||||||
Dim Delay As Integer = 0
|
Dim Delay As Integer = 0
|
||||||
For Each Element In RealElements
|
For Each Element In RealElements
|
||||||
For Each Control As FrameworkElement In GetAllAnimControls(Element)
|
For Each Control As FrameworkElement In GetAllAnimControls(Element)
|
||||||
|
If TypeOf Control Is MyExtraTextButton Then
|
||||||
|
CType(Control, MyExtraTextButton).Show = False
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
Control.IsHitTestVisible = False
|
Control.IsHitTestVisible = False
|
||||||
AniList.Add(AaOpacity(Control, -1, 90, Delay))
|
AniList.Add(AaOpacity(Control, -1, 90, Delay))
|
||||||
AniList.Add(AaTranslateY(Control, -6, 90, Delay))
|
AniList.Add(AaTranslateY(Control, -6, 90, Delay))
|
||||||
@@ -392,7 +400,8 @@
|
|||||||
AniList.Add(AaTranslateX(Scroll, 10 - CType(Scroll.RenderTransform, TranslateTransform).X, 90, 0, New AniEaseInFluent))
|
AniList.Add(AaTranslateX(Scroll, 10 - CType(Scroll.RenderTransform, TranslateTransform).X, 90, 0, New AniEaseInFluent))
|
||||||
End If
|
End If
|
||||||
'结束
|
'结束
|
||||||
AniList.Add(AaCode(Sub()
|
AniList.Add(AaCode(
|
||||||
|
Sub()
|
||||||
For Each Element In RealElements
|
For Each Element In RealElements
|
||||||
Element.Visibility = Visibility.Collapsed
|
Element.Visibility = Visibility.Collapsed
|
||||||
Next
|
Next
|
||||||
@@ -409,7 +418,7 @@
|
|||||||
End Function
|
End Function
|
||||||
Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
|
Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
|
||||||
If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Exit Sub
|
If Not IgnoreInvisibility AndAlso Element.Visibility = Visibility.Collapsed Then Exit Sub
|
||||||
If TypeOf Element Is MyCard OrElse TypeOf Element Is MyHint OrElse TypeOf Element Is TextBlock OrElse TypeOf Element Is MyTextButton Then
|
If TypeOf Element Is MyCard OrElse TypeOf Element Is MyHint OrElse TypeOf Element Is MyExtraTextButton OrElse TypeOf Element Is TextBlock OrElse TypeOf Element Is MyTextButton Then
|
||||||
AllControls.Add(Element)
|
AllControls.Add(Element)
|
||||||
ElseIf TypeOf Element Is ContentControl Then
|
ElseIf TypeOf Element Is ContentControl Then
|
||||||
Dim Content = CType(Element, ContentControl).Content
|
Dim Content = CType(Element, ContentControl).Content
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
FocusVisualStyle="{x:Null}"
|
FocusVisualStyle="{x:Null}"
|
||||||
MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True">
|
MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True">
|
||||||
<TextBlock IsHitTestVisible="False" x:Name="LabText" FontSize="13" Padding="0" Margin="26,0,0,0" Text="Radiobox" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock IsHitTestVisible="False" x:Name="LabText" FontSize="13" Padding="0" Margin="26,0,0,0" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
<Ellipse IsHitTestVisible="False" x:Name="ShapeBorder" StrokeThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" Stroke="{DynamicResource ColorBrush1}" Margin="1,0,0,0" Fill="{StaticResource ColorBrushHalfWhite}" />
|
<Ellipse IsHitTestVisible="False" x:Name="ShapeBorder" StrokeThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" Stroke="{DynamicResource ColorBrush1}" Margin="1,0,0,0" Fill="{StaticResource ColorBrushHalfWhite}" />
|
||||||
<Ellipse IsHitTestVisible="False" x:Name="ShapeDot" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding Stroke, ElementName=ShapeBorder}" Width="0" Height="0" Margin="10,0,0,0" StrokeThickness="0" />
|
<Ellipse IsHitTestVisible="False" x:Name="ShapeDot" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding Stroke, ElementName=ShapeBorder}" Width="0" Height="0" Margin="10,0,0,0" StrokeThickness="0" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Public Class MyRadioBox
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyRadioBox
|
||||||
Implements IMyRadio
|
Implements IMyRadio
|
||||||
|
|
||||||
'基础
|
'基础
|
||||||
@@ -10,27 +13,29 @@
|
|||||||
Public Event Changed(sender As Object, e As RouteEventArgs) Implements IMyRadio.Changed
|
Public Event Changed(sender As Object, e As RouteEventArgs) Implements IMyRadio.Changed
|
||||||
|
|
||||||
'自定义属性
|
'自定义属性
|
||||||
|
|
||||||
Private _Checked As Boolean = False '是否选中
|
|
||||||
Public Property Checked As Boolean
|
Public Property Checked As Boolean
|
||||||
Get
|
Get
|
||||||
Return _Checked
|
Return GetValue(CheckedProperty)
|
||||||
End Get
|
End Get
|
||||||
Set(value As Boolean)
|
Set(value As Boolean)
|
||||||
SetChecked(value, False, True)
|
SetChecked(value, False)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Public Shared ReadOnly CheckedProperty As DependencyProperty =
|
||||||
|
DependencyProperty.Register("Checked", GetType(Boolean), GetType(MyRadioBox), New PropertyMetadata(False,
|
||||||
|
Sub(d As MyRadioBox, e As DependencyPropertyChangedEventArgs)
|
||||||
|
'在使用 XAML 设置 Checked 属性时,不会触发 Checked_Set 方法,所以需要在这里手动触发 UI 改变
|
||||||
|
If Not d.IsLoaded Then d.SyncUI()
|
||||||
|
End Sub))
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 手动设置 Checked 属性。
|
''' 手动设置 Checked 属性。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="value">新的 Checked 属性。</param>
|
''' <param name="value">新的 Checked 属性。</param>
|
||||||
''' <param name="user">是否由用户引发。</param>
|
''' <param name="user">是否由用户引发。</param>
|
||||||
''' <param name="anime">是否执行动画。</param>
|
Public Sub SetChecked(value As Boolean, user As Boolean)
|
||||||
Public Sub SetChecked(value As Boolean, user As Boolean, anime As Boolean)
|
|
||||||
Try
|
Try
|
||||||
|
|
||||||
'Preview 事件
|
'Preview 事件
|
||||||
|
|
||||||
If value AndAlso user Then
|
If value AndAlso user Then
|
||||||
Dim e = New RouteEventArgs(user)
|
Dim e = New RouteEventArgs(user)
|
||||||
RaiseEvent PreviewCheck(Me, e)
|
RaiseEvent PreviewCheck(Me, e)
|
||||||
@@ -41,28 +46,24 @@
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
'自定义属性基础
|
'自定义属性基础
|
||||||
|
|
||||||
Dim IsChanged As Boolean = False
|
Dim IsChanged As Boolean = False
|
||||||
If IsLoaded AndAlso Not value = _Checked Then RaiseEvent PreviewChange(Me, New RouteEventArgs(user))
|
If IsLoaded AndAlso Not value = Checked Then RaiseEvent PreviewChange(Me, New RouteEventArgs(user))
|
||||||
If Not value = _Checked Then
|
If Not value = Checked Then
|
||||||
_Checked = value
|
SetValue(CheckedProperty, value)
|
||||||
IsChanged = True
|
IsChanged = True
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'保证只有一个单选框选中
|
'保证只有一个单选框选中
|
||||||
|
|
||||||
If Parent Is Nothing Then Exit Sub
|
If Parent Is Nothing Then Exit Sub
|
||||||
Dim RadioboxList As New List(Of MyRadioBox)
|
Dim RadioboxList As New List(Of MyRadioBox)
|
||||||
Dim CheckedCount As Integer = 0
|
Dim CheckedCount As Integer = 0
|
||||||
'收集控件列表与选中个数
|
For Each Control In CType(Parent, Object).Children '收集控件列表与选中个数
|
||||||
For Each Control In CType(Parent, Object).Children
|
|
||||||
If TypeOf Control Is MyRadioBox Then
|
If TypeOf Control Is MyRadioBox Then
|
||||||
RadioboxList.Add(Control)
|
RadioboxList.Add(Control)
|
||||||
If Control.Checked Then CheckedCount += 1
|
If Control.Checked Then CheckedCount += 1
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
'判断选中情况
|
Select Case CheckedCount '判断选中情况
|
||||||
Select Case CheckedCount
|
|
||||||
Case 0
|
Case 0
|
||||||
'没有任何单选框被选中,选择第一个
|
'没有任何单选框被选中,选择第一个
|
||||||
RadioboxList(0).Checked = True
|
RadioboxList(0).Checked = True
|
||||||
@@ -87,12 +88,21 @@
|
|||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End Select
|
End Select
|
||||||
'End If
|
|
||||||
|
'触发事件
|
||||||
|
If IsChanged Then
|
||||||
|
If Checked Then RaiseEvent Check(Me, New RouteEventArgs(user))
|
||||||
|
RaiseEvent Changed(Me, New RouteEventArgs(user))
|
||||||
|
End If
|
||||||
|
|
||||||
'更改动画
|
'更改动画
|
||||||
|
SyncUI()
|
||||||
If Not IsChanged Then Exit Sub
|
Catch ex As Exception
|
||||||
If IsLoaded AndAlso AniControlEnabled = 0 AndAlso anime Then '防止默认属性变更触发动画
|
Log(ex, "单选框勾选改变错误", LogLevel.Hint)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub SyncUI()
|
||||||
|
If AniControlEnabled = 0 AndAlso IsLoaded Then '防止默认属性变更触发动画
|
||||||
If Checked Then
|
If Checked Then
|
||||||
'由无变有
|
'由无变有
|
||||||
If ShapeDot.Opacity < 0.01 Then ShapeDot.Opacity = 1
|
If ShapeDot.Opacity < 0.01 Then ShapeDot.Opacity = 1
|
||||||
@@ -139,15 +149,13 @@
|
|||||||
ShapeBorder.SetResourceReference(Ellipse.StrokeProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"))
|
ShapeBorder.SetResourceReference(Ellipse.StrokeProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"))
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'触发事件
|
|
||||||
If Checked Then RaiseEvent Check(Me, New RouteEventArgs(user))
|
|
||||||
RaiseEvent Changed(Me, New RouteEventArgs(user))
|
|
||||||
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "单选框勾选改变错误", LogLevel.Hint)
|
|
||||||
End Try
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Text As String
|
Public Property Text As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(TextProperty)
|
Return GetValue(TextProperty)
|
||||||
@@ -165,9 +173,9 @@
|
|||||||
Private AllowMouseDown As Boolean = True
|
Private AllowMouseDown As Boolean = True
|
||||||
Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
|
Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
|
||||||
If Not MouseDowned Then Exit Sub
|
If Not MouseDowned Then Exit Sub
|
||||||
MouseDowned = False
|
|
||||||
Log("[Control] 按下单选框:" & Text)
|
Log("[Control] 按下单选框:" & Text)
|
||||||
SetChecked(True, True, True)
|
SetChecked(True, True)
|
||||||
|
MouseDowned = False
|
||||||
AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
|
AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub Radiobox_MouseDown() Handles Me.MouseLeftButtonDown
|
Private Sub Radiobox_MouseDown() Handles Me.MouseLeftButtonDown
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Public Class MyRadioButton
|
Imports System.Windows.Markup
|
||||||
|
|
||||||
|
<ContentProperty("Inlines")>
|
||||||
|
Public Class MyRadioButton
|
||||||
|
|
||||||
'基础
|
'基础
|
||||||
|
|
||||||
@@ -108,6 +111,12 @@
|
|||||||
Log(ex, "单选按钮勾选改变错误", LogLevel.Hint)
|
Log(ex, "单选按钮勾选改变错误", LogLevel.Hint)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
Public ReadOnly Property Inlines As InlineCollection
|
||||||
|
Get
|
||||||
|
Return LabText.Inlines
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Property Text As String
|
Public Property Text As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(TextProperty)
|
Return GetValue(TextProperty)
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid x:Name="PanTitleInner" Visibility="Collapsed" Margin="-16,0,0,0" Opacity="0" HorizontalAlignment="Left" Width="{Binding ActualWidth, ElementName=PanTitle, Mode=OneWay}">
|
<Grid x:Name="PanTitleInner" Visibility="Collapsed" Margin="-16,0,0,0" Opacity="0" HorizontalAlignment="Left" Width="{Binding ActualWidth, ElementName=PanTitle, Mode=OneWay}">
|
||||||
<local:MyIconButton HorizontalAlignment="Left" Theme="White" x:Name="BtnTitleInner" Margin="12,0,0,0" Height="28" Width="28"
|
<local:MyIconButton HorizontalAlignment="Left" Theme="White" x:Name="BtnTitleInner" Margin="12,0,0,0" Height="28" Width="28"
|
||||||
LogoScale="0.87" Logo="M1097.162313 584.707482 250.272424 584.707482 562.833701 896.95123C591.749274 925.859979 591.749274 972.659975 562.833701 1001.568724 533.91812 1030.477473 487.058315 1030.477473 458.142742 1001.568724L21.580946 565.451235C6.757449 550.631234-0.361728 531.131238 0.028357 511.679985L0.028357 511.631236 0.028357 511.582486C-0.361728 492.13124 6.757449 472.582488 21.580946 457.762487L458.142742 21.644997C487.058315-7.215002 533.91812-7.215002 562.833701 21.644997 591.749274 50.553746 591.749274 97.4025 562.833701 126.262499L250.272424 438.55499 1097.162313 438.55499C1137.585605 438.55499 1170.304578 471.266238 1170.304578 511.631236 1170.304578 551.947483 1137.585605 584.707482 1097.162313 584.707482L1097.162313 584.707482Z" />
|
LogoScale="0.87" Logo="M1097 584 250 584 562 896C591 925 591 972 562 1001 533 1030 487 1030 458 1001L21 565C6 550-0 531 0 511L0 511 0 511C-0 492 6 472 21 457L458 21C487-7 533-7 562 21 591 50 591 97 562 126L250 438 1097 438C1137 438 1170 471 1170 511 1170 551 1137 584 1097 584L1097 584Z" />
|
||||||
<TextBlock SnapsToDevicePixels="False" IsHitTestVisible="False" Name="LabTitleInner" VerticalAlignment="Center" Margin="47,1,60,0" HorizontalAlignment="Left" Foreground="{DynamicResource ColorBrush8}" FontSize="15" />
|
<TextBlock SnapsToDevicePixels="False" IsHitTestVisible="False" Name="LabTitleInner" VerticalAlignment="Center" Margin="47,1,60,0" HorizontalAlignment="Left" Foreground="{DynamicResource ColorBrush8}" FontSize="15" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -10,201 +10,112 @@ Public Class FormMain
|
|||||||
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
|
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
|
||||||
'统计更新日志条目
|
'统计更新日志条目
|
||||||
#If BETA Then
|
#If BETA Then
|
||||||
|
If LastVersion < 352 Then 'Release 2.9.1
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "新增:导出整合包功能"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:支持在超长路径下安装、启动游戏"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法安装 1.21 OptiFine"))
|
||||||
|
FeatureCount += 23
|
||||||
|
BugCount += 10
|
||||||
|
End If
|
||||||
|
If LastVersion < 349 Then 'Release 2.8.13
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:网络环境不佳时,Mod、整合包页面的加载速度"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:部分电脑无法打开程序"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:可能无法识别、更新 Mod"))
|
||||||
|
FeatureCount += 6
|
||||||
|
BugCount += 14
|
||||||
|
End If
|
||||||
If LastVersion < 347 Then 'Release 2.8.12
|
If LastVersion < 347 Then 'Release 2.8.12
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面添加下载 Mod、安装 Mod 选项"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:Mod 管理页面添加下载 Mod、安装 Mod 选项"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 详情页面支持按加载器、游戏版本进行分类和筛选"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:Mod 详情页面支持按加载器、游戏版本进行分类和筛选"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持安装同时包含 modpack 文件和启动器的懒人包"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "新增:支持安装同时包含 modpack 文件和启动器的懒人包"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化整合包导入流程"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化:整合包导入流程"))
|
||||||
FeatureCount += 43
|
FeatureCount += 43
|
||||||
BugCount += 37
|
BugCount += 37
|
||||||
End If
|
End If
|
||||||
If LastVersion < 342 Then 'Release 2.8.9
|
If LastVersion < 342 Then 'Release 2.8.9
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持下载原版服务端"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:支持下载原版服务端"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "本地 Mod 的标题支持选择显示 Mod 原始文件名"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "新增:本地 Mod 的标题支持选择显示 Mod 原始文件名"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复搜索后启用/禁用 Mod 时出错的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:搜索后启用/禁用 Mod 时出错"))
|
||||||
FeatureCount += 17
|
FeatureCount += 17
|
||||||
BugCount += 13
|
BugCount += 13
|
||||||
End If
|
End If
|
||||||
If LastVersion < 340 Then 'Release 2.8.8
|
If LastVersion < 340 Then 'Release 2.8.8
|
||||||
If LastVersion = 338 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复数个与新正版登录相关的严重 Bug"))
|
If LastVersion = 338 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:数个与新正版登录相关的严重 Bug"))
|
||||||
FeatureCount += 3
|
FeatureCount += 3
|
||||||
BugCount += 7
|
BugCount += 7
|
||||||
End If
|
End If
|
||||||
If LastVersion < 338 Then 'Release 2.8.7
|
If LastVersion < 338 Then 'Release 2.8.7
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "使用新的正版登录方式,以提高安全性"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化:使用新的正版登录方式,以提高安全性"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化安装整合包、检索 Mod 的稳定性"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:安装整合包、检索 Mod 的稳定性"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法加载部分 Mod 的图标的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法加载部分 Mod 的图标"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复在 Mod 管理页面删除 Mod 导致报错的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:在 Mod 管理页面删除 Mod 导致报错"))
|
||||||
FeatureCount += 11
|
FeatureCount += 11
|
||||||
BugCount += 21
|
BugCount += 21
|
||||||
End If
|
End If
|
||||||
If LastVersion < 336 Then 'Release 2.8.6
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "下载 Mod 时会使用 MCIM 国内镜像源"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面允许筛选可更新/启用/禁用的 Mod"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "打开 PCL 时会自动安装同目录下的 modpack.zip"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "爱发电域名迁移至 afdian.com"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复 1.20.1+ 离线登录使用正版皮肤时无法保存游戏的 Bug"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复安装的 1.14~1.15 Forge+OptiFine 无法进入世界的 Bug"))
|
|
||||||
FeatureCount += 19
|
|
||||||
BugCount += 24
|
|
||||||
End If
|
|
||||||
If LastVersion < 332 Then 'Release 2.8.3
|
|
||||||
If LastVersion = 330 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复部分玩家无法启动 MC 的 Bug"))
|
|
||||||
End If
|
|
||||||
If LastVersion < 330 Then 'Release 2.8.2
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "NeoForge 兼容与自动安装"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持编译、运行 PCL 开源代码"))
|
|
||||||
FeatureCount += 15
|
|
||||||
BugCount += 22
|
|
||||||
End If
|
|
||||||
If LastVersion < 326 Then 'Release 2.7.4
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "会自动隐藏明显不可用的自动安装选项"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化正版登录流程和 MC 性能"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复正版登录时弹出脚本错误提示的 Bug"))
|
|
||||||
FeatureCount += 17
|
|
||||||
BugCount += 19
|
|
||||||
End If
|
|
||||||
If LastVersion < 323 Then 'Release 2.7.3
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 启动游戏前进行内存优化 设置"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 MC 性能"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复安装 OptiFine 有概率失败的 Bug"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复启动 Fabric 1.20.5+ 时无法正确选择 Java 的 Bug"))
|
|
||||||
FeatureCount += 22
|
|
||||||
BugCount += 21
|
|
||||||
End If
|
|
||||||
If LastVersion < 321 Then 'Release 2.7.1
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复启动部分整合包导致设置丢失的 Bug"))
|
|
||||||
BugCount += 1
|
|
||||||
End If
|
|
||||||
If LastVersion < 319 Then 'Release 2.7.0
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持更新 Mod"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持查看可更新的 Mod 的更新日志"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持滑动鼠标快速选中、取消选中多个 Mod"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动 MC 24w14a+ 的 Bug"))
|
|
||||||
FeatureCount += 10
|
|
||||||
BugCount += 10
|
|
||||||
End If
|
|
||||||
#Else
|
#Else
|
||||||
'5: FEAT+
|
'5: FEAT+
|
||||||
'4: IMP+ FEAT*
|
'4: IMP+ FEAT*
|
||||||
'3:BUG+ IMP* FEAT-
|
'3:BUG+ IMP* FEAT-
|
||||||
'2:BUG* IMP-
|
'2:BUG* IMP-
|
||||||
'1:BUG-
|
'1:BUG-
|
||||||
If LastVersion < 346 Then 'Snapshot 2.8.13
|
If LastVersion < 351 Then 'Snapshot 2.9.1
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化网络环境不佳时,Mod、整合包页面的加载速度"))
|
If LastVersion = 350 Then
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复部分电脑无法打开程序的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化:对导出整合包功能进行了 7 项优化,详见完整更新日志"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复可能无法识别、更新 Mod 的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法进行第三方登录"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:在部分版本下,打开导出页面会导致启动器崩溃"))
|
||||||
|
BugCount += 1
|
||||||
|
End If
|
||||||
|
BugCount += 2
|
||||||
|
End If
|
||||||
|
If LastVersion < 350 Then 'Snapshot 2.9.0
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "新增:导出整合包功能"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:支持在超长路径下安装、启动游戏"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法安装 1.21 OptiFine"))
|
||||||
|
FeatureCount += 21
|
||||||
|
BugCount += 10
|
||||||
|
End If
|
||||||
|
If LastVersion < 348 Then 'Snapshot 2.8.13
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:网络环境不佳时,Mod、整合包页面的加载速度"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:部分电脑无法打开程序"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:可能无法识别、更新 Mod"))
|
||||||
FeatureCount += 6
|
FeatureCount += 6
|
||||||
BugCount += 14
|
BugCount += 14
|
||||||
End If
|
End If
|
||||||
If LastVersion < 346 Then 'Snapshot 2.8.12
|
If LastVersion < 346 Then 'Snapshot 2.8.12
|
||||||
If LastVersion = 345 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复帮助页面报错的 Bug"))
|
If LastVersion = 345 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:帮助页面报错"))
|
||||||
End If
|
End If
|
||||||
If LastVersion < 345 Then 'Snapshot 2.8.11
|
If LastVersion < 345 Then 'Snapshot 2.8.11
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面添加下载 Mod、安装 Mod 选项"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:Mod 管理页面添加下载 Mod、安装 Mod 选项"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 详情页面支持按加载器、游戏版本进行分类和筛选"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:Mod 详情页面支持按加载器、游戏版本进行分类和筛选"))
|
||||||
FeatureCount += 23
|
FeatureCount += 23
|
||||||
BugCount += 21
|
BugCount += 21
|
||||||
End If
|
End If
|
||||||
If LastVersion < 343 Then 'Snapshot 2.8.10
|
If LastVersion < 343 Then 'Snapshot 2.8.10
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持安装同时包含 modpack 文件和启动器的懒人包"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "新增:支持安装同时包含 modpack 文件和启动器的懒人包"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化整合包导入流程"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化:整合包导入流程"))
|
||||||
FeatureCount += 20
|
FeatureCount += 20
|
||||||
BugCount += 16
|
BugCount += 16
|
||||||
End If
|
End If
|
||||||
If LastVersion < 341 Then 'Snapshot 2.8.9
|
If LastVersion < 341 Then 'Snapshot 2.8.9
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持下载原版服务端"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增:支持下载原版服务端"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "本地 Mod 的标题支持选择显示 Mod 原始文件名"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "新增:本地 Mod 的标题支持选择显示 Mod 原始文件名"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复搜索后启用/禁用 Mod 时出错的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:搜索后启用/禁用 Mod 时出错"))
|
||||||
FeatureCount += 17
|
FeatureCount += 17
|
||||||
BugCount += 13
|
BugCount += 13
|
||||||
End If
|
End If
|
||||||
If LastVersion < 339 Then 'Snapshot 2.8.8
|
If LastVersion < 339 Then 'Snapshot 2.8.8
|
||||||
If LastVersion = 337 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复数个与新正版登录相关的严重 Bug"))
|
If LastVersion = 337 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:数个与新正版登录相关的严重 Bug"))
|
||||||
FeatureCount += 3
|
FeatureCount += 3
|
||||||
BugCount += 7
|
BugCount += 7
|
||||||
End If
|
End If
|
||||||
If LastVersion < 337 Then 'Snapshot 2.8.7
|
If LastVersion < 337 Then 'Snapshot 2.8.7
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "使用新的正版登录方式,以提高安全性"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "优化:使用新的正版登录方式,以提高安全性"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化安装整合包、检索 Mod 的稳定性"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:安装整合包、检索 Mod 的稳定性"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法加载部分 Mod 的图标的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法加载部分 Mod 的图标"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复在 Mod 管理页面删除 Mod 导致报错的 Bug"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:在 Mod 管理页面删除 Mod 导致报错"))
|
||||||
FeatureCount += 11
|
FeatureCount += 11
|
||||||
BugCount += 21
|
BugCount += 21
|
||||||
End If
|
End If
|
||||||
If LastVersion < 335 Then 'Snapshot 2.8.6
|
|
||||||
BugCount += 2
|
|
||||||
End If
|
|
||||||
If LastVersion < 334 Then 'Snapshot 2.8.5
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面允许筛选可更新/启用/禁用的 Mod"))
|
|
||||||
If LastVersion = 333 Then
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装愚人节和预发布版本的 Bug"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法导出错误报告的 Bug"))
|
|
||||||
End If
|
|
||||||
FeatureCount += 6
|
|
||||||
BugCount += 7
|
|
||||||
End If
|
|
||||||
If LastVersion < 333 Then 'Snapshot 2.8.4
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "下载 Mod 时会使用 MCIM 国内镜像源"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "打开 PCL 时会自动安装同目录下的 modpack.zip"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "爱发电域名迁移至 afdian.com"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复 1.20.1+ 离线登录使用正版皮肤时无法保存游戏的 Bug"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复安装的 1.14~1.15 Forge+OptiFine 无法进入世界的 Bug"))
|
|
||||||
FeatureCount += 13
|
|
||||||
BugCount += 17
|
|
||||||
End If
|
|
||||||
If LastVersion < 331 Then 'Snapshot 2.8.3
|
|
||||||
If LastVersion = 329 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复部分玩家无法启动 MC 的 Bug"))
|
|
||||||
End If
|
|
||||||
If LastVersion < 329 Then 'Snapshot 2.8.2
|
|
||||||
If LastVersion >= 327 Then
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Beta 版 NeoForge 的整合包的 Bug"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复自动安装无法选择部分 OptiFine 的 Bug"))
|
|
||||||
End If
|
|
||||||
FeatureCount += 4
|
|
||||||
BugCount += 8
|
|
||||||
End If
|
|
||||||
If LastVersion < 328 Then 'Snapshot 2.8.1
|
|
||||||
If LastVersion = 327 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.12.2- 的 Bug"))
|
|
||||||
If LastVersion = 327 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法输入解锁码的 Bug"))
|
|
||||||
If LastVersion = 327 Then BugCount += 1
|
|
||||||
End If
|
|
||||||
If LastVersion < 327 Then 'Snapshot 2.8.0
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "NeoForge 兼容与自动安装"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持编译、运行 PCL 开源代码"))
|
|
||||||
FeatureCount += 11
|
|
||||||
BugCount += 14
|
|
||||||
End If
|
|
||||||
If LastVersion < 325 Then 'Snapshot 2.7.4
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "会自动隐藏明显不可用的自动安装选项"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化正版登录流程和 MC 性能"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复正版登录时弹出脚本错误提示的 Bug"))
|
|
||||||
FeatureCount += 17
|
|
||||||
BugCount += 19
|
|
||||||
End If
|
|
||||||
If LastVersion < 324 Then 'Snapshot 2.7.3
|
|
||||||
FeatureCount += 4
|
|
||||||
BugCount += 3
|
|
||||||
End If
|
|
||||||
If LastVersion < 322 Then 'Snapshot 2.7.2
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 启动游戏前进行内存优化 设置"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复安装 OptiFine 有概率失败的 Bug"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复启动 Fabric 1.20.5+ 时无法正确选择 Java 的 Bug"))
|
|
||||||
FeatureCount += 18
|
|
||||||
BugCount += 18
|
|
||||||
End If
|
|
||||||
If LastVersion < 320 Then 'Snapshot 2.7.1
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复启动部分整合包导致设置丢失的 Bug"))
|
|
||||||
BugCount += 1
|
|
||||||
End If
|
|
||||||
If LastVersion < 318 Then 'Snapshot 2.7.0
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持更新 Mod"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持查看可更新的 Mod 的更新日志"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持滑动鼠标快速选中、取消选中多个 Mod"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动 MC 24w14a+ 的 Bug"))
|
|
||||||
FeatureCount += 10
|
|
||||||
BugCount += 10
|
|
||||||
End If
|
|
||||||
#End If
|
#End If
|
||||||
'整理更新日志文本
|
'整理更新日志文本
|
||||||
Dim ContentList As New List(Of String)
|
Dim ContentList As New List(Of String)
|
||||||
@@ -366,6 +277,7 @@ Public Class FormMain
|
|||||||
DlClientListMojangLoader.Start(1)
|
DlClientListMojangLoader.Start(1)
|
||||||
RunCountSub()
|
RunCountSub()
|
||||||
ServerLoader.Start(1)
|
ServerLoader.Start(1)
|
||||||
|
RunInNewThread(AddressOf TryClearTaskTemp, "TryClearTaskTemp", ThreadPriority.BelowNormal)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "初始化加载池运行失败", LogLevel.Feedback)
|
Log(ex, "初始化加载池运行失败", LogLevel.Feedback)
|
||||||
End Try
|
End Try
|
||||||
@@ -466,7 +378,7 @@ Public Class FormMain
|
|||||||
Log("[Start] 已从老版本迁移微软登录结果")
|
Log("[Start] 已从老版本迁移微软登录结果")
|
||||||
End If
|
End If
|
||||||
'输出更新日志
|
'输出更新日志
|
||||||
If LastVersionCode = 0 Then Exit Sub
|
If LastVersionCode <= 0 Then Exit Sub
|
||||||
If LowerVersionCode >= VersionCode Then Exit Sub
|
If LowerVersionCode >= VersionCode Then Exit Sub
|
||||||
ShowUpdateLog(LowerVersionCode)
|
ShowUpdateLog(LowerVersionCode)
|
||||||
End Sub
|
End Sub
|
||||||
@@ -657,6 +569,7 @@ Public Class FormMain
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub FormMain_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseDown
|
Private Sub FormMain_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseDown
|
||||||
'鼠标侧键返回上一级
|
'鼠标侧键返回上一级
|
||||||
|
If FrmMain.PanMsg.Children.Count > 0 OrElse WaitingMyMsgBox.Any Then Exit Sub '弹窗中(#5513)
|
||||||
If e.ChangedButton = MouseButton.XButton1 OrElse e.ChangedButton = MouseButton.XButton2 Then TriggerPageBack()
|
If e.ChangedButton = MouseButton.XButton1 OrElse e.ChangedButton = MouseButton.XButton2 Then TriggerPageBack()
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub TriggerPageBack()
|
Private Sub TriggerPageBack()
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ Public Module ModBase
|
|||||||
#Region "声明"
|
#Region "声明"
|
||||||
|
|
||||||
'下列版本信息由更新器自动修改
|
'下列版本信息由更新器自动修改
|
||||||
Public Const VersionBaseName As String = "2.8.13" '不含分支前缀的显示用版本名
|
Public Const VersionBaseName As String = "2.9.1" '不含分支前缀的显示用版本名
|
||||||
Public Const VersionStandardCode As String = "2.8.13." & VersionBranchCode '标准格式的四段式版本号
|
Public Const VersionStandardCode As String = "2.9.1." & VersionBranchCode '标准格式的四段式版本号
|
||||||
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
||||||
#If BETA Then
|
#If BETA Then
|
||||||
Public Const VersionCode As Integer = 347 'Release
|
Public Const VersionCode As Integer = 352 'Release
|
||||||
#Else
|
#Else
|
||||||
Public Const VersionCode As Integer = 348 'Snapshot
|
Public Const VersionCode As Integer = 351 'Snapshot
|
||||||
#End If
|
#End If
|
||||||
'自动生成的版本信息
|
'自动生成的版本信息
|
||||||
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
||||||
@@ -180,10 +180,6 @@ Public Module ModBase
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Const IconButtonServer As String = "M224 160a64 64 0 0 0-64 64v576a64 64 0 0 0 64 64h576a64 64 0 0 0 64-64V224a64 64 0 0 0-64-64H224z m0 384h576v256H224v-256z m192 96v64h320v-64H416z m-128 0v64h64v-64H288zM224 224h576v256H224V224z m192 96v64h320v-64H416z m-128 0v64h64v-64H288z"
|
Public Const IconButtonServer As String = "M224 160a64 64 0 0 0-64 64v576a64 64 0 0 0 64 64h576a64 64 0 0 0 64-64V224a64 64 0 0 0-64-64H224z m0 384h576v256H224v-256z m192 96v64h320v-64H416z m-128 0v64h64v-64H288zM224 224h576v256H224V224z m192 96v64h320v-64H416z m-128 0v64h64v-64H288z"
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 图标,向右箭头,1x
|
|
||||||
''' </summary>
|
|
||||||
Public Const IconButtonRight As String = "M757.792745 435.407215L419.597482 96.904967c-40.010393-40.010393-104.886579-40.010393-144.896972 0-40.010393 40.010393-40.010393 104.988908 0 144.9993L540.344959 507.855701 274.70051 773.807135c-40.010393 40.112721-40.010393 104.988908 0 144.9993 40.010393 40.010393 104.886579 40.010393 144.896972 0l338.092935-338.39992c40.112721-40.010393 40.112721-104.988908 0.102328-144.9993z"
|
|
||||||
''' <summary>
|
|
||||||
''' 图标,音符,1x
|
''' 图标,音符,1x
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Const IconMusic As String = "M348.293565 716.53287V254.797913c0-41.672348 28.004174-78.358261 68.919652-90.37913L815.994435 40.826435c62.775652-18.610087 125.907478 26.579478 125.907478 89.933913v539.158261c8.013913 42.25113-8.94887 89.177043-47.014956 127.109565a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c21.014261 1.024 40.514783 5.164522 57.878261 12.065391V233.338435c0-12.109913-10.551652-20.034783-20.569044-20.034783a24.620522 24.620522 0 0 0-5.787826 0.934957L439.785739 338.18713a19.545043 19.545043 0 0 0-14.825739 19.144348v438.984348H423.846957c11.53113 43.987478-5.164522 94.208-45.412174 134.322087a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c20.791652 1.024 40.069565 5.075478 57.299478 11.842783z"
|
Public Const IconMusic As String = "M348.293565 716.53287V254.797913c0-41.672348 28.004174-78.358261 68.919652-90.37913L815.994435 40.826435c62.775652-18.610087 125.907478 26.579478 125.907478 89.933913v539.158261c8.013913 42.25113-8.94887 89.177043-47.014956 127.109565a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c21.014261 1.024 40.514783 5.164522 57.878261 12.065391V233.338435c0-12.109913-10.551652-20.034783-20.569044-20.034783a24.620522 24.620522 0 0 0-5.787826 0.934957L439.785739 338.18713a19.545043 19.545043 0 0 0-14.825739 19.144348v438.984348H423.846957c11.53113 43.987478-5.164522 94.208-45.412174 134.322087a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c20.791652 1.024 40.069565 5.075478 57.299478 11.842783z"
|
||||||
@@ -961,17 +957,17 @@ Public Module ModBase
|
|||||||
''' <param name="FileFilter">要求的格式。如:“常用图片文件(*.png;*.jpg)|*.png;*.jpg”。</param>
|
''' <param name="FileFilter">要求的格式。如:“常用图片文件(*.png;*.jpg)|*.png;*.jpg”。</param>
|
||||||
''' <param name="Title">弹窗的标题。</param>
|
''' <param name="Title">弹窗的标题。</param>
|
||||||
''' <param name="FileName">默认的文件名。</param>
|
''' <param name="FileName">默认的文件名。</param>
|
||||||
Public Function SelectAs(Title As String, FileName As String, Optional FileFilter As String = Nothing, Optional DefaultDir As String = Nothing) As String
|
Public Function SelectSaveFile(Title As String, FileName As String, Optional FileFilter As String = Nothing, Optional InitialDirectory As String = Nothing) As String
|
||||||
Using fileDialog As New Forms.SaveFileDialog
|
Using fileDialog As New Forms.SaveFileDialog
|
||||||
fileDialog.AddExtension = True
|
fileDialog.AddExtension = True
|
||||||
fileDialog.AutoUpgradeEnabled = True
|
fileDialog.AutoUpgradeEnabled = True
|
||||||
fileDialog.Title = Title
|
fileDialog.Title = Title
|
||||||
fileDialog.FileName = FileName
|
fileDialog.FileName = FileName
|
||||||
If FileFilter IsNot Nothing Then fileDialog.Filter = FileFilter
|
If FileFilter IsNot Nothing Then fileDialog.Filter = FileFilter
|
||||||
If DefaultDir IsNot Nothing Then fileDialog.InitialDirectory = DefaultDir
|
If Not String.IsNullOrEmpty(InitialDirectory) AndAlso Directory.Exists(InitialDirectory) Then fileDialog.InitialDirectory = InitialDirectory
|
||||||
fileDialog.ShowDialog()
|
fileDialog.ShowDialog()
|
||||||
SelectAs = If(fileDialog.FileName.Contains(":\"), fileDialog.FileName, "")
|
SelectSaveFile = If(fileDialog.FileName.Contains(":\"), fileDialog.FileName, "")
|
||||||
Log("[UI] 选择文件返回:" & SelectAs)
|
Log("[UI] 选择文件返回:" & SelectSaveFile)
|
||||||
End Using
|
End Using
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -979,7 +975,7 @@ Public Module ModBase
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="FileFilter">要求的格式。如:“常用图片文件(*.png;*.jpg)|*.png;*.jpg”。</param>
|
''' <param name="FileFilter">要求的格式。如:“常用图片文件(*.png;*.jpg)|*.png;*.jpg”。</param>
|
||||||
''' <param name="Title">弹窗的标题。</param>
|
''' <param name="Title">弹窗的标题。</param>
|
||||||
Public Function SelectFile(FileFilter As String, Title As String) As String
|
Public Function SelectFile(FileFilter As String, Title As String, Optional InitialDirectory As String = Nothing) As String
|
||||||
Using fileDialog As New Forms.OpenFileDialog
|
Using fileDialog As New Forms.OpenFileDialog
|
||||||
fileDialog.AddExtension = True
|
fileDialog.AddExtension = True
|
||||||
fileDialog.AutoUpgradeEnabled = True
|
fileDialog.AutoUpgradeEnabled = True
|
||||||
@@ -988,6 +984,7 @@ Public Module ModBase
|
|||||||
fileDialog.Multiselect = False
|
fileDialog.Multiselect = False
|
||||||
fileDialog.Title = Title
|
fileDialog.Title = Title
|
||||||
fileDialog.ValidateNames = True
|
fileDialog.ValidateNames = True
|
||||||
|
If Not String.IsNullOrEmpty(InitialDirectory) AndAlso Directory.Exists(InitialDirectory) Then fileDialog.InitialDirectory = InitialDirectory
|
||||||
fileDialog.ShowDialog()
|
fileDialog.ShowDialog()
|
||||||
Log("[UI] 选择单个文件返回:" & fileDialog.FileName)
|
Log("[UI] 选择单个文件返回:" & fileDialog.FileName)
|
||||||
Return fileDialog.FileName
|
Return fileDialog.FileName
|
||||||
@@ -1084,6 +1081,37 @@ Re:
|
|||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
|
''' 获取文件 SHA512,若失败则返回空字符串。
|
||||||
|
''' </summary>
|
||||||
|
Public Function GetFileSHA512(FilePath As String) As String
|
||||||
|
Dim Retry As Boolean = False
|
||||||
|
Re:
|
||||||
|
Try
|
||||||
|
''检测该文件是否在下载中,若在下载则放弃检测
|
||||||
|
'If IgnoreOnDownloading AndAlso NetManage.Files.ContainsKey(FilePath) AndAlso NetManage.Files(FilePath).State <= NetState.Merge Then Return ""
|
||||||
|
'获取 SHA512
|
||||||
|
Dim file As New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
||||||
|
Dim sha512 As SHA512 = New SHA512CryptoServiceProvider()
|
||||||
|
Dim retval As Byte() = sha512.ComputeHash(file)
|
||||||
|
file.Close()
|
||||||
|
Dim Result As New StringBuilder()
|
||||||
|
For i As Integer = 0 To retval.Length - 1
|
||||||
|
Result.Append(retval(i).ToString("x2"))
|
||||||
|
Next
|
||||||
|
Return Result.ToString
|
||||||
|
Catch ex As Exception
|
||||||
|
If Retry OrElse TypeOf ex Is FileNotFoundException Then
|
||||||
|
Log(ex, "获取文件 SHA512 失败:" & FilePath)
|
||||||
|
Return ""
|
||||||
|
Else
|
||||||
|
Retry = True
|
||||||
|
Log(ex, "获取文件 SHA512 可重试失败:" & FilePath, LogLevel.Normal)
|
||||||
|
Thread.Sleep(RandomInteger(200, 500))
|
||||||
|
GoTo Re
|
||||||
|
End If
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
''' <summary>
|
||||||
''' 获取文件 SHA256,若失败则返回空字符串。
|
''' 获取文件 SHA256,若失败则返回空字符串。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function GetFileSHA256(FilePath As String) As String
|
Public Function GetFileSHA256(FilePath As String) As String
|
||||||
@@ -1094,8 +1122,8 @@ Re:
|
|||||||
'If IgnoreOnDownloading AndAlso NetManage.Files.ContainsKey(FilePath) AndAlso NetManage.Files(FilePath).State <= NetState.Merge Then Return ""
|
'If IgnoreOnDownloading AndAlso NetManage.Files.ContainsKey(FilePath) AndAlso NetManage.Files(FilePath).State <= NetState.Merge Then Return ""
|
||||||
'获取 SHA256
|
'获取 SHA256
|
||||||
Dim file As New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
Dim file As New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
||||||
Dim sha1 As SHA256 = New SHA256CryptoServiceProvider()
|
Dim sha256 As SHA256 = New SHA256CryptoServiceProvider()
|
||||||
Dim retval As Byte() = sha1.ComputeHash(file)
|
Dim retval As Byte() = sha256.ComputeHash(file)
|
||||||
file.Close()
|
file.Close()
|
||||||
Dim Result As New StringBuilder()
|
Dim Result As New StringBuilder()
|
||||||
For i As Integer = 0 To retval.Length - 1
|
For i As Integer = 0 To retval.Length - 1
|
||||||
@@ -1144,7 +1172,7 @@ Re:
|
|||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 获取流 SHA1,若失败则返回空字符串。
|
''' 获取流的 SHA1,若失败则返回空字符串。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function GetAuthSHA1(Stream As Stream) As String
|
Public Function GetAuthSHA1(Stream As Stream) As String
|
||||||
Try
|
Try
|
||||||
@@ -1336,11 +1364,22 @@ RetryDir:
|
|||||||
''' 遍历文件夹中的所有文件。
|
''' 遍历文件夹中的所有文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function EnumerateFiles(Directory As String) As IEnumerable(Of FileInfo)
|
Public Function EnumerateFiles(Directory As String) As IEnumerable(Of FileInfo)
|
||||||
Dim Info As New DirectoryInfo(Directory)
|
Dim Info As New DirectoryInfo(ShortenPath(Directory))
|
||||||
If Not Info.Exists Then Return New List(Of FileInfo)
|
If Not Info.Exists Then Return New List(Of FileInfo)
|
||||||
Return Info.EnumerateFiles("*", SearchOption.AllDirectories)
|
Return Info.EnumerateFiles("*", SearchOption.AllDirectories)
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 若路径长度大于指定值,则将长路径转换为短路径。
|
||||||
|
''' </summary>
|
||||||
|
Public Function ShortenPath(LongPath As String, Optional ShortenThreshold As Integer = 247) As String
|
||||||
|
If LongPath.Length <= ShortenThreshold Then Return LongPath
|
||||||
|
Dim ShortPath As New StringBuilder(260)
|
||||||
|
GetShortPathName(LongPath, ShortPath, 260)
|
||||||
|
Return ShortPath.ToString
|
||||||
|
End Function
|
||||||
|
Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As StringBuilder, ByVal cchBuffer As Integer) As Integer
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
#Region "文本"
|
#Region "文本"
|
||||||
@@ -1350,8 +1389,8 @@ RetryDir:
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 提取 Exception 的具体描述与堆栈。
|
''' 提取 Exception 的具体描述与堆栈。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="ShowAllTrace">是否必须显示所有堆栈。通常用于判定堆栈信息。</param>
|
''' <param name="ShowAllStacks">是否必须显示所有堆栈。通常用于判定堆栈信息。</param>
|
||||||
Public Function GetExceptionDetail(Ex As Exception, Optional ShowAllTrace As Boolean = False) As String
|
Public Function GetExceptionDetail(Ex As Exception, Optional ShowAllStacks As Boolean = False) As String
|
||||||
If Ex Is Nothing Then Return "无可用错误信息!"
|
If Ex Is Nothing Then Return "无可用错误信息!"
|
||||||
|
|
||||||
'获取最底层的异常
|
'获取最底层的异常
|
||||||
@@ -1362,19 +1401,20 @@ RetryDir:
|
|||||||
|
|
||||||
'获取各级错误的描述与堆栈信息
|
'获取各级错误的描述与堆栈信息
|
||||||
Dim DescList As New List(Of String)
|
Dim DescList As New List(Of String)
|
||||||
Dim StackList As New List(Of String)
|
Dim IsInner As Boolean = False
|
||||||
Do Until Ex Is Nothing
|
Do Until Ex Is Nothing
|
||||||
DescList.Add(Ex.Message.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, vbCrLf))
|
DescList.Add(If(IsInner, "→ ", "") & Ex.Message.Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, vbCrLf))
|
||||||
If Ex.StackTrace IsNot Nothing Then
|
If Ex.StackTrace IsNot Nothing Then
|
||||||
For Each St As String In Ex.StackTrace.Split(vbCrLf)
|
For Each Stack As String In Ex.StackTrace.Split(vbCrLf.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
|
||||||
If ShowAllTrace OrElse St.ToLower.Contains("pcl") Then StackList.Add(St.Replace(vbCr, String.Empty).Replace(vbLf, String.Empty))
|
If ShowAllStacks OrElse Stack.ContainsF("pcl", True) Then
|
||||||
|
DescList.Add(Stack.Replace(vbCr, String.Empty).Replace(vbLf, String.Empty))
|
||||||
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
|
If Ex.GetType.FullName <> "System.Exception" Then DescList.Add(" 错误类型:" & Ex.GetType.FullName)
|
||||||
Ex = Ex.InnerException
|
Ex = Ex.InnerException
|
||||||
|
IsInner = True
|
||||||
Loop
|
Loop
|
||||||
DescList = DescList.Distinct.ToList
|
|
||||||
Dim Desc As String = Join(DescList, vbCrLf & "→ ")
|
|
||||||
Dim Stack As String = If(StackList.Any, vbCrLf & Join(StackList, vbCrLf), "")
|
|
||||||
|
|
||||||
'常见错误(记得同时修改下面的)
|
'常见错误(记得同时修改下面的)
|
||||||
Dim CommonReason As String = Nothing
|
Dim CommonReason As String = Nothing
|
||||||
@@ -1387,20 +1427,15 @@ RetryDir:
|
|||||||
ElseIf TypeOf InnerEx Is Runtime.InteropServices.COMException Then
|
ElseIf TypeOf InnerEx Is Runtime.InteropServices.COMException Then
|
||||||
CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
|
CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
|
||||||
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
|
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
|
||||||
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
|
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) DescList.Any(Function(l) l.Contains(s))) Then
|
||||||
CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
|
CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'获取错误类型
|
|
||||||
Dim TypeDesc As String = If(InnerEx.GetType.FullName = "System.Exception", "", vbCrLf & "错误类型:" & InnerEx.GetType.FullName)
|
|
||||||
|
|
||||||
'构造输出信息
|
'构造输出信息
|
||||||
If CommonReason Is Nothing Then
|
If CommonReason Is Nothing Then
|
||||||
Return Desc & Stack & TypeDesc
|
Return DescList.Join(vbCrLf)
|
||||||
Else
|
Else
|
||||||
Dim Result As String = CommonReason & vbCrLf & DescList.First & vbCrLf & "————————————" & vbCrLf
|
Return CommonReason & vbCrLf & vbCrLf & "————————————" & vbCrLf & "详细错误信息:" & vbCrLf & DescList.Join(vbCrLf)
|
||||||
DescList(0) = "详细错误信息:"
|
|
||||||
Return Result & Join(DescList, vbCrLf & "→ ") & Stack & TypeDesc
|
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -1444,7 +1479,7 @@ RetryDir:
|
|||||||
Return CommonReason & "详细错误:" & DescList.First
|
Return CommonReason & "详细错误:" & DescList.First
|
||||||
Else
|
Else
|
||||||
DescList.Reverse() '让最深层错误在最左边
|
DescList.Reverse() '让最深层错误在最左边
|
||||||
Return Join(DescList, " → ")
|
Return Join(DescList, " ← ")
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
@@ -1722,6 +1757,21 @@ RetryDir:
|
|||||||
Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("'", "'").
|
Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("'", "'").
|
||||||
Replace("""", """).Replace(vbCrLf, "
")
|
Replace("""", """).Replace(vbCrLf, "
")
|
||||||
End Function
|
End Function
|
||||||
|
''' <summary>
|
||||||
|
''' 为字符串进行 Like 关键字转义。
|
||||||
|
''' </summary>
|
||||||
|
Public Function EscapeLikePattern(input As String) As String
|
||||||
|
Dim sb As New StringBuilder()
|
||||||
|
For Each c As Char In input
|
||||||
|
Select Case c
|
||||||
|
Case "["c, "]"c, "*"c, "?"c, "#"c
|
||||||
|
sb.Append("["c).Append(c).Append("]"c)
|
||||||
|
Case Else
|
||||||
|
sb.Append(c)
|
||||||
|
End Select
|
||||||
|
Next
|
||||||
|
Return sb.ToString()
|
||||||
|
End Function
|
||||||
|
|
||||||
'正则
|
'正则
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -2134,6 +2184,7 @@ NextElement:
|
|||||||
''' <param name="FileName">文件名。可以为“notepad”等缩写。</param>
|
''' <param name="FileName">文件名。可以为“notepad”等缩写。</param>
|
||||||
''' <param name="Arguments">运行参数。</param>
|
''' <param name="Arguments">运行参数。</param>
|
||||||
Public Sub ShellOnly(FileName As String, Optional Arguments As String = "")
|
Public Sub ShellOnly(FileName As String, Optional Arguments As String = "")
|
||||||
|
FileName = ShortenPath(FileName)
|
||||||
Using Program As New Process
|
Using Program As New Process
|
||||||
Program.StartInfo.Arguments = Arguments
|
Program.StartInfo.Arguments = Arguments
|
||||||
Program.StartInfo.FileName = FileName
|
Program.StartInfo.FileName = FileName
|
||||||
@@ -2179,7 +2230,7 @@ NextElement:
|
|||||||
.CreateNoWindow = True,
|
.CreateNoWindow = True,
|
||||||
.RedirectStandardError = True,
|
.RedirectStandardError = True,
|
||||||
.RedirectStandardOutput = True,
|
.RedirectStandardOutput = True,
|
||||||
.WorkingDirectory = If(WorkingDirectory, Path.TrimEnd("\"c))
|
.WorkingDirectory = ShortenPath(If(WorkingDirectory, Path.TrimEnd("\"c)))
|
||||||
}
|
}
|
||||||
If WorkingDirectory IsNot Nothing Then
|
If WorkingDirectory IsNot Nothing Then
|
||||||
If Info.EnvironmentVariables.ContainsKey("appdata") Then
|
If Info.EnvironmentVariables.ContainsKey("appdata") Then
|
||||||
@@ -2288,6 +2339,27 @@ NextElement:
|
|||||||
Return New List(Of T)(list)
|
Return New List(Of T)(list)
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 尝试从字典中获取某项,如果该项不存在,则返回默认值。
|
||||||
|
''' </summary>
|
||||||
|
<Extension> Public Function GetOrDefault(Of TKey, TValue)(Dict As Dictionary(Of TKey, TValue), Key As TKey, Optional DefaultValue As TValue = Nothing) As TValue
|
||||||
|
If Dict.ContainsKey(Key) Then
|
||||||
|
Return Dict(Key)
|
||||||
|
Else
|
||||||
|
Return DefaultValue
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
''' <summary>
|
||||||
|
''' 将某项添加到以列表作为值的字典中。
|
||||||
|
''' </summary>
|
||||||
|
<Extension> Public Sub AddToList(Of TKey, TValue)(Dict As Dictionary(Of TKey, List(Of TValue)), Key As TKey, Value As TValue)
|
||||||
|
If Dict.ContainsKey(Key) Then
|
||||||
|
Dict(Key).Add(Value)
|
||||||
|
Else
|
||||||
|
Dict.Add(Key, New List(Of TValue) From {Value})
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 获取程序启动参数。
|
''' 获取程序启动参数。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@@ -2337,11 +2409,18 @@ NextElement:
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 打开 explorer。注意参数中的路径要尽量加上双引号!
|
''' 打开 explorer。
|
||||||
|
''' 若不以 \ 结尾,则将视作文件路径,打开并选中此文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Sub OpenExplorer(Argument As String)
|
Public Sub OpenExplorer(Location As String)
|
||||||
Try
|
Try
|
||||||
ShellOnly("explorer.exe", Argument)
|
Location = ShortenPath(Location.Replace("/", "\").Trim(" "c, """"c))
|
||||||
|
Log("[System] 正在打开资源管理器:" & Location)
|
||||||
|
If Location.EndsWith("\") Then
|
||||||
|
ShellOnly(Location)
|
||||||
|
Else
|
||||||
|
ShellOnly("explorer", $"/select,""{Location}""")
|
||||||
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "打开资源管理器失败,请尝试关闭安全软件(如 360 安全卫士)", LogLevel.Msgbox)
|
Log(ex, "打开资源管理器失败,请尝试关闭安全软件(如 360 安全卫士)", LogLevel.Msgbox)
|
||||||
End Try
|
End Try
|
||||||
@@ -2792,7 +2871,7 @@ Retry:
|
|||||||
On Error Resume Next
|
On Error Resume Next
|
||||||
FeedbackInfo()
|
FeedbackInfo()
|
||||||
If ForceOpenLog OrElse (ShowMsgbox AndAlso MyMsgBox("若你在汇报一个 Bug,请点击 打开文件夹 按钮,并上传 Log(1~5).txt 中包含错误信息的文件。" & vbCrLf & "游戏崩溃一般与启动器无关,请不要因为游戏崩溃而提交反馈。", "反馈提交提醒", "打开文件夹", "不需要") = 1) Then
|
If ForceOpenLog OrElse (ShowMsgbox AndAlso MyMsgBox("若你在汇报一个 Bug,请点击 打开文件夹 按钮,并上传 Log(1~5).txt 中包含错误信息的文件。" & vbCrLf & "游戏崩溃一般与启动器无关,请不要因为游戏崩溃而提交反馈。", "反馈提交提醒", "打开文件夹", "不需要") = 1) Then
|
||||||
OpenExplorer("""" & Path & "PCL\""")
|
OpenExplorer(Path & "PCL\Log1.txt")
|
||||||
End If
|
End If
|
||||||
OpenWebsite("https://github.com/Hex-Dragon/PCL2/issues/")
|
OpenWebsite("https://github.com/Hex-Dragon/PCL2/issues/")
|
||||||
End Sub
|
End Sub
|
||||||
@@ -2869,3 +2948,87 @@ Retry:
|
|||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
End Module
|
End Module
|
||||||
|
|
||||||
|
#Region "WPF"
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 对数据绑定进行加法运算,使用参数决定加数。
|
||||||
|
''' </summary>
|
||||||
|
Public Class AdditionConverter
|
||||||
|
Implements IValueConverter
|
||||||
|
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
|
||||||
|
If value Is Nothing Then Return 0
|
||||||
|
Dim before As Double
|
||||||
|
If Not Double.TryParse(value.ToString(), before) Then Return 0
|
||||||
|
Dim scale As Double = 1
|
||||||
|
If parameter IsNot Nothing Then Double.TryParse(parameter.ToString(), scale)
|
||||||
|
Return before + scale
|
||||||
|
End Function
|
||||||
|
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
|
||||||
|
If value Is Nothing Then Return Binding.DoNothing
|
||||||
|
Dim before As Double
|
||||||
|
If Not Double.TryParse(value.ToString(), before) Then Return Binding.DoNothing
|
||||||
|
Dim scale As Double = 1
|
||||||
|
If parameter IsNot Nothing Then Double.TryParse(parameter.ToString(), scale)
|
||||||
|
If scale = 0 Then Return Binding.DoNothing
|
||||||
|
Return before - scale
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 对数据绑定进行乘法运算,使用参数决定乘数。
|
||||||
|
''' </summary>
|
||||||
|
Public Class MultiplicationConverter
|
||||||
|
Implements IValueConverter
|
||||||
|
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
|
||||||
|
If value Is Nothing Then Return 0
|
||||||
|
Dim before As Double
|
||||||
|
If Not Double.TryParse(value.ToString(), before) Then Return 0
|
||||||
|
Dim scale As Double = 1
|
||||||
|
If parameter IsNot Nothing Then Double.TryParse(parameter.ToString(), scale)
|
||||||
|
Return before * scale
|
||||||
|
End Function
|
||||||
|
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
|
||||||
|
If value Is Nothing Then Return Binding.DoNothing
|
||||||
|
Dim before As Double
|
||||||
|
If Not Double.TryParse(value.ToString(), before) Then Return Binding.DoNothing
|
||||||
|
Dim scale As Double = 1
|
||||||
|
If parameter IsNot Nothing Then Double.TryParse(parameter.ToString(), scale)
|
||||||
|
If scale = 0 Then Return Binding.DoNothing
|
||||||
|
Return before / scale
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 将取反的 Boolean 绑定到 Visibility。
|
||||||
|
''' </summary>
|
||||||
|
Public Class InverseBooleanToVisibilityConverter
|
||||||
|
Implements IValueConverter
|
||||||
|
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
|
||||||
|
If value Is Nothing Then Return Visibility.Visible
|
||||||
|
Dim boolValue As Boolean
|
||||||
|
Return If(Boolean.TryParse(value.ToString(), boolValue), If(boolValue, Visibility.Collapsed, Visibility.Visible), Visibility.Visible)
|
||||||
|
End Function
|
||||||
|
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
|
||||||
|
If value Is Nothing Then Return False
|
||||||
|
Return If(TypeOf value Is Visibility, value <> Visibility.Visible, False)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 将 Boolean 取反。
|
||||||
|
''' </summary>
|
||||||
|
Public Class InverseBooleanConverter
|
||||||
|
Implements IValueConverter
|
||||||
|
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
|
||||||
|
If value Is Nothing Then Return False
|
||||||
|
Dim boolValue As Boolean
|
||||||
|
Return If(Boolean.TryParse(value.ToString(), boolValue), Not boolValue, False)
|
||||||
|
End Function
|
||||||
|
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
|
||||||
|
If value Is Nothing Then Return False
|
||||||
|
Return If(Boolean.TryParse(value.ToString(), value), Not value, False)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|||||||
@@ -315,23 +315,26 @@
|
|||||||
Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
IsForceRestarting = IsForceRestart
|
IsForceRestarting = IsForceRestart
|
||||||
If ModeDebug Then Log("[Loader] 加载线程 " & Name & " (" & Thread.CurrentThread.ManagedThreadId & ") 已" & If(IsForceRestarting, "强制", "") & "启动")
|
If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已{If(IsForceRestarting, "强制", "")}启动")
|
||||||
LoadDelegate(Me)
|
LoadDelegate(Me)
|
||||||
If IsAborted Then
|
If IsAborted Then
|
||||||
Log("[Loader] 加载线程 " & Name & " (" & Thread.CurrentThread.ManagedThreadId & ") 已中断但线程正常运行至结束,输出被弃用(最新线程:" & If(LastRunningThread Is Nothing, -1, LastRunningThread.ManagedThreadId) & ")", LogLevel.Developer)
|
Log($"[Loader] 加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已中断但线程正常运行至结束,输出被弃用(最新线程:{If(LastRunningThread Is Nothing, -1, LastRunningThread.ManagedThreadId)})", LogLevel.Developer)
|
||||||
Else
|
Else
|
||||||
RaisePreviewFinish()
|
RaisePreviewFinish()
|
||||||
State = LoadState.Finished
|
State = LoadState.Finished
|
||||||
LastFinishedTime = GetTimeTick() '未中断,本次输出有效
|
LastFinishedTime = GetTimeTick() '未中断,本次输出有效
|
||||||
End If
|
End If
|
||||||
|
Catch ex As CancelledException
|
||||||
|
If ModeDebug Then Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已触发取消中断,已完成 {Math.Round(Progress * 100)}%")
|
||||||
|
If Not IsAborted Then State = LoadState.Aborted
|
||||||
Catch ex As ThreadInterruptedException
|
Catch ex As ThreadInterruptedException
|
||||||
If ModeDebug Then Log(ex, "加载线程 " & Name & " (" & Thread.CurrentThread.ManagedThreadId & ") 已触发线程中断")
|
If ModeDebug Then Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已触发线程中断,已完成 {Math.Round(Progress * 100)}%")
|
||||||
'如果线程是因为判断到 IsAborted 而提前中止,则代表已有新线程被重启,此时不应当改为 Aborted
|
'如果线程是因为判断到 IsAborted 而提前中止,则代表已有新线程被重启,此时不应当改为 Aborted
|
||||||
'如果线程是在没有 IsAborted 时手动引发了 ThreadInterruptedException,则代表没有重启线程,这通常代表用户手动取消,应当改为 Aborted
|
'如果线程是在没有 IsAborted 时手动引发了 ThreadInterruptedException,则代表没有重启线程,这通常代表用户手动取消,应当改为 Aborted
|
||||||
If Not IsAborted Then State = LoadState.Aborted
|
If Not IsAborted Then State = LoadState.Aborted
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If IsAborted Then Exit Sub
|
If IsAborted Then Exit Sub
|
||||||
Log(ex, "加载线程 " & Name & " (" & Thread.CurrentThread.ManagedThreadId & ") 发生运行时错误", LogLevel.Developer)
|
Log(ex, $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 出错,已完成 {Math.Round(Progress * 100)}%", LogLevel.Developer)
|
||||||
[Error] = ex
|
[Error] = ex
|
||||||
State = LoadState.Failed
|
State = LoadState.Failed
|
||||||
End Try
|
End Try
|
||||||
@@ -347,7 +350,7 @@
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub TriggerThreadAbort()
|
Private Sub TriggerThreadAbort()
|
||||||
If LastRunningThread Is Nothing Then Exit Sub
|
If LastRunningThread Is Nothing Then Exit Sub
|
||||||
If ModeDebug Then Log("[Loader] 加载线程 " & Name & " (" & LastRunningThread.ManagedThreadId & ") 已中断")
|
If ModeDebug Then Log($"[Loader] 加载线程 {Name} ({LastRunningThread.ManagedThreadId}) 已中断")
|
||||||
If LastRunningThread.IsAlive Then LastRunningThread.Interrupt()
|
If LastRunningThread.IsAlive Then LastRunningThread.Interrupt()
|
||||||
LastRunningThread = Nothing
|
LastRunningThread = Nothing
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -220,12 +220,12 @@ RequestFinished:
|
|||||||
''' 以多线程下载网页文件的方式获取网页源代码。
|
''' 以多线程下载网页文件的方式获取网页源代码。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="Url">网页的 Url。</param>
|
''' <param name="Url">网页的 Url。</param>
|
||||||
Public Function NetGetCodeByDownload(Url As String, Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional UseBrowserUserAgent As Boolean = False) As String
|
Public Function NetGetCodeByLoader(Url As String, Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional UseBrowserUserAgent As Boolean = False) As String
|
||||||
Dim Temp As String = PathTemp & "Cache\Code\" & Url.GetHashCode() & "_" & GetUuid()
|
Dim Temp As String = PathTemp & "Cache\Code\" & Url.GetHashCode() & "_" & GetUuid()
|
||||||
Dim NewTask As New LoaderDownload("源码获取 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile({Url}, Temp, New FileChecker With {.IsJson = IsJson}, UseBrowserUserAgent)})
|
Dim NewTask As New LoaderDownload("源码获取 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile({Url}, Temp, New FileChecker With {.IsJson = IsJson}, UseBrowserUserAgent)})
|
||||||
Try
|
Try
|
||||||
NewTask.WaitForExitTime(Timeout, TimeoutMessage:="连接服务器超时(" & Url & ")")
|
NewTask.WaitForExitTime(Timeout, TimeoutMessage:="连接服务器超时(" & Url & ")")
|
||||||
NetGetCodeByDownload = ReadFile(Temp)
|
NetGetCodeByLoader = ReadFile(Temp)
|
||||||
File.Delete(Temp)
|
File.Delete(Temp)
|
||||||
Finally
|
Finally
|
||||||
NewTask.Abort()
|
NewTask.Abort()
|
||||||
@@ -235,12 +235,12 @@ RequestFinished:
|
|||||||
''' 以多线程下载网页文件的方式获取网页源代码。
|
''' 以多线程下载网页文件的方式获取网页源代码。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="Urls">网页的 Url 列表。</param>
|
''' <param name="Urls">网页的 Url 列表。</param>
|
||||||
Public Function NetGetCodeByDownload(Urls As IEnumerable(Of String), Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional UseBrowserUserAgent As Boolean = False) As String
|
Public Function NetGetCodeByLoader(Urls As IEnumerable(Of String), Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional UseBrowserUserAgent As Boolean = False) As String
|
||||||
Dim Temp As String = PathTemp & "Cache\Code\" & Urls.First.GetHashCode() & "_" & GetUuid()
|
Dim Temp As String = PathTemp & "Cache\Code\" & Urls.First.GetHashCode() & "_" & GetUuid()
|
||||||
Dim NewTask As New LoaderDownload("源码获取 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile(Urls, Temp, New FileChecker With {.IsJson = IsJson}, UseBrowserUserAgent)})
|
Dim NewTask As New LoaderDownload("源码获取 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile(Urls, Temp, New FileChecker With {.IsJson = IsJson}, UseBrowserUserAgent)})
|
||||||
Try
|
Try
|
||||||
NewTask.WaitForExitTime(Timeout, TimeoutMessage:="连接服务器超时(第一下载源:" & Urls.First & ")")
|
NewTask.WaitForExitTime(Timeout, TimeoutMessage:="连接服务器超时(第一下载源:" & Urls.First & ")")
|
||||||
NetGetCodeByDownload = ReadFile(Temp)
|
NetGetCodeByLoader = ReadFile(Temp)
|
||||||
File.Delete(Temp)
|
File.Delete(Temp)
|
||||||
Finally
|
Finally
|
||||||
NewTask.Abort()
|
NewTask.Abort()
|
||||||
@@ -248,13 +248,12 @@ RequestFinished:
|
|||||||
End Function
|
End Function
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 从网络中直接下载文件。这不能下载 CDN 中的文件。
|
''' 使用 WebClient 从网络中下载文件。这不能下载 CDN 中的文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="Url">网络 Url。</param>
|
''' <param name="Url">网络 Url。</param>
|
||||||
''' <param name="LocalFile">下载的本地地址。</param>
|
''' <param name="LocalFile">下载的本地地址。</param>
|
||||||
Public Sub NetDownload(Url As String, LocalFile As String, Optional UseBrowserUserAgent As Boolean = False)
|
Public Sub NetDownloadByClient(Url As String, LocalFile As String, Optional UseBrowserUserAgent As Boolean = False)
|
||||||
Log("[Net] 直接下载文件:" & Url)
|
Log("[Net] 直接下载文件:" & Url)
|
||||||
|
|
||||||
'初始化
|
'初始化
|
||||||
Try
|
Try
|
||||||
'建立目录
|
'建立目录
|
||||||
@@ -262,9 +261,8 @@ RequestFinished:
|
|||||||
'尝试删除原文件
|
'尝试删除原文件
|
||||||
File.Delete(LocalFile)
|
File.Delete(LocalFile)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Throw New WebException("预处理下载文件路径失败(" & LocalFile & ")。", ex)
|
Throw New WebException($"预处理下载文件路径失败({LocalFile})", ex)
|
||||||
End Try
|
End Try
|
||||||
|
|
||||||
'下载
|
'下载
|
||||||
Using Client As New WebClient
|
Using Client As New WebClient
|
||||||
Try
|
Try
|
||||||
@@ -272,10 +270,41 @@ RequestFinished:
|
|||||||
Client.DownloadFile(Url, LocalFile)
|
Client.DownloadFile(Url, LocalFile)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
File.Delete(LocalFile)
|
File.Delete(LocalFile)
|
||||||
Throw New WebException("直接下载文件失败(" & Url & ")。", ex)
|
Throw New WebException($"直接下载文件失败({Url})", ex)
|
||||||
End Try
|
End Try
|
||||||
End Using
|
End Using
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 简单的多线程下载文件。可以下载 CDN 中的文件。
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="Url">文件的 Url。</param>
|
||||||
|
''' <param name="LocalFile">下载的本地地址。</param>
|
||||||
|
Public Sub NetDownloadByLoader(Url As String, LocalFile As String, Optional LoaderToSyncProgress As LoaderBase = Nothing, Optional Check As FileChecker = Nothing, Optional UseBrowserUserAgent As Boolean = False)
|
||||||
|
Dim NewTask As New LoaderDownload("文件下载 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile({Url}, LocalFile, Check, UseBrowserUserAgent)})
|
||||||
|
Try
|
||||||
|
NewTask.WaitForExit(LoaderToSyncProgress:=LoaderToSyncProgress)
|
||||||
|
Catch ex As Exception
|
||||||
|
Throw New WebException($"多线程直接下载文件失败({Url})", ex)
|
||||||
|
Finally
|
||||||
|
NewTask.Abort()
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 简单的多线程下载文件。可以下载 CDN 中的文件。
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="Urls">文件的 Url 列表。</param>
|
||||||
|
''' <param name="LocalFile">下载的本地地址。</param>
|
||||||
|
Public Sub NetDownloadByLoader(Urls As IEnumerable(Of String), LocalFile As String, Optional LoaderToSyncProgress As LoaderBase = Nothing, Optional Check As FileChecker = Nothing, Optional UseBrowserUserAgent As Boolean = False)
|
||||||
|
Dim NewTask As New LoaderDownload("文件下载 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile(Urls, LocalFile, Check, UseBrowserUserAgent)})
|
||||||
|
Try
|
||||||
|
NewTask.WaitForExit(LoaderToSyncProgress:=LoaderToSyncProgress)
|
||||||
|
Catch ex As Exception
|
||||||
|
Throw New WebException($"多线程直接下载文件失败(第一下载源:" & Urls.First() & ")", ex)
|
||||||
|
Finally
|
||||||
|
NewTask.Abort()
|
||||||
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -1885,7 +1914,7 @@ Retry:
|
|||||||
For Each File As NetFile In WaitingFiles
|
For Each File As NetFile In WaitingFiles
|
||||||
If NetTaskThreadCount >= NetTaskThreadLimit Then Continue While '最大线程数检查
|
If NetTaskThreadCount >= NetTaskThreadLimit Then Continue While '最大线程数检查
|
||||||
Dim NewThread = File.TryBeginThread()
|
Dim NewThread = File.TryBeginThread()
|
||||||
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(100) '减少 BMCLAPI 请求频率,避免 Too Many Requests
|
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(30) '减少 BMCLAPI 请求频率(目前每分钟限制 4000 次)
|
||||||
Next
|
Next
|
||||||
'为进行中的文件追加线程
|
'为进行中的文件追加线程
|
||||||
If Speed >= NetTaskSpeedLimitLow Then Continue While '下载速度足够,无需新增
|
If Speed >= NetTaskSpeedLimitLow Then Continue While '下载速度足够,无需新增
|
||||||
@@ -1905,7 +1934,7 @@ Retry:
|
|||||||
'新增线程
|
'新增线程
|
||||||
If PreparingCount > DownloadingCount Then Continue For '准备中的线程已多于下载中的线程,不再新增
|
If PreparingCount > DownloadingCount Then Continue For '准备中的线程已多于下载中的线程,不再新增
|
||||||
Dim NewThread = File.TryBeginThread()
|
Dim NewThread = File.TryBeginThread()
|
||||||
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(100) '减少 BMCLAPI 请求频率,避免 Too Many Requests
|
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(30) '减少 BMCLAPI 请求频率(目前每分钟限制 4000 次)
|
||||||
Next
|
Next
|
||||||
End While
|
End While
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
|||||||
@@ -262,7 +262,6 @@ Public Class ValidateFileName
|
|||||||
Public Property IgnoreCase As Boolean = True
|
Public Property IgnoreCase As Boolean = True
|
||||||
Public Property ParentFolder As String = Nothing
|
Public Property ParentFolder As String = Nothing
|
||||||
Public Property RequireParentFolderExists = True
|
Public Property RequireParentFolderExists = True
|
||||||
Public Property AllowNull As Boolean = False
|
|
||||||
Public Sub New()
|
Public Sub New()
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub New(Name As String, Optional UseMinecraftCharCheck As Boolean = True, Optional IgnoreCase As Boolean = True)
|
Public Sub New(Name As String, Optional UseMinecraftCharCheck As Boolean = True, Optional IgnoreCase As Boolean = True)
|
||||||
@@ -272,16 +271,14 @@ Public Class ValidateFileName
|
|||||||
End Sub
|
End Sub
|
||||||
Public Overrides Function Validate(Str As String) As String
|
Public Overrides Function Validate(Str As String) As String
|
||||||
Try
|
Try
|
||||||
If Not AllowNull Then
|
|
||||||
'检查是否为空
|
'检查是否为空
|
||||||
Dim NullCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
|
Dim LengthCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
|
||||||
If Not NullCheck = "" Then Return NullCheck
|
If Not LengthCheck = "" Then Return LengthCheck
|
||||||
End If
|
|
||||||
'检查空格
|
'检查空格
|
||||||
If Str.StartsWithF(" ") Then Return "文件名不能以空格开头!"
|
If Str.StartsWithF(" ") Then Return "文件名不能以空格开头!"
|
||||||
If Str.EndsWithF(" ") Then Return "文件名不能以空格结尾!"
|
If Str.EndsWithF(" ") Then Return "文件名不能以空格结尾!"
|
||||||
'检查长度
|
'检查长度
|
||||||
Dim LengthCheck = New ValidateLength(If(AllowNull, 0, 1), 253).Validate(Str & If(ParentFolder, ""))
|
LengthCheck = New ValidateLength(1, 253).Validate(Str & If(ParentFolder, ""))
|
||||||
If Not LengthCheck = "" Then Return LengthCheck
|
If Not LengthCheck = "" Then Return LengthCheck
|
||||||
'检查尾部小数点
|
'检查尾部小数点
|
||||||
If Str.EndsWithF(".") Then Return "文件名不能以小数点结尾!"
|
If Str.EndsWithF(".") Then Return "文件名不能以小数点结尾!"
|
||||||
@@ -318,7 +315,6 @@ End Class
|
|||||||
Public Class ValidateFolderPath
|
Public Class ValidateFolderPath
|
||||||
Inherits Validate
|
Inherits Validate
|
||||||
Public Property UseMinecraftCharCheck As Boolean = True
|
Public Property UseMinecraftCharCheck As Boolean = True
|
||||||
Public Property AllowNull As Boolean = False
|
|
||||||
Public Sub New()
|
Public Sub New()
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub New(UseMinecraftCharCheck As Boolean)
|
Public Sub New(UseMinecraftCharCheck As Boolean)
|
||||||
@@ -330,9 +326,9 @@ Public Class ValidateFolderPath
|
|||||||
If Not Str.TrimEnd("\").EndsWithF(":") Then Str = Str.TrimEnd("\")
|
If Not Str.TrimEnd("\").EndsWithF(":") Then Str = Str.TrimEnd("\")
|
||||||
'检查是否为空
|
'检查是否为空
|
||||||
Dim LengthCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
|
Dim LengthCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
|
||||||
If Not AllowNull AndAlso Not LengthCheck = "" Then Return LengthCheck
|
If Not LengthCheck = "" Then Return LengthCheck
|
||||||
'检查长度
|
'检查长度
|
||||||
LengthCheck = New ValidateLength(If(AllowNull, 0, 1), 254).Validate(Str)
|
LengthCheck = New ValidateLength(1, 254).Validate(Str)
|
||||||
If Not LengthCheck = "" Then Return LengthCheck
|
If Not LengthCheck = "" Then Return LengthCheck
|
||||||
'检查开头
|
'检查开头
|
||||||
If Str.StartsWithF("\\Mac\") Then GoTo Fin
|
If Str.StartsWithF("\\Mac\") Then GoTo Fin
|
||||||
|
|||||||
@@ -360,7 +360,7 @@
|
|||||||
'Tags & ModLoaders
|
'Tags & ModLoaders
|
||||||
Tags = New List(Of String)
|
Tags = New List(Of String)
|
||||||
ModLoaders = New List(Of CompModLoaderType)
|
ModLoaders = New List(Of CompModLoaderType)
|
||||||
If Data?("loaders") IsNot Nothing Then
|
If Data.ContainsKey("loaders") Then
|
||||||
For Each Category In Data("loaders").Select(Function(t) t.ToString)
|
For Each Category In Data("loaders").Select(Function(t) t.ToString)
|
||||||
Select Case Category
|
Select Case Category
|
||||||
Case "forge" : ModLoaders.Add(CompModLoaderType.Forge)
|
Case "forge" : ModLoaders.Add(CompModLoaderType.Forge)
|
||||||
@@ -402,7 +402,7 @@
|
|||||||
Case "technology" : Tags.Add("科技")
|
Case "technology" : Tags.Add("科技")
|
||||||
Case "magic" : Tags.Add("魔法")
|
Case "magic" : Tags.Add("魔法")
|
||||||
Case "adventure" : Tags.Add("冒险")
|
Case "adventure" : Tags.Add("冒险")
|
||||||
Case "kitchen-sink" : Tags.Add("大杂烩")
|
Case "kitchen-sink" : Tags.Add("水槽包/大杂烩")
|
||||||
Case "lightweight" : Tags.Add("轻量")
|
Case "lightweight" : Tags.Add("轻量")
|
||||||
'FUTURE: Res
|
'FUTURE: Res
|
||||||
End Select
|
End Select
|
||||||
@@ -1274,10 +1274,7 @@ Retry:
|
|||||||
Dim Url = Data("downloadUrl").ToString
|
Dim Url = Data("downloadUrl").ToString
|
||||||
If Url = "" Then Url = $"https://media.forgecdn.net/files/{CInt(Id.ToString.Substring(0, 4))}/{CInt(Id.ToString.Substring(4))}/{FileName}"
|
If Url = "" Then Url = $"https://media.forgecdn.net/files/{CInt(Id.ToString.Substring(0, 4))}/{CInt(Id.ToString.Substring(4))}/{FileName}"
|
||||||
Url = Url.Replace(FileName, Net.WebUtility.UrlEncode(FileName)) '对文件名进行编码
|
Url = Url.Replace(FileName, Net.WebUtility.UrlEncode(FileName)) '对文件名进行编码
|
||||||
DownloadUrls = (New List(Of String) From {Url.Replace("-service.overwolf.wtf", ".forgecdn.net").Replace("://edge", "://media"),
|
DownloadUrls = HandleCurseForgeDownloadUrls(Url) '对脑残 CurseForge 的下载地址进行多种修正
|
||||||
Url.Replace("-service.overwolf.wtf", ".forgecdn.net"),
|
|
||||||
Url.Replace("://edge", "://media"),
|
|
||||||
Url}).Distinct.ToList '对脑残 CurseForge 的下载地址进行多种修正
|
|
||||||
DownloadUrls.AddRange(DownloadUrls.Select(Function(u) DlSourceModGet(u)).ToList) '添加镜像源,这个写法是为了让镜像源排在后面
|
DownloadUrls.AddRange(DownloadUrls.Select(Function(u) DlSourceModGet(u)).ToList) '添加镜像源,这个写法是为了让镜像源排在后面
|
||||||
DownloadUrls = DownloadUrls.Distinct.ToList '最终去重
|
DownloadUrls = DownloadUrls.Distinct.ToList '最终去重
|
||||||
'Dependencies
|
'Dependencies
|
||||||
@@ -1352,6 +1349,19 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 重新整理 CurseForge 的下载地址。
|
||||||
|
''' </summary>
|
||||||
|
Public Shared Function HandleCurseForgeDownloadUrls(Url As String) As List(Of String)
|
||||||
|
Return {
|
||||||
|
Url.Replace("-service.overwolf.wtf", ".forgecdn.net").Replace("://edge", "://media"),
|
||||||
|
Url.Replace("-service.overwolf.wtf", ".forgecdn.net"),
|
||||||
|
Url.Replace("://edge", "://media"),
|
||||||
|
Url
|
||||||
|
}.Distinct.ToList
|
||||||
|
End Function
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 将当前实例转为可用于保存缓存的 Json。
|
''' 将当前实例转为可用于保存缓存的 Json。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
|
|||||||
@@ -1,24 +1,10 @@
|
|||||||
Public Class CrashAnalyzer
|
Public Class CrashAnalyzer
|
||||||
Private Shared IsAnalyzeCacheCleared As Boolean = False
|
|
||||||
Private Shared IsAnalyzeCacheClearedLock As New Object
|
|
||||||
|
|
||||||
'构造函数
|
'构造函数
|
||||||
Private TempFolder As String
|
Private TempFolder As String
|
||||||
Public Sub New(UUID As Integer)
|
Public Sub New(UUID As Integer)
|
||||||
'清理缓存
|
|
||||||
SyncLock IsAnalyzeCacheClearedLock
|
|
||||||
If Not IsAnalyzeCacheCleared Then
|
|
||||||
Try
|
|
||||||
DeleteDirectory(PathTemp & "CrashAnalyzer\")
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "清理崩溃分析缓存失败")
|
|
||||||
End Try
|
|
||||||
IsAnalyzeCacheCleared = True
|
|
||||||
End If
|
|
||||||
End SyncLock
|
|
||||||
'构建文件结构
|
'构建文件结构
|
||||||
TempFolder = PathTemp & "CrashAnalyzer\" & UUID & RandomInteger(0, 99999999) & "\"
|
TempFolder = RequestTaskTempFolder()
|
||||||
DeleteDirectory(TempFolder)
|
|
||||||
Directory.CreateDirectory(TempFolder & "Temp\")
|
Directory.CreateDirectory(TempFolder & "Temp\")
|
||||||
Directory.CreateDirectory(TempFolder & "Report\")
|
Directory.CreateDirectory(TempFolder & "Report\")
|
||||||
Log("[Crash] 崩溃分析暂存文件夹:" & TempFolder)
|
Log("[Crash] 崩溃分析暂存文件夹:" & TempFolder)
|
||||||
@@ -873,7 +859,7 @@ NextStack:
|
|||||||
Sub()
|
Sub()
|
||||||
'弹窗选择:查看日志
|
'弹窗选择:查看日志
|
||||||
If File.Exists(DirectFile.Value.Key) Then
|
If File.Exists(DirectFile.Value.Key) Then
|
||||||
ShellOnly("notepad", DirectFile.Value.Key)
|
ShellOnly(DirectFile.Value.Key)
|
||||||
Else
|
Else
|
||||||
Dim FilePath As String = PathTemp & "Crash.txt"
|
Dim FilePath As String = PathTemp & "Crash.txt"
|
||||||
WriteFile(FilePath, Join(DirectFile.Value.Value, vbCrLf))
|
WriteFile(FilePath, Join(DirectFile.Value.Value, vbCrLf))
|
||||||
@@ -885,7 +871,7 @@ NextStack:
|
|||||||
Dim FileAddress As String = Nothing
|
Dim FileAddress As String = Nothing
|
||||||
Try
|
Try
|
||||||
'获取文件路径
|
'获取文件路径
|
||||||
RunInUiWait(Sub() FileAddress = SelectAs("选择保存位置", "错误报告-" & Date.Now.ToString("G").Replace("/", "-").Replace(":", ".").Replace(" ", "_") & ".zip", "Minecraft 错误报告(*.zip)|*.zip"))
|
RunInUiWait(Sub() FileAddress = SelectSaveFile("选择保存位置", "错误报告-" & Date.Now.ToString("G").Replace("/", "-").Replace(":", ".").Replace(" ", "_") & ".zip", "Minecraft 错误报告(*.zip)|*.zip"))
|
||||||
If String.IsNullOrEmpty(FileAddress) Then Exit Sub
|
If String.IsNullOrEmpty(FileAddress) Then Exit Sub
|
||||||
Directory.CreateDirectory(GetPathFromFullPath(FileAddress))
|
Directory.CreateDirectory(GetPathFromFullPath(FileAddress))
|
||||||
If File.Exists(FileAddress) Then File.Delete(FileAddress)
|
If File.Exists(FileAddress) Then File.Delete(FileAddress)
|
||||||
@@ -923,7 +909,7 @@ NextStack:
|
|||||||
Log(ex, "导出错误报告失败", LogLevel.Feedback)
|
Log(ex, "导出错误报告失败", LogLevel.Feedback)
|
||||||
Exit Sub
|
Exit Sub
|
||||||
End Try
|
End Try
|
||||||
OpenExplorer("/select,""" & FileAddress & """")
|
OpenExplorer(FileAddress)
|
||||||
End Select
|
End Select
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
|
|||||||
@@ -622,7 +622,7 @@
|
|||||||
Public Sub DlForgeVersionOfficialMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
|
Public Sub DlForgeVersionOfficialMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
|
||||||
Dim Result As String
|
Dim Result As String
|
||||||
Try
|
Try
|
||||||
Result = NetGetCodeByDownload("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" &
|
Result = NetGetCodeByLoader("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" &
|
||||||
Loader.Input.Replace("-", "_") & '兼容 Forge 1.7.10-pre4,#4057
|
Loader.Input.Replace("-", "_") & '兼容 Forge 1.7.10-pre4,#4057
|
||||||
".html", UseBrowserUserAgent:=True)
|
".html", UseBrowserUserAgent:=True)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -829,8 +829,8 @@
|
|||||||
Public DlNeoForgeListOfficialLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Official", AddressOf DlNeoForgeListOfficialMain)
|
Public DlNeoForgeListOfficialLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Official", AddressOf DlNeoForgeListOfficialMain)
|
||||||
Private Sub DlNeoForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
Private Sub DlNeoForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
||||||
'获取版本列表 JSON
|
'获取版本列表 JSON
|
||||||
Dim ResultLatest As String = NetGetCodeByDownload("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge", UseBrowserUserAgent:=True, IsJson:=True)
|
Dim ResultLatest As String = NetGetCodeByLoader("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge", UseBrowserUserAgent:=True, IsJson:=True)
|
||||||
Dim ResultLegacy As String = NetGetCodeByDownload("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/forge", UseBrowserUserAgent:=True, IsJson:=True)
|
Dim ResultLegacy As String = NetGetCodeByLoader("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/forge", UseBrowserUserAgent:=True, IsJson:=True)
|
||||||
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
||||||
'解析
|
'解析
|
||||||
Try
|
Try
|
||||||
@@ -847,8 +847,8 @@
|
|||||||
Public DlNeoForgeListBmclapiLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Bmclapi", AddressOf DlNeoForgeListBmclapiMain)
|
Public DlNeoForgeListBmclapiLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Bmclapi", AddressOf DlNeoForgeListBmclapiMain)
|
||||||
Public Sub DlNeoForgeListBmclapiMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
Public Sub DlNeoForgeListBmclapiMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
||||||
'获取版本列表 JSON
|
'获取版本列表 JSON
|
||||||
Dim ResultLatest As String = NetGetCodeByDownload("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/neoforge", UseBrowserUserAgent:=True, IsJson:=True)
|
Dim ResultLatest As String = NetGetCodeByLoader("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/neoforge", UseBrowserUserAgent:=True, IsJson:=True)
|
||||||
Dim ResultLegacy As String = NetGetCodeByDownload("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/forge", UseBrowserUserAgent:=True, IsJson:=True)
|
Dim ResultLegacy As String = NetGetCodeByLoader("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/forge", UseBrowserUserAgent:=True, IsJson:=True)
|
||||||
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
||||||
'解析
|
'解析
|
||||||
Try
|
Try
|
||||||
@@ -1095,12 +1095,12 @@
|
|||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 对可能涉及 Mod 镜像源的请求进行处理,返回字符串或 JObject。
|
''' 对可能涉及 Mod 镜像源的请求进行处理,返回字符串或 JObject。
|
||||||
''' 调用 NetGetCodeByRequest。
|
''' 调用 NetGetCodeByRequest,会进行重试。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function DlModRequest(Url As String, Optional IsJson As Boolean = False) As Object
|
Public Function DlModRequest(Url As String, Optional IsJson As Boolean = False) As Object
|
||||||
Dim Urls As New List(Of KeyValuePair(Of String, Integer))
|
Dim Urls As New List(Of KeyValuePair(Of String, Integer))
|
||||||
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 5))
|
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 5))
|
||||||
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 15))
|
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 20))
|
||||||
'Dim McimUrl As String = DlSourceModGet(Url)
|
'Dim McimUrl As String = DlSourceModGet(Url)
|
||||||
'If McimUrl <> Url Then
|
'If McimUrl <> Url Then
|
||||||
' Select Case Setup.Get("ToolDownloadMod")
|
' Select Case Setup.Get("ToolDownloadMod")
|
||||||
@@ -1132,12 +1132,12 @@
|
|||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 对可能涉及 Mod 镜像源的请求进行处理。
|
''' 对可能涉及 Mod 镜像源的请求进行处理。
|
||||||
''' 调用 NetRequest。
|
''' 调用 NetRequest,会进行重试。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function DlModRequest(Url As String, Method As String, Data As String, ContentType As String) As String
|
Public Function DlModRequest(Url As String, Method As String, Data As String, ContentType As String) As String
|
||||||
Dim Urls As New List(Of KeyValuePair(Of String, Integer))
|
Dim Urls As New List(Of KeyValuePair(Of String, Integer))
|
||||||
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 5))
|
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 5))
|
||||||
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 15))
|
Urls.Add(New KeyValuePair(Of String, Integer)(Url, 20))
|
||||||
'Dim McimUrl As String = DlSourceModGet(Url)
|
'Dim McimUrl As String = DlSourceModGet(Url)
|
||||||
'If McimUrl <> Url Then
|
'If McimUrl <> Url Then
|
||||||
' Select Case Setup.Get("ToolDownloadMod")
|
' Select Case Setup.Get("ToolDownloadMod")
|
||||||
|
|||||||
@@ -653,7 +653,7 @@ Wait:
|
|||||||
Private Sub JavaSearchFolder(OriginalPath As String, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
|
Private Sub JavaSearchFolder(OriginalPath As String, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
|
||||||
Try
|
Try
|
||||||
Log("[Java] 开始" & If(IsFullSearch, "完全", "部分") & "遍历查找:" & OriginalPath)
|
Log("[Java] 开始" & If(IsFullSearch, "完全", "部分") & "遍历查找:" & OriginalPath)
|
||||||
JavaSearchFolder(New DirectoryInfo(OriginalPath), Results, Source, IsFullSearch)
|
JavaSearchFolder(New DirectoryInfo(ShortenPath(OriginalPath)), Results, Source, IsFullSearch)
|
||||||
Catch ex As UnauthorizedAccessException
|
Catch ex As UnauthorizedAccessException
|
||||||
Log("[Java] 遍历查找 Java 时遭遇无权限的文件夹:" & OriginalPath)
|
Log("[Java] 遍历查找 Java 时遭遇无权限的文件夹:" & OriginalPath)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -741,7 +741,7 @@ Wait:
|
|||||||
Private LastJavaBaseDir As String = Nothing '用于在下载中断或失败时删除未完成下载的 Java 文件夹,防止残留只下了一半但 -version 能跑的 Java
|
Private LastJavaBaseDir As String = Nothing '用于在下载中断或失败时删除未完成下载的 Java 文件夹,防止残留只下了一半但 -version 能跑的 Java
|
||||||
Private Sub JavaFileList(Loader As LoaderTask(Of Integer, List(Of NetFile)))
|
Private Sub JavaFileList(Loader As LoaderTask(Of Integer, List(Of NetFile)))
|
||||||
Log("[Java] 开始获取 Java 下载信息")
|
Log("[Java] 开始获取 Java 下载信息")
|
||||||
Dim IndexFileStr As String = NetGetCodeByDownload(
|
Dim IndexFileStr As String = NetGetCodeByLoader(
|
||||||
{"https://bmclapi2.bangbang93.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
{"https://bmclapi2.bangbang93.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
||||||
"https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"},
|
"https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"},
|
||||||
IsJson:=True)
|
IsJson:=True)
|
||||||
@@ -753,7 +753,7 @@ Wait:
|
|||||||
Dim Address As String = TargetEntry.Value("manifest")("url")
|
Dim Address As String = TargetEntry.Value("manifest")("url")
|
||||||
Log($"[Java] 准备下载 Java {TargetEntry.Value("version")("name")}({TargetEntry.Key}):{Address}")
|
Log($"[Java] 准备下载 Java {TargetEntry.Value("version")("name")}({TargetEntry.Key}):{Address}")
|
||||||
'获取文件列表
|
'获取文件列表
|
||||||
Dim ListFileStr As String = NetGetCodeByDownload({Address.Replace("piston-meta.mojang.com", "bmclapi2.bangbang93.com"), Address}, IsJson:=True)
|
Dim ListFileStr As String = NetGetCodeByLoader({Address.Replace("piston-meta.mojang.com", "bmclapi2.bangbang93.com"), Address}, IsJson:=True)
|
||||||
LastJavaBaseDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\runtime\" & TargetEntry.Key & "\"
|
LastJavaBaseDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\runtime\" & TargetEntry.Key & "\"
|
||||||
Dim Results As New List(Of NetFile)
|
Dim Results As New List(Of NetFile)
|
||||||
For Each File As JProperty In CType(GetJson(ListFileStr), JObject)("files")
|
For Each File As JProperty In CType(GetJson(ListFileStr), JObject)("files")
|
||||||
|
|||||||
@@ -574,7 +574,7 @@ SkipLogin:
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub McLoginServerStart(Data As LoaderTask(Of McLoginServer, McLoginResult))
|
Private Sub McLoginServerStart(Data As LoaderTask(Of McLoginServer, McLoginResult))
|
||||||
Dim Input As McLoginServer = Data.Input
|
Dim Input As McLoginServer = Data.Input
|
||||||
Dim NeedRefresh As Boolean = False
|
Dim NeedRefresh As Boolean = False, WasRefreshed As Boolean = False
|
||||||
Dim LogUsername As String = Input.UserName
|
Dim LogUsername As String = Input.UserName
|
||||||
If LogUsername.Contains("@") AndAlso Setup.Get("UiLauncherEmail") Then
|
If LogUsername.Contains("@") AndAlso Setup.Get("UiLauncherEmail") Then
|
||||||
LogUsername = AccountFilter(LogUsername)
|
LogUsername = AccountFilter(LogUsername)
|
||||||
@@ -595,7 +595,7 @@ SkipLogin:
|
|||||||
McLoginRequestValidate(Data)
|
McLoginRequestValidate(Data)
|
||||||
GoTo LoginFinish
|
GoTo LoginFinish
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Dim AllMessage = GetExceptionSummary(ex)
|
Dim AllMessage = GetExceptionDetail(ex)
|
||||||
McLaunchLog("验证登录失败:" & AllMessage)
|
McLaunchLog("验证登录失败:" & AllMessage)
|
||||||
If (AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout")) AndAlso Not AllMessage.Contains("403") Then
|
If (AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout")) AndAlso Not AllMessage.Contains("403") Then
|
||||||
McLaunchLog("已触发超时登录失败")
|
McLaunchLog("已触发超时登录失败")
|
||||||
@@ -610,7 +610,8 @@ Refresh:
|
|||||||
McLoginRequestRefresh(Data, NeedRefresh)
|
McLoginRequestRefresh(Data, NeedRefresh)
|
||||||
GoTo LoginFinish
|
GoTo LoginFinish
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
McLaunchLog("刷新登录失败:" & GetExceptionSummary(ex))
|
McLaunchLog("刷新登录失败:" & GetExceptionDetail(ex))
|
||||||
|
If WasRefreshed Then Throw New Exception("二轮刷新登录失败", ex)
|
||||||
End Try
|
End Try
|
||||||
Data.Progress = If(NeedRefresh, 0.85, 0.45)
|
Data.Progress = If(NeedRefresh, 0.85, 0.45)
|
||||||
End If
|
End If
|
||||||
@@ -619,10 +620,12 @@ Refresh:
|
|||||||
If Data.IsAborted Then Throw New ThreadInterruptedException
|
If Data.IsAborted Then Throw New ThreadInterruptedException
|
||||||
NeedRefresh = McLoginRequestLogin(Data)
|
NeedRefresh = McLoginRequestLogin(Data)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
McLaunchLog("登录失败:" & GetExceptionSummary(ex))
|
McLaunchLog("登录失败:" & GetExceptionDetail(ex))
|
||||||
Throw
|
Throw
|
||||||
End Try
|
End Try
|
||||||
If NeedRefresh Then
|
If NeedRefresh Then
|
||||||
|
McLaunchLog("重新进行刷新登录")
|
||||||
|
WasRefreshed = True
|
||||||
Data.Progress = 0.65
|
Data.Progress = 0.65
|
||||||
GoTo Refresh
|
GoTo Refresh
|
||||||
End If
|
End If
|
||||||
@@ -699,19 +702,17 @@ LoginFinish:
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub McLoginRequestRefresh(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult), RequestUser As Boolean)
|
Private Sub McLoginRequestRefresh(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult), RequestUser As Boolean)
|
||||||
McLaunchLog("刷新登录开始(Refresh, " & Data.Input.Token & ")")
|
McLaunchLog("刷新登录开始(Refresh, " & Data.Input.Token & ")")
|
||||||
|
|
||||||
Dim RefreshInfo As JObject = New JObject
|
|
||||||
Dim SelectProfile As JObject = New JObject()
|
|
||||||
SelectProfile.Add(New JProperty("name", Setup.Get("Cache" & Data.Input.Token & "Name")))
|
|
||||||
SelectProfile.Add(New JProperty("id", Setup.Get("Cache" & Data.Input.Token & "Uuid")))
|
|
||||||
RefreshInfo.Add("selectedProfile", SelectProfile)
|
|
||||||
RefreshInfo.Add(New JProperty("accessToken", Setup.Get("Cache" & Data.Input.Token & "Access")))
|
|
||||||
RefreshInfo.Add(New JProperty("requestUser", True))
|
|
||||||
|
|
||||||
Dim LoginJson As JObject = GetJson(NetRequestRetry(
|
Dim LoginJson As JObject = GetJson(NetRequestRetry(
|
||||||
Url:=Data.Input.BaseUrl & "/refresh",
|
Url:=Data.Input.BaseUrl & "/refresh",
|
||||||
Method:="POST",
|
Method:="POST",
|
||||||
Data:=RefreshInfo.ToString(0),
|
Data:=New JObject(
|
||||||
|
New JProperty("selectedProfile", New JObject(
|
||||||
|
New JProperty("name", Setup.Get($"Cache{Data.Input.Token}Name")),
|
||||||
|
New JProperty("id", Setup.Get($"Cache{Data.Input.Token}Uuid"))
|
||||||
|
)),
|
||||||
|
New JProperty("accessToken", Setup.Get($"Cache{Data.Input.Token}Access")),
|
||||||
|
New JProperty("requestUser", True)
|
||||||
|
).ToString(Newtonsoft.Json.Formatting.None),
|
||||||
Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh-CN"}},
|
Headers:=New Dictionary(Of String, String) From {{"Accept-Language", "zh-CN"}},
|
||||||
ContentType:="application/json; charset=utf-8"))
|
ContentType:="application/json; charset=utf-8"))
|
||||||
'将登录结果输出
|
'将登录结果输出
|
||||||
@@ -768,7 +769,8 @@ LoginFinish:
|
|||||||
'缓存无效,要求玩家选择
|
'缓存无效,要求玩家选择
|
||||||
If SelectedName Is Nothing Then
|
If SelectedName Is Nothing Then
|
||||||
McLaunchLog("要求玩家选择角色")
|
McLaunchLog("要求玩家选择角色")
|
||||||
RunInUiWait(Sub()
|
RunInUiWait(
|
||||||
|
Sub()
|
||||||
Dim SelectionControl As New List(Of IMyRadio)
|
Dim SelectionControl As New List(Of IMyRadio)
|
||||||
Dim SelectionJson As New List(Of JToken)
|
Dim SelectionJson As New List(Of JToken)
|
||||||
For Each Profile In LoginJson("availableProfiles")
|
For Each Profile In LoginJson("availableProfiles")
|
||||||
@@ -1072,7 +1074,8 @@ Retry:
|
|||||||
Case 3
|
Case 3
|
||||||
'使用正版用户名
|
'使用正版用户名
|
||||||
Try
|
Try
|
||||||
If SkinName <> "" AndAlso McVersionCurrent.Version.McCodeMain < 20 Then '1.20+ 或快照版不能使用该项(#3746)
|
If SkinName <> "" AndAlso
|
||||||
|
McVersionCurrent IsNot Nothing AndAlso McVersionCurrent.Version.McCodeMain < 20 Then '1.20+ 或快照版不能使用该项(#3746)
|
||||||
Log("[Skin] 由于离线皮肤设置,使用正版 UUID:" & SkinName)
|
Log("[Skin] 由于离线皮肤设置,使用正版 UUID:" & SkinName)
|
||||||
Uuid = McLoginMojangUuid(SkinName, False)
|
Uuid = McLoginMojangUuid(SkinName, False)
|
||||||
End If
|
End If
|
||||||
@@ -1629,16 +1632,16 @@ NextVersion:
|
|||||||
|
|
||||||
'基础参数
|
'基础参数
|
||||||
GameArguments.Add("${classpath_separator}", ";")
|
GameArguments.Add("${classpath_separator}", ";")
|
||||||
GameArguments.Add("${natives_directory}", GetNativesFolder())
|
GameArguments.Add("${natives_directory}", ShortenPath(GetNativesFolder()))
|
||||||
GameArguments.Add("${library_directory}", PathMcFolder & "libraries")
|
GameArguments.Add("${library_directory}", ShortenPath(PathMcFolder & "libraries"))
|
||||||
GameArguments.Add("${libraries_directory}", PathMcFolder & "libraries")
|
GameArguments.Add("${libraries_directory}", ShortenPath(PathMcFolder & "libraries"))
|
||||||
GameArguments.Add("${launcher_name}", "PCL")
|
GameArguments.Add("${launcher_name}", "PCL")
|
||||||
GameArguments.Add("${launcher_version}", VersionCode)
|
GameArguments.Add("${launcher_version}", VersionCode)
|
||||||
GameArguments.Add("${version_name}", Version.Name)
|
GameArguments.Add("${version_name}", Version.Name)
|
||||||
Dim ArgumentInfo As String = Setup.Get("VersionArgumentInfo", Version:=McVersionCurrent)
|
Dim ArgumentInfo As String = Setup.Get("VersionArgumentInfo", Version:=McVersionCurrent)
|
||||||
GameArguments.Add("${version_type}", If(ArgumentInfo = "", Setup.Get("LaunchArgumentInfo"), ArgumentInfo))
|
GameArguments.Add("${version_type}", If(ArgumentInfo = "", Setup.Get("LaunchArgumentInfo"), ArgumentInfo))
|
||||||
GameArguments.Add("${game_directory}", Left(McVersionCurrent.PathIndie, McVersionCurrent.PathIndie.Count - 1))
|
GameArguments.Add("${game_directory}", ShortenPath(Left(McVersionCurrent.PathIndie, McVersionCurrent.PathIndie.Count - 1)))
|
||||||
GameArguments.Add("${assets_root}", PathMcFolder & "assets")
|
GameArguments.Add("${assets_root}", ShortenPath(PathMcFolder & "assets"))
|
||||||
GameArguments.Add("${user_properties}", "{}")
|
GameArguments.Add("${user_properties}", "{}")
|
||||||
GameArguments.Add("${auth_player_name}", McLoginLoader.Output.Name)
|
GameArguments.Add("${auth_player_name}", McLoginLoader.Output.Name)
|
||||||
GameArguments.Add("${auth_uuid}", McLoginLoader.Output.Uuid)
|
GameArguments.Add("${auth_uuid}", McLoginLoader.Output.Uuid)
|
||||||
@@ -1672,7 +1675,7 @@ NextVersion:
|
|||||||
GameArguments.Add("${resolution_height}", Math.Round(GameSize.Height))
|
GameArguments.Add("${resolution_height}", Math.Round(GameSize.Height))
|
||||||
|
|
||||||
'Assets 相关参数
|
'Assets 相关参数
|
||||||
GameArguments.Add("${game_assets}", PathMcFolder & "assets\virtual\legacy") '1.5.2 的 pre-1.6 资源索引应与 legacy 合并
|
GameArguments.Add("${game_assets}", ShortenPath(PathMcFolder & "assets\virtual\legacy")) '1.5.2 的 pre-1.6 资源索引应与 legacy 合并
|
||||||
GameArguments.Add("${assets_index_name}", McAssetsGetIndexName(Version))
|
GameArguments.Add("${assets_index_name}", McAssetsGetIndexName(Version))
|
||||||
|
|
||||||
'支持库参数
|
'支持库参数
|
||||||
@@ -1689,7 +1692,7 @@ NextVersion:
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
If OptiFineCp IsNot Nothing Then CpStrings.Insert(CpStrings.Count - 2, OptiFineCp)
|
If OptiFineCp IsNot Nothing Then CpStrings.Insert(CpStrings.Count - 2, OptiFineCp)
|
||||||
GameArguments.Add("${classpath}", Join(CpStrings, ";"))
|
GameArguments.Add("${classpath}", Join(CpStrings.Select(Function(c) ShortenPath(c)), ";"))
|
||||||
|
|
||||||
Return GameArguments
|
Return GameArguments
|
||||||
End Function
|
End Function
|
||||||
@@ -2050,8 +2053,8 @@ IgnoreCustomSkin:
|
|||||||
"@echo off" & vbCrLf &
|
"@echo off" & vbCrLf &
|
||||||
"title 启动 - " & McVersionCurrent.Name & vbCrLf &
|
"title 启动 - " & McVersionCurrent.Name & vbCrLf &
|
||||||
"echo 游戏正在启动,请稍候。" & vbCrLf &
|
"echo 游戏正在启动,请稍候。" & vbCrLf &
|
||||||
"set APPDATA=""" & McVersionCurrent.PathIndie & """" & vbCrLf &
|
"set APPDATA=""" & ShortenPath(McVersionCurrent.PathIndie) & """" & vbCrLf &
|
||||||
"cd /D """ & McVersionCurrent.PathIndie & """" & vbCrLf &
|
"cd /D """ & ShortenPath(McVersionCurrent.PathIndie) & """" & vbCrLf &
|
||||||
CustomCommandGlobal & vbCrLf &
|
CustomCommandGlobal & vbCrLf &
|
||||||
CustomCommandVersion & vbCrLf &
|
CustomCommandVersion & vbCrLf &
|
||||||
"""" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf &
|
"""" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf &
|
||||||
@@ -2062,7 +2065,7 @@ IgnoreCustomSkin:
|
|||||||
If CurrentLaunchOptions.SaveBatch IsNot Nothing Then
|
If CurrentLaunchOptions.SaveBatch IsNot Nothing Then
|
||||||
McLaunchLog("导出启动脚本完成,强制结束启动过程")
|
McLaunchLog("导出启动脚本完成,强制结束启动过程")
|
||||||
AbortHint = "导出启动脚本成功!"
|
AbortHint = "导出启动脚本成功!"
|
||||||
OpenExplorer("/select,""" & CurrentLaunchOptions.SaveBatch & """")
|
OpenExplorer(CurrentLaunchOptions.SaveBatch)
|
||||||
Loader.Parent.Abort()
|
Loader.Parent.Abort()
|
||||||
Exit Sub '导出脚本完成
|
Exit Sub '导出脚本完成
|
||||||
End If
|
End If
|
||||||
@@ -2078,7 +2081,7 @@ IgnoreCustomSkin:
|
|||||||
Try
|
Try
|
||||||
CustomProcess.StartInfo.FileName = "cmd.exe"
|
CustomProcess.StartInfo.FileName = "cmd.exe"
|
||||||
CustomProcess.StartInfo.Arguments = "/c """ & CustomCommandGlobal & """"
|
CustomProcess.StartInfo.Arguments = "/c """ & CustomCommandGlobal & """"
|
||||||
CustomProcess.StartInfo.WorkingDirectory = PathMcFolder
|
CustomProcess.StartInfo.WorkingDirectory = ShortenPath(PathMcFolder)
|
||||||
CustomProcess.StartInfo.UseShellExecute = False
|
CustomProcess.StartInfo.UseShellExecute = False
|
||||||
CustomProcess.StartInfo.CreateNoWindow = True
|
CustomProcess.StartInfo.CreateNoWindow = True
|
||||||
CustomProcess.Start()
|
CustomProcess.Start()
|
||||||
@@ -2102,7 +2105,7 @@ IgnoreCustomSkin:
|
|||||||
Try
|
Try
|
||||||
CustomProcess.StartInfo.FileName = "cmd.exe"
|
CustomProcess.StartInfo.FileName = "cmd.exe"
|
||||||
CustomProcess.StartInfo.Arguments = "/c """ & CustomCommandVersion & """"
|
CustomProcess.StartInfo.Arguments = "/c """ & CustomCommandVersion & """"
|
||||||
CustomProcess.StartInfo.WorkingDirectory = PathMcFolder
|
CustomProcess.StartInfo.WorkingDirectory = ShortenPath(PathMcFolder)
|
||||||
CustomProcess.StartInfo.UseShellExecute = False
|
CustomProcess.StartInfo.UseShellExecute = False
|
||||||
CustomProcess.StartInfo.CreateNoWindow = True
|
CustomProcess.StartInfo.CreateNoWindow = True
|
||||||
CustomProcess.Start()
|
CustomProcess.Start()
|
||||||
@@ -2130,18 +2133,18 @@ IgnoreCustomSkin:
|
|||||||
|
|
||||||
'设置环境变量
|
'设置环境变量
|
||||||
If StartInfo.EnvironmentVariables.ContainsKey("appdata") Then
|
If StartInfo.EnvironmentVariables.ContainsKey("appdata") Then
|
||||||
StartInfo.EnvironmentVariables("appdata") = PathMcFolder
|
StartInfo.EnvironmentVariables("appdata") = ShortenPath(PathMcFolder)
|
||||||
Else
|
Else
|
||||||
StartInfo.EnvironmentVariables.Add("appdata", PathMcFolder)
|
StartInfo.EnvironmentVariables.Add("appdata", ShortenPath(PathMcFolder))
|
||||||
End If
|
End If
|
||||||
Dim Paths As New List(Of String)(StartInfo.EnvironmentVariables("Path").Split(";"))
|
Dim Paths As New List(Of String)(StartInfo.EnvironmentVariables("Path").Split(";"))
|
||||||
Paths.Add(McLaunchJavaSelected.PathFolder)
|
Paths.Add(ShortenPath(McLaunchJavaSelected.PathFolder))
|
||||||
StartInfo.EnvironmentVariables("Path") = Join(Paths.Distinct.ToList, ";")
|
StartInfo.EnvironmentVariables("Path") = Join(Paths.Distinct.ToList, ";")
|
||||||
|
|
||||||
'设置其他参数
|
'设置其他参数
|
||||||
StartInfo.StandardErrorEncoding = Encoding.UTF8
|
StartInfo.StandardErrorEncoding = Encoding.UTF8
|
||||||
StartInfo.StandardOutputEncoding = Encoding.UTF8
|
StartInfo.StandardOutputEncoding = Encoding.UTF8
|
||||||
StartInfo.WorkingDirectory = McVersionCurrent.PathIndie
|
StartInfo.WorkingDirectory = ShortenPath(McVersionCurrent.PathIndie)
|
||||||
StartInfo.UseShellExecute = False
|
StartInfo.UseShellExecute = False
|
||||||
StartInfo.RedirectStandardOutput = True
|
StartInfo.RedirectStandardOutput = True
|
||||||
StartInfo.RedirectStandardError = True
|
StartInfo.RedirectStandardError = True
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ Public Module ModMinecraft
|
|||||||
End If
|
End If
|
||||||
Dim Name As String = Folder.Split(">")(0)
|
Dim Name As String = Folder.Split(">")(0)
|
||||||
Dim Path As String = Folder.Split(">")(1)
|
Dim Path As String = Folder.Split(">")(1)
|
||||||
If CheckPermission(Path) Then
|
Try
|
||||||
|
CheckPermissionWithException(Path)
|
||||||
'若已有该文件夹,则直接重命名;没有则添加
|
'若已有该文件夹,则直接重命名;没有则添加
|
||||||
Dim Renamed As Boolean = False
|
Dim Renamed As Boolean = False
|
||||||
For Each OriginalFolder As McFolder In CacheMcFolderList
|
For Each OriginalFolder As McFolder In CacheMcFolderList
|
||||||
@@ -84,9 +85,10 @@ Public Module ModMinecraft
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
If Not Renamed Then CacheMcFolderList.Add(New McFolder With {.Name = Name, .Path = Path, .Type = McFolderType.Custom})
|
If Not Renamed Then CacheMcFolderList.Add(New McFolder With {.Name = Name, .Path = Path, .Type = McFolderType.Custom})
|
||||||
Else
|
Catch ex As Exception
|
||||||
Hint("无法访问 Minecraft 文件夹:" & Path, HintType.Critical)
|
MyMsgBox("失效的 Minecraft 文件夹:" & vbCrLf & Path & vbCrLf & vbCrLf & GetExceptionSummary(ex), "Minecraft 文件夹失效", IsWarn:=True)
|
||||||
End If
|
Log(ex, $"无法访问 Minecraft 文件夹 {Path}")
|
||||||
|
End Try
|
||||||
Next
|
Next
|
||||||
|
|
||||||
'将自定义文件夹情况同步到设置
|
'将自定义文件夹情况同步到设置
|
||||||
@@ -482,17 +484,27 @@ VersionSearchFinish:
|
|||||||
Return TrimedJson.StartsWithF("{") AndAlso TrimedJson.EndsWithF("}")
|
Return TrimedJson.StartsWithF("{") AndAlso TrimedJson.EndsWithF("}")
|
||||||
End Function
|
End Function
|
||||||
If _JsonText Is Nothing Then
|
If _JsonText Is Nothing Then
|
||||||
If Not File.Exists(Path & Name & ".json") Then Throw New Exception($"未找到版本 JSON 文件:{Path}{Name}.json")
|
Dim JsonPath As String = Path & Name & ".json"
|
||||||
_JsonText = ReadFile(Path & Name & ".json")
|
If Not File.Exists(JsonPath) Then
|
||||||
|
'如果文件夹下只有一个 JSON 文件,则将其作为版本 JSON
|
||||||
|
Dim JsonFiles As String() = Directory.GetFiles(Path, "*.json")
|
||||||
|
If JsonFiles.Count = 1 Then
|
||||||
|
JsonPath = JsonFiles(0)
|
||||||
|
Log("[Minecraft] 未找到同名版本 JSON,自动换用 " & JsonPath, LogLevel.Debug)
|
||||||
|
Else
|
||||||
|
Throw New Exception($"未找到版本 JSON 文件:{Path}{Name}.json")
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
_JsonText = ReadFile(JsonPath)
|
||||||
'如果 ReadFile 失败会返回空字符串;这可能是由于文件被临时占用,故延时后重试
|
'如果 ReadFile 失败会返回空字符串;这可能是由于文件被临时占用,故延时后重试
|
||||||
If Not FastJsonCheck(_JsonText) Then
|
If Not FastJsonCheck(_JsonText) Then
|
||||||
If RunInUi() Then
|
If RunInUi() Then
|
||||||
Log("[Minecraft] 版本 JSON 文件为空或有误,由于代码在主线程运行,将不再进行重试", LogLevel.Debug)
|
Log("[Minecraft] 版本 JSON 文件为空或有误,由于代码在主线程运行,将不再进行重试", LogLevel.Debug)
|
||||||
GetJson(_JsonText) '触发异常
|
GetJson(_JsonText) '触发异常
|
||||||
Else
|
Else
|
||||||
Log("[Minecraft] 版本 JSON 文件为空或有误,将在 2s 后重试读取(" & Path & Name & ".json)", LogLevel.Debug)
|
Log($"[Minecraft] 版本 JSON 文件为空或有误,将在 2s 后重试读取({JsonPath})", LogLevel.Debug)
|
||||||
Thread.Sleep(2000)
|
Thread.Sleep(2000)
|
||||||
_JsonText = ReadFile(Path & Name & ".json")
|
_JsonText = ReadFile(JsonPath)
|
||||||
If Not FastJsonCheck(_JsonText) Then GetJson(_JsonText) '触发异常
|
If Not FastJsonCheck(_JsonText) Then GetJson(_JsonText) '触发异常
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -779,37 +791,7 @@ ExitDataLoad:
|
|||||||
End If
|
End If
|
||||||
'确定版本描述
|
'确定版本描述
|
||||||
Dim CustomInfo As String = ReadIni(Path & "PCL\Setup.ini", "CustomInfo")
|
Dim CustomInfo As String = ReadIni(Path & "PCL\Setup.ini", "CustomInfo")
|
||||||
If CustomInfo = "" Then
|
Info = If(CustomInfo <> "", CustomInfo, GetDefaultDescription())
|
||||||
Select Case State
|
|
||||||
Case McVersionState.Snapshot
|
|
||||||
If Version.McName.ContainsF("pre", True) Then
|
|
||||||
Info = "预发布版 " & Version.McName
|
|
||||||
ElseIf Version.McName.ContainsF("rc", True) Then
|
|
||||||
Info = "发布候选 " & Version.McName
|
|
||||||
ElseIf Version.McName.Contains("experimental") OrElse Version.McName = "pending" Then
|
|
||||||
Info = "实验性快照"
|
|
||||||
Else
|
|
||||||
Info = "快照 " & Version.McName
|
|
||||||
End If
|
|
||||||
Case McVersionState.Old
|
|
||||||
Info = "远古版本"
|
|
||||||
Case McVersionState.Original, McVersionState.Forge, McVersionState.NeoForge, McVersionState.Fabric, McVersionState.OptiFine, McVersionState.LiteLoader
|
|
||||||
Info = Version.ToString
|
|
||||||
Case McVersionState.Fool
|
|
||||||
Info = GetMcFoolName(Version.McName)
|
|
||||||
Case McVersionState.Error
|
|
||||||
'已有错误信息
|
|
||||||
Case Else
|
|
||||||
Info = "发生了未知错误,请向作者反馈此问题"
|
|
||||||
End Select
|
|
||||||
If Not State = McVersionState.Error Then
|
|
||||||
If HasJumpLoader Then Info += ", JumpLoader"
|
|
||||||
If Setup.Get("VersionServerLogin", Version:=Me) = 3 Then Info += ", 统一通行证验证"
|
|
||||||
If Setup.Get("VersionServerLogin", Version:=Me) = 4 Then Info += ", Authlib 验证"
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
Info = CustomInfo
|
|
||||||
End If
|
|
||||||
'确定版本收藏状态
|
'确定版本收藏状态
|
||||||
IsStar = ReadIni(Path & "PCL\Setup.ini", "IsStar", False)
|
IsStar = ReadIni(Path & "PCL\Setup.ini", "IsStar", False)
|
||||||
'确定版本显示种类
|
'确定版本显示种类
|
||||||
@@ -842,6 +824,41 @@ ExitDataLoad:
|
|||||||
End Try
|
End Try
|
||||||
Return Me
|
Return Me
|
||||||
End Function
|
End Function
|
||||||
|
''' <summary>
|
||||||
|
''' 获取版本的默认描述。
|
||||||
|
''' </summary>
|
||||||
|
Public Function GetDefaultDescription() As String
|
||||||
|
Dim Info As String = ""
|
||||||
|
Select Case State
|
||||||
|
Case McVersionState.Snapshot
|
||||||
|
If Version.McName.ContainsF("pre", True) Then
|
||||||
|
Info = "预发布版 " & Version.McName
|
||||||
|
ElseIf Version.McName.ContainsF("rc", True) Then
|
||||||
|
Info = "发布候选 " & Version.McName
|
||||||
|
ElseIf Version.McName.Contains("experimental") OrElse Version.McName = "pending" Then
|
||||||
|
Info = "实验性快照"
|
||||||
|
Else
|
||||||
|
Info = "快照 " & Version.McName
|
||||||
|
End If
|
||||||
|
Case McVersionState.Old
|
||||||
|
Info = "远古版本"
|
||||||
|
Case McVersionState.Original, McVersionState.Forge, McVersionState.NeoForge, McVersionState.Fabric, McVersionState.OptiFine, McVersionState.LiteLoader
|
||||||
|
Info = Version.ToString
|
||||||
|
Case McVersionState.Fool
|
||||||
|
Info = GetMcFoolName(Version.McName)
|
||||||
|
Case McVersionState.Error
|
||||||
|
Return Me.Info '已有错误信息
|
||||||
|
Case Else
|
||||||
|
Info = "发生了未知错误,请向作者反馈此问题"
|
||||||
|
End Select
|
||||||
|
If Not State = McVersionState.Error Then
|
||||||
|
If HasJumpLoader Then Info += ", JumpLoader"
|
||||||
|
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 IsLoaded As Boolean = False
|
||||||
|
|
||||||
Public Overrides Function Equals(obj As Object) As Boolean
|
Public Overrides Function Equals(obj As Object) As Boolean
|
||||||
@@ -1123,10 +1140,10 @@ Reload:
|
|||||||
McVersionList = McVersionListLoadNoCache(Path)
|
McVersionList = McVersionListLoadNoCache(Path)
|
||||||
End If
|
End If
|
||||||
IsFirstMcVersionListLoad = False
|
IsFirstMcVersionListLoad = False
|
||||||
If Loader.IsAborted Then Exit Sub
|
|
||||||
|
|
||||||
'改变当前选择的版本
|
'改变当前选择的版本
|
||||||
OnLoaded:
|
OnLoaded:
|
||||||
|
If Loader.IsAborted Then Exit Sub
|
||||||
If McVersionList.Any(Function(v) v.Key <> McVersionCardType.Error) Then
|
If McVersionList.Any(Function(v) v.Key <> McVersionCardType.Error) Then
|
||||||
'尝试读取已储存的选择
|
'尝试读取已储存的选择
|
||||||
Dim SavedSelection As String = ReadIni(Path & "PCL.ini", "Version")
|
Dim SavedSelection As String = ReadIni(Path & "PCL.ini", "Version")
|
||||||
@@ -1619,7 +1636,7 @@ OnLoaded:
|
|||||||
Dim FileAddress As String = PathTemp & "Cache\Skin\" & GetHash(Address) & ".png"
|
Dim FileAddress As String = PathTemp & "Cache\Skin\" & GetHash(Address) & ".png"
|
||||||
SyncLock McSkinDownloadLock
|
SyncLock McSkinDownloadLock
|
||||||
If Not File.Exists(FileAddress) Then
|
If Not File.Exists(FileAddress) Then
|
||||||
NetDownload(Address, FileAddress & NetDownloadEnd)
|
NetDownloadByClient(Address, FileAddress & NetDownloadEnd)
|
||||||
File.Delete(FileAddress)
|
File.Delete(FileAddress)
|
||||||
FileSystem.Rename(FileAddress & NetDownloadEnd, FileAddress)
|
FileSystem.Rename(FileAddress & NetDownloadEnd, FileAddress)
|
||||||
Log("[Minecraft] 皮肤下载成功:" & FileAddress)
|
Log("[Minecraft] 皮肤下载成功:" & FileAddress)
|
||||||
@@ -1962,7 +1979,7 @@ OnLoaded:
|
|||||||
Try
|
Try
|
||||||
Log("[Minecraft] 开始获取统一通行证下载信息")
|
Log("[Minecraft] 开始获取统一通行证下载信息")
|
||||||
'测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/
|
'测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/
|
||||||
DownloadInfo = GetJson(NetGetCodeByDownload({
|
DownloadInfo = GetJson(NetGetCodeByLoader({
|
||||||
"https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version)}, IsJson:=True))
|
"https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version)}, IsJson:=True))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "获取统一通行证下载信息失败")
|
Log(ex, "获取统一通行证下载信息失败")
|
||||||
@@ -1985,7 +2002,7 @@ OnLoaded:
|
|||||||
'获取下载信息
|
'获取下载信息
|
||||||
Try
|
Try
|
||||||
Log("[Minecraft] 开始获取 Authlib-Injector 下载信息")
|
Log("[Minecraft] 开始获取 Authlib-Injector 下载信息")
|
||||||
DownloadInfo = GetJson(NetGetCodeByDownload({
|
DownloadInfo = GetJson(NetGetCodeByLoader({
|
||||||
"https://authlib-injector.yushi.moe/artifact/latest.json",
|
"https://authlib-injector.yushi.moe/artifact/latest.json",
|
||||||
"https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json"
|
"https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json"
|
||||||
}, IsJson:=True))
|
}, IsJson:=True))
|
||||||
@@ -2085,8 +2102,8 @@ OnLoaded:
|
|||||||
Splited(0).Replace(".", "\") & "\" & Splited(1) & "\" & Splited(2) & "\" & Splited(1) & "-" & Splited(2) & ".jar"
|
Splited(0).Replace(".", "\") & "\" & Splited(1) & "\" & Splited(2) & "\" & Splited(1) & "-" & Splited(2) & ".jar"
|
||||||
'判断 OptiFine 是否应该使用 installer
|
'判断 OptiFine 是否应该使用 installer
|
||||||
If McLibGet.Contains("optifine\OptiFine\1.") AndAlso Splited(2).Split(".").Count > 1 Then
|
If McLibGet.Contains("optifine\OptiFine\1.") AndAlso Splited(2).Split(".").Count > 1 Then
|
||||||
Dim MajorVersion As Integer = Val(Splited(2).Split(".")(1))
|
Dim MajorVersion As Integer = Val(Splited(2).Split(".")(1).BeforeFirst("_"))
|
||||||
Dim MinorVersion As Integer = If(Splited(2).Split(".").Count > 1, Val(Splited(2).Split(".")(2).BeforeFirst("_")), 0)
|
Dim MinorVersion As Integer = If(Splited(2).Split(".").Count > 2, Val(Splited(2).Split(".")(2).BeforeFirst("_")), 0)
|
||||||
If (MajorVersion = 12 OrElse (MajorVersion = 20 AndAlso MinorVersion >= 4) OrElse MajorVersion >= 21) AndAlso '仅在 1.12 (无法追溯) 和 1.20.4+ (#5376) 遇到此问题
|
If (MajorVersion = 12 OrElse (MajorVersion = 20 AndAlso MinorVersion >= 4) OrElse MajorVersion >= 21) AndAlso '仅在 1.12 (无法追溯) 和 1.20.4+ (#5376) 遇到此问题
|
||||||
File.Exists($"{CustomMcFolder}libraries\{Splited(0).Replace(".", "\")}\{Splited(1)}\{Splited(2)}\{Splited(1)}-{Splited(2)}-installer.jar") Then
|
File.Exists($"{CustomMcFolder}libraries\{Splited(0).Replace(".", "\")}\{Splited(1)}\{Splited(2)}\{Splited(1)}-{Splited(2)}-installer.jar") Then
|
||||||
McLaunchLog("已将 " & Original & " 替换为对应的 Installer 文件")
|
McLaunchLog("已将 " & Original & " 替换为对应的 Installer 文件")
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
Imports System.IO.Compression
|
Imports System.IO.Compression
|
||||||
Imports System.Linq.Expressions
|
|
||||||
|
|
||||||
Public Module ModModpack
|
Public Module ModModpack
|
||||||
|
|
||||||
#Region "安装"
|
|
||||||
'触发整合包安装的外部接口
|
'触发整合包安装的外部接口
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 弹窗要求选择一个整合包文件并进行安装。
|
''' 弹窗要求选择一个整合包文件并进行安装。
|
||||||
@@ -31,6 +29,9 @@ Public Module ModModpack
|
|||||||
Dim Archive As ZipArchive = Nothing
|
Dim Archive As ZipArchive = Nothing
|
||||||
Dim ArchiveBaseFolder As String = ""
|
Dim ArchiveBaseFolder As String = ""
|
||||||
Try
|
Try
|
||||||
|
'字符校验
|
||||||
|
Dim TargetFolder As String = $"{PathMcFolder}versions\{VersionName}\"
|
||||||
|
If TargetFolder.Contains("!") OrElse TargetFolder.Contains(";") Then Hint("游戏路径中不能含有感叹号或分号:" & TargetFolder, HintType.Critical) : Throw New CancelledException
|
||||||
'获取整合包种类与关键 Json
|
'获取整合包种类与关键 Json
|
||||||
Dim PackType As Integer = -1
|
Dim PackType As Integer = -1
|
||||||
Try
|
Try
|
||||||
@@ -108,29 +109,7 @@ Public Module ModModpack
|
|||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
'整合包缓存清理
|
|
||||||
Private IsInstallCacheCleared As Boolean = False
|
|
||||||
Private IsInstallCacheClearing As Boolean = False
|
|
||||||
Private Sub ExtractModpackFiles(InstallTemp As String, FileAddress As String, Loader As LoaderBase, LoaderProgressDelta As Double)
|
Private Sub ExtractModpackFiles(InstallTemp As String, FileAddress As String, Loader As LoaderBase, LoaderProgressDelta As Double)
|
||||||
'清理缓存文件夹
|
|
||||||
If Not IsInstallCacheCleared Then
|
|
||||||
IsInstallCacheCleared = True
|
|
||||||
IsInstallCacheClearing = True
|
|
||||||
Try
|
|
||||||
Log("[ModPack] 开始清理整合包安装缓存")
|
|
||||||
DeleteDirectory(PathTemp & "PackInstall\")
|
|
||||||
Log("[ModPack] 已清理整合包安装缓存")
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "清理整合包安装缓存失败")
|
|
||||||
Finally
|
|
||||||
IsInstallCacheClearing = False
|
|
||||||
End Try
|
|
||||||
ElseIf IsInstallCacheClearing Then
|
|
||||||
'等待另一个整合包安装的清理步骤完成
|
|
||||||
Do While IsInstallCacheClearing
|
|
||||||
Thread.Sleep(1)
|
|
||||||
Loop
|
|
||||||
End If
|
|
||||||
'解压文件
|
'解压文件
|
||||||
Dim RetryCount As Integer = 1
|
Dim RetryCount As Integer = 1
|
||||||
Dim Encode = Encoding.GetEncoding("GB18030")
|
Dim Encode = Encoding.GetEncoding("GB18030")
|
||||||
@@ -204,7 +183,7 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
'解压与配置文件
|
'解压与配置文件
|
||||||
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
|
Dim InstallTemp As String = RequestTaskTempFolder()
|
||||||
Dim InstallLoaders As New List(Of LoaderBase)
|
Dim InstallLoaders As New List(Of LoaderBase)
|
||||||
Dim OverrideHome As String = If(Json("overrides"), "")
|
Dim OverrideHome As String = If(Json("overrides"), "")
|
||||||
If OverrideHome <> "" Then
|
If OverrideHome <> "" Then
|
||||||
@@ -212,13 +191,15 @@ Retry:
|
|||||||
Sub(Task As LoaderTask(Of String, Integer))
|
Sub(Task As LoaderTask(Of String, Integer))
|
||||||
ExtractModpackFiles(InstallTemp, FileAddress, Task, 0.6)
|
ExtractModpackFiles(InstallTemp, FileAddress, Task, 0.6)
|
||||||
Task.Progress = 0.6
|
Task.Progress = 0.6
|
||||||
Dim OverridePath As String = InstallTemp & ArchiveBaseFolder & OverrideHome
|
|
||||||
'复制结果
|
'复制结果
|
||||||
If Directory.Exists(OverridePath) Then
|
Log("[ModPack] 整合包 override 目标:" & OverrideHome)
|
||||||
CopyDirectory(OverridePath, PathMcFolder & "versions\" & VersionName, Sub(Delta) Task.Progress += Delta * 0.35)
|
Dim OverrideRoot = InstallTemp & ArchiveBaseFolder & If(OverrideHome = "." OrElse OverrideHome = "./", "", OverrideHome) '#5613
|
||||||
Log($"[ModPack] 整合包 override 复制:{OverridePath} -> {PathMcFolder & "versions\" & VersionName}")
|
If Directory.Exists(OverrideRoot) Then
|
||||||
|
Dim CopyTarget = $"{PathMcFolder}versions\{VersionName}"
|
||||||
|
CopyDirectory(OverrideRoot, CopyTarget, Sub(Delta) Task.Progress += Delta * 0.35)
|
||||||
|
Log($"[ModPack] 整合包 override 复制:{OverrideRoot} -> {CopyTarget}")
|
||||||
Else
|
Else
|
||||||
Log($"[ModPack] 整合包中未找到 override 文件夹:{OverridePath}")
|
Log($"[ModPack] 整合包中未找到 override 文件夹:{OverrideRoot}")
|
||||||
End If
|
End If
|
||||||
Task.Progress = 0.95
|
Task.Progress = 0.95
|
||||||
'开启版本隔离
|
'开启版本隔离
|
||||||
@@ -314,7 +295,7 @@ Retry:
|
|||||||
Loaders.Add(New LoaderTask(Of String, String)("最终整理文件",
|
Loaders.Add(New LoaderTask(Of String, String)("最终整理文件",
|
||||||
Sub(Task As LoaderTask(Of String, String))
|
Sub(Task As LoaderTask(Of String, String))
|
||||||
'设置图标
|
'设置图标
|
||||||
Dim VersionFolder As String = PathMcFolder & "versions\" & VersionName & "\"
|
Dim VersionFolder As String = $"{PathMcFolder}versions\{VersionName}\"
|
||||||
If Logo IsNot Nothing AndAlso File.Exists(Logo) Then
|
If Logo IsNot Nothing AndAlso File.Exists(Logo) Then
|
||||||
File.Copy(Logo, VersionFolder & "PCL\Logo.png", True)
|
File.Copy(Logo, VersionFolder & "PCL\Logo.png", True)
|
||||||
WriteIni(VersionFolder & "PCL\Setup.ini", "Logo", "PCL\Logo.png")
|
WriteIni(VersionFolder & "PCL\Setup.ini", "Logo", "PCL\Logo.png")
|
||||||
@@ -328,6 +309,10 @@ Retry:
|
|||||||
File.Delete(Target)
|
File.Delete(Target)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
If File.Exists(FileAddress) AndAlso GetFileNameWithoutExtentionFromPath(FileAddress) = "modpack" Then
|
||||||
|
Log("[ModPack] 删除安装整合包文件:" & FileAddress)
|
||||||
|
File.Delete(FileAddress)
|
||||||
|
End If
|
||||||
End Sub) With {.ProgressWeight = 0.1, .Show = False})
|
End Sub) With {.ProgressWeight = 0.1, .Show = False})
|
||||||
|
|
||||||
'重复任务检查
|
'重复任务检查
|
||||||
@@ -392,7 +377,7 @@ Retry:
|
|||||||
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
||||||
End If
|
End If
|
||||||
'解压和配置文件
|
'解压和配置文件
|
||||||
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
|
Dim InstallTemp As String = RequestTaskTempFolder()
|
||||||
Dim InstallLoaders As New List(Of LoaderBase)
|
Dim InstallLoaders As New List(Of LoaderBase)
|
||||||
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
||||||
Sub(Task As LoaderTask(Of String, Integer))
|
Sub(Task As LoaderTask(Of String, Integer))
|
||||||
@@ -421,7 +406,7 @@ Retry:
|
|||||||
If File("env") IsNot Nothing Then
|
If File("env") IsNot Nothing Then
|
||||||
Select Case File("env")("client").ToString
|
Select Case File("env")("client").ToString
|
||||||
Case "optional"
|
Case "optional"
|
||||||
If MyMsgBox("是否要下载整合包中的可选文件 " & GetFileNameFromPath(File("path").ToString) & "?",
|
If MyMsgBox("是否要下载可选文件 " & GetFileNameFromPath(File("path").ToString) & "?",
|
||||||
"下载可选文件", "是", "否") = 2 Then
|
"下载可选文件", "是", "否") = 2 Then
|
||||||
Continue For
|
Continue For
|
||||||
End If
|
End If
|
||||||
@@ -476,10 +461,14 @@ Retry:
|
|||||||
File.Delete(Target)
|
File.Delete(Target)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
If File.Exists(FileAddress) AndAlso GetFileNameWithoutExtentionFromPath(FileAddress) = "modpack" Then
|
||||||
|
Log("[ModPack] 删除安装整合包文件:" & FileAddress)
|
||||||
|
File.Delete(FileAddress)
|
||||||
|
End If
|
||||||
End Sub) With {.ProgressWeight = 0.1, .Show = False})
|
End Sub) With {.ProgressWeight = 0.1, .Show = False})
|
||||||
|
|
||||||
'重复任务检查
|
'重复任务检查
|
||||||
Dim LoaderName As String = "Modrinth 整合包安装:" & VersionName & " "
|
Dim LoaderName As String = $"Modrinth 整合包安装:{VersionName} "
|
||||||
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
|
If LoaderTaskbar.Any(Function(l) l.Name = LoaderName) Then
|
||||||
Hint("该整合包正在安装中!", HintType.Critical)
|
Hint("该整合包正在安装中!", HintType.Critical)
|
||||||
Throw New CancelledException
|
Throw New CancelledException
|
||||||
@@ -510,7 +499,7 @@ Retry:
|
|||||||
If VersionName = "" Then VersionName = MyMsgBoxInput("输入版本名称", "", "", New ObjectModel.Collection(Of Validate) From {Validate})
|
If VersionName = "" Then VersionName = MyMsgBoxInput("输入版本名称", "", "", New ObjectModel.Collection(Of Validate) From {Validate})
|
||||||
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
||||||
'解压与配置文件
|
'解压与配置文件
|
||||||
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
|
Dim InstallTemp As String = RequestTaskTempFolder()
|
||||||
Dim InstallLoaders As New List(Of LoaderBase)
|
Dim InstallLoaders As New List(Of LoaderBase)
|
||||||
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
||||||
Sub(Task As LoaderTask(Of String, Integer))
|
Sub(Task As LoaderTask(Of String, Integer))
|
||||||
@@ -593,7 +582,7 @@ Retry:
|
|||||||
If VersionName = "" Then VersionName = MyMsgBoxInput("输入版本名称", "", "", New ObjectModel.Collection(Of Validate) From {Validate})
|
If VersionName = "" Then VersionName = MyMsgBoxInput("输入版本名称", "", "", New ObjectModel.Collection(Of Validate) From {Validate})
|
||||||
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
||||||
'解压、配置设置文件
|
'解压、配置设置文件
|
||||||
Dim InstallTemp As String = $"{PathTemp}PackInstall\{RandomInteger(0, 100000)}\"
|
Dim InstallTemp As String = RequestTaskTempFolder()
|
||||||
Dim SetupFile As String = $"{PathMcFolder}versions\{VersionName}\PCL\Setup.ini"
|
Dim SetupFile As String = $"{PathMcFolder}versions\{VersionName}\PCL\Setup.ini"
|
||||||
Dim InstallLoaders As New List(Of LoaderBase)
|
Dim InstallLoaders As New List(Of LoaderBase)
|
||||||
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
||||||
@@ -613,21 +602,14 @@ Retry:
|
|||||||
Try
|
Try
|
||||||
Dim MMCSetupFile As String = InstallTemp & ArchiveBaseFolder & "instance.cfg"
|
Dim MMCSetupFile As String = InstallTemp & ArchiveBaseFolder & "instance.cfg"
|
||||||
If File.Exists(MMCSetupFile) Then
|
If File.Exists(MMCSetupFile) Then
|
||||||
'部分等号替换为冒号,以符合 ini 文件格式
|
'将其中的等号替换为冒号,以符合 ini 文件格式
|
||||||
'为JvmArgs添加排除项,防止参数中的等号被错误的替换
|
Dim Lines As New List(Of String)
|
||||||
Dim MMCSetupFileLines() As String = File.ReadAllLines(MMCSetupFile)
|
For Each Line In ReadFile(MMCSetupFile).Split({vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
|
||||||
For i As Integer = 0 To MMCSetupFileLines.Length - 1
|
If Not Line.Contains("=") Then Continue For
|
||||||
'按行读取,检查开头是否为"JvmArgs="
|
Lines.Add(Line.BeforeFirst("=") & ":" & Line.AfterFirst("="))
|
||||||
If MMCSetupFileLines(i).StartsWith("JvmArgs=") Then
|
|
||||||
'有则只替换这个等号,忽略参数部分
|
|
||||||
MMCSetupFileLines(i) = "JvmArgs:" & MMCSetupFileLines(i).Substring("JvmArgs=".Length)
|
|
||||||
Else
|
|
||||||
'无则全部替换
|
|
||||||
MMCSetupFileLines(i) = MMCSetupFileLines(i).Replace("=", ":")
|
|
||||||
End If
|
|
||||||
Next
|
Next
|
||||||
'修改后写回文件
|
WriteFile(MMCSetupFile, Join(Lines, vbCrLf))
|
||||||
File.WriteAllLines(MMCSetupFile, MMCSetupFileLines)
|
'读取文件
|
||||||
If ReadIni(MMCSetupFile, "OverrideCommands", False) Then
|
If ReadIni(MMCSetupFile, "OverrideCommands", False) Then
|
||||||
Dim PreLaunchCommand As String = ReadIni(MMCSetupFile, "PreLaunchCommand")
|
Dim PreLaunchCommand As String = ReadIni(MMCSetupFile, "PreLaunchCommand")
|
||||||
If PreLaunchCommand <> "" Then
|
If PreLaunchCommand <> "" Then
|
||||||
@@ -656,16 +638,17 @@ Retry:
|
|||||||
CopyFile($"{InstallTemp}{ArchiveBaseFolder}{Logo}.png", $"{PathMcFolder}versions\{VersionName}\PCL\Logo.png")
|
CopyFile($"{InstallTemp}{ArchiveBaseFolder}{Logo}.png", $"{PathMcFolder}versions\{VersionName}\PCL\Logo.png")
|
||||||
Log($"[ModPack] 迁移 MultiMC 版本独立设置:版本图标({Logo}.png)")
|
Log($"[ModPack] 迁移 MultiMC 版本独立设置:版本图标({Logo}.png)")
|
||||||
End If
|
End If
|
||||||
'JvmArgs参数
|
'JVM 参数
|
||||||
Dim JvmArgs As String = ReadIni(MMCSetupFile, "JvmArgs", "")
|
Dim JvmArgs As String = ReadIni(MMCSetupFile, "JvmArgs", "")
|
||||||
If JvmArgs <> "" Then
|
If JvmArgs <> "" Then
|
||||||
WriteIni(SetupFile, "VersionAdvanceJvm", JvmArgs)
|
|
||||||
Log("[ModPack] 迁移 MultiMC 版本独立设置:JVM 参数:" & JvmArgs)
|
|
||||||
End If
|
|
||||||
'这段我看参数有就给加上了...
|
|
||||||
If ReadIni(MMCSetupFile, "OverrideJavaArgs", False) Then
|
If ReadIni(MMCSetupFile, "OverrideJavaArgs", False) Then
|
||||||
WriteIni(SetupFile, "VersionAdvanceJavaArgs", True)
|
WriteIni(SetupFile, "VersionAdvanceJvm", JvmArgs)
|
||||||
Log("[ModPack] 迁移 MultiMC 版本独立设置:覆盖 JavaArgs")
|
Log("[ModPack] 迁移 MultiMC 版本独立设置:JVM 参数(覆盖):" & JvmArgs)
|
||||||
|
Else
|
||||||
|
JvmArgs += " " & Setup.Get("LaunchAdvanceJvm")
|
||||||
|
WriteIni(SetupFile, "VersionAdvanceJvm", JvmArgs)
|
||||||
|
Log("[ModPack] 迁移 MultiMC 版本独立设置:JVM 参数(追加):" & JvmArgs)
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -740,7 +723,7 @@ Retry:
|
|||||||
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
If String.IsNullOrEmpty(VersionName) Then Throw New CancelledException
|
||||||
End If
|
End If
|
||||||
'解压与配置文件
|
'解压与配置文件
|
||||||
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
|
Dim InstallTemp As String = RequestTaskTempFolder()
|
||||||
Dim InstallLoaders As New List(Of LoaderBase)
|
Dim InstallLoaders As New List(Of LoaderBase)
|
||||||
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
InstallLoaders.Add(New LoaderTask(Of String, Integer)("解压整合包文件",
|
||||||
Sub(Task As LoaderTask(Of String, Integer))
|
Sub(Task As LoaderTask(Of String, Integer))
|
||||||
@@ -811,7 +794,6 @@ Retry:
|
|||||||
MyMsgBox("接下来请选择一个空文件夹,它会被安装到这个文件夹里。", "安装", "继续", ForceWait:=True)
|
MyMsgBox("接下来请选择一个空文件夹,它会被安装到这个文件夹里。", "安装", "继续", ForceWait:=True)
|
||||||
Dim TargetFolder As String = SelectFolder("选择安装目标(必须是一个空文件夹)")
|
Dim TargetFolder As String = SelectFolder("选择安装目标(必须是一个空文件夹)")
|
||||||
If String.IsNullOrEmpty(TargetFolder) Then Throw New CancelledException
|
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 Directory.GetFileSystemEntries(TargetFolder).Length > 0 Then Hint("请选择一个空文件夹作为安装目标!", HintType.Critical) : Throw New CancelledException
|
||||||
'解压
|
'解压
|
||||||
Dim Loader As New LoaderCombo(Of String)("解压压缩包", {
|
Dim Loader As New LoaderCombo(Of String)("解压压缩包", {
|
||||||
@@ -839,8 +821,9 @@ Retry:
|
|||||||
'尝试使用附带的启动器打开
|
'尝试使用附带的启动器打开
|
||||||
If Launcher IsNot Nothing Then
|
If Launcher IsNot Nothing Then
|
||||||
Log("[Modpack] 找到压缩包中附带的启动器:" & Launcher)
|
Log("[Modpack] 找到压缩包中附带的启动器:" & Launcher)
|
||||||
If MyMsgBox($"整合包中似乎自带了启动器,是否换用它继续安装?{vbCrLf}通常推荐这样做,以获得最佳体验。{vbCrLf}即将打开:{Launcher}", "换用整合包启动器?", "继续", "取消") = 1 Then
|
If MyMsgBox($"整合包里似乎自带了启动器,是否换用它继续安装?{vbCrLf}即将打开:{Launcher}", "换用整合包启动器?", "换用", "不换用") = 1 Then
|
||||||
ShellOnly(Launcher, "--wait")
|
OpenExplorer(TargetFolder)
|
||||||
|
ShellOnly(Launcher, "--wait") '要求等待已有的 PCL 退出
|
||||||
Log("[Modpack] 为换用整合包中的启动器启动,强制结束程序")
|
Log("[Modpack] 为换用整合包中的启动器启动,强制结束程序")
|
||||||
FrmMain.EndProgram(False)
|
FrmMain.EndProgram(False)
|
||||||
Return
|
Return
|
||||||
@@ -848,15 +831,17 @@ Retry:
|
|||||||
Else
|
Else
|
||||||
Log("[Modpack] 未找到压缩包中附带的启动器")
|
Log("[Modpack] 未找到压缩包中附带的启动器")
|
||||||
End If
|
End If
|
||||||
|
OpenExplorer(TargetFolder)
|
||||||
'加入文件夹列表
|
'加入文件夹列表
|
||||||
Dim VersionName As String = GetFolderNameFromPath(TargetFolder)
|
Dim VersionName As String = GetFolderNameFromPath(TargetFolder)
|
||||||
|
Directory.CreateDirectory(TargetFolder & ".minecraft\")
|
||||||
PageSelectLeft.AddFolder(
|
PageSelectLeft.AddFolder(
|
||||||
TargetFolder & ArchiveBaseFolder.Replace("/", "\").TrimStart("\"), '格式例如:包裹文件夹\.minecraft\(最短为空字符串)
|
TargetFolder & ".minecraft\" & ArchiveBaseFolder.Replace("/", "\").TrimStart("\"), '格式例如:包裹文件夹\.minecraft\(最短为空字符串)
|
||||||
VersionName, False)
|
VersionName, False)
|
||||||
'调用 modpack 文件进行安装
|
'调用 modpack 文件进行安装
|
||||||
Dim ModpackFile = Directory.GetFiles(TargetFolder, "modpack.*", SearchOption.AllDirectories).First
|
Dim ModpackFile = Directory.GetFiles(TargetFolder, "modpack.*", SearchOption.AllDirectories).First
|
||||||
Log("[Modpack] 调用 modpack 文件继续安装:" & ModpackFile)
|
Log("[Modpack] 调用 modpack 文件继续安装:" & ModpackFile)
|
||||||
ModpackInstall(ModpackFile, VersionName)
|
ModpackInstall(ModpackFile)
|
||||||
End Sub)
|
End Sub)
|
||||||
})
|
})
|
||||||
Loader.Start(TargetFolder)
|
Loader.Start(TargetFolder)
|
||||||
@@ -906,340 +891,6 @@ Retry:
|
|||||||
Return Loader
|
Return Loader
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
#End Region
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
#Region "导出"
|
|
||||||
Private ExpTempDir As String = PathTemp & "PackExport\"
|
|
||||||
''' <summary>
|
|
||||||
''' 整合包类型。
|
|
||||||
''' </summary>
|
|
||||||
Public Enum ModpackType
|
|
||||||
Modrinth
|
|
||||||
End Enum
|
|
||||||
''' <summary>
|
|
||||||
''' 导出整合包的选项。
|
|
||||||
''' </summary>
|
|
||||||
Public Class ExportOptions
|
|
||||||
''' <summary>
|
|
||||||
''' 要导出的版本。
|
|
||||||
''' </summary>
|
|
||||||
Public Version As McVersion
|
|
||||||
''' <summary>
|
|
||||||
''' 要保存整合包的位置。
|
|
||||||
''' </summary>
|
|
||||||
Public Dest As String
|
|
||||||
''' <summary>
|
|
||||||
''' 是否包括 PCL 文件。
|
|
||||||
''' </summary>
|
|
||||||
Public IncludePCL As Boolean
|
|
||||||
''' <summary>
|
|
||||||
''' 整合包类型。
|
|
||||||
''' </summary>
|
|
||||||
Public Type As ModpackType
|
|
||||||
''' <summary>
|
|
||||||
''' 要保留到整合包的文件。
|
|
||||||
''' </summary>
|
|
||||||
Public Additional As String()
|
|
||||||
''' <summary>
|
|
||||||
''' 是否需要保留 PCL 全局设置。仅在包括 PCL 时有效。
|
|
||||||
''' </summary>
|
|
||||||
Public PCLSetupGlobal As Boolean = True
|
|
||||||
''' <summary>
|
|
||||||
''' 整合包名称。
|
|
||||||
''' </summary>
|
|
||||||
Public Name As String = ""
|
|
||||||
''' <summary>
|
|
||||||
''' 整合包描述。
|
|
||||||
''' </summary>
|
|
||||||
Public Desc As String = ""
|
|
||||||
''' <summary>
|
|
||||||
''' 版本号。
|
|
||||||
''' </summary>
|
|
||||||
Public VerID As String = ""
|
|
||||||
Public Sub New(Version As McVersion,
|
|
||||||
Dest As String,
|
|
||||||
IncludePCL As Boolean,
|
|
||||||
Additional As String(),
|
|
||||||
Optional PCLSetupGlobal As Boolean = True,
|
|
||||||
Optional Name As String = "",
|
|
||||||
Optional Desc As String = "",
|
|
||||||
Optional VerID As String = "")
|
|
||||||
Me.Version = Version
|
|
||||||
Me.Dest = Dest
|
|
||||||
Me.IncludePCL = IncludePCL
|
|
||||||
Me.Additional = Additional
|
|
||||||
Me.PCLSetupGlobal = PCLSetupGlobal
|
|
||||||
Me.Name = Name
|
|
||||||
Me.Desc = Desc
|
|
||||||
Me.VerID = VerID
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
''' <summary>
|
|
||||||
''' 导出整合包,返回是否成功。
|
|
||||||
''' </summary>
|
|
||||||
Public Function ModpackExport(Task As LoaderTask(Of ExportOptions, Boolean)) As Boolean
|
|
||||||
If Task.Input.IncludePCL Then Return ExportCompressed(Task)
|
|
||||||
Return ExportModrinth(Task)
|
|
||||||
End Function
|
|
||||||
|
|
||||||
#Region "冗余"
|
|
||||||
Private VersionRedundant As String() = {"^screenshots", "^backups", "^command_history\.txt$", '个人文件
|
|
||||||
"^.*-natives", "^server-resource-packs", "^user.*cache\.json$", "^\.optifine", "^\.fabric", "^\.mixin\.out", '缓存
|
|
||||||
"^.*\.jar$", "^downloads", "^realms_persistence.json$", "^\$\{natives_directory\}", "^essential", '可联网更新
|
|
||||||
"^logs", "^crash-reports", ".*\.log$", "^debug", '日志
|
|
||||||
".*\.dat_old$", ".*\.old$", '备份
|
|
||||||
"^\$\{quickPlayPath\}", '服务器
|
|
||||||
"^\.replay_cache", "^replay_recordings", "^replay_videos", 'ReplayMod
|
|
||||||
"^irisUpdateInfo\.json$", 'Iris
|
|
||||||
"^modernfix", 'ModernFix 模组
|
|
||||||
"^modtranslations", 'Mod 翻译
|
|
||||||
"^schematics", 'schematics 模组
|
|
||||||
"^journeymap\\data", 'JourneyMap 模组
|
|
||||||
"^mods\\\.connector", '信雅互联
|
|
||||||
"^.*\.BakaCoreInfo$", 'BakaXL 配置
|
|
||||||
"^hmclversion\.cfg$", "^log4j2\.xml$", 'HMCL 配置
|
|
||||||
"^assets$", "^libraries$", "^\$natives$", "^launcher_profiles\.json$", "^versions$" '开启版本隔离时排除的文件
|
|
||||||
}
|
|
||||||
Public Function IsVerRedundant(FilePath As String, PathIndie As String) As Boolean
|
|
||||||
FilePath = FilePath.Replace("/", "\")
|
|
||||||
For Each regex In VersionRedundant
|
|
||||||
If RegexCheck(FilePath.Replace(PathIndie, ""), regex, RegularExpressions.RegexOptions.IgnoreCase) Then Return True
|
|
||||||
Next
|
|
||||||
Return False
|
|
||||||
End Function
|
|
||||||
Private MustExport As String() = {
|
|
||||||
"mods", "PCL", ".*\.json"
|
|
||||||
}
|
|
||||||
Public Function IsMustExport(FilePath As String, PathIndie As String) As Boolean
|
|
||||||
For Each regex In MustExport
|
|
||||||
If RegexCheck(FilePath.Replace(PathIndie, ""), regex, RegularExpressions.RegexOptions.IgnoreCase) AndAlso Not (FilePath.EndsWithF(".zip") OrElse FilePath.EndsWithF("\")) Then Return True
|
|
||||||
Next
|
|
||||||
Return False
|
|
||||||
End Function
|
|
||||||
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
#Region "不同类型整合包的导出方法"
|
|
||||||
Private Function ExportModrinth(Task As LoaderTask(Of ExportOptions, Boolean)) As Boolean
|
|
||||||
Try
|
|
||||||
Dim Version = Task.Input.Version
|
|
||||||
Dim DestPath = Task.Input.Dest
|
|
||||||
Dim Additional = Task.Input.Additional
|
|
||||||
Dim Name = Task.Input.Name
|
|
||||||
Dim Description = Task.Input.Desc
|
|
||||||
Dim VerID = Task.Input.VerID
|
|
||||||
Log($"[Export] 导出整合包(Modrinth):{Version.Path} -> {DestPath},额外版本文件 {Additional.Count} 个")
|
|
||||||
Dim tempDir As String = $"{ExpTempDir}{GetUuid()}\"
|
|
||||||
Log($"[Export] 缓存文件夹:{tempDir}")
|
|
||||||
DeleteDirectory(tempDir)
|
|
||||||
Directory.CreateDirectory(tempDir)
|
|
||||||
|
|
||||||
#Region "0.04-0.40:从 Modrinth 获取 Mod 工程信息,得到 URL"
|
|
||||||
Dim Mods As New Dictionary(Of String, McMod)
|
|
||||||
If Directory.Exists(Version.Path & "mods\") Then
|
|
||||||
For Each m In Directory.EnumerateFiles(Version.Path & "mods\")
|
|
||||||
If m.EndsWithF(".jar") Then Mods.Add(GetFileNameFromPath(m), New McMod(m))
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
|
|
||||||
'从 Modrinth 获取信息
|
|
||||||
Dim ModrinthMapping As New Dictionary(Of String, JObject) 'Modrinth 获取到的 Mod
|
|
||||||
Dim CurseForgeMapping As New Dictionary(Of String, JObject) 'CurseForge 获取到的 Mod
|
|
||||||
Dim Failed = Mods.ToArray().ToDictionary(Function(a) a.Key, Function(a) a.Value) '获取失败的 Mod
|
|
||||||
Dim ModrinthHashes = Mods.Select(Function(m) m.Value.ModrinthHash).ToList()
|
|
||||||
If Mods.Count = 0 Then GoTo JumpMod
|
|
||||||
Dim ModrinthRaw = CType(GetJson(NetRequestRetry("https://api.modrinth.com/v2/version_files", "POST",
|
|
||||||
$"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject)
|
|
||||||
Log($"[Export] 从 Modrinth 获取到 {ModrinthRaw.Count} 个本地 Mod 的对应信息")
|
|
||||||
Task.Progress = 0.35
|
|
||||||
|
|
||||||
For Each Entry In Mods
|
|
||||||
If (Not ModrinthRaw.ContainsKey(Entry.Value.ModrinthHash)) OrElse
|
|
||||||
(ModrinthRaw(Entry.Value.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.Value.ModrinthHash) Then
|
|
||||||
Continue For
|
|
||||||
End If
|
|
||||||
Failed.Remove(Entry.Key)
|
|
||||||
ModrinthMapping.Add(Entry.Key, ModrinthRaw(Entry.Value.ModrinthHash)("files")(0))
|
|
||||||
Next
|
|
||||||
Task.Progress = 0.4
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
#Region "0.40-0.80:从 CurseForge 继续获取"
|
|
||||||
Dim CurseForgeHashes = Mods.Select(Function(m) m.Value.CurseForgeHash).ToList()
|
|
||||||
Dim CurseForgeRaw = CType(CType(GetJson(NetRequestRetry("https://api.curseforge.com/v1/fingerprints/432/", "POST",
|
|
||||||
$"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer)
|
|
||||||
Log($"[Export] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息")
|
|
||||||
Task.Progress = 0.7
|
|
||||||
|
|
||||||
For Each m In CurseForgeRaw
|
|
||||||
Dim hash As String = ""
|
|
||||||
For Each h In m("file")("hashes") '获取 Modrinth Hash
|
|
||||||
If h("algo").ToString = 1 Then
|
|
||||||
hash = h("value")
|
|
||||||
Exit For
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
If String.IsNullOrEmpty(hash) OrElse String.IsNullOrEmpty(m("file")("downloadUrl")) Then Continue For
|
|
||||||
|
|
||||||
m("file")("ModrinthHash") = hash
|
|
||||||
Dim f = Mods.ToArray()
|
|
||||||
For Each file In f
|
|
||||||
If file.Value.ModrinthHash = hash Then
|
|
||||||
CurseForgeMapping.Add(file.Key, m("file"))
|
|
||||||
Failed.Remove(file.Key)
|
|
||||||
Exit For
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
Next
|
|
||||||
Task.Progress = 0.8
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
JumpMod:
|
|
||||||
#Region "0.80-0.90:合并下载链接,复制 Logo,写入 Json 文件"
|
|
||||||
'获取作为检查目标的加载器和版本
|
|
||||||
Dim ModLoaders = GetTargetModLoaders()
|
|
||||||
Dim McVersion = Version.Version.McName
|
|
||||||
Log($"[Export] 目标加载器:{ModLoaders.Join("/")},版本:{McVersion}")
|
|
||||||
|
|
||||||
'合并下载链接
|
|
||||||
Dim BothUrls As New Dictionary(Of String, String()) '两个下载源都有 URL 的 Mod
|
|
||||||
For Each modrinth In ModrinthMapping
|
|
||||||
Dim curseforge As New JObject
|
|
||||||
If CurseForgeMapping.TryGetValue(modrinth.Key, curseforge) Then
|
|
||||||
BothUrls.Add(modrinth.Key, {modrinth.Value("url"), curseforge("downloadUrl")})
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
Task.Progress = 0.83
|
|
||||||
|
|
||||||
Dim files As New JArray
|
|
||||||
For Each m In ModrinthMapping
|
|
||||||
files.Add(New JObject From {
|
|
||||||
{"path", $"mods/{m.Key}"},
|
|
||||||
{"hashes", m.Value("hashes")},
|
|
||||||
{"env", New JObject From {{"client", "required"}, {"server", "required"}}},
|
|
||||||
{"downloads", If(BothUrls.ContainsKey(m.Key), JArray.FromObject(BothUrls(m.Key)), New JArray From {m.Value("url")})},
|
|
||||||
{"fileSize", m.Value("size")}
|
|
||||||
})
|
|
||||||
Next
|
|
||||||
For Each m In CurseForgeMapping
|
|
||||||
If Not BothUrls.ContainsKey(m.Key) Then
|
|
||||||
files.Add(New JObject From {
|
|
||||||
{"path", $"mods/{m.Key}"},
|
|
||||||
{"hashes", New JObject From {{"sha1", m.Value("ModrinthHash").ToString}}},
|
|
||||||
{"env", New JObject From {{"client", "required"}, {"server", "required"}}},
|
|
||||||
{"downloads", New JArray From {m.Value("downloadUrl")}},
|
|
||||||
{"fileSize", m.Value("fileLength")}
|
|
||||||
})
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
Task.Progress = 0.86
|
|
||||||
'If Not String.IsNullOrEmpty(Logo) Then
|
|
||||||
' Dim LogoObj As New MyBitmap(Logo)
|
|
||||||
' LogoObj.Save(tempDir & "Logo.png")
|
|
||||||
'End If
|
|
||||||
'Task.Progress = 0.88
|
|
||||||
|
|
||||||
Dim depend As New JObject From {{"minecraft", McVersion}}
|
|
||||||
If Version.Version.HasForge Then depend.Add("forge", Version.Version.ForgeVersion)
|
|
||||||
If Version.Version.HasFabric Then depend.Add("fabric-loader", Version.Version.FabricVersion)
|
|
||||||
If Version.Version.HasNeoForge Then depend.Add("neoforge", Version.Version.NeoForgeVersion)
|
|
||||||
|
|
||||||
Dim json As New JObject From {
|
|
||||||
{"game", "minecraft"},
|
|
||||||
{"formatVersion", 1},
|
|
||||||
{"versionId", VerID},
|
|
||||||
{"name", If(String.IsNullOrEmpty(Name), Version.Name, Name)},
|
|
||||||
{"summary", Description},
|
|
||||||
{"files", files},
|
|
||||||
{"dependencies", depend}
|
|
||||||
}
|
|
||||||
'If Not String.IsNullOrEmpty(Logo) Then json.Add("logo", tempDir & "Logo.png")
|
|
||||||
|
|
||||||
File.WriteAllText(tempDir & "modrinth.index.json", json.ToString)
|
|
||||||
Task.Progress = 0.9
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
#Region "0.90-0.99:将其余文件保存到 overrides 目录"
|
|
||||||
For Each m In Failed
|
|
||||||
CopyFile(m.Value.Path, tempDir & "overrides\mods\" & m.Value.FileName)
|
|
||||||
Next
|
|
||||||
Task.Progress = 0.92
|
|
||||||
|
|
||||||
'额外文件
|
|
||||||
For Each p In Additional
|
|
||||||
If String.IsNullOrWhiteSpace(p) Then Continue For '传空字串进去会直接把整个版本文件夹拷过去
|
|
||||||
If Not p.StartsWithF(GetPathFromFullPath(GetPathFromFullPath(Version.Path)), IgnoreCase:=True) Then Continue For
|
|
||||||
Dim relative As String = p.Replace(Version.Path, "").Replace(GetPathFromFullPath(GetPathFromFullPath(Version.Path)), "")
|
|
||||||
If File.Exists(p) AndAlso Not IsVerRedundant(p, Version.PathIndie) Then
|
|
||||||
CopyFile(p, $"{tempDir}overrides\{relative}")
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
Task.Progress = 0.96
|
|
||||||
|
|
||||||
'如果 resourcepacks shaderpacks 文件夹中有文件夹格式的包,则先将文件夹压缩成 Zip 文件后再打包入对应位置
|
|
||||||
'这可以避免安装时出现路径长度限制而出错
|
|
||||||
If Directory.Exists($"{tempDir}overrides\resourcepacks\") Then
|
|
||||||
For Each d In Directory.EnumerateDirectories($"{tempDir}overrides\resourcepacks\")
|
|
||||||
If Not File.Exists(d + ".zip") Then ZipFile.CreateFromDirectory(d, d + ".zip")
|
|
||||||
DeleteDirectory(d)
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
If Directory.Exists($"{tempDir}overrides\shaderpacks\") Then
|
|
||||||
For Each d In Directory.EnumerateDirectories($"{tempDir}overrides\shaderpacks\")
|
|
||||||
If Not File.Exists(d + ".zip") Then ZipFile.CreateFromDirectory(d, d + ".zip")
|
|
||||||
DeleteDirectory(d)
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
If File.Exists(DestPath) Then File.Delete(DestPath) '选择文件的时候已经确认了要替换
|
|
||||||
ZipFile.CreateFromDirectory(tempDir, DestPath)
|
|
||||||
DeleteDirectory(tempDir)
|
|
||||||
Return True
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "导出整合包失败", LogLevel.Msgbox)
|
|
||||||
Return False
|
|
||||||
End Try
|
|
||||||
End Function
|
|
||||||
Private Function ExportCompressed(Task As LoaderTask(Of ExportOptions, Boolean)) As Boolean
|
|
||||||
Try
|
|
||||||
Dim Version = Task.Input.Version
|
|
||||||
Dim DestPath = Task.Input.Dest
|
|
||||||
Dim Additional = Task.Input.Additional
|
|
||||||
Dim Name = Task.Input.Name
|
|
||||||
Dim VerID = Task.Input.VerID
|
|
||||||
Dim PCLSetupGlobal = Task.Input.PCLSetupGlobal
|
|
||||||
Log($"[Export] 导出整合包(含启动器):{Version.Path} -> {DestPath},额外版本文件 {Additional.Count} 个,全局设置 {If(PCLSetupGlobal, "导出", "不导出")}")
|
|
||||||
Dim tempDir As String = $"{ExpTempDir}{GetUuid()}\"
|
|
||||||
Log($"[Export] 最终压缩包的缓存文件夹:{tempDir}")
|
|
||||||
Directory.CreateDirectory(tempDir)
|
|
||||||
|
|
||||||
Task.Progress = 0.04
|
|
||||||
|
|
||||||
Log("[Export] 开始导出 Modrinth 整合包")
|
|
||||||
Task.Input.Dest = $"{tempDir}modpack.mrpack"
|
|
||||||
ExportModrinth(Task)
|
|
||||||
|
|
||||||
Log($"[Export] 正在复制 PCL 本体")
|
|
||||||
CopyFile(PathWithName, tempDir & GetFileNameFromPath(PathWithName))
|
|
||||||
|
|
||||||
If PCLSetupGlobal Then
|
|
||||||
Log($"[Export] 正在复制 PCL 全局配置")
|
|
||||||
CopyFile(Path & "PCL\Setup.ini", tempDir & "PCL\Setup.ini")
|
|
||||||
End If
|
|
||||||
|
|
||||||
If File.Exists(DestPath) Then File.Delete(DestPath) '选择文件的时候已经确认了要替换
|
|
||||||
ZipFile.CreateFromDirectory(tempDir, DestPath)
|
|
||||||
DeleteDirectory(tempDir)
|
|
||||||
Return True
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "导出整合包失败", LogLevel.Msgbox)
|
|
||||||
Return False
|
|
||||||
End Try
|
|
||||||
End Function
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
End Module
|
End Module
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
Hint("正在开启中,请稍候……")
|
Hint("正在开启中,请稍候……")
|
||||||
OpenWebsite(Data(0))
|
OpenWebsite(Data(0))
|
||||||
|
|
||||||
Case "打开文件", "打开帮助"
|
Case "打开文件", "打开帮助", "执行命令"
|
||||||
RunInThread(
|
RunInThread(
|
||||||
Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
@@ -29,15 +29,25 @@
|
|||||||
Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1)
|
Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1)
|
||||||
Log($"[Control] 打开类自定义事件实际路径:{Location},工作目录:{WorkingDir}")
|
Log($"[Control] 打开类自定义事件实际路径:{Location},工作目录:{WorkingDir}")
|
||||||
'执行
|
'执行
|
||||||
If Type = "打开文件" Then
|
If Type = "打开帮助" Then
|
||||||
|
PageOtherHelp.EnterHelpPage(Location)
|
||||||
|
Else
|
||||||
|
If Not Setup.Get("HintCustomCommand") Then
|
||||||
|
Select Case MyMsgBox(
|
||||||
|
"即将执行:" & Location & If(Data.Length >= 2, " " & Data(1), "") & vbCrLf &
|
||||||
|
"请在确认该操作没有安全隐患后继续。", "执行确认", "继续", "继续且今后不再要求确认", "取消")
|
||||||
|
Case 2
|
||||||
|
Setup.Set("HintCustomCommand", True)
|
||||||
|
Case 3
|
||||||
|
Exit Sub
|
||||||
|
End Select
|
||||||
|
End If
|
||||||
Dim Info As New ProcessStartInfo With {
|
Dim Info As New ProcessStartInfo With {
|
||||||
.Arguments = If(Data.Length >= 2, Data(1), ""),
|
.Arguments = If(Data.Length >= 2, Data(1), ""),
|
||||||
.FileName = Location,
|
.FileName = Location,
|
||||||
.WorkingDirectory = WorkingDir
|
.WorkingDirectory = ShortenPath(WorkingDir)
|
||||||
}
|
}
|
||||||
Process.Start(Info)
|
Process.Start(Info)
|
||||||
Else '打开帮助
|
|
||||||
PageOtherHelp.EnterHelpPage(Location)
|
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "执行打开类自定义事件失败", LogLevel.Msgbox)
|
Log(ex, "执行打开类自定义事件失败", LogLevel.Msgbox)
|
||||||
@@ -140,8 +150,8 @@
|
|||||||
Dim LocalTemp2 As String = PathTemp & "CustomEvent\" & RawFileName.Replace(".json", ".xaml")
|
Dim LocalTemp2 As String = PathTemp & "CustomEvent\" & RawFileName.Replace(".json", ".xaml")
|
||||||
Log("[Event] 转换网络资源:" & RelativeUrl & " -> " & LocalTemp1)
|
Log("[Event] 转换网络资源:" & RelativeUrl & " -> " & LocalTemp1)
|
||||||
Try
|
Try
|
||||||
NetDownload(RelativeUrl, LocalTemp1)
|
NetDownloadByClient(RelativeUrl, LocalTemp1)
|
||||||
NetDownload(RelativeUrl.Replace(".json", ".xaml"), LocalTemp1.Replace(".json", ".xaml"))
|
NetDownloadByClient(RelativeUrl.Replace(".json", ".xaml"), LocalTemp1.Replace(".json", ".xaml"))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Throw New Exception("下载指定的文件失败!" & vbCrLf &
|
Throw New Exception("下载指定的文件失败!" & vbCrLf &
|
||||||
"注意,联网帮助页面须指向一个帮助 JSON 文件,并在同路径下包含相应 XAML 文件!" & vbCrLf &
|
"注意,联网帮助页面须指向一个帮助 JSON 文件,并在同路径下包含相应 XAML 文件!" & vbCrLf &
|
||||||
@@ -174,7 +184,7 @@
|
|||||||
Location = PathTemp & "Help\" & RelativeUrl
|
Location = PathTemp & "Help\" & RelativeUrl
|
||||||
WorkingDir = PathTemp & "Help\"
|
WorkingDir = PathTemp & "Help\"
|
||||||
Log("[Control] 自定义事件中由相对 PCL 自带帮助文件夹的路径" & EventType & ":" & Location)
|
Log("[Control] 自定义事件中由相对 PCL 自带帮助文件夹的路径" & EventType & ":" & Location)
|
||||||
ElseIf EventType = "打开文件" Then
|
ElseIf EventType = "打开文件" OrElse EventType = "执行命令" Then
|
||||||
'直接使用原有路径启动程序
|
'直接使用原有路径启动程序
|
||||||
Location = RelativeUrl
|
Location = RelativeUrl
|
||||||
Log("[Control] 自定义事件中直接" & EventType & ":" & Location)
|
Log("[Control] 自定义事件中直接" & EventType & ":" & Location)
|
||||||
|
|||||||
@@ -811,6 +811,54 @@ NextFile:
|
|||||||
Public Declare Function SetForegroundWindow Lib "user32" (hWnd As IntPtr) As Integer
|
Public Declare Function SetForegroundWindow Lib "user32" (hWnd As IntPtr) As Integer
|
||||||
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (hWnd As IntPtr, msg As UInteger, wParam As Long, lParam As Long) As Boolean
|
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (hWnd As IntPtr, msg As UInteger, wParam As Long, lParam As Long) As Boolean
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
#Region "任务缓存"
|
||||||
|
|
||||||
|
Private IsTaskTempCleared As Boolean = False
|
||||||
|
Private IsTaskTempClearing As Boolean = False
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 尝试清理任务缓存文件夹。
|
||||||
|
''' 在整次运行中只会实际清理一次。
|
||||||
|
''' </summary>
|
||||||
|
Public Sub TryClearTaskTemp()
|
||||||
|
If Not IsTaskTempCleared Then
|
||||||
|
IsTaskTempCleared = True
|
||||||
|
IsTaskTempClearing = True
|
||||||
|
Try
|
||||||
|
Log("[System] 开始清理任务缓存文件夹")
|
||||||
|
DeleteDirectory($"{OsDrive}ProgramData\PCL\TaskTemp\")
|
||||||
|
DeleteDirectory($"{PathTemp}TaskTemp\")
|
||||||
|
Log("[System] 已清理任务缓存文件夹")
|
||||||
|
Catch ex As Exception
|
||||||
|
Log(ex, "清理任务缓存文件夹失败")
|
||||||
|
Finally
|
||||||
|
IsTaskTempClearing = False
|
||||||
|
End Try
|
||||||
|
ElseIf IsTaskTempClearing Then
|
||||||
|
'等待另一个清理步骤完成
|
||||||
|
Do While IsTaskTempClearing
|
||||||
|
Thread.Sleep(1)
|
||||||
|
Loop
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 申请一个可用于任务缓存的临时文件夹,以 \ 结尾。
|
||||||
|
''' 这些文件夹无需进行后续清理。
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="RequireNonSpace">是否要求路径不包含空格。</param>
|
||||||
|
Public Function RequestTaskTempFolder(Optional RequireNonSpace As Boolean = False) As String
|
||||||
|
TryClearTaskTemp()
|
||||||
|
If RequireNonSpace Then
|
||||||
|
RequestTaskTempFolder = $"{OsDrive}ProgramData\PCL\Install\{GetUuid()}-{RandomInteger(0, 1000000)}\"
|
||||||
|
Else
|
||||||
|
RequestTaskTempFolder = $"{PathTemp}TaskTemp\{GetUuid()}-{RandomInteger(0, 1000000)}\"
|
||||||
|
End If
|
||||||
|
Directory.CreateDirectory(RequestTaskTempFolder)
|
||||||
|
End Function
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
Public DragControl = Nothing
|
Public DragControl = Nothing
|
||||||
|
|||||||
@@ -246,18 +246,18 @@ Friend Module ModSecret
|
|||||||
FrmMain.PanForm.Background.Freeze()
|
FrmMain.PanForm.Background.Freeze()
|
||||||
End Sub)
|
End Sub)
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub ThemeCheckAll(EffectSetup As Boolean)
|
Friend Sub ThemeCheckAll(EffectSetup As Boolean)
|
||||||
End Sub
|
End Sub
|
||||||
Public Function ThemeCheckOne(Id As Integer) As Boolean
|
Friend Function ThemeCheckOne(Id As Integer) As Boolean
|
||||||
Return True
|
Return True
|
||||||
End Function
|
End Function
|
||||||
Friend Function ThemeUnlock(Id As Integer, Optional ShowDoubleHint As Boolean = True, Optional UnlockHint As String = Nothing) As Boolean
|
Friend Function ThemeUnlock(Id As Integer, Optional ShowDoubleHint As Boolean = True, Optional UnlockHint As String = Nothing) As Boolean
|
||||||
Return False
|
Return False
|
||||||
End Function
|
End Function
|
||||||
Public Function ThemeCheckGold(Optional Code As String = Nothing) As Boolean
|
Friend Function ThemeCheckGold(Optional Code As String = Nothing) As Boolean
|
||||||
Return False
|
Return False
|
||||||
End Function
|
End Function
|
||||||
Public Function DonateCodeInput() As Boolean?
|
Friend Function DonateCodeInput() As Boolean?
|
||||||
Return Nothing
|
Return Nothing
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
@@ -276,6 +276,13 @@ Friend Module ModSecret
|
|||||||
End Sub
|
End Sub
|
||||||
Public Sub UpdateReplace(ProcessId As Integer, OldFileName As String, NewFileName As String, TriggerRestart As Boolean)
|
Public Sub UpdateReplace(ProcessId As Integer, OldFileName As String, NewFileName As String, TriggerRestart As Boolean)
|
||||||
End Sub
|
End Sub
|
||||||
|
''' <summary>
|
||||||
|
''' 确保 PathTemp 下的 Latest.exe 是最新正式版的 PCL,它会被用于整合包打包。
|
||||||
|
''' 如果不是,则下载一个。
|
||||||
|
''' </summary>
|
||||||
|
Friend Sub DownloadLatestPCL(Optional LoaderToSyncProgress As LoaderBase = Nothing)
|
||||||
|
'注意:如果要自行实现这个功能,请换用另一个文件路径,以免与官方版本冲突
|
||||||
|
End Sub
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||||
' 方法是按如下所示使用“*”
|
' 方法是按如下所示使用“*”
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2.8.13.0")>
|
<Assembly: AssemblyVersion("2.9.1.0")>
|
||||||
<Assembly: AssemblyFileVersion("2.8.13.0")>
|
<Assembly: AssemblyFileVersion("2.9.1.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("")>
|
<Assembly: NeutralResourcesLanguage("")>
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ Public Module ModDownloadLib
|
|||||||
Dim LoadersLib As New List(Of LoaderBase)
|
Dim LoadersLib As New List(Of LoaderBase)
|
||||||
LoadersLib.Add(New LoaderTask(Of String, List(Of NetFile))("分析原版支持库文件(副加载器)",
|
LoadersLib.Add(New LoaderTask(Of String, List(Of NetFile))("分析原版支持库文件(副加载器)",
|
||||||
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||||
|
Thread.Sleep(50) '等待 JSON 文件实际写入硬盘(#3710)
|
||||||
Log("[Download] 开始分析原版支持库文件:" & VersionFolder)
|
Log("[Download] 开始分析原版支持库文件:" & VersionFolder)
|
||||||
Task.Output = McLibFix(New McVersion(VersionFolder))
|
Task.Output = McLibFix(New McVersion(VersionFolder))
|
||||||
End Sub) With {.ProgressWeight = 1, .Show = False})
|
End Sub) With {.ProgressWeight = 1, .Show = False})
|
||||||
@@ -271,7 +272,7 @@ pause"
|
|||||||
Loaders.Add(New LoaderDownload("下载服务端文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
Loaders.Add(New LoaderDownload("下载服务端文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
||||||
|
|
||||||
'启动
|
'启动
|
||||||
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 服务端下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 服务端下载", Loaders) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(Id)
|
Loader.Start(Id)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -316,7 +317,7 @@ pause"
|
|||||||
Loaders.Add(New LoaderDownload("下载核心 JAR 文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
Loaders.Add(New LoaderDownload("下载核心 JAR 文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
||||||
|
|
||||||
'启动
|
'启动
|
||||||
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 下载", Loaders) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(Id)
|
Loader.Start(Id)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -394,7 +395,7 @@ pause"
|
|||||||
Private Sub McDownloadOptiFineSave(DownloadInfo As DlOptiFineListEntry)
|
Private Sub McDownloadOptiFineSave(DownloadInfo As DlOptiFineListEntry)
|
||||||
Try
|
Try
|
||||||
Dim Id As String = DownloadInfo.NameVersion
|
Dim Id As String = DownloadInfo.NameVersion
|
||||||
Dim Target As String = SelectAs("选择保存位置", DownloadInfo.NameFile, "OptiFine Jar (*.jar)|*.jar")
|
Dim Target As String = SelectSaveFile("选择保存位置", DownloadInfo.NameFile, "OptiFine Jar (*.jar)|*.jar")
|
||||||
If Not Target.Contains("\") Then Exit Sub
|
If Not Target.Contains("\") Then Exit Sub
|
||||||
|
|
||||||
'重复任务检查
|
'重复任务检查
|
||||||
@@ -404,7 +405,7 @@ pause"
|
|||||||
Exit Sub
|
Exit Sub
|
||||||
Next
|
Next
|
||||||
|
|
||||||
Dim Loader As New LoaderCombo(Of DlOptiFineListEntry)("OptiFine " & DownloadInfo.NameDisplay & " 下载", McDownloadOptiFineSaveLoader(DownloadInfo, Target)) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader As New LoaderCombo(Of DlOptiFineListEntry)("OptiFine " & DownloadInfo.NameDisplay & " 下载", McDownloadOptiFineSaveLoader(DownloadInfo, Target)) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(DownloadInfo)
|
Loader.Start(DownloadInfo)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -454,7 +455,7 @@ pause"
|
|||||||
.CreateNoWindow = True,
|
.CreateNoWindow = True,
|
||||||
.RedirectStandardError = True,
|
.RedirectStandardError = True,
|
||||||
.RedirectStandardOutput = True,
|
.RedirectStandardOutput = True,
|
||||||
.WorkingDirectory = BaseMcFolderHome
|
.WorkingDirectory = ShortenPath(BaseMcFolderHome)
|
||||||
}
|
}
|
||||||
If Info.EnvironmentVariables.ContainsKey("appdata") Then
|
If Info.EnvironmentVariables.ContainsKey("appdata") Then
|
||||||
Info.EnvironmentVariables("appdata") = BaseMcFolderHome
|
Info.EnvironmentVariables("appdata") = BaseMcFolderHome
|
||||||
@@ -857,7 +858,7 @@ Retry:
|
|||||||
Private Sub McDownloadLiteLoaderSave(DownloadInfo As DlLiteLoaderListEntry)
|
Private Sub McDownloadLiteLoaderSave(DownloadInfo As DlLiteLoaderListEntry)
|
||||||
Try
|
Try
|
||||||
Dim Id As String = DownloadInfo.Inherit
|
Dim Id As String = DownloadInfo.Inherit
|
||||||
Dim Target As String = SelectAs("选择保存位置", DownloadInfo.FileName.Replace("-SNAPSHOT", ""), "LiteLoader 安装器 (*.jar)|*.jar")
|
Dim Target As String = SelectSaveFile("选择保存位置", DownloadInfo.FileName.Replace("-SNAPSHOT", ""), "LiteLoader 安装器 (*.jar)|*.jar")
|
||||||
If Not Target.Contains("\") Then Exit Sub
|
If Not Target.Contains("\") Then Exit Sub
|
||||||
|
|
||||||
'重复任务检查
|
'重复任务检查
|
||||||
@@ -893,7 +894,7 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
Loaders.Add(New LoaderDownload("下载主文件", New List(Of NetFile) From {New NetFile(Address.ToArray, Target, New FileChecker(MinSize:=1024 * 1024))}) With {.ProgressWeight = 15})
|
Loaders.Add(New LoaderDownload("下载主文件", New List(Of NetFile) From {New NetFile(Address.ToArray, Target, New FileChecker(MinSize:=1024 * 1024))}) With {.ProgressWeight = 15})
|
||||||
'启动
|
'启动
|
||||||
Dim Loader As New LoaderCombo(Of DlLiteLoaderListEntry)("LiteLoader " & Id & " 安装器下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader As New LoaderCombo(Of DlLiteLoaderListEntry)("LiteLoader " & Id & " 安装器下载", Loaders) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(DownloadInfo)
|
Loader.Start(DownloadInfo)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -1037,7 +1038,7 @@ Retry:
|
|||||||
|
|
||||||
Public Sub McDownloadForgelikeSave(Info As DlForgelikeEntry)
|
Public Sub McDownloadForgelikeSave(Info As DlForgelikeEntry)
|
||||||
Try
|
Try
|
||||||
Dim Target As String = SelectAs("选择保存位置", $"{Info.LoaderName}-{Info.Inherit}-{Info.VersionName}.{Info.FileExtension}",
|
Dim Target As String = SelectSaveFile("选择保存位置", $"{Info.LoaderName}-{Info.Inherit}-{Info.VersionName}.{Info.FileExtension}",
|
||||||
$"{Info.LoaderName} 安装器 (*.{Info.FileExtension})|*.{Info.FileExtension}")
|
$"{Info.LoaderName} 安装器 (*.{Info.FileExtension})|*.{Info.FileExtension}")
|
||||||
Dim DisplayName As String = $"{Info.LoaderName} {Info.Inherit} - {Info.VersionName}"
|
Dim DisplayName As String = $"{Info.LoaderName} {Info.Inherit} - {Info.VersionName}"
|
||||||
If Not Target.Contains("\") Then Exit Sub
|
If Not Target.Contains("\") Then Exit Sub
|
||||||
@@ -1072,7 +1073,7 @@ Retry:
|
|||||||
Loaders.Add(New LoaderDownload("下载主文件", Files) With {.ProgressWeight = 6})
|
Loaders.Add(New LoaderDownload("下载主文件", Files) With {.ProgressWeight = 6})
|
||||||
|
|
||||||
'启动
|
'启动
|
||||||
Dim Loader = New LoaderCombo(Of DlForgelikeEntry)(DisplayName & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader = New LoaderCombo(Of DlForgelikeEntry)(DisplayName & " 下载", Loaders) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(Info)
|
Loader.Start(Info)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -1339,7 +1340,7 @@ Retry:
|
|||||||
If Json("data") IsNot Nothing AndAlso Json("data")("MOJMAPS") IsNot Nothing Then
|
If Json("data") IsNot Nothing AndAlso Json("data")("MOJMAPS") IsNot Nothing Then
|
||||||
'下载原版 Json 文件
|
'下载原版 Json 文件
|
||||||
Task.Progress = 0.4
|
Task.Progress = 0.4
|
||||||
Dim RawJson As JObject = GetJson(NetGetCodeByDownload(DlSourceLauncherOrMetaGet(DlClientListGet(Inherit)), IsJson:=True))
|
Dim RawJson As JObject = GetJson(NetGetCodeByLoader(DlSourceLauncherOrMetaGet(DlClientListGet(Inherit)), IsJson:=True))
|
||||||
'[net.minecraft:client:1.17.1-20210706.113038:mappings@txt] 或 @tsrg]
|
'[net.minecraft:client:1.17.1-20210706.113038:mappings@txt] 或 @tsrg]
|
||||||
Dim OriginalName As String = Json("data")("MOJMAPS")("client").ToString.Trim("[]".ToCharArray()).BeforeFirst("@")
|
Dim OriginalName As String = Json("data")("MOJMAPS")("client").ToString.Trim("[]".ToCharArray()).BeforeFirst("@")
|
||||||
Dim Address = McLibGet(OriginalName).Replace(".jar", "-mappings." & Json("data")("MOJMAPS")("client").ToString.Trim("[]".ToCharArray()).Split("@")(1))
|
Dim Address = McLibGet(OriginalName).Replace(".jar", "-mappings." & Json("data")("MOJMAPS")("client").ToString.Trim("[]".ToCharArray()).Split("@")(1))
|
||||||
@@ -1641,7 +1642,7 @@ Retry:
|
|||||||
RunInNewThread(Sub()
|
RunInNewThread(Sub()
|
||||||
Try
|
Try
|
||||||
Log("[Download] 刷新 Forge 推荐版本缓存开始")
|
Log("[Download] 刷新 Forge 推荐版本缓存开始")
|
||||||
Dim Result As String = NetGetCodeByDownload("https://bmclapi2.bangbang93.com/forge/promos")
|
Dim Result As String = NetGetCodeByLoader("https://bmclapi2.bangbang93.com/forge/promos")
|
||||||
If Result.Length < 1000 Then Throw New Exception("获取的结果过短(" & Result & ")")
|
If Result.Length < 1000 Then Throw New Exception("获取的结果过短(" & Result & ")")
|
||||||
Dim ResultJson As JContainer = GetJson(Result)
|
Dim ResultJson As JContainer = GetJson(Result)
|
||||||
'获取所有推荐版本列表
|
'获取所有推荐版本列表
|
||||||
@@ -1789,7 +1790,7 @@ Retry:
|
|||||||
Dim Url As String = DownloadInfo("url").ToString
|
Dim Url As String = DownloadInfo("url").ToString
|
||||||
Dim FileName As String = GetFileNameFromPath(Url)
|
Dim FileName As String = GetFileNameFromPath(Url)
|
||||||
Dim Version As String = GetFileNameFromPath(DownloadInfo("version").ToString)
|
Dim Version As String = GetFileNameFromPath(DownloadInfo("version").ToString)
|
||||||
Dim Target As String = SelectAs("选择保存位置", FileName, "Fabric 安装器 (*.jar)|*.jar")
|
Dim Target As String = SelectSaveFile("选择保存位置", FileName, "Fabric 安装器 (*.jar)|*.jar")
|
||||||
If Not Target.Contains("\") Then Exit Sub
|
If Not Target.Contains("\") Then Exit Sub
|
||||||
|
|
||||||
'重复任务检查
|
'重复任务检查
|
||||||
@@ -1807,7 +1808,7 @@ Retry:
|
|||||||
Address.Add(Url)
|
Address.Add(Url)
|
||||||
Loaders.Add(New LoaderDownload("下载主文件", New List(Of NetFile) From {New NetFile(Address.ToArray, Target, New FileChecker(MinSize:=1024 * 64))}) With {.ProgressWeight = 15})
|
Loaders.Add(New LoaderDownload("下载主文件", New List(Of NetFile) From {New NetFile(Address.ToArray, Target, New FileChecker(MinSize:=1024 * 64))}) With {.ProgressWeight = 15})
|
||||||
'启动
|
'启动
|
||||||
Dim Loader As New LoaderCombo(Of JObject)("Fabric " & Version & " 安装器下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader As New LoaderCombo(Of JObject)("Fabric " & Version & " 安装器下载", Loaders) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(DownloadInfo)
|
Loader.Start(DownloadInfo)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -1974,6 +1975,20 @@ Retry:
|
|||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 在加载器状态改变后显示一条提示。
|
||||||
|
''' 不会进行任何其他操作。
|
||||||
|
''' </summary>
|
||||||
|
Public Sub LoaderStateChangedHintOnly(Loader)
|
||||||
|
Select Case Loader.State
|
||||||
|
Case LoadState.Finished
|
||||||
|
Hint(Loader.Name & "成功!", HintType.Finish)
|
||||||
|
Case LoadState.Failed
|
||||||
|
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
|
||||||
|
Case LoadState.Aborted
|
||||||
|
Hint(Loader.Name & "已取消!", HintType.Info)
|
||||||
|
End Select
|
||||||
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 安装加载器状态改变后进行提示和重载文件夹列表的方法。
|
''' 安装加载器状态改变后进行提示和重载文件夹列表的方法。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@@ -1992,21 +2007,6 @@ Retry:
|
|||||||
McInstallFailedClearFolder(Loader)
|
McInstallFailedClearFolder(Loader)
|
||||||
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
|
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
|
||||||
''' 安装加载器状态改变后进行提示的方法。它不会在失败时删除文件夹,也不会刷新 MC 文件夹。
|
|
||||||
''' </summary>
|
|
||||||
Public Sub DownloadStateSave(Loader)
|
|
||||||
Select Case Loader.State
|
|
||||||
Case LoadState.Finished
|
|
||||||
Hint(Loader.Name & "成功!", HintType.Finish)
|
|
||||||
Case LoadState.Failed
|
|
||||||
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
|
|
||||||
Case LoadState.Aborted
|
|
||||||
Hint(Loader.Name & "已取消!", HintType.Info)
|
|
||||||
Case LoadState.Loading
|
|
||||||
Exit Sub '不重新加载版本列表
|
|
||||||
End Select
|
|
||||||
End Sub
|
|
||||||
Public Sub McInstallFailedClearFolder(Loader)
|
Public Sub McInstallFailedClearFolder(Loader)
|
||||||
Try
|
Try
|
||||||
Thread.Sleep(1000) '防止存在尚未完全释放的文件,导致清理失败(例如整合包安装)
|
Thread.Sleep(1000) '防止存在尚未完全释放的文件,导致清理失败(例如整合包安装)
|
||||||
@@ -2053,26 +2053,12 @@ Retry:
|
|||||||
''' <exception cref="CancelledException" />
|
''' <exception cref="CancelledException" />
|
||||||
Public Function McInstallLoader(Request As McInstallRequest, Optional DontFixLibraries As Boolean = False) As List(Of LoaderBase)
|
Public Function McInstallLoader(Request As McInstallRequest, Optional DontFixLibraries As Boolean = False) As List(Of LoaderBase)
|
||||||
'获取缓存目录
|
'获取缓存目录
|
||||||
Dim PathInstallTemp As String
|
Dim TempMcFolder As String = RequestTaskTempFolder(
|
||||||
If PathTemp.Contains(" ") AndAlso (Request.OptiFineEntry IsNot Nothing OrElse Request.ForgeEntry IsNot Nothing OrElse Request.NeoForgeEntry IsNot Nothing) Then
|
PathTemp.Contains(" ") AndAlso '要求路径不包含空格
|
||||||
PathInstallTemp = OsDrive & "ProgramData\PCL\Install\"
|
(Request.OptiFineEntry IsNot Nothing OrElse Request.ForgeEntry IsNot Nothing OrElse Request.NeoForgeEntry IsNot Nothing))
|
||||||
Else
|
|
||||||
PathInstallTemp = PathTemp & "Install\"
|
|
||||||
End If
|
|
||||||
|
|
||||||
'清理缓存
|
|
||||||
Try
|
|
||||||
If IsInstallTempCleared Then Exit Try
|
|
||||||
IsInstallTempCleared = True
|
|
||||||
DeleteDirectory(PathInstallTemp, True)
|
|
||||||
Log("[Download] 已清理合并安装缓存")
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "清理合并安装缓存失败")
|
|
||||||
End Try
|
|
||||||
|
|
||||||
'获取参数
|
'获取参数
|
||||||
Dim OutputFolder As String = PathMcFolder & "versions\" & Request.TargetVersionName & "\"
|
Dim OutputFolder As String = PathMcFolder & "versions\" & Request.TargetVersionName & "\"
|
||||||
Dim TempMcFolder As String = PathInstallTemp & Request.TargetVersionName.GetHashCode() & "\"
|
|
||||||
If Directory.Exists(TempMcFolder) Then DeleteDirectory(TempMcFolder)
|
If Directory.Exists(TempMcFolder) Then DeleteDirectory(TempMcFolder)
|
||||||
Dim OptiFineFolder As String = Nothing
|
Dim OptiFineFolder As String = Nothing
|
||||||
If Request.OptiFineVersion IsNot Nothing Then
|
If Request.OptiFineVersion IsNot Nothing Then
|
||||||
@@ -2188,7 +2174,6 @@ Retry:
|
|||||||
'总加载器
|
'总加载器
|
||||||
Return LoaderList
|
Return LoaderList
|
||||||
End Function
|
End Function
|
||||||
Private IsInstallTempCleared As Boolean = False
|
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 将多个版本 Json 进行合并,如果目标已存在则直接覆盖。失败会抛出异常。
|
''' 将多个版本 Json 进行合并,如果目标已存在则直接覆盖。失败会抛出异常。
|
||||||
|
|||||||
@@ -92,7 +92,6 @@
|
|||||||
NewButton.LabText.Margin = New Thickness(-2, 0, 8, 0)
|
NewButton.LabText.Margin = New Thickness(-2, 0, 8, 0)
|
||||||
AddHandler NewButton.Check,
|
AddHandler NewButton.Check,
|
||||||
Sub(sender As MyRadioButton, raiseByMouse As Boolean)
|
Sub(sender As MyRadioButton, raiseByMouse As Boolean)
|
||||||
PanScroll.ScrollToHome()
|
|
||||||
VersionFilter = If(sender.Text = "全部", Nothing, sender.Text)
|
VersionFilter = If(sender.Text = "全部", Nothing, sender.Text)
|
||||||
UpdateFilterResult()
|
UpdateFilterResult()
|
||||||
End Sub
|
End Sub
|
||||||
@@ -379,7 +378,7 @@
|
|||||||
Sub()
|
Sub()
|
||||||
'弹窗要求选择保存位置
|
'弹窗要求选择保存位置
|
||||||
Dim Target As String
|
Dim Target As String
|
||||||
Target = SelectAs("选择保存位置", FileName,
|
Target = SelectSaveFile("选择保存位置", FileName,
|
||||||
Desc & "文件|" &
|
Desc & "文件|" &
|
||||||
If(Project.Type = CompType.Mod,
|
If(Project.Type = CompType.Mod,
|
||||||
If(File.FileName.EndsWith(".litemod"), "*.litemod", "*.jar"),
|
If(File.FileName.EndsWith(".litemod"), "*.litemod", "*.jar"),
|
||||||
@@ -391,7 +390,7 @@
|
|||||||
Dim Loaders As New List(Of LoaderBase)
|
Dim Loaders As New List(Of LoaderBase)
|
||||||
Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.ToNetFile(Target)}) With {.ProgressWeight = 6, .Block = True})
|
Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.ToNetFile(Target)}) With {.ProgressWeight = 6, .Block = True})
|
||||||
'启动
|
'启动
|
||||||
Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf LoaderStateChangedHintOnly}
|
||||||
Loader.Start(1)
|
Loader.Start(1)
|
||||||
LoaderTaskbarAdd(Loader)
|
LoaderTaskbarAdd(Loader)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
@@ -410,7 +409,7 @@
|
|||||||
OpenWebsite("https://www.mcmod.cn/class/" & Project.WikiId & ".html")
|
OpenWebsite("https://www.mcmod.cn/class/" & Project.WikiId & ".html")
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BtnIntroCopy_Click(sender As Object, e As EventArgs) Handles BtnIntroCopy.Click
|
Private Sub BtnIntroCopy_Click(sender As Object, e As EventArgs) Handles BtnIntroCopy.Click
|
||||||
ClipboardSet(CompItem.LabTitle.Text)
|
ClipboardSet(CompItem.LabTitle.Text & CompItem.LabTitleRaw.Text)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -64,9 +64,11 @@
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
'如果在选择页面按了刷新键,选择页的东西可能会由于动画被隐藏,但不会由于加载结束而再次显示,因此这里需要手动恢复
|
'如果在选择页面按了刷新键,选择页的东西可能会由于动画被隐藏,但不会由于加载结束而再次显示,因此这里需要手动恢复
|
||||||
For Each Card In GetAllAnimControls(PanSelect)
|
For Each Control In GetAllAnimControls(PanSelect)
|
||||||
Card.Opacity = 1
|
Control.Opacity = 1
|
||||||
Card.RenderTransform = New TranslateTransform
|
If Control.RenderTransform Is Nothing OrElse TypeOf Control.RenderTransform Is TranslateTransform Then
|
||||||
|
Control.RenderTransform = New TranslateTransform
|
||||||
|
End If
|
||||||
Next
|
Next
|
||||||
|
|
||||||
'启动 Forge 加载
|
'启动 Forge 加载
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
Exit Sub
|
Exit Sub
|
||||||
End If
|
End If
|
||||||
Try
|
Try
|
||||||
Dim FileAddress As String = SelectAs("选取保存皮肤的位置", GetFileNameFromPath(Address), "皮肤图片文件(*.png)|*.png")
|
Dim FileAddress As String = SelectSaveFile("选取保存皮肤的位置", GetFileNameFromPath(Address), "皮肤图片文件(*.png)|*.png")
|
||||||
If FileAddress.Contains("\") Then
|
If FileAddress.Contains("\") Then
|
||||||
File.Delete(FileAddress)
|
File.Delete(FileAddress)
|
||||||
If Address.StartsWith(PathImage) Then
|
If Address.StartsWith(PathImage) Then
|
||||||
|
|||||||
@@ -53,10 +53,10 @@
|
|||||||
'自动整合包安装
|
'自动整合包安装
|
||||||
If PackInstallPath IsNot Nothing Then
|
If PackInstallPath IsNot Nothing Then
|
||||||
Try
|
Try
|
||||||
Dim InstallLoader = ModpackInstall(PackInstallPath, GetFolderNameFromPath(Path))
|
Dim InstallLoader = ModpackInstall(PackInstallPath)
|
||||||
Log("[Launch] 自动安装整合包已开始:" & PackInstallPath)
|
Log("[Launch] 自动安装整合包已开始:" & PackInstallPath)
|
||||||
InstallLoader.WaitForExit()
|
InstallLoader.WaitForExit()
|
||||||
If InstallLoader.State = LoadState.Finished Then
|
If InstallLoader.State = LoadState.Finished AndAlso File.Exists(PackInstallPath) Then
|
||||||
Log("[Launch] 自动安装整合包成功,删除安装包:" & PackInstallPath)
|
Log("[Launch] 自动安装整合包成功,删除安装包:" & PackInstallPath)
|
||||||
File.Delete(PackInstallPath)
|
File.Delete(PackInstallPath)
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ Download:
|
|||||||
PanCustom.Children.Add(GetObjectFromXML(Content))
|
PanCustom.Children.Add(GetObjectFromXML(Content))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log("[Page] 加载失败的自定义主页内容:" & vbCrLf & Content)
|
Log("[Page] 加载失败的自定义主页内容:" & vbCrLf & Content)
|
||||||
If MyMsgBox($"自定义主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{ex.Message}", "加载自定义主页失败", "重试", "取消") = 1 Then
|
If MyMsgBox($"自定义主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{GetExceptionSummary(ex)}", "加载自定义主页失败", "重试", "取消") = 1 Then
|
||||||
GoTo Refresh '防止 SyncLock 死锁
|
GoTo Refresh '防止 SyncLock 死锁
|
||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ Retry:
|
|||||||
'获取新皮肤地址
|
'获取新皮肤地址
|
||||||
Log("[Skin] 皮肤修改返回值:" & vbCrLf & Result)
|
Log("[Skin] 皮肤修改返回值:" & vbCrLf & Result)
|
||||||
Dim ResultJson As JObject = GetJson(Result)
|
Dim ResultJson As JObject = GetJson(Result)
|
||||||
|
If ResultJson.ContainsKey("errorMessage") Then Throw New Exception(ResultJson("errorMessage").ToString) '#5309
|
||||||
For Each Skin As JObject In ResultJson("skins")
|
For Each Skin As JObject In ResultJson("skins")
|
||||||
If Skin("state").ToString = "ACTIVE" Then
|
If Skin("state").ToString = "ACTIVE" Then
|
||||||
MySkin.ReloadCache(Skin("url"))
|
MySkin.ReloadCache(Skin("url"))
|
||||||
|
|||||||
@@ -104,120 +104,195 @@
|
|||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
<local:MyCard Margin="0,0,0,15" Title="赞助者">
|
<local:MyCard Margin="0,0,0,15" Title="赞助者">
|
||||||
<StackPanel Margin="25,40,10,20">
|
<StackPanel Margin="25,40,10,20">
|
||||||
<TextBlock HorizontalAlignment="Left" Text="以下是 2024 年 12 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
|
<TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 1 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
|
||||||
<WrapPanel Margin="0,0,0,10">
|
<WrapPanel Margin="0,0,0,10">
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="是阿改哦" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="dingyaa1" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="李白" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Xpinger" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="执念" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="张一凡" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="yu" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="quer" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="SHALLOW_SUMMER" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="AnLingHai" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="The_Ren" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="阿彪" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="汤圆不胖" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="凑热闹的顶针" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="德凯" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="凌肆玖" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="破星辰只寻你" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="飞猫FlyingCat" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Jethro_Y" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="浩天" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="redston_8788" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="羽毛球awa" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="maximum zombie" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="可塔Kita" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="染桐" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="飞蛙" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="团长" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="妙天纸袋君" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="YJL" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="天水" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Anonymism" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="佳明" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小创世peng" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="炽热的钢铁" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小邓子" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="QianYirui" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Korica" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="司徒牺痕" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="流萤" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="神愆" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="44379" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="cool" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="白凌" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="弓虽女干亻尔女马" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="是雾霭啊233" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小豆" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="整天摸鱼的Dx" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="LEVI" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="虚空" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Mako" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="禾鳥" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="MILA_326" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="韩大仙尊" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="僭苏寒" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="福渡恒" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Yu氚" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="限制_limited" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="麦克斯韦妖" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="承挨" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="略略略zbc" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="CYOSK" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Atmoon" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="DBTB" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Bongocat1337" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="AD_AIR" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="KenshenLove" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="晚柠" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="H.Jane" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="tanolin" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="乐高漫画君" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="白起床了" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="ClassicNT" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="土地的誓言" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="nanamik" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="阿宸大大" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="渡边贤人" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="千羽星语" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="喵~" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="路过的没心人" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="牢轮" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Littleduan" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Sta_Rain_Wx" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="大西几" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="阿道" />
|
<TextBlock Width="120" Margin="0,1.5" Text="阿道" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Smile_Cindy" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Yi_Zhi" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="耿一闲" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="我是露娜的√" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="EagleEye" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Cherry林" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="心海鱼豆腐" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="墨染" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="物流2051 朱叶" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="二月霜" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="祈喵" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="阿斯塔" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="夜长梦梦多" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="汐洺ao" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="塞巴斯蒂安" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="琅山先生" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="123" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Alans1gn" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="迷茫LTQ" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Raveniume" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="D六菌" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="WHITE" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="warmaQwQ" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Haroinfather" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="赫乐瑢音" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="陈坤城" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="史莱姆SAMA" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="ciallp" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="步衷" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="雨沫" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Tabula" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="黑宇" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="awawa" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Yi_Joy" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="津竹捏" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="LinusWu" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="LizTtxs" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="徐正阳" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Nxvblack" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="夏弥·零" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="诗云白" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="danall" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="TySNow_" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="悲戚霜雪" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="GThistle-Frddy" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="INTOMETE." />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="千秋" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="原来这里是四宫啊" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="TianDLG" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="隐”" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="瑶龍龘" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小小" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="憨憨游云" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="名字要六个字" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="牢大是我" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="伊卡律泽斯" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="stars.夜冰" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="匿名用户" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Fancy" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="唯一白色" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="伊利丹的父亲" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="千星yousa" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Axet." />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Ares" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="ding_i" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="林逝a" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="wihz" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="11034" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="xi0st" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="空无" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Andywyl" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="g~m" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="雁枫" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="YX修行" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="雇佣兵v" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="背着氧气的鱼" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="......." />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="艾因·斯芬克斯" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="威宝" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="真言之归" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="奈斯特" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="青春没有售价,扣一复活牢大" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="GuZhuJing" />
|
<TextBlock Width="120" Margin="0,1.5" Text="GuZhuJing" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="情鼠啾啾" />
|
<TextBlock Width="120" Margin="0,1.5" Text="UKasumigaoka" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="蛇蛇W" />
|
<TextBlock Width="120" Margin="0,1.5" Text="梦不依" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="蜜汁青柠檬" />
|
<TextBlock Width="120" Margin="0,1.5" Text="绫波丽" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="纸先生" />
|
<TextBlock Width="120" Margin="0,1.5" Text="桃子" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="CLOUD079" />
|
<TextBlock Width="120" Margin="0,1.5" Text="方村明" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="xiaoioax" />
|
<TextBlock Width="120" Margin="0,1.5" Text="苏离" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="CH土块警长" />
|
<TextBlock Width="120" Margin="0,1.5" Text="EnergyBeta" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="CHENJUN551" />
|
<TextBlock Width="120" Margin="0,1.5" Text="邵寒洛" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Ezzo" />
|
<TextBlock Width="120" Margin="0,1.5" Text="雨下雫" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="夜抱?吃火炉" />
|
<TextBlock Width="120" Margin="0,1.5" Text="HoshinoAlice" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Rn_Og" />
|
<TextBlock Width="120" Margin="0,1.5" Text="1121" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="六个芙桃" />
|
<TextBlock Width="120" Margin="0,1.5" Text="1742" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="月月月子喵" />
|
<TextBlock Width="120" Margin="0,1.5" Text="奥顿" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Kuang3lian" />
|
<TextBlock Width="120" Margin="0,1.5" Text="LYSGBZL" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="烨芽" />
|
<TextBlock Width="120" Margin="0,1.5" Text="X_Lu" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="王ZEAN" />
|
<TextBlock Width="120" Margin="0,1.5" Text="细雪" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="CCYY" />
|
<TextBlock Width="120" Margin="0,1.5" Text="虎牙该隐" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="19921454753" />
|
<TextBlock Width="120" Margin="0,1.5" Text="坎儿井窖藏咸鱼" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="房非缝" />
|
<TextBlock Width="120" Margin="0,1.5" Text="ClarkeTAT" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Ashburn" />
|
<TextBlock Width="120" Margin="0,1.5" Text="matin" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="绯念" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="PseudoStar" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="符之渡尘" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="singegg" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="白泽麒麟" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="拥抱烟霞不太专心" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="风起" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="白羽" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="所求化如愿" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="小小抱枕" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Horrizen" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="浮光" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="songhy" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="任我被回忆捉弄" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="飘飘ppiao" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="EnerG4" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="tiredl" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="有梦想的罐头" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Hasturnyth" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="犇犇" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="初晴" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="just ugly" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="宇ovo" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="斑马" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="? AXH" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="璃音233" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="凌源羡辰" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="雨巷" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="NoDoors" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="幕若" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="星期六" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="感念" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="凉城uwu" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="栀玖夕夏" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="X11aou" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Bobo_s1" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="玛卡巴卡" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="鸱影" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="一曲明清" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="曹予" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="kk" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="XDDDD" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="梵星" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="梦师A" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="傻傻" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="西柚味儿小猫" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="樱花成雨(烟雨)" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="瑞云生" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="桑什么鸟" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="桂花" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="stone devil" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="乄心" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="渡白" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="鬼鬼" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="菠萝飞走惹" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="陆山君" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="张无忧" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="缄默" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="影铉" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="酸菜鱼鱼" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="哈哈哈嗝" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="鸡逆苔煤" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="许柯" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ChuaLinyZ" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="墨依小夕" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="柚可喝" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="m1350096708" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="猫南北丶QAQ" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="此时彼刻" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Yukino" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Paveway" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="明月栞那" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="默默无为" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="屑喵" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="枫雪" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="孩子气" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="纳西妲的狗" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Barb" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="小镰刀菌" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="DiceA" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="朴振澈" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="YinYang_SHI" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="网底游鱼" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="xc_xiaoxian" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="playermin" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="祈听神命" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="嘎子" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="柠檬爱恰柠檬水" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="游戏人生" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Lunaunde" />
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<Grid Height="35">
|
<Grid Height="35">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -171,6 +171,9 @@
|
|||||||
Log(ex, "添加文件夹失败(" & NewFolder & ")", LogLevel.Feedback)
|
Log(ex, "添加文件夹失败(" & NewFolder & ")", LogLevel.Feedback)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
''' <summary>
|
||||||
|
''' 将指定文件夹添加到 Minecraft 文件夹列表,并选中它。
|
||||||
|
''' </summary>
|
||||||
Public Shared Sub AddFolder(FolderPath As String, DisplayName As String, ShowHint As Boolean)
|
Public Shared Sub AddFolder(FolderPath As String, DisplayName As String, ShowHint As Boolean)
|
||||||
RunInThread(
|
RunInThread(
|
||||||
Sub()
|
Sub()
|
||||||
@@ -328,7 +331,8 @@
|
|||||||
Next
|
Next
|
||||||
Setup.Set("LaunchFolders", If(Not Folders.Any(), "", Join(Folders.ToArray, "|")))
|
Setup.Set("LaunchFolders", If(Not Folders.Any(), "", Join(Folders.ToArray, "|")))
|
||||||
End If
|
End If
|
||||||
RunInNewThread(Sub()
|
RunInNewThread(
|
||||||
|
Sub()
|
||||||
'删除文件夹
|
'删除文件夹
|
||||||
Try
|
Try
|
||||||
Hint("正在" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Info)
|
Hint("正在" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Info)
|
||||||
@@ -344,7 +348,7 @@
|
|||||||
End Sub, "Folder Delete " & GetUuid(), ThreadPriority.BelowNormal)
|
End Sub, "Folder Delete " & GetUuid(), ThreadPriority.BelowNormal)
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub Open_Click(sender As Object, e As RoutedEventArgs)
|
Public Sub Open_Click(sender As Object, e As RoutedEventArgs)
|
||||||
OpenExplorer("""" & CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Info & """")
|
OpenExplorer(CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Info)
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub Refresh_Click(sender As Object, e As RoutedEventArgs)
|
Public Sub Refresh_Click(sender As Object, e As RoutedEventArgs)
|
||||||
Dim Data As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
|
Dim Data As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
|
||||||
|
|||||||
@@ -20,11 +20,13 @@
|
|||||||
{"HintBuy", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"HintBuy", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
{"HintClearRubbish", New SetupEntry(0, Source:=SetupSource.Registry)},
|
{"HintClearRubbish", New SetupEntry(0, Source:=SetupSource.Registry)},
|
||||||
{"HintUpdateMod", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"HintUpdateMod", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
|
{"HintCustomCommand", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
{"TestSetupReader", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"TestSetupReader", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"SystemEula", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"SystemEula", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
{"SystemCount", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
{"SystemCount", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"SystemLaunchCount", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
{"SystemLaunchCount", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"SystemLastVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
{"SystemLastVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
{"SystemHighestSavedBetaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"SystemHighestBetaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
{"SystemHighestBetaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"SystemHighestAlphaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
{"SystemHighestAlphaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"SystemSetupVersionReg", New SetupEntry(VersionSetup, Source:=SetupSource.Registry)},
|
{"SystemSetupVersionReg", New SetupEntry(VersionSetup, Source:=SetupSource.Registry)},
|
||||||
@@ -37,6 +39,7 @@
|
|||||||
{"SystemSystemCache", New SetupEntry("", Source:=SetupSource.Registry)},
|
{"SystemSystemCache", New SetupEntry("", Source:=SetupSource.Registry)},
|
||||||
{"SystemSystemUpdate", New SetupEntry(0)},
|
{"SystemSystemUpdate", New SetupEntry(0)},
|
||||||
{"SystemSystemActivity", New SetupEntry(0)},
|
{"SystemSystemActivity", New SetupEntry(0)},
|
||||||
|
{"CacheExportConfig", New SetupEntry("", Source:=SetupSource.Registry)},
|
||||||
{"CacheSavedPageUrl", New SetupEntry("", Source:=SetupSource.Registry)},
|
{"CacheSavedPageUrl", New SetupEntry("", Source:=SetupSource.Registry)},
|
||||||
{"CacheSavedPageVersion", New SetupEntry("", Source:=SetupSource.Registry)},
|
{"CacheSavedPageVersion", New SetupEntry("", Source:=SetupSource.Registry)},
|
||||||
{"CacheMsOAuthRefresh", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheMsOAuthRefresh", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
Private Sub BtnSkinDelete_Click(sender As Object, e As EventArgs) Handles BtnSkinDelete.Click
|
Private Sub BtnSkinDelete_Click(sender As Object, e As EventArgs) Handles BtnSkinDelete.Click
|
||||||
Try
|
Try
|
||||||
File.Delete(PathAppdata & "CustomSkin.png")
|
File.Delete(PathAppdata & "CustomSkin.png")
|
||||||
RadioSkinType0.SetChecked(True, True, True)
|
RadioSkinType0.SetChecked(True, True)
|
||||||
Hint("离线皮肤已清空!", HintType.Finish)
|
Hint("离线皮肤已清空!", HintType.Finish)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "清空离线皮肤失败", LogLevel.Msgbox)
|
Log(ex, "清空离线皮肤失败", LogLevel.Msgbox)
|
||||||
@@ -194,11 +194,11 @@
|
|||||||
If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.Setup OrElse FrmSetupLeft.PageID <> FormMain.PageSubType.SetupLaunch Then Exit Sub
|
If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.Setup OrElse FrmSetupLeft.PageID <> FormMain.PageSubType.SetupLaunch Then Exit Sub
|
||||||
'获取内存情况
|
'获取内存情况
|
||||||
Dim RamGame As Double = GetRam(McVersionCurrent, False)
|
Dim RamGame As Double = GetRam(McVersionCurrent, False)
|
||||||
Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
|
Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024, 1)
|
||||||
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
|
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024, 1)
|
||||||
Dim RamGameActual As Double = Math.Min(RamGame, RamAvailable)
|
Dim RamGameActual As Double = Math.Round(Math.Min(RamGame, RamAvailable), 5)
|
||||||
Dim RamUsed As Double = RamTotal - RamAvailable
|
Dim RamUsed As Double = Math.Round(RamTotal - RamAvailable, 5)
|
||||||
Dim RamEmpty As Double = Math.Round(MathClamp(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10
|
Dim RamEmpty As Double = Math.Round(MathClamp(RamTotal - RamUsed - RamGame, 0, 1000), 1)
|
||||||
'设置最大可用内存
|
'设置最大可用内存
|
||||||
If RamTotal <= 1.5 Then
|
If RamTotal <= 1.5 Then
|
||||||
SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1)
|
SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1)
|
||||||
|
|||||||
@@ -45,11 +45,6 @@
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub BtnHiperLog_Click(sender As Object, e As EventArgs) Handles BtnHiperLog.Click
|
Private Sub BtnHiperLog_Click(sender As Object, e As EventArgs) Handles BtnHiperLog.Click
|
||||||
If File.Exists(PageLinkHiper.PathHiper & "logs\hiper.log") Then
|
|
||||||
OpenExplorer("/select,""" & PageLinkHiper.PathHiper & "logs\hiper.log""")
|
|
||||||
Else
|
|
||||||
Hint("没有找到 HiPer 联机模块的日志!")
|
|
||||||
End If
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -179,7 +179,7 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="标题栏文本" Margin="0,0,25,0" />
|
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="标题栏文本" Margin="0,0,25,0" />
|
||||||
<local:MyTextBox x:Name="TextLogoText" Tag="UiLogoText" Grid.Column="1" MaxLength="30" />
|
<local:MyTextBox x:Name="TextLogoText" Tag="UiLogoText" Grid.Column="1" MaxLength="100" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid x:Name="PanLogoChange" Margin="0,14,0,5" Height="35" Visibility="Collapsed">
|
<Grid x:Name="PanLogoChange" Margin="0,14,0,5" Height="35" Visibility="Collapsed">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
<local:MyComboBoxItem Content="PCL 主页市场(作者:凌云)" />
|
<local:MyComboBoxItem Content="PCL 主页市场(作者:凌云)" />
|
||||||
<local:MyComboBoxItem Content="PCL 新闻速报(作者:Joker2184)" />
|
<local:MyComboBoxItem Content="PCL 新闻速报(作者:Joker2184)" />
|
||||||
<local:MyComboBoxItem Content="PCL 新功能说明书(作者:WForst-Breeze)" />
|
<local:MyComboBoxItem Content="PCL 新功能说明书(作者:WForst-Breeze)" />
|
||||||
<local:MyComboBoxItem Content="OpenMCIM 仪表盘(作者:SALTWOOD)" />
|
<local:MyComboBoxItem Content="OpenMCIM 仪表盘(作者:SALTWOOD)" Visibility="Collapsed" />
|
||||||
<local:MyComboBoxItem Content="杂志主页(作者:CreeperIsASpy)" />
|
<local:MyComboBoxItem Content="杂志主页(作者:CreeperIsASpy)" />
|
||||||
</local:MyComboBox>
|
</local:MyComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -189,7 +189,7 @@
|
|||||||
|
|
||||||
'背景图片
|
'背景图片
|
||||||
Private Sub BtnUIBgOpen_Click(sender As Object, e As EventArgs) Handles BtnBackgroundOpen.Click
|
Private Sub BtnUIBgOpen_Click(sender As Object, e As EventArgs) Handles BtnBackgroundOpen.Click
|
||||||
OpenExplorer("""" & Path & "PCL\Pictures""")
|
OpenExplorer(Path & "PCL\Pictures\")
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BtnBackgroundRefresh_Click(sender As Object, e As EventArgs) Handles BtnBackgroundRefresh.Click
|
Private Sub BtnBackgroundRefresh_Click(sender As Object, e As EventArgs) Handles BtnBackgroundRefresh.Click
|
||||||
BackgroundRefresh(True, True)
|
BackgroundRefresh(True, True)
|
||||||
@@ -335,7 +335,7 @@ Refresh:
|
|||||||
Private Sub BtnLogoDelete_Click(sender As Object, e As EventArgs) Handles BtnLogoDelete.Click
|
Private Sub BtnLogoDelete_Click(sender As Object, e As EventArgs) Handles BtnLogoDelete.Click
|
||||||
Try
|
Try
|
||||||
File.Delete(Path & "PCL\Logo.png")
|
File.Delete(Path & "PCL\Logo.png")
|
||||||
RadioLogoType1.SetChecked(True, True, True)
|
RadioLogoType1.SetChecked(True, True)
|
||||||
Hint("标题栏图片已清空!", HintType.Finish)
|
Hint("标题栏图片已清空!", HintType.Finish)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "清空标题栏图片失败", LogLevel.Msgbox)
|
Log(ex, "清空标题栏图片失败", LogLevel.Msgbox)
|
||||||
@@ -344,7 +344,7 @@ Refresh:
|
|||||||
|
|
||||||
'背景音乐
|
'背景音乐
|
||||||
Private Sub BtnMusicOpen_Click(sender As Object, e As EventArgs) Handles BtnMusicOpen.Click
|
Private Sub BtnMusicOpen_Click(sender As Object, e As EventArgs) Handles BtnMusicOpen.Click
|
||||||
OpenExplorer("""" & Path & "PCL\Musics""")
|
OpenExplorer(Path & "PCL\Musics\")
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BtnMusicRefresh_Click(sender As Object, e As EventArgs) Handles BtnMusicRefresh.Click
|
Private Sub BtnMusicRefresh_Click(sender As Object, e As EventArgs) Handles BtnMusicRefresh.Click
|
||||||
MusicRefreshPlay(True)
|
MusicRefreshPlay(True)
|
||||||
@@ -407,7 +407,7 @@ Refresh:
|
|||||||
End If
|
End If
|
||||||
WriteFile(Path & "PCL\Custom.xaml", GetResources("Custom"))
|
WriteFile(Path & "PCL\Custom.xaml", GetResources("Custom"))
|
||||||
Hint("教学文件已生成!", HintType.Finish)
|
Hint("教学文件已生成!", HintType.Finish)
|
||||||
OpenExplorer("/select,""" & Path & "PCL\Custom.xaml""")
|
OpenExplorer(Path & "PCL\Custom.xaml")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "生成教学文件失败", LogLevel.Feedback)
|
Log(ex, "生成教学文件失败", LogLevel.Feedback)
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -5,117 +5,267 @@
|
|||||||
xmlns:System="clr-namespace:System;assembly=mscorlib"
|
xmlns:System="clr-namespace:System;assembly=mscorlib"
|
||||||
mc:Ignorable="d" x:Class="PageVersionExport"
|
mc:Ignorable="d" x:Class="PageVersionExport"
|
||||||
PanScroll="{Binding ElementName=PanBack}">
|
PanScroll="{Binding ElementName=PanBack}">
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
<local:MyPageRight.Resources>
|
||||||
<StackPanel Margin="25,10">
|
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
<local:MyHint Margin="0,10,0,0" IsWarn="False" Text="当前页面导出的整合包是 Modrinth 格式(.mrpack)。" />
|
</local:MyPageRight.Resources>
|
||||||
|
<Grid x:Name="PanAllBack">
|
||||||
<local:MyCard Margin="0,15" Title="导出预览">
|
<Grid.Resources>
|
||||||
<StackPanel Margin="25,38,15,15">
|
<Style TargetType="local:MyCheckBox">
|
||||||
<Grid Margin="-10,-5,10,0">
|
<Setter Property="Height" Value="26" />
|
||||||
<Grid.ColumnDefinitions>
|
</Style>
|
||||||
<ColumnDefinition Width="1*" />
|
</Grid.Resources>
|
||||||
<ColumnDefinition Width="150" />
|
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
||||||
</Grid.ColumnDefinitions>
|
<StackPanel Margin="25,10,25,65">
|
||||||
<Grid Margin="10,7,10,7" Name="PanDisplayItem" Grid.Column="0" />
|
<local:MyHint Margin="0,15,0,0" Text="受 Modrinth 整合包规范限制,导出的整合包中暂不包含 OptiFine。" IsWarn="False" x:Name="HintOptiFine" />
|
||||||
<local:MyButton x:Name="BtnExportExport" Grid.Column="1" HorizontalAlignment="Right"
|
<local:MyCard Margin="0,15">
|
||||||
Text="导出整合包" Width="150" Height="35" ColorType="Highlight" />
|
<Grid Margin="22,15,25,15">
|
||||||
</Grid>
|
|
||||||
<Grid Margin="0,5,10,5">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
|
|
||||||
<ColumnDefinition Width="1*" />
|
|
||||||
<ColumnDefinition Width="60" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="28" />
|
|
||||||
<RowDefinition Height="9" />
|
|
||||||
<RowDefinition Height="28" />
|
|
||||||
<!--<RowDefinition Height="9" />
|
|
||||||
<RowDefinition Height="28" />-->
|
|
||||||
<RowDefinition Height="9" />
|
|
||||||
<RowDefinition Height="28" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="整合包名称" Margin="0,0,25,0" />
|
|
||||||
<local:MyTextBox Grid.Row="0" x:Name="TbExportName" Grid.ColumnSpan="2" Grid.Column="1" MaxLength="100" ShowValidateResult="True" />
|
|
||||||
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="整合包版本" Margin="0,0,25,0" />
|
|
||||||
<local:MyTextBox Grid.Row="2" x:Name="TbExportVersion" HintText="1.0.0" Grid.ColumnSpan="2" Tag="VersionArgumentTitle" Grid.Column="1" MaxLength="100" />
|
|
||||||
<!--<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="图标" Margin="0,0,25,0" />
|
|
||||||
<local:MyComboBox x:Name="ComboDisplayLogo" Grid.Row="4" Grid.ColumnSpan="2" Grid.Column="1">
|
|
||||||
<local:MyComboBoxItem Content="自动" IsSelected="True" Tag="" />
|
|
||||||
<local:MyComboBoxItem x:Name="ItemDisplayLogoCustom" Content="自定义..." />
|
|
||||||
<local:MyComboBoxItem Content="圆石" Tag="pack://application:,,,/images/Blocks/CobbleStone.png" />
|
|
||||||
<local:MyComboBoxItem Content="命令方块" Tag="pack://application:,,,/images/Blocks/CommandBlock.png" />
|
|
||||||
<local:MyComboBoxItem Content="金块" Tag="pack://application:,,,/images/Blocks/GoldBlock.png" />
|
|
||||||
<local:MyComboBoxItem Content="草方块" Tag="pack://application:,,,/images/Blocks/Grass.png" />
|
|
||||||
<local:MyComboBoxItem Content="草径" Tag="pack://application:,,,/images/Blocks/GrassPath.png" />
|
|
||||||
<local:MyComboBoxItem Content="铁砧" Tag="pack://application:,,,/images/Blocks/Anvil.png" />
|
|
||||||
<local:MyComboBoxItem Content="红石块" Tag="pack://application:,,,/images/Blocks/RedstoneBlock.png" />
|
|
||||||
<local:MyComboBoxItem Content="红石灯(开)" Tag="pack://application:,,,/images/Blocks/RedstoneLampOn.png" />
|
|
||||||
<local:MyComboBoxItem Content="红石灯(关)" Tag="pack://application:,,,/images/Blocks/RedstoneLampOff.png" />
|
|
||||||
<local:MyComboBoxItem Content="鸡蛋" Tag="pack://application:,,,/images/Blocks/Egg.png" />
|
|
||||||
<local:MyComboBoxItem Content="布料(Fabric)" Tag="pack://application:,,,/images/Blocks/Fabric.png" />
|
|
||||||
<local:MyComboBoxItem Content="狐狸(NeoForge)" Tag="pack://application:,,,/images/Blocks/NeoForge.png" />
|
|
||||||
</local:MyComboBox>-->
|
|
||||||
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="描述" Margin="0,0,25,0" />
|
|
||||||
<local:MyTextBox Grid.Row="4" x:Name="TbExportDesc" Grid.ColumnSpan="2" Grid.Column="1" TextWrapping="Wrap" VerticalContentAlignment="Top" Padding="0,5" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
|
|
||||||
<local:MyCard x:Name="CardSwitch" Margin="0,0,0,15" Title="基础选项">
|
|
||||||
<StackPanel Margin="25,38,15,15">
|
|
||||||
<TextBlock x:Name="TbHint" Margin="0,1,0,1" Text="你可以在此勾选需要包含进整合包的文件或文件夹,其他文件或文件夹在高级选项添加。" TextWrapping="Wrap" />
|
|
||||||
<!-- 注意:以上 TextBlock 的 Text 属性可能会在代码中被改动。 -->
|
|
||||||
<Grid x:Name="PanCommonFiles">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="18" />
|
<ColumnDefinition Width="1*" />
|
||||||
<ColumnDefinition Width="1.7*" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="1.9*" />
|
<ColumnDefinition Width="0.3*" />
|
||||||
<ColumnDefinition Width="1.4*" />
|
|
||||||
<ColumnDefinition Width="1.0*" />
|
|
||||||
<ColumnDefinition Width="1.0*" />
|
|
||||||
<ColumnDefinition Width="1.0*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="4" />
|
<RowDefinition Height="28" />
|
||||||
<RowDefinition Height="30" />
|
|
||||||
<RowDefinition Height="30" />
|
|
||||||
<RowDefinition Height="30" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock Text="游戏配置" VerticalAlignment="Center" Grid.Column="0" Grid.Row="1" />
|
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="整合包名称" Margin="0,0,20,0" />
|
||||||
<local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="2" Text="服务器列表"
|
<local:MyTextBox Grid.Row="0" Grid.Column="1" x:Name="TextExportName" MaxLength="100" />
|
||||||
Tag="servers.dat" ToolTip="servers.dat 文件" />
|
<TextBlock Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="整合包版本" Margin="30,0,20,0" />
|
||||||
<local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="3" Text="Mod 配置"
|
<local:MyTextBox Grid.Row="0" Grid.Column="3" x:Name="TextExportVersion" Tag="VersionArgumentTitle" MaxLength="100" />
|
||||||
Tag="config" ToolTip="config 文件夹" />
|
</Grid>
|
||||||
<local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="1" Grid.Column="4" Text="游戏配置"
|
</local:MyCard>
|
||||||
Tag="options.txt" ToolTip="options.txt 文件" />
|
<local:MyCard Margin="0,0,0,15" x:Name="CardOptions" MinHeight="39">
|
||||||
<TextBlock Text="游戏文件" VerticalAlignment="Center" Grid.Column="0" Grid.Row="2" />
|
<local:MyIconTextButton x:Name="BtnOverrideCancel" Height="24" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0"
|
||||||
<local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="2" Text="存档"
|
IsHitTestVisible="False" Opacity="0.5"
|
||||||
Tag="saves" ToolTip="saves 文件夹" />
|
Text="重置" 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" />
|
||||||
<local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" Text="资源包"
|
<StackPanel Margin="25,38,15,15" Name="PanOptions">
|
||||||
Tag="resourcepacks" ToolTip="resourcepacks 文件夹" />
|
<local:MyCheckBox IsEnabled="False" x:Name="CheckOptionsBasic">
|
||||||
<local:MyCheckBox Height="22" VerticalAlignment="Center" Grid.Row="2" Grid.Column="4" Text="光影包"
|
<local:MyCheckBox.Tag>
|
||||||
Tag="shaderpacks" ToolTip="shaderpacks 文件夹" />
|
<local:ExportOption
|
||||||
<TextBlock Text="PCL 配置" VerticalAlignment="Center" Grid.Column="0" Grid.Row="3" />
|
Title="游戏本体"
|
||||||
<local:MyCheckBox x:Name="CheckIncludePCL" Height="22" VerticalAlignment="Center" Grid.Row="3" Grid.Column="2" Text="包含启动器"
|
DefaultChecked="True" />
|
||||||
Tag="" ToolTip="将 PCL 程序包含在整合包内" />
|
</local:MyCheckBox.Tag>
|
||||||
<local:MyCheckBox x:Name="CheckIncludeSetup" Height="22" VerticalAlignment="Center" Grid.Row="3" Grid.Column="3" Text="PCL 全局配置"
|
</local:MyCheckBox>
|
||||||
Tag="" ToolTip="将 PCL 全局配置包含在整合包内" />
|
<local:MyCheckBox x:Name="CheckOptionsOptions" Margin="30,0,0,0">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="游戏本体设置"
|
||||||
|
Description="键位、音量、视频设置等"
|
||||||
|
Rules="options.txt|configureddefaults/"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox Margin="30,0,0,0">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="游戏本体个人信息"
|
||||||
|
Description="命令历史、已保存的快捷栏"
|
||||||
|
Rules="hotbar.nbt|command_history.txt"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox Margin="30,0,0,0">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="OptiFine 设置"
|
||||||
|
Rules="optionsof.txt|optionsshaders.txt"
|
||||||
|
DefaultChecked="True"
|
||||||
|
RequireOptiFine="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox x:Name="CheckOptionsMod">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="Mod"
|
||||||
|
Description="模组"
|
||||||
|
Rules="mods/|!mods/*.disabled|!mods/*.old|!mods/.connector/|coremods/|lib/"
|
||||||
|
DefaultChecked="True"
|
||||||
|
RequireModLoader="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<StackPanel Margin="30,0,0,0"
|
||||||
|
Visibility="{Binding Checked, ElementName=CheckOptionsMod, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="已禁用的 Mod"
|
||||||
|
Rules="mods/*.disabled|mods/*.old" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="整合包重要数据"
|
||||||
|
Description="脚本文件、内置资源包、数据包等"
|
||||||
|
Rules="addons/|multiblocked/|modpack-update-checker/|global_packs/|global_resource_packs/|global_data_packs/|optional_data_packs/|maps/|icon.png|mods-resourcepacks/|matmos/|resource_assorts/|resource_assorts.json|patchouli_books/|datapacks/|kubejs*/|!kubejs*/probe/|!kubejs*/exported/|!kubejs*/jsconfig.json|!kubejs*/README.txt|openloader/|worldshape/|resources/|scripts/|structures/|fontfiles/|oresources/|packmenu/|craftpresence/|pointblanks/|template*/|!template*/playerdata/|!template*/stats/"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="Mod 设置"
|
||||||
|
Rules="config/|!config/jei/world/|!config/worldedit/|config/worldedit/worldedit.properties|!config/spark/|config/spark/config.json|defaultconfigs/|journeymap/config/|journeymap/server/|TrashSlotSaveState.json|customfov.txt|gg.essential.mod/|essential/|!essential/*/|!essential/*.jar*|!essential/screenshot-checksum-caches.json|!essential/microsoft_accounts.json|paragliderSettings.nbt|local/client_config.json|local/ftbl.json|local/client/sidebar_buttons.json|local/client/ftbutilities.cfg|local/client/ftblib.cfg|local/client/xencraft.cfg|liteloader.properties|default_reference.xml|CustomSkinLoader/CustomSkinLoader.json"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="已绘制的地图"
|
||||||
|
Description="地图类 Mod 为现有的存档、服务器记录的地图、路标点等"
|
||||||
|
Rules="journeymap/data/|xaero/"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="JEI 个人信息"
|
||||||
|
Description="物品收藏夹等"
|
||||||
|
Rules="config/jei/world/"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="EMI 个人信息"
|
||||||
|
Description="物品收藏夹、默认配方、合成历史记录等"
|
||||||
|
Rules="emi.json"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="帕秋莉手册个人信息"
|
||||||
|
Description="教程书的已读记录、书签、阅读历史记录等"
|
||||||
|
Rules="patchouli_data.json"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
</StackPanel>
|
||||||
|
<local:MyCheckBox x:Name="CheckOptionsResourcePacks">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="资源包"
|
||||||
|
Description="纹理包/材质包"
|
||||||
|
ShowRules="resourcepacks/|texturepacks/"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<StackPanel Margin="30,0,0,0" x:Name="PanOptionsResourcePacks"
|
||||||
|
Visibility="{Binding Checked, ElementName=CheckOptionsResourcePacks, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
</StackPanel>
|
||||||
|
<local:MyCheckBox x:Name="CheckOptionsShaderPacks">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="光影包"
|
||||||
|
ShowRules="shaderpacks/"
|
||||||
|
DefaultChecked="True"
|
||||||
|
RequireModLoaderOrOptiFine="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<StackPanel Margin="30,0,0,0" x:Name="PanOptionsShaderPacks"
|
||||||
|
Visibility="{Binding Checked, ElementName=CheckOptionsShaderPacks, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
</StackPanel>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="截图"
|
||||||
|
Rules="screenshots/"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="导出的结构"
|
||||||
|
Description="schematics 文件夹"
|
||||||
|
Rules="schematics/"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="录像回放"
|
||||||
|
Description="Replay Mod 的录像文件"
|
||||||
|
Rules="replay_recordings/|replay_videos/"
|
||||||
|
RequireModLoader="True"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox x:Name="CheckOptionsSaves">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="单人游戏存档"
|
||||||
|
Description="世界/地图"
|
||||||
|
ShowRules="saves/"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<StackPanel Margin="30,0,0,0" x:Name="PanOptionsSaves"
|
||||||
|
Visibility="{Binding Checked, ElementName=CheckOptionsSaves, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
</StackPanel>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="多人游戏服务器列表"
|
||||||
|
Rules="servers.dat"
|
||||||
|
DefaultChecked="False" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox x:Name="CheckOptionsPcl">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="PCL 启动器程序"
|
||||||
|
Description="打包正式版 PCL,以便没有启动器的玩家安装整合包"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
<StackPanel Margin="30,0,0,0"
|
||||||
|
Visibility="{Binding Checked, ElementName=CheckOptionsPcl, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<local:MyCheckBox x:Name="CheckOptionsPclCustom">
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="PCL 个性化内容"
|
||||||
|
Description="功能隐藏设置、主页、背景音乐和图片等"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</local:MyCard>
|
||||||
|
<local:MyCard Title="高级选项" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
|
<StackPanel Margin="25,37,23,20">
|
||||||
|
<local:MyHint Text="建议仅在无法稳定连接 CurseForge 或 Modrinth 时才打包资源文件。
二次分发可能违反使用协议,请尽量不要公开发布包含资源文件的整合包!"
|
||||||
|
IsWarn="False" Margin="0,0,0,4"
|
||||||
|
Visibility="{Binding Checked, ElementName=CheckAdvancedInclude, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||||
|
<local:MyCheckBox Text="打包资源文件,以避免在导入时下载" x:Name="CheckAdvancedInclude"
|
||||||
|
ToolTip="将 Mod、资源包、光影包的文件直接放入整合包中,这样在导入时就无需联网下载它们。
建议仅在无法稳定连接 CurseForge 或 Modrinth 时才考虑勾选。" />
|
||||||
|
<local:MyCheckBox Text="Modrinth 上传模式" x:Name="CheckAdvancedModrinth"
|
||||||
|
ToolTip="如果你想要打包上传到 Modrinth,勾选此项会生成完全符合 Modrinth 要求的整合包文件。
由于 Modrinth 要求,只能从 CurseForge 下载的资源将无法联网下载,会被直接放入整合包中。
此外,勾选后也不能在整合包中包含 PCL 启动器文件。" />
|
||||||
|
<Rectangle Height="1" Fill="{StaticResource ColorBrushGray5}" Margin="0,15,0,15" />
|
||||||
|
<TextBlock Text="通过配置文件,你可以精准地控制导出内容的范围,或是保存当前的配置以便之后使用。" TextWrapping="WrapWithOverflow" />
|
||||||
|
<Grid Height="35" Margin="0,12,0,0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
||||||
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
||||||
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<local:MyButton Grid.Column="0" x:Name="BtnAdvancedImport" MinWidth="140" Text="读取配置" Padding="13,0" Margin="0,0,20,0" ColorType="Highlight" />
|
||||||
|
<local:MyButton Grid.Column="1" x:Name="BtnAdvancedExport" MinWidth="140" Text="保存配置" Padding="13,0" Margin="0,0,20,0" />
|
||||||
|
<local:MyButton Grid.Column="2" MinWidth="140" Text="整合包制作指南" Padding="13,0" Margin="0,0,20,0" x:Name="BtnAdvancedHelp"
|
||||||
|
EventType="打开帮助" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
<local:MyCard x:Name="CardMore" Title="高级选项" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
|
||||||
<StackPanel x:Name="PanFileList" Margin="25,40,23,15">
|
|
||||||
<TextBlock Margin="0,1,0,10" Text="你可以在此勾选其他需要包含进整合包的内容。
请注意:部分必须包含在整合包中的内容(如 Mods 等),以及被排除的冗余文件(如游戏日志等),将不会在列表中展示。" TextWrapping="Wrap" />
|
|
||||||
<local:MyListItem Type="CheckBox" Title="游戏存档" Height="35" Logo="M889.018182 418.909091H884.363636V316.509091a93.090909 93.090909 0 0 0-99.607272-89.832727h-302.545455l-93.090909-76.334546A46.545455 46.545455 0 0 0 358.865455 139.636364H146.152727A93.090909 93.090909 0 0 0 46.545455 229.469091V837.818182a46.545455 46.545455 0 0 0 46.545454 46.545454 46.545455 46.545455 0 0 0 16.756364-3.258181 109.381818 109.381818 0 0 0 25.134545 3.258181h586.472727a85.178182 85.178182 0 0 0 87.04-63.301818l163.374546-302.545454a46.545455 46.545455 0 0 0 5.585454-21.876364A82.385455 82.385455 0 0 0 889.018182 418.909091z m-744.727273-186.181818h198.283636l93.09091 76.334545a46.545455 46.545455 0 0 0 29.323636 10.705455h319.301818a12.101818 12.101818 0 0 1 6.516364 0V418.909091H302.545455a85.178182 85.178182 0 0 0-87.04 63.301818L139.636364 622.778182V232.727273a19.549091 19.549091 0 0 1 6.516363 0z m578.094546 552.029091a27.461818 27.461818 0 0 0-2.792728 6.516363H154.530909l147.083636-272.290909a27.461818 27.461818 0 0 0 2.792728-6.981818h565.061818z" />
|
|
||||||
<local:MyListItem Type="CheckBox" Title="游戏存档" Height="35" Logo="M586.9 436h-74.7V62.4H177.1c-20.6 0-37.4 16.7-37.4 37.4v821.9c0 20.6 16.7 37.4 37.4 37.4h672.5c20.6 0 37.4-16.7 37.4-37.4V436H586.9z m0-74.7h297.8c-7.3-57.4-31.2-70.9-58.4-98.1l-66.5-66.5-0.1-0.1 0.1 0.1-0.9-0.9-22.8-22.8-0.9-0.9 0.1 0.1-0.1-0.1-66.5-66.5c-21.8-21.8-38.8-36.5-81.7-41.4l-0.1 297.1z" />
|
|
||||||
<local:MyListItem Type="CheckBox" Title="游戏存档" Height="35" Logo="M757.792745 435.407215L419.597482 96.904967c-40.010393-40.010393-104.886579-40.010393-144.896972 0-40.010393 40.010393-40.010393 104.988908 0 144.9993L540.344959 507.855701 274.70051 773.807135c-40.010393 40.112721-40.010393 104.988908 0 144.9993 40.010393 40.010393 104.886579 40.010393 144.896972 0l338.092935-338.39992c40.112721-40.010393 40.112721-104.988908 0.102328-144.9993z" />
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyScrollViewer>
|
</local:MyScrollViewer>
|
||||||
|
<local:MyExtraTextButton HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="20"
|
||||||
|
x:Name="BtnExport" Text="开始导出"
|
||||||
|
LogoScale="1.1" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z" />
|
||||||
|
</Grid>
|
||||||
</local:MyPageRight>
|
</local:MyPageRight>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,13 @@
|
|||||||
</local:MyListItem>
|
</local:MyListItem>
|
||||||
<local:MyListItem x:Name="ItemModDisabled" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="3" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod 管理"
|
<local:MyListItem x:Name="ItemModDisabled" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="3" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod 管理"
|
||||||
Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z" />
|
Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z" />
|
||||||
<local:MyListItem x:Name="ItemExport" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="4" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="导出整合包"
|
<local:MyListItem x:Name="ItemExport" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="4" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="导出"
|
||||||
Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z" >
|
Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z">
|
||||||
|
<local:MyListItem.Buttons>
|
||||||
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
|
<local:MyIconButton Tag="4" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" Click="Refresh" LogoScale="0.85" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
|
</x:Array>
|
||||||
|
</local:MyListItem.Buttons>
|
||||||
</local:MyListItem>
|
</local:MyListItem>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyPageLeft>
|
</local:MyPageLeft>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
Public Class PageVersionLeft
|
Public Class PageVersionLeft
|
||||||
|
Implements IRefreshable
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 当前显示设置的 MC 版本。
|
''' 当前显示设置的 MC 版本。
|
||||||
@@ -91,7 +92,20 @@
|
|||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
Public Sub Refresh(sender As Object, e As EventArgs) '由边栏按钮匿名调用
|
Public Sub Refresh(sender As Object, e As EventArgs) '由边栏按钮匿名调用
|
||||||
|
Refresh(Val(sender.Tag))
|
||||||
|
End Sub
|
||||||
|
Public Sub Refresh() Implements IRefreshable.Refresh
|
||||||
|
Refresh(FrmMain.PageCurrentSub)
|
||||||
|
End Sub
|
||||||
|
Public Sub Refresh(SubType As FormMain.PageSubType)
|
||||||
|
Select Case SubType
|
||||||
|
Case FormMain.PageSubType.VersionMod
|
||||||
PageVersionMod.Refresh()
|
PageVersionMod.Refresh()
|
||||||
|
ItemMod.Checked = True
|
||||||
|
Case FormMain.PageSubType.VersionExport
|
||||||
|
If FrmVersionExport IsNot Nothing Then FrmVersionExport.RefreshAll()
|
||||||
|
ItemExport.Checked = True
|
||||||
|
End Select
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub Reset(sender As Object, e As EventArgs)
|
Public Sub Reset(sender As Object, e As EventArgs)
|
||||||
|
|||||||
@@ -289,7 +289,7 @@
|
|||||||
Private Sub BtnManageOpen_Click(sender As Object, e As EventArgs) Handles BtnManageOpen.Click, BtnHintOpen.Click
|
Private Sub BtnManageOpen_Click(sender As Object, e As EventArgs) Handles BtnManageOpen.Click, BtnHintOpen.Click
|
||||||
Try
|
Try
|
||||||
Directory.CreateDirectory(PageVersionLeft.Version.PathIndie & "mods\")
|
Directory.CreateDirectory(PageVersionLeft.Version.PathIndie & "mods\")
|
||||||
OpenExplorer("""" & PageVersionLeft.Version.PathIndie & "mods\""")
|
OpenExplorer(PageVersionLeft.Version.PathIndie & "mods\")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "打开 Mods 文件夹失败", LogLevel.Msgbox)
|
Log(ex, "打开 Mods 文件夹失败", LogLevel.Msgbox)
|
||||||
End Try
|
End Try
|
||||||
@@ -856,10 +856,8 @@ Install:
|
|||||||
'打开文件所在的位置
|
'打开文件所在的位置
|
||||||
Public Sub Open_Click(sender As MyIconButton, e As EventArgs)
|
Public Sub Open_Click(sender As MyIconButton, e As EventArgs)
|
||||||
Try
|
Try
|
||||||
|
|
||||||
Dim ListItem As MyLocalModItem = sender.Tag
|
Dim ListItem As MyLocalModItem = sender.Tag
|
||||||
OpenExplorer("/select,""" & ListItem.Entry.Path & """")
|
OpenExplorer(ListItem.Entry.Path)
|
||||||
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "打开 Mod 文件位置失败", LogLevel.Feedback)
|
Log(ex, "打开 Mod 文件位置失败", LogLevel.Feedback)
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -235,21 +235,21 @@
|
|||||||
OpenVersionFolder(PageVersionLeft.Version)
|
OpenVersionFolder(PageVersionLeft.Version)
|
||||||
End Sub
|
End Sub
|
||||||
Public Shared Sub OpenVersionFolder(Version As McVersion)
|
Public Shared Sub OpenVersionFolder(Version As McVersion)
|
||||||
OpenExplorer("""" & Version.Path & """")
|
OpenExplorer(Version.Path)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'存档文件夹
|
'存档文件夹
|
||||||
Private Sub BtnFolderSaves_Click() Handles BtnFolderSaves.Click
|
Private Sub BtnFolderSaves_Click() Handles BtnFolderSaves.Click
|
||||||
Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "saves\"
|
Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "saves\"
|
||||||
Directory.CreateDirectory(FolderPath)
|
Directory.CreateDirectory(FolderPath)
|
||||||
OpenExplorer("""" & FolderPath & """")
|
OpenExplorer(FolderPath)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'Mod 文件夹
|
'Mod 文件夹
|
||||||
Private Sub BtnFolderMods_Click() Handles BtnFolderMods.Click
|
Private Sub BtnFolderMods_Click() Handles BtnFolderMods.Click
|
||||||
Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "mods\"
|
Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "mods\"
|
||||||
Directory.CreateDirectory(FolderPath)
|
Directory.CreateDirectory(FolderPath)
|
||||||
OpenExplorer("""" & FolderPath & """")
|
OpenExplorer(FolderPath)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
Private Sub BtnManageScript_Click() Handles BtnManageScript.Click
|
Private Sub BtnManageScript_Click() Handles BtnManageScript.Click
|
||||||
Try
|
Try
|
||||||
'弹窗要求指定脚本的保存位置
|
'弹窗要求指定脚本的保存位置
|
||||||
Dim SavePath As String = SelectAs("选择脚本保存位置", "启动 " & PageVersionLeft.Version.Name & ".bat", "批处理文件(*.bat)|*.bat")
|
Dim SavePath As String = SelectSaveFile("选择脚本保存位置", "启动 " & PageVersionLeft.Version.Name & ".bat", "批处理文件(*.bat)|*.bat")
|
||||||
If SavePath = "" Then Exit Sub
|
If SavePath = "" Then Exit Sub
|
||||||
'检查中断(等玩家选完弹窗指不定任务就结束了呢……)
|
'检查中断(等玩家选完弹窗指不定任务就结束了呢……)
|
||||||
If McLaunchLoader.State = LoadState.Loading Then
|
If McLaunchLoader.State = LoadState.Loading Then
|
||||||
|
|||||||
@@ -153,11 +153,11 @@
|
|||||||
If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.VersionSetup OrElse FrmVersionLeft.PageID <> FormMain.PageSubType.VersionSetup Then Exit Sub
|
If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.VersionSetup OrElse FrmVersionLeft.PageID <> FormMain.PageSubType.VersionSetup Then Exit Sub
|
||||||
'获取内存情况
|
'获取内存情况
|
||||||
Dim RamGame As Double = GetRam(PageVersionLeft.Version)
|
Dim RamGame As Double = GetRam(PageVersionLeft.Version)
|
||||||
Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
|
Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024, 1)
|
||||||
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
|
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024, 1)
|
||||||
Dim RamGameActual As Double = Math.Min(RamGame, RamAvailable)
|
Dim RamGameActual As Double = Math.Round(Math.Min(RamGame, RamAvailable), 5)
|
||||||
Dim RamUsed As Double = RamTotal - RamAvailable
|
Dim RamUsed As Double = Math.Round(RamTotal - RamAvailable, 5)
|
||||||
Dim RamEmpty As Double = Math.Round(MathClamp(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10
|
Dim RamEmpty As Double = Math.Round(MathClamp(RamTotal - RamUsed - RamGame, 0, 1000), 1)
|
||||||
'设置最大可用内存
|
'设置最大可用内存
|
||||||
If RamTotal <= 1.5 Then
|
If RamTotal <= 1.5 Then
|
||||||
SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1)
|
SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1)
|
||||||
|
|||||||
@@ -186,6 +186,9 @@
|
|||||||
<Compile Include="Controls\MyComboBox.vb" />
|
<Compile Include="Controls\MyComboBox.vb" />
|
||||||
<Compile Include="Controls\MyComboBoxItem.vb" />
|
<Compile Include="Controls\MyComboBoxItem.vb" />
|
||||||
<Compile Include="Controls\MyCard.vb" />
|
<Compile Include="Controls\MyCard.vb" />
|
||||||
|
<Compile Include="Controls\MyExtraTextButton.xaml.vb">
|
||||||
|
<DependentUpon>MyExtraTextButton.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Controls\MyImage.vb" />
|
<Compile Include="Controls\MyImage.vb" />
|
||||||
<Compile Include="Controls\MyPageRight.vb" />
|
<Compile Include="Controls\MyPageRight.vb" />
|
||||||
<Compile Include="Controls\MyPageLeft.vb" />
|
<Compile Include="Controls\MyPageLeft.vb" />
|
||||||
@@ -385,6 +388,10 @@
|
|||||||
<Compile Include="Pages\PageSpeedRight.xaml.vb">
|
<Compile Include="Pages\PageSpeedRight.xaml.vb">
|
||||||
<DependentUpon>PageSpeedRight.xaml</DependentUpon>
|
<DependentUpon>PageSpeedRight.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Page Include="Controls\MyExtraTextButton.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Include="Controls\MyExtraButton.xaml">
|
<Page Include="Controls\MyExtraButton.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@@ -479,10 +486,10 @@
|
|||||||
<DependentUpon>MyRadioButton.xaml</DependentUpon>
|
<DependentUpon>MyRadioButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="FormMain.xaml.vb">
|
<Compile Include="FormMain.xaml.vb">
|
||||||
|
|
||||||
<DependentUpon>FormMain.xaml</DependentUpon>
|
<DependentUpon>FormMain.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
||||||
<Page Include="Modules\Minecraft\MyLocalModItem.xaml">
|
<Page Include="Modules\Minecraft\MyLocalModItem.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -565,8 +572,8 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Pages\PageVersion\PageVersionExport.xaml">
|
<Page Include="Pages\PageVersion\PageVersionExport.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Resources\Language\en_US.xaml">
|
<Page Include="Resources\Language\en_US.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -917,11 +924,11 @@
|
|||||||
<Resource Include="Images\Icons\Disabled.png" />
|
<Resource Include="Images\Icons\Disabled.png" />
|
||||||
<Resource Include="Images\Icons\Unavailable.png" />
|
<Resource Include="Images\Icons\Unavailable.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Images\Heads\MCBBS.png" />
|
<Resource Include="Images\Heads\MCBBS.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Images\Blocks\NeoForge.png" />
|
<Resource Include="Images\Blocks\NeoForge.png" />
|
||||||
|
|||||||
@@ -87,22 +87,22 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="事件 3:打开文件" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="事件 3:执行命令" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="将 EventType 设置为 打开文件,EventData 设置为文件路径,即可点击打开特定文件或启动程序。" />
|
Text="将 EventType 设置为 执行命令(或 打开文件),EventData 设置为文件路径,即可点击打开特定文件或启动程序。" />
|
||||||
<local:MyButton Margin="0,4,0,8" Width="200" Height="35"
|
<local:MyButton Margin="0,4,0,8" Width="200" Height="35"
|
||||||
Text="打开记事本" EventType="打开文件" EventData="notepad.exe" />
|
Text="打开记事本" EventType="执行命令" EventData="notepad.exe" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,4,0,0"
|
<TextBlock TextWrapping="Wrap" Margin="0,4,0,0"
|
||||||
Text="如果能在 PCL 文件夹中找到该文件,则会优先打开 PCL 文件夹中的文件。当然,你可以使用例如 C:\ 开头的绝对路径。" />
|
Text="如果能在 PCL 文件夹中找到该文件,则会优先打开 PCL 文件夹中的文件。当然,你可以使用例如 C:\ 开头的绝对路径。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="此外,PCL 会将文件中的 “花括号 path” 替换为 PCL 可执行文件所在文件夹({path}),可以用于执行特定程序或加载图片。" />
|
Text="此外,PCL 会将文件中的 “花括号 path” 替换为 PCL 可执行文件所在文件夹({path}),可以用于执行特定程序或加载图片。" />
|
||||||
<local:MyButton Margin="0,4,0,10" Width="200" Height="35"
|
<local:MyButton Margin="0,4,0,10" Width="200" Height="35"
|
||||||
Text="打开 PCL 日志" EventType="打开文件" EventData="Log1.txt" ToolTip="PCL 的日志文件就在 PCL 文件夹内,且名为 Log1.txt" />
|
Text="打开 PCL 日志" EventType="执行命令" EventData="Log1.txt" ToolTip="PCL 的日志文件就在 PCL 文件夹内,且名为 Log1.txt" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="就像为游戏指定服务器 IP 一样,你也可以在 EventData 的竖线后为程序添加启动参数。" />
|
Text="就像为游戏指定服务器 IP 一样,你也可以在 EventData 的竖线后为程序添加启动参数。" />
|
||||||
<local:MyButton Margin="0,4,0,0" Width="200" Height="35"
|
<local:MyButton Margin="0,4,0,0" Width="200" Height="35"
|
||||||
Text="定位游戏启动脚本" EventType="打开文件" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。
点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
|
Text="定位游戏启动脚本" EventType="执行命令" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。
点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,7 @@
|
|||||||
<!-- 更改原因见 #5337 -->
|
<!-- 更改原因见 #5337 -->
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
<windowsSettings>
|
<windowsSettings>
|
||||||
|
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> <!-- 长路径支持 -->
|
||||||
<!-- The combination of below two tags have the following effect :
|
<!-- The combination of below two tags have the following effect :
|
||||||
1. Per-Monitor for >= Windows 10 Anniversary Update
|
1. Per-Monitor for >= Windows 10 Anniversary Update
|
||||||
2. System < Windows 10 Anniversary Update -->
|
2. System < Windows 10 Anniversary Update -->
|
||||||
|
|||||||
Reference in New Issue
Block a user