Compare commits

...
16 Commits
Author SHA1 Message Date
龙腾猫跃 d540b94448 2.4.9 2023-02-06 22:54:56 +08:00
龙腾猫跃 64539ad55c 2.4.8 正式版 2023-02-06 16:36:43 +08:00
龙腾猫跃 b06328645c 2.4.8 2023-02-04 18:35:32 +08:00
龙腾猫跃 eb9e7864c9 2.4.7 正式版 2023-01-29 14:23:27 +08:00
龙腾猫跃 c2b282c8db 2.4.7 2023-01-27 01:11:26 +08:00
龙腾猫跃 48214557da Merge branch 'main' of https://github.com/Hex-Dragon/PCL2 2023-01-26 01:50:57 +08:00
龙腾猫跃 06b50fa74c 2.4.6 2023-01-26 01:50:52 +08:00
龙腾猫跃 7cab6b281a Merge pull request #1002 from WForst-Breeze/main
更改对于无法加载 Mod 的版本的提示
2023-01-24 20:22:09 +08:00
风释清然SC c28f05aae1 想了想还是改回来吧…… 2023-01-24 20:15:27 +08:00
风释清然SC f11aedef5d Update PageVersionModDisabled.xaml 2023-01-24 19:55:35 +08:00
风释清然SC 63e002780a PCL2 #1001 2023-01-24 19:54:04 +08:00
龙腾猫跃 8e5362e2df Merge pull request #925 from WorldHim/main
修复反馈链接问题
2023-01-24 18:47:55 +08:00
WorldHim 3129edd09f 修复反馈链接问题 2023-01-16 08:05:54 +08:00
龙腾猫跃 45a9bf1096 2.4.5 2023-01-08 20:36:30 +08:00
龙腾猫跃 bef94fa743 2.4.4 正式版 2022-12-16 16:44:47 +08:00
龙腾猫跃 fd329037e7 2.4.4 2022-12-12 02:34:19 +08:00
81 changed files with 10576 additions and 5175 deletions

No files matched your search

+19 -18
View File
@@ -23,7 +23,8 @@
<SolidColorBrush x:Key="ColorBrush6">#d5e6fd</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrush7">#e0eafd</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrush8">#eaf2fe</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrush9">#80e0eafd</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushBg0">#96c0f9</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushBg1">#bee0eafd</SolidColorBrush>
<Color x:Key="ColorObject1">#343d4a</Color>
<Color x:Key="ColorObject2">#0b5bcb</Color>
<Color x:Key="ColorObject3">#1370f3</Color>
@@ -32,7 +33,8 @@
<Color x:Key="ColorObject6">#d5e6fd</Color>
<Color x:Key="ColorObject7">#e0eafd</Color>
<Color x:Key="ColorObject8">#eaf2fe</Color>
<Color x:Key="ColorObject9">#40eaf2fe</Color>
<Color x:Key="ColorObjectBg0">#96c0f9</Color>
<Color x:Key="ColorObjectBg1">#bee0eafd</Color>
<SolidColorBrush x:Key="ColorBrushGray1">#404040</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushGray2">#737373</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushGray3">#8c8c8c</SolidColorBrush>
@@ -52,7 +54,9 @@
<SolidColorBrush x:Key="ColorBrushRedBack">#80fbdddd</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushRedLight">#ff4c4c</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushRedDark">#ce2111</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushHalfWhite" Color="#44ffffff" />
<SolidColorBrush x:Key="ColorBrushHalfWhite" Color="#55ffffff" />
<SolidColorBrush x:Key="ColorBrushSemiWhite" Color="#bbffffff" />
<SolidColorBrush x:Key="ColorBrushWhite" Color="#ffffff" />
<SolidColorBrush x:Key="ColorBrushTransparent" Color="Transparent" />
<SolidColorBrush x:Key="ColorBrushSemiTransparent">#01eaf2fe</SolidColorBrush>
<SolidColorBrush x:Key="ColorBrushBackgroundTransparentSidebar" Color="#D2FFFFFF" />
@@ -274,7 +278,7 @@
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="UndoLimit" Value="15" />
<Setter Property="MaxLength" Value="10000" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrush1}" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrushBg0}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
@@ -283,14 +287,14 @@
<RowDefinition MinHeight="28" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Margin="{TemplateBinding Padding}" IsHitTestVisible="False" VerticalAlignment="Center" BorderThickness="0">
<TextBlock x:Name="labHint" Foreground="{StaticResource ColorBrushGray3}" Margin="7,0,0,0" Padding="{TemplateBinding BorderThickness}" FontSize="{TemplateBinding FontSize}" FontFamily="Resources/#PCL English, Microsoft YaHei UI" />
</Border>
<Border x:Name="border" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" CornerRadius="3">
<ScrollViewer x:Name="PART_ContentHost" Style="{StaticResource ScrollViewerNoMargin}" RenderOptions.ClearTypeHint="Enabled" BorderThickness="0"
Margin="5,0,0,0" Cursor="IBeam" />
<!-- 由于未知原因,TextView 会有 2,0 的 Margin -->
</Border>
<Border Margin="{TemplateBinding Padding}" IsHitTestVisible="False" VerticalAlignment="Center" BorderThickness="0">
<TextBlock x:Name="labHint" Foreground="{DynamicResource ColorBrush1}" Opacity="0.3" Margin="7,0,0,0" Padding="{TemplateBinding BorderThickness}" FontSize="{TemplateBinding FontSize}" FontFamily="Resources/#PCL English, Microsoft YaHei UI" />
</Border>
<TextBlock Grid.Row="1" x:Name="labWrong" Height="0" Foreground="{TemplateBinding BorderBrush}" Padding="0,4,0,0" />
</Grid>
</ControlTemplate>
@@ -303,7 +307,7 @@
<Setter Property="SelectionBrush" Value="{DynamicResource ColorBrush3}" />
<Setter Property="Foreground" Value="{DynamicResource ColorBrush1}" />
<Setter Property="Background" Value="{StaticResource ColorBrushHalfWhite}" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrush1}" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrushBg0}" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
@@ -317,19 +321,20 @@
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Trigger.Setters>
<Setter Property="Foreground" Value="{StaticResource ColorBrushGray4}" />
<Setter Property="BorderBrush" Value="{StaticResource ColorBrushGray4}" />
<Setter Property="BorderBrush" Value="{StaticResource ColorBrushGray5}" />
<Setter Property="Background" Value="{StaticResource ColorBrushGray6}" />
</Trigger.Setters>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.Setters>
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrush3}" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrush4}" />
<Setter Property="Background" Value="{DynamicResource ColorBrush7}" />
</Trigger.Setters>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="{DynamicResource ColorBrush9}" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrush4}" />
<Setter Property="BorderBrush" Value="{DynamicResource ColorBrush3}" />
<Setter Property="Background" Value="{DynamicResource ColorBrush7}" />
</Trigger.Setters>
</Trigger>
</ControlTemplate.Triggers>
@@ -348,16 +353,12 @@
</local:MyListItem.Buttons>
</local:MyListItem>
</DataTemplate>
<!--<DataTemplate x:Key="ComboBoxItemTemplateNormal">
<local:MyListItem Title="{Binding}" FontSize="13" PaddingRight="40" Height="26" Margin="-1,0,0,0" />
</DataTemplate>-->
<Style TargetType="local:MyComboBox">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="{DynamicResource ColorBrush1}" />
<Setter Property="Foreground" Value="{DynamicResource ColorBrushBg0}" />
<Setter Property="Background" Value="{StaticResource ColorBrushHalfWhite}" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<!--<Setter Property="ItemTemplate" Value="{StaticResource ComboBoxItemTemplateNormal}"/>-->
<Setter Property="FontSize" Value="13" />
<Setter Property="MaxDropDownHeight" Value="160" />
<Setter Property="Template">
+6 -6
View File
@@ -32,7 +32,7 @@ Public Class Application
ElseIf e.Args(0).StartsWith("--link") Then
'稍作等待后切换到联机页面
Thread.Sleep(1000)
FormMain.IsLinkRestart = True
'FormMain.IsLinkRestart = True
#If DEBUG Then
ElseIf e.Args(0) = "--make" Then
'制作更新包
@@ -49,7 +49,7 @@ Public Class Application
Directory.CreateDirectory(PathTemp)
If Not CheckPermission(PathTemp) Then Throw New Exception("PCL2 没有对 " & PathTemp & " 的访问权限")
Catch ex As Exception
MyMsgBox("手动设置的缓存文件夹不可用,PCL2 将使用默认缓存文件夹。" & vbCrLf & "错误原因:" & GetString(ex, False), "缓存文件夹不可用")
MyMsgBox("手动设置的缓存文件夹不可用,PCL2 将使用默认缓存文件夹。" & vbCrLf & "错误原因:" & GetExceptionDetail(ex), "缓存文件夹不可用")
Setup.Set("SystemSystemCache", "")
PathTemp = IO.Path.GetTempPath() & "PCL\"
End Try
@@ -104,7 +104,7 @@ Public Class Application
#End If
AniControlEnabled += 1
Catch ex As Exception
MsgBox(GetString(ex, False, True), MsgBoxStyle.Critical, "PCL2 初始化错误")
MsgBox(GetExceptionDetail(ex, True), MsgBoxStyle.Critical, "PCL2 初始化错误")
FormMain.EndProgramForce(Result.Exception)
End Try
End Sub
@@ -126,13 +126,13 @@ Public Class Application
Exit Sub
End If
IsCritErrored = True
Dim ExceptionString As String = GetString(e.Exception, False, True)
Dim ExceptionString As String = GetExceptionDetail(e.Exception, True)
If ExceptionString.Contains("System.Windows.Threading.Dispatcher.Invoke") OrElse
ExceptionString.Contains("MS.Internal.AppModel.ITaskbarList.HrInit") OrElse
ExceptionString.Contains(".Net Framework") OrElse ' “自动错误判断” 的结果分析
ExceptionString.Contains(".NET Framework") OrElse ' “自动错误判断” 的结果分析
ExceptionString.Contains("未能加载文件或程序集") Then
OpenWebsite("https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-offline-installer")
MsgBox("你的 .Net Framework 版本过低或损坏,请在打开的网页中重新下载并安装 .NET Framework 4.6.2 后重试!", MsgBoxStyle.Information, "运行环境错误")
MsgBox("你的 .NET Framework 版本过低或损坏,请在打开的网页中重新下载并安装 .NET Framework 4.6.2 后重试!", MsgBoxStyle.Information, "运行环境错误")
FormMain.EndProgramForce(Result.Cancel)
Else
FeedbackInfo()
@@ -177,7 +177,7 @@
}, "MyButton Scale " & Uuid)
End Sub
Private Sub Button_MouseEnter() Handles Me.MouseEnter
AniStart(AaColor(PanFore, BackgroundProperty, If(_ColorType = ColorState.Red, "ColorBrushRedBack", "ColorBrush9"), AnimationColorIn), "MyButton Background " & Uuid)
AniStart(AaColor(PanFore, BackgroundProperty, If(_ColorType = ColorState.Red, "ColorBrushRedBack", "ColorBrush7"), AnimationColorIn), "MyButton Background " & Uuid)
End Sub
Private Sub Button_MouseUp() Handles Me.MouseLeftButtonUp
If Not IsMouseDown Then Exit Sub
+5 -1
View File
@@ -130,7 +130,9 @@
Case 6
Stack.Children.Add(ForgeDownloadListItem(Data, AddressOf ForgeSave_Click, True))
Case 7
Stack.Children.Add(McDownloadListItem(Data, AddressOf FrmDownloadInstall.MinecraftSelected, False))
Stack.Children.Add(McDownloadListItem(Data, Sub(sender, e) '不能使用 AddressOf,这导致了 #535,原因完全不明,疑似是编译器 Bug
FrmDownloadInstall.MinecraftSelected(sender, e)
End Sub, False))
Case 8
Stack.Children.Add(CType(Data, DlCfFile).ToListItem(AddressOf FrmDownloadCfDetail.Save_Click))
Case 9
@@ -295,6 +297,7 @@ Partial Public Module ModAnimation
AaHeight(Control, -Control.ActualHeight, 150, 100, New AniEaseOutFluent),
AaCode(Sub()
If RemoveFromChildren Then
If Control.Parent Is Nothing Then Exit Sub
CType(Control.Parent, Object).Children.Remove(Control)
Else
Control.Visibility = Visibility.Collapsed
@@ -304,6 +307,7 @@ Partial Public Module ModAnimation
}, "MyCard Dispose " & Control.Uuid)
Else
If RemoveFromChildren Then
If Control.Parent Is Nothing Then Exit Sub
CType(Control.Parent, Object).Children.Remove(Control)
Else
Control.Visibility = Visibility.Collapsed
@@ -130,7 +130,7 @@
If Not AllowMouseDown Then Exit Sub
MouseDowned = True
Focus()
AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrush9", 100), "MyCheckBox Background " & Uuid)
AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushBg1", 100), "MyCheckBox Background " & Uuid)
If Checked Then
AniStart({
AaScale(ShapeBorder, 16.5 - ShapeBorder.Width, 1000, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True),
+17 -21
View File
@@ -62,44 +62,40 @@
'指向动画
Public Sub RefreshColor() Handles Me.IsEnabledChanged, Me.MouseEnter, Me.MouseLeave, Me.PreviewMouseLeftButtonDown, Me.PreviewMouseLeftButtonUp, Me.GotKeyboardFocus
'判断当前颜色
Dim ColorName As String
Dim BackName As String
Dim ForeColorName As String
Dim BackColorName As String
Dim Time As Integer
If IsEnabled Then
If IsEditable AndAlso Template.FindName("PART_EditableTextBox", Me).IsFocused Then
ColorName = "ColorBrush4"
BackName = "ColorBrush9"
Time = 60
ElseIf IsMouseDown OrElse IsDropDownOpen Then
ColorName = "ColorBrush3"
BackName = "ColorBrush9"
Time = 60
If IsMouseDown OrElse IsDropDownOpen OrElse (IsEditable AndAlso Template.FindName("PART_EditableTextBox", Me).IsFocused) Then
ForeColorName = "ColorBrush3"
BackColorName = "ColorBrush7"
Time = 10
ElseIf IsMouseOver Then
ColorName = "ColorBrush3"
BackName = "ColorBrushHalfWhite"
ForeColorName = "ColorBrush4"
BackColorName = "ColorBrush7"
Time = 100
Else
ColorName = "ColorBrush1"
BackName = "ColorBrushHalfWhite"
Time = 200
ForeColorName = "ColorBrushBg0"
BackColorName = "ColorBrushHalfWhite"
Time = 100
End If
Else
ColorName = "ColorBrushGray4"
BackName = "ColorBrushHalfWhite"
ForeColorName = "ColorBrushGray5"
BackColorName = "ColorBrushGray6"
Time = 200
End If
'触发颜色动画
If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
'有动画
AniStart({
AaColor(Me, ForegroundProperty, ColorName, Time),
AaColor(Me, BackgroundProperty, BackName, Time)
AaColor(Me, ForegroundProperty, ForeColorName, Time),
AaColor(Me, BackgroundProperty, BackColorName, Time)
}, "MyComboBox Color " & Uuid)
Else
'无动画
AniStop("MyComboBox Color " & Uuid)
SetResourceReference(ForegroundProperty, ColorName)
SetResourceReference(BackgroundProperty, BackName)
SetResourceReference(ForegroundProperty, ForeColorName)
SetResourceReference(BackgroundProperty, BackColorName)
End If
End Sub
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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="MyExtraButton"
Width="40" RenderTransformOrigin="0.5,0.5" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="16" ToolTipService.HorizontalOffset="-8" Height="0">
Width="40" RenderTransformOrigin="0.5,0.5" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="16" ToolTipService.HorizontalOffset="-8" Height="0">
<Grid.RenderTransform>
<ScaleTransform ScaleX="0" ScaleY="0" />
</Grid.RenderTransform>
@@ -231,7 +231,7 @@
.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale},
.SnapsToDevicePixels = True, .UseLayoutRounding = False}
RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.Linear)
ElseIf _Logo.ToLower.EndsWith(".png") Then
ElseIf _Logo.ToLower.EndsWith(".png") OrElse _Logo.ToLower.EndsWith(".jpg") Then
'位图
Dim Bitmap = New MyBitmap(_Logo)
PathLogo = New Canvas With {
@@ -461,8 +461,8 @@
AniStart(Anim, "MyListItem Checked " & Uuid)
Else
'不使用动画
AniStop("MyListItem Checked " & Uuid)
If Checked Then
'If Not IsNothing(RectCheck) Then RectCheck.Width = 4
If Not IsNothing(RectCheck) Then
RectCheck.Height = Double.NaN
RectCheck.Margin = New Thickness(-1, 6, 0, 6)
@@ -471,7 +471,6 @@
End If
SetResourceReference(ForegroundProperty, "ColorBrush3")
Else
'If Not IsNothing(RectCheck) Then RectCheck.Width = 0
If Not IsNothing(RectCheck) Then
RectCheck.Height = 0
RectCheck.Margin = New Thickness(-1, 0, 0, 0)
@@ -507,27 +506,26 @@
'触发点击事件
Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
If IsMouseDown Then
RaiseEvent Click(sender, e)
If e.Handled Then Exit Sub
'触发自定义事件
If Not String.IsNullOrEmpty(EventType) Then
ModEvent.TryStartEvent(EventType, EventData)
e.Handled = True
End If
If e.Handled Then Exit Sub
'实际的单击处理
Select Case Type
Case CheckType.Clickable
Log("[Control] 按下单击列表项:" & Title)
Case CheckType.RadioBox
Log("[Control] 按下单选列表项:" & Title)
If Not Checked Then SetChecked(True, True, True)
Case CheckType.CheckBox
Log("[Control] 按下复选列表项(" & (Not Checked).ToString & "):" & Title)
SetChecked(Not Checked, True, True)
End Select
If Not IsMouseDown Then Exit Sub
RaiseEvent Click(sender, e)
If e.Handled Then Exit Sub
'触发自定义事件
If Not String.IsNullOrEmpty(EventType) Then
ModEvent.TryStartEvent(EventType, EventData)
e.Handled = True
End If
If e.Handled Then Exit Sub
'实际的单击处理
Select Case Type
Case CheckType.Clickable
Log("[Control] 按下单击列表项:" & Title)
Case CheckType.RadioBox
Log("[Control] 按下单选列表项:" & Title)
If Not Checked Then SetChecked(True, True, True)
Case CheckType.CheckBox
Log("[Control] 按下复选列表项(" & (Not Checked).ToString & "):" & Title)
SetChecked(Not Checked, True, True)
End Select
'AniStart({
' AaScaleTransform(Me, 1.004 - CType(RenderTransform, ScaleTransform).ScaleX, 150,, New AniEaseOutFluent),
' AaScaleTransform(Me, -0.004, 100, 150, New AniEaseInFluent)
@@ -603,7 +601,7 @@
If IsMouseOver AndAlso IsMouseOverAnimationEnabled Then
If ButtonStack IsNot Nothing Then Ani.Add(AaOpacity(ButtonStack, 1 - ButtonStack.Opacity, Time * 0.7, Time * 0.3))
Ani.AddRange({
AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrush9"), Time),
AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrushBg1"), Time),
AaOpacity(RectBack, 1 - RectBack.Opacity, Time,, New AniEaseOutFluent)
})
If IsScaleAnimationEnabled Then
@@ -630,7 +628,7 @@
If IsMouseOver AndAlso IsMouseOverAnimationEnabled Then
If ButtonStack IsNot Nothing Then ButtonStack.Opacity = 1
'由于鼠标已经移入,所以直接实例化 RectBack
RectBack.Background = Color9
RectBack.Background = ColorBg1
RectBack.Opacity = 1
RectBack.RenderTransform = New ScaleTransform(1, 1)
Me.RenderTransform = New ScaleTransform(1, 1)
@@ -638,9 +636,9 @@
If ButtonStack IsNot Nothing Then ButtonStack.Opacity = 0
Me.RenderTransform = New ScaleTransform(1, 1)
If _RectBack IsNot Nothing Then
If IsScaleAnimationEnabled Then RectBack.Background = Color7
If IsScaleAnimationEnabled Then RectBack.RenderTransform = New ScaleTransform(0.75, 0.75)
RectBack.Background = Color7
RectBack.Opacity = 0
RectBack.RenderTransform = New ScaleTransform(0.75, 0.75)
End If
End If
AniStop("ListItem Color " & Uuid)
@@ -2,22 +2,38 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:PCL"
UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="500" HorizontalAlignment="Center" VerticalAlignment="Center">
<Border Name="PanBorder" CornerRadius="5" Width="{Binding ActualWidth, ElementName=PanMain, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=PanMain, Mode=OneWay}" Background="#00FBFBFB">
RenderTransformOrigin="0,0.5" UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="25">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="TransformRotate" Angle="-4" />
<TranslateTransform x:Name="TransformPos" X="0" Y="40" />
</TransformGroup>
</Grid.RenderTransform>
<Border Name="PanBorder" CornerRadius="7" Background="#FBFBFB">
<Border.Effect>
<DropShadowEffect Color="{DynamicResource ColorObject1}" BlurRadius="15" ShadowDepth="0" Opacity="0" x:Name="EffectShadow" />
<DropShadowEffect Color="{DynamicResource ColorObject1}" BlurRadius="20" ShadowDepth="4" RenderingBias="Performance" Opacity="0.8" x:Name="EffectShadow" />
</Border.Effect>
<Grid Name="PanMain" VerticalAlignment="Top" Margin="22,22,22,23">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="2" />
<RowDefinition Height="13" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="23" TextTrimming="None" Foreground="{DynamicResource ColorBrush2}" HorizontalAlignment="Left" Name="LabTitle" Margin="7,-1,70,9" Text="测试标题文本" VerticalAlignment="Top" SnapsToDevicePixels="False" UseLayoutRounding="False" />
<Rectangle x:Name="ShapeLine" Grid.Row="1" Height="2" Fill="{Binding Foreground, ElementName=LabTitle}" />
<my:MyScrollViewer Grid.Row="3" VerticalAlignment="Top" x:Name="PanText" Margin="0,0,0,7" Padding="7,0,15,0"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" DeltaMuity="0.7">
<TextBlock VerticalAlignment="Top" TextTrimming="None" TextWrapping="Wrap" Name="LabText" FontSize="15" LineHeight="18"
Foreground="#FF5C5C5C" FontWeight="Normal" Padding="1" />
</my:MyScrollViewer>
<my:MyTextBox Grid.Row="4" Margin="7,0,7,12" x:Name="TextArea" UseLayoutRounding="False" MaxLength="1000" MinWidth="450" />
<StackPanel Grid.Row="5" Name="PanBtn" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="150,0,8,0" Orientation="Horizontal">
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮1" x:Name="Btn1" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮2" x:Name="Btn2" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
</StackPanel>
</Grid>
</Border>
<StackPanel Name="PanMain" VerticalAlignment="Top">
<TextBlock FontSize="23" TextTrimming="None" Foreground="{DynamicResource ColorBrush2}" HorizontalAlignment="Left" Name="LabTitle" Margin="27,19,28,0" Text="测试标题文本" VerticalAlignment="Top" SnapsToDevicePixels="False" UseLayoutRounding="False" />
<Rectangle Height="2" Fill="{DynamicResource ColorBrush2}" Margin="20,9,20,15" Name="ShapeLine" Opacity="0" />
<Border Name="PanCaption" Padding="28,0,28,15">
<my:MyTextBox x:Name="TextCaption" UseLayoutRounding="False" MaxLength="1000" Width="450" Margin="1" />
</Border>
<StackPanel Name="PanBtn" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="150,0,22,20" Orientation="Horizontal">
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮1" x:Name="Btn1" Margin="15,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮2" x:Name="Btn2" Margin="15,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮3" x:Name="Btn3" Margin="15,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
</StackPanel>
</StackPanel>
</Grid>
@@ -9,26 +9,21 @@
InitializeComponent()
Btn1.Name = Btn1.Name & GetUuid()
Btn2.Name = Btn2.Name & GetUuid()
Btn3.Name = Btn3.Name & GetUuid()
MyConverter = Converter
LabTitle.Text = Converter.Title
TextCaption.Text = Converter.Content
TextCaption.HintText = Converter.HintText
TextCaption.ValidateRules = Converter.ValidateRules
LabText.Text = Converter.Text
PanText.Visibility = If(Converter.Text = "", Visibility.Collapsed, Visibility.Visible)
TextArea.Text = Converter.Content
TextArea.HintText = Converter.HintText
TextArea.ValidateRules = Converter.ValidateRules
Btn1.Text = Converter.Button1
If Converter.IsWarn Then
Btn1.ColorType = MyButton.ColorState.Red
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrushRedLight")
ShapeLine.SetResourceReference(Rectangle.FillProperty, "ColorBrushRedLight")
End If
Btn2.Text = Converter.Button2
Btn3.Text = Converter.Button3
Btn2.Visibility = If(Converter.Button2 = "", Visibility.Collapsed, Visibility.Visible)
Btn3.Visibility = If(Converter.Button3 = "", Visibility.Collapsed, Visibility.Visible)
'If Converter.Caption > 0 Then
' TextCaption.Focus()
' TextCaption.Select(Converter.Caption.Length - 1, 0)
'End If
ShapeLine.StrokeThickness = GetWPFSize(1)
Catch ex As Exception
Log(ex, "输入弹窗初始化失败", LogLevel.Hint)
@@ -40,39 +35,16 @@
'UI 初始化
If Btn2.IsVisible AndAlso Not Btn1.ColorType = MyButton.ColorState.Red Then Btn1.ColorType = MyButton.ColorState.Highlight
ShapeLine.StrokeThickness = GetWPFSize(1)
Measure(New Size(FrmMain.Width, FrmMain.Height))
Arrange(New Rect(0, 0, FrmMain.Width, FrmMain.Height))
If FrmMain.Width - ActualWidth < 20 Then Width = FrmMain.Width - GetWPFSize(2)
TextCaption.Focus()
TextArea.Focus()
TextArea.SelectionStart = TextArea.Text.Length
'动画
Opacity = 0
AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, If(MyConverter.IsWarn, New MyColor(140, 80, 0, 0), New MyColor(90, 0, 0, 0)) - FrmMain.PanMsg.Background, 200), "PanMsg Background")
AniStart({
AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(60, 0, 0, 0), 250, , New AniEaseInFluent),
AaColor(PanBorder, Border.BackgroundProperty, New MyColor(255, 0, 0, 0), 150, , New AniEaseInFluent),
AaOpacity(EffectShadow, 0.75, 400, 50),
AaWidth(ShapeLine, ShapeLine.ActualWidth, 250, 100, New AniEaseOutFluent),
AaOpacity(ShapeLine, 1, 200, 100),
AaWidth(LabTitle, LabTitle.ActualWidth, 200, 100, New AniEaseOutFluent),
AaOpacity(LabTitle, 1, 150, 150),
AaOpacity(PanCaption, 1, 150, 150),
AaOpacity(Btn1, 1, 150, 100),
AaOpacity(Btn2, 1, 150, 150),
AaOpacity(Btn3, 1, 150, 200),
AaCode(Sub()
ShapeLine.MinWidth = ShapeLine.ActualWidth
ShapeLine.HorizontalAlignment = HorizontalAlignment.Stretch
ShapeLine.Width = Double.NaN
LabTitle.Width = Double.NaN
LabTitle.TextTrimming = TextTrimming.CharacterEllipsis
End Sub, 350)
}, "MyMsgBox Start " & Uuid)
'动画初始化
ShapeLine.Width = 0
ShapeLine.HorizontalAlignment = HorizontalAlignment.Center
LabTitle.Width = 0
LabTitle.Opacity = 0
LabTitle.TextWrapping = TextWrapping.NoWrap
PanCaption.Opacity = 0
AaOpacity(Me, 1, 120, 60),
AaDouble(Sub(i) TransformPos.Y += i, -TransformPos.Y, 300, 60, New AniEaseOutBack(AniEasePower.Weak)),
AaDouble(Sub(i) TransformRotate.Angle += i, -TransformRotate.Angle, 300, 60, New AniEaseOutFluent(AniEasePower.Weak))
}, "MyMsgBox " & Uuid)
'记录日志
Log("[Control] 输入弹窗:" & LabTitle.Text)
@@ -84,29 +56,24 @@
'结束线程阻塞
MyConverter.WaitFrame.Continue = False
Interop.ComponentDispatcher.PopModal()
'弹窗动画
LabTitle.TextTrimming = TextTrimming.None
LabTitle.TextWrapping = TextWrapping.NoWrap
'动画
AniStart({
AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(-60, 0, 0, 0), 350, , New AniEaseInFluent),
AaColor(PanBorder, Border.BackgroundProperty, New MyColor(-255, 0, 0, 0), 300, 100, New AniEaseInFluent),
AaOpacity(EffectShadow, -0.75, 150),
AaWidth(ShapeLine, -ShapeLine.ActualWidth, 250, , New AniEaseInFluent),
AaOpacity(ShapeLine, -1, 150, 100),
AaWidth(LabTitle, -LabTitle.ActualWidth, 250),
AaOpacity(LabTitle, -1, 200),
AaOpacity(PanCaption, -1, 200),
AaOpacity(Btn1, -1, 150),
AaOpacity(Btn2, -1, 150, 50),
AaOpacity(Btn3, -1, 150, 100),
AaCode(Sub()
If WaitingMyMsgBox.Count = 0 Then
AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(0, 0, 0, 0) - FrmMain.PanMsg.Background, 200, Ease:=New AniEaseOutFluent(AniEasePower.Weak)))
End If
End Sub, 30),
AaOpacity(Me, -Opacity, 80, 20),
AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 150, 0, New AniEaseOutFluent),
AaDouble(Sub(i) TransformRotate.Angle += i, 6 - TransformRotate.Angle, 150, 0, New AniEaseInFluent(AniEasePower.Weak)),
AaCode(Sub() CType(Parent, Grid).Children.Remove(Me), , True)
}, "MyMsgBox Close " & Uuid)
}, "MyMsgBox " & Uuid)
End Sub
Public Sub Btn1_Click() Handles Btn1.Click
If MyConverter.IsExited OrElse Not TextCaption.ValidateResult = "" Then Exit Sub
If MyConverter.IsExited OrElse Not TextArea.ValidateResult = "" Then Exit Sub
MyConverter.IsExited = True
MyConverter.Result = TextCaption.Text
MyConverter.Result = TextArea.Text
Close()
End Sub
Public Sub Btn2_Click() Handles Btn2.Click
@@ -115,15 +82,9 @@
MyConverter.Result = Nothing
Close()
End Sub
Public Sub Btn3_Click() Handles Btn3.Click
If MyConverter.IsExited Then Exit Sub
MyConverter.IsExited = True
MyConverter.Result = Nothing
Close()
End Sub
Private Sub TextCaption_ValidateChanged(sender As Object, e As EventArgs) Handles TextCaption.ValidateChanged
Btn1.IsEnabled = TextCaption.ValidateResult = ""
Private Sub TextCaption_ValidateChanged(sender As Object, e As EventArgs) Handles TextArea.ValidateChanged
Btn1.IsEnabled = TextArea.ValidateResult = ""
End Sub
Private Sub Drag(sender As Object, e As MouseButtonEventArgs) Handles PanBorder.MouseLeftButtonDown, LabTitle.MouseLeftButtonDown
@@ -1,27 +1,36 @@
<Grid x:Name="PanBack" x:Class="MyMsgSelect"
<Grid x:Class="MyMsgSelect"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:PCL"
UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="450" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Name="PanBorder" Grid.RowSpan="99" Width="{Binding ActualWidth, ElementName=PanBack, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=PanBack, Mode=OneWay}" Background="#00FBFBFB" CornerRadius="5">
RenderTransformOrigin="0,0.5" UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="25">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="TransformRotate" Angle="-4" />
<TranslateTransform x:Name="TransformPos" X="0" Y="40" />
</TransformGroup>
</Grid.RenderTransform>
<Border Name="PanBorder" CornerRadius="7" Background="#FBFBFB">
<Border.Effect>
<DropShadowEffect Color="{DynamicResource ColorObject1}" BlurRadius="15" ShadowDepth="0" Opacity="0" x:Name="EffectShadow" />
<DropShadowEffect Color="{DynamicResource ColorObject1}" BlurRadius="20" ShadowDepth="4" RenderingBias="Performance" Opacity="0.8" x:Name="EffectShadow" />
</Border.Effect>
<Grid Name="PanMain" VerticalAlignment="Top" Margin="22,22,22,23">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="2" />
<RowDefinition Height="13" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="23" TextTrimming="None" Foreground="{DynamicResource ColorBrush2}" HorizontalAlignment="Left" Name="LabTitle" Margin="7,-1,70,9" Text="测试标题文本" VerticalAlignment="Top" SnapsToDevicePixels="False" UseLayoutRounding="False" />
<Rectangle x:Name="ShapeLine" Grid.Row="1" Height="2" Fill="{Binding Foreground, ElementName=LabTitle}" />
<my:MyScrollViewer Grid.Row="3" VerticalAlignment="Top" x:Name="PanCaption" Margin="0,0,0,17" Padding="7,0,15,0"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" DeltaMuity="0.7">
<StackPanel x:Name="PanSelection" Orientation="Vertical" />
</my:MyScrollViewer>
<StackPanel Grid.Row="4" Name="PanBtn" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="150,0,8,0" Orientation="Horizontal">
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮1" x:Name="Btn1" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮2" x:Name="Btn2" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
</StackPanel>
</Grid>
</Border>
<TextBlock FontSize="23" TextTrimming="None" Foreground="{DynamicResource ColorBrush2}" HorizontalAlignment="Left" Name="LabTitle" Margin="28,19,28,0" Text="测试标题文本" VerticalAlignment="Top" SnapsToDevicePixels="False" UseLayoutRounding="False" />
<Rectangle Height="2" Grid.Row="1" Fill="{DynamicResource ColorBrush2}" Margin="20,9,20,13" Name="ShapeLine" Opacity="0" />
<my:MyScrollViewer x:Name="PanCaption" Grid.Row="2" Margin="19,0,19,20" Padding="9,0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" SnapsToDevicePixels="True" UseLayoutRounding="True" DeltaMuity="0.5">
<StackPanel x:Name="PanSelection" Orientation="Vertical" />
</my:MyScrollViewer>
<StackPanel Name="PanBtn" Grid.Row="3" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="150,0,22,20" Orientation="Horizontal">
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮1" x:Name="Btn1" Margin="15,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" IsEnabled="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮2" x:Name="Btn2" Margin="15,0,0,0" TextPadding="7" Visibility="Visible" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮3" x:Name="Btn3" TextPadding="7" Margin="15,0,0,0" Visibility="Visible" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
</StackPanel>
</Grid>
</Grid>
@@ -9,20 +9,18 @@
InitializeComponent()
Btn1.Name = Btn1.Name & GetUuid()
Btn2.Name = Btn2.Name & GetUuid()
Btn3.Name = Btn3.Name & GetUuid()
MyConverter = Converter
LabTitle.Text = Converter.Title
Btn1.Text = Converter.Button1
If Converter.IsWarn Then
Btn1.ColorType = MyButton.ColorState.Red
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrushRedLight")
ShapeLine.SetResourceReference(Rectangle.FillProperty, "ColorBrushRedLight")
End If
Btn2.Text = Converter.Button2
Btn3.Text = Converter.Button3
Btn2.Visibility = If(Converter.Button2 = "", Visibility.Collapsed, Visibility.Visible)
Btn3.Visibility = If(Converter.Button3 = "", Visibility.Collapsed, Visibility.Visible)
ShapeLine.StrokeThickness = GetWPFSize(1)
'添加选择控件
Btn1.IsEnabled = False
For Each Selection As IMyRadio In Converter.Content
PanSelection.Children.Add(Selection)
AddHandler Selection.Check, AddressOf OnChecked
@@ -30,7 +28,7 @@
CType(Selection, MyListItem).Type = MyListItem.CheckType.RadioBox
CType(Selection, MyListItem).MinHeight = 24
Else
CType(Selection, MyRadioBox).MinHeight = 26
CType(Selection, MyRadioBox).MinHeight = 24
End If
Next
@@ -44,38 +42,14 @@
'UI 初始化
If Btn2.IsVisible AndAlso Not Btn1.ColorType = MyButton.ColorState.Red Then Btn1.ColorType = MyButton.ColorState.Highlight
ShapeLine.StrokeThickness = GetWPFSize(1)
Measure(New Size(FrmMain.Width, FrmMain.Height))
Arrange(New Rect(0, 0, FrmMain.Width, FrmMain.Height))
If FrmMain.Width - ActualWidth < 20 Then Width = FrmMain.Width - GetWPFSize(2)
'动画
Opacity = 0
AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, If(MyConverter.IsWarn, New MyColor(140, 80, 0, 0), New MyColor(90, 0, 0, 0)) - FrmMain.PanMsg.Background, 200), "PanMsg Background")
AniStart({
AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(60, 0, 0, 0), 250, , New AniEaseInFluent),
AaColor(PanBorder, Border.BackgroundProperty, New MyColor(255, 0, 0, 0), 150, , New AniEaseInFluent),
AaOpacity(EffectShadow, 0.75, 400, 50),
AaWidth(ShapeLine, ShapeLine.ActualWidth, 250, 100, New AniEaseOutFluent),
AaOpacity(ShapeLine, 1, 200, 100),
AaWidth(LabTitle, LabTitle.ActualWidth, 200, 100, New AniEaseOutFluent),
AaOpacity(LabTitle, 1, 150, 150),
AaOpacity(PanCaption, 1, 150, 150),
AaOpacity(Btn1, 1, 150, 100),
AaOpacity(Btn2, 1, 150, 150),
AaOpacity(Btn3, 1, 150, 200),
AaCode(Sub()
ShapeLine.MinWidth = ShapeLine.ActualWidth
ShapeLine.HorizontalAlignment = HorizontalAlignment.Stretch
ShapeLine.Width = Double.NaN
LabTitle.Width = Double.NaN
LabTitle.TextTrimming = TextTrimming.CharacterEllipsis
End Sub, 350)
}, "MyMsgBox Start " & Uuid)
'动画初始化
ShapeLine.Width = 0
ShapeLine.HorizontalAlignment = HorizontalAlignment.Center
LabTitle.Width = 0
LabTitle.Opacity = 0
LabTitle.TextWrapping = TextWrapping.NoWrap
PanCaption.Opacity = 0
AaOpacity(Me, 1, 120, 60),
AaDouble(Sub(i) TransformPos.Y += i, -TransformPos.Y, 300, 60, New AniEaseOutBack(AniEasePower.Weak)),
AaDouble(Sub(i) TransformRotate.Angle += i, -TransformRotate.Angle, 300, 60, New AniEaseOutFluent(AniEasePower.Weak))
}, "MyMsgBox " & Uuid)
'记录日志
Log("[Control] 选择弹窗:" & LabTitle.Text)
@@ -87,23 +61,18 @@
'结束线程阻塞
MyConverter.WaitFrame.Continue = False
Interop.ComponentDispatcher.PopModal()
'弹窗动画
LabTitle.TextTrimming = TextTrimming.None
LabTitle.TextWrapping = TextWrapping.NoWrap
'动画
AniStart({
AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(-60, 0, 0, 0), 350, , New AniEaseInFluent),
AaColor(PanBorder, Border.BackgroundProperty, New MyColor(-255, 0, 0, 0), 300, 100, New AniEaseInFluent),
AaOpacity(EffectShadow, -0.75, 150),
AaWidth(ShapeLine, -ShapeLine.ActualWidth, 250, , New AniEaseInFluent),
AaOpacity(ShapeLine, -1, 150, 100),
AaWidth(LabTitle, -LabTitle.ActualWidth, 250),
AaOpacity(LabTitle, -1, 200),
AaOpacity(PanCaption, -1, 200),
AaOpacity(Btn1, -1, 150),
AaOpacity(Btn2, -1, 150, 50),
AaOpacity(Btn3, -1, 150, 100),
AaCode(Sub()
If WaitingMyMsgBox.Count = 0 Then
AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(0, 0, 0, 0) - FrmMain.PanMsg.Background, 200, Ease:=New AniEaseOutFluent(AniEasePower.Weak)))
End If
End Sub, 30),
AaOpacity(Me, -Opacity, 80, 20),
AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 150, 0, New AniEaseOutFluent),
AaDouble(Sub(i) TransformRotate.Angle += i, 6 - TransformRotate.Angle, 150, 0, New AniEaseInFluent(AniEasePower.Weak)),
AaCode(Sub() CType(Parent, Grid).Children.Remove(Me), , True)
}, "MyMsgBox Close " & Uuid)
}, "MyMsgBox " & Uuid)
End Sub
Public Sub Btn1_Click() Handles Btn1.Click
@@ -118,12 +87,6 @@
MyConverter.Result = Nothing
Close()
End Sub
Public Sub Btn3_Click() Handles Btn3.Click
If MyConverter.IsExited Then Exit Sub
MyConverter.IsExited = True
MyConverter.Result = Nothing
Close()
End Sub
Private SelectedIndex As Integer = -1
Private Sub OnChecked(sender As IMyRadio, e As EventArgs)
@@ -1,27 +1,38 @@
<Grid x:Name="PanBack" x:Class="MyMsgText"
<Grid x:Class="MyMsgText"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:PCL"
UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="450" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Name="PanBorder" Grid.RowSpan="99" Background="#00FBFBFB" CornerRadius="5">
RenderTransformOrigin="0,0.5" UseLayoutRounding="True" SnapsToDevicePixels="True" MinWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="25">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="TransformRotate" Angle="-4" />
<TranslateTransform x:Name="TransformPos" X="0" Y="40" />
</TransformGroup>
</Grid.RenderTransform>
<Border Name="PanBorder" CornerRadius="7" Background="#FBFBFB">
<Border.Effect>
<DropShadowEffect Color="{DynamicResource ColorObject1}" BlurRadius="15" ShadowDepth="0" Opacity="0" x:Name="EffectShadow" />
<DropShadowEffect Color="{DynamicResource ColorObject1}" BlurRadius="20" ShadowDepth="4" RenderingBias="Performance" Opacity="0.8" x:Name="EffectShadow" />
</Border.Effect>
<Grid Name="PanMain" VerticalAlignment="Top" Margin="22,22,22,23">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="2" />
<RowDefinition Height="13" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="23" TextTrimming="None" Foreground="{DynamicResource ColorBrush2}" HorizontalAlignment="Left" Name="LabTitle" Margin="7,-1,70,9" Text="测试标题文本" VerticalAlignment="Top" SnapsToDevicePixels="False" UseLayoutRounding="False" />
<Rectangle x:Name="ShapeLine" Grid.Row="1" Height="2" Fill="{Binding Foreground, ElementName=LabTitle}" />
<my:MyScrollViewer Grid.Row="3" VerticalAlignment="Top" x:Name="PanCaption" Margin="0,0,0,17" Padding="7,0,15,0"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" DeltaMuity="0.7">
<TextBlock VerticalAlignment="Top" TextTrimming="None" TextWrapping="Wrap" Name="LabCaption" FontSize="15" LineHeight="18"
Foreground="#FF5C5C5C" FontWeight="Normal" Padding="1" />
</my:MyScrollViewer>
<StackPanel Grid.Row="4" Name="PanBtn" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="150,0,8,0" Orientation="Horizontal">
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮1" x:Name="Btn1" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮2" x:Name="Btn2" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮3" x:Name="Btn3" Margin="12,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" UseLayoutRounding="False" />
</StackPanel>
</Grid>
</Border>
<TextBlock FontSize="23" TextTrimming="None" Foreground="{DynamicResource ColorBrush2}" HorizontalAlignment="Left" Name="LabTitle" Margin="28,19,28,0" Text="测试标题文本" VerticalAlignment="Top" SnapsToDevicePixels="False" UseLayoutRounding="False" />
<Rectangle Height="2" Grid.Row="1" Fill="{DynamicResource ColorBrush2}" Margin="20,9,20,13" Name="ShapeLine" Opacity="0" />
<my:MyScrollViewer VerticalAlignment="Top" x:Name="PanCaption" Grid.Row="2" Margin="19,0,19,20" Padding="9,0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" SnapsToDevicePixels="True" UseLayoutRounding="True" DeltaMuity="0.5">
<TextBlock VerticalAlignment="Top" TextTrimming="None" TextWrapping="Wrap" Name="LabCaption" FontSize="15" Foreground="#FF5C5C5C" FontWeight="Normal" Padding="1" />
</my:MyScrollViewer>
<StackPanel Name="PanBtn" Grid.Row="3" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="150,0,22,20" Orientation="Horizontal">
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮1" x:Name="Btn1" Margin="15,0,0,0" TextPadding="7" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮2" x:Name="Btn2" Margin="15,0,0,0" TextPadding="7" Visibility="Visible" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
<my:MyButton ColorType="Normal" x:FieldModifier="public" Text="测试按钮3" x:Name="Btn3" TextPadding="7" Margin="15,0,0,0" Visibility="Visible" SnapsToDevicePixels="False" Padding="5,0" Opacity="0" UseLayoutRounding="False" />
</StackPanel>
</Grid>
@@ -12,12 +12,11 @@
Btn3.Name = Btn3.Name & GetUuid()
MyConverter = Converter
LabTitle.Text = Converter.Title
LabCaption.Text = Converter.Content
LabCaption.Text = Converter.Text
Btn1.Text = Converter.Button1
If Converter.IsWarn Then
Btn1.ColorType = MyButton.ColorState.Red
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrushRedLight")
ShapeLine.SetResourceReference(Rectangle.FillProperty, "ColorBrushRedLight")
End If
Btn2.Text = Converter.Button2
Btn3.Text = Converter.Button3
@@ -35,37 +34,15 @@
'UI 初始化
If Btn2.IsVisible AndAlso Not Btn1.ColorType = MyButton.ColorState.Red Then Btn1.ColorType = MyButton.ColorState.Highlight
Measure(New Size(FrmMain.Width - 20, FrmMain.Height - 20))
Arrange(New Rect(0, 0, FrmMain.Width - 20, FrmMain.Height - 20))
Btn1.Focus()
'动画
Opacity = 0
AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, If(MyConverter.IsWarn, New MyColor(140, 80, 0, 0), New MyColor(90, 0, 0, 0)) - FrmMain.PanMsg.Background, 200), "PanMsg Background")
AniStart({
AaColor(FrmMain.PanMsg, BackgroundProperty, New MyColor(60, 0, 0, 0), 250, , New AniEaseInFluent),
AaColor(PanBorder, Border.BackgroundProperty, New MyColor(255, 0, 0, 0), 150, , New AniEaseInFluent),
AaOpacity(EffectShadow, 0.75, 400, 50),
AaWidth(ShapeLine, ShapeLine.ActualWidth, 250, 100, New AniEaseOutFluent),
AaOpacity(ShapeLine, 1, 200, 100),
AaWidth(LabTitle, LabTitle.ActualWidth, 200, 150, New AniEaseOutFluent),
AaOpacity(LabTitle, 1, 150, 150),
AaOpacity(PanCaption, 1, 150, 150),
AaOpacity(Btn1, 1, 150, 100),
AaOpacity(Btn2, 1, 150, 150),
AaOpacity(Btn3, 1, 150, 200),
AaCode(Sub()
ShapeLine.MinWidth = ShapeLine.ActualWidth
ShapeLine.HorizontalAlignment = HorizontalAlignment.Stretch
ShapeLine.Width = Double.NaN
LabTitle.Width = Double.NaN
LabTitle.TextTrimming = TextTrimming.CharacterEllipsis
End Sub, 350)
}, "MyMsgBox Start " & Uuid)
'动画初始化
ShapeLine.Width = 0
ShapeLine.HorizontalAlignment = HorizontalAlignment.Center
LabTitle.Width = 0
LabTitle.Opacity = 0
LabTitle.TextWrapping = TextWrapping.NoWrap
PanCaption.Opacity = 0
AaOpacity(Me, 1, 120, 60),
AaDouble(Sub(i) TransformPos.Y += i, -TransformPos.Y, 300, 60, New AniEaseOutBack(AniEasePower.Weak)),
AaDouble(Sub(i) TransformRotate.Angle += i, -TransformRotate.Angle, 300, 60, New AniEaseOutFluent(AniEasePower.Weak))
}, "MyMsgBox " & Uuid)
'记录日志
Log("[Control] 普通弹窗:" & LabTitle.Text & vbCrLf & LabCaption.Text)
@@ -77,25 +54,18 @@
'结束线程阻塞
If MyConverter.ForceWait OrElse Not MyConverter.Button2 = "" Then MyConverter.WaitFrame.Continue = False
Interop.ComponentDispatcher.PopModal()
'弹窗动画
LabTitle.TextTrimming = TextTrimming.None
LabTitle.TextWrapping = TextWrapping.NoWrap
'动画
AniStart({
AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(-60, 0, 0, 0), 350, , New AniEaseInFluent),
AaColor(PanBorder, Border.BackgroundProperty, New MyColor(-255, 0, 0, 0), 300, 100, New AniEaseInFluent),
AaOpacity(EffectShadow, -0.75, 150),
AaWidth(ShapeLine, -ShapeLine.ActualWidth, 250, , New AniEaseInFluent(AniEasePower.Weak)),
AaOpacity(ShapeLine, -1, 200),
AaWidth(LabTitle, -LabTitle.ActualWidth, 250),
AaOpacity(LabTitle, -1, 200),
AaOpacity(PanCaption, -1, 200),
AaOpacity(Btn1, -1, 150),
AaOpacity(Btn2, -1, 150, 50),
AaOpacity(Btn3, -1, 150, 100),
AaCode(Sub()
If WaitingMyMsgBox.Count = 0 Then
AniStart(AaColor(FrmMain.PanMsg, Grid.BackgroundProperty, New MyColor(0, 0, 0, 0) - FrmMain.PanMsg.Background, 200, Ease:=New AniEaseOutFluent(AniEasePower.Weak)))
End If
End Sub, 30),
AaOpacity(Me, -Opacity, 80, 20),
AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 150, 0, New AniEaseOutFluent),
AaDouble(Sub(i) TransformRotate.Angle += i, 6 - TransformRotate.Angle, 150, 0, New AniEaseInFluent(AniEasePower.Weak)),
AaCode(Sub() CType(Parent, Grid).Children.Remove(Me), , True)
}, "MyMsgBox Close " & Uuid)
'动画初始化
ShapeLine.MinWidth = 0
}, "MyMsgBox " & Uuid)
End Sub
Public Sub Btn1_Click() Handles Btn1.Click
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
FocusVisualStyle="{x:Null}"
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" Text="Radiobox" 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="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>
@@ -170,12 +170,12 @@
MouseDowned = False
Log("[Control] 按下单选框:" & Text)
SetChecked(True, True, True)
AniStart(AaColor(ShapeBorder, Shapes.Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
End Sub
Private Sub Radiobox_MouseDown() Handles Me.MouseLeftButtonDown
MouseDowned = True
Focus()
AniStart(AaColor(ShapeBorder, Shapes.Ellipse.FillProperty, "ColorBrush9", 100), "MyRadioBox Background " & Uuid)
AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushBg1", 100), "MyRadioBox Background " & Uuid)
If Not Checked Then
AniStart(AaScale(ShapeBorder, 16.5 - ShapeBorder.Width, 1000, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True), "MyRadioBox Border " & Uuid)
End If
@@ -183,7 +183,7 @@
Private Sub Radiobox_MouseLeave() Handles Me.MouseLeave
If Not MouseDowned Then Exit Sub
MouseDowned = False
AniStart(AaColor(ShapeBorder, Shapes.Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
AniStart(AaColor(ShapeBorder, Ellipse.FillProperty, "ColorBrushHalfWhite", 100), "MyRadioBox Background " & Uuid)
If Not Checked Then
AniStart(AaScale(ShapeBorder, 18 - ShapeBorder.Width, 400, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True), "MyRadioBox Border " & Uuid)
End If
@@ -223,6 +223,8 @@
AniStart(AaColor(ShapeBorder, Ellipse.StrokeProperty, If(IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray4"), AnimationTimeOfMouseOut), "MyRadioBox BorderColor " & Uuid)
AniStart(AaColor(LabText, TextBlock.ForegroundProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"), AnimationTimeOfMouseOut), "MyRadioBox TextColor " & Uuid)
Else
AniStop("MyRadioBox BorderColor " & Uuid)
AniStop("MyRadioBox TextColor " & Uuid)
ShapeBorder.SetResourceReference(Ellipse.StrokeProperty, If(IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray4"))
LabText.SetResourceReference(TextBlock.ForegroundProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"))
End If
@@ -6,11 +6,13 @@
mc:Ignorable="d"
d:DesignHeight="16" d:DesignWidth="162"
FocusVisualStyle="{x:Null}"
MinHeight="16" UseLayoutRounding="False" SnapsToDevicePixels="False" BorderBrush="{DynamicResource ColorBrush1}" Name="PanBack" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True">
MinHeight="16" UseLayoutRounding="False" SnapsToDevicePixels="False" BorderBrush="{DynamicResource ColorBrushBg0}" Name="PanBack" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True">
<Grid x:Name="PanMain" MinHeight="16" MaxHeight="16" IsHitTestVisible="False">
<Line Height="4" Name="LineBack" Stroke="{StaticResource ColorBrushGray5}" StrokeThickness="1.1" X2="10000" Y1="2" Y2="2" HorizontalAlignment="Right" Width="0" SnapsToDevicePixels="True" Margin="0,0,1,0" />
<Line Height="4" Name="LineFore" Stroke="{Binding ElementName=PanBack, Path=BorderBrush}" StrokeThickness="1.1" X2="10000" Y1="2" Y2="2" Width="0" HorizontalAlignment="Left" SnapsToDevicePixels="True" Margin="1,0,0,0" />
<Ellipse HorizontalAlignment="Left" Width="16" Stroke="{Binding BorderBrush, ElementName=PanBack}" StrokeThickness="1.1" Fill="{StaticResource ColorBrushHalfWhite}" Name="ShapeDot" Height="16" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Line Height="4" Name="LineBack" Stroke="{DynamicResource ColorBrushBg0}" Opacity="0.3" StrokeThickness="1" X2="10000" Y1="2" Y2="2" HorizontalAlignment="Right" Width="0" SnapsToDevicePixels="True" Margin="0,0,1,0" />
<Line Height="4" Name="LineFore" Stroke="{Binding ElementName=PanBack, Path=BorderBrush}" StrokeThickness="1" X2="10000" Y1="2" Y2="2" Width="0" HorizontalAlignment="Left" SnapsToDevicePixels="True" Margin="1,0,0,0" />
<Ellipse HorizontalAlignment="Left" Width="10" Height="10"
Stroke="{Binding BorderBrush, ElementName=PanBack}" StrokeThickness="1.2"
Fill="{DynamicResource ColorBrushBg0}" Name="ShapeDot" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<ScaleTransform />
</Ellipse.RenderTransform>
@@ -45,13 +45,13 @@
End If
If IsLoaded AndAlso AniControlEnabled = 0 Then
If ActualWidth < 16 Then Exit Property
Dim NewWidth As Double = _Value / MaxValue * (ActualWidth - 16)
Dim DeltaProcess As Double = Math.Abs(LineFore.Width / (ActualWidth - 16) - _Value / MaxValue)
If ActualWidth < ShapeDot.Width Then Exit Property
Dim NewWidth As Double = _Value / MaxValue * (ActualWidth - ShapeDot.Width)
Dim DeltaProcess As Double = Math.Abs(LineFore.Width / (ActualWidth - ShapeDot.Width) - _Value / MaxValue)
Dim Time As Double = (1 - Math.Pow(1 - DeltaProcess, 3)) * 300 + If(ChangeByKey, 100, 0)
AniStart({
AaWidth(LineFore, Math.Max(0, NewWidth + If(NewWidth < 0.5, 0, 0.5)) - LineFore.Width, Time,, If(Time > 50, New AniEaseOutFluent, New AniEaseLinear)),
AaWidth(LineBack, Math.Max(0, ActualWidth - 16 - NewWidth + If(ActualWidth - 16 - NewWidth < 0.5, 0, 0.5)) - LineBack.Width, Time,, If(Time > 50, New AniEaseOutFluent, New AniEaseLinear)),
AaWidth(LineBack, Math.Max(0, ActualWidth - ShapeDot.Width - NewWidth + If(ActualWidth - ShapeDot.Width - NewWidth < 0.5, 0, 0.5)) - LineBack.Width, Time,, If(Time > 50, New AniEaseOutFluent, New AniEaseLinear)),
AaX(ShapeDot, NewWidth - ShapeDot.Margin.Left, Time,, If(Time > 50, New AniEaseOutFluent, New AniEaseLinear))
}, "MySlider Progress " & Uuid)
Else
@@ -67,9 +67,9 @@
Private Sub RefreshWidth(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
If Not IsNothing(e) Then PanMain.Width = e.NewSize.Width
AniStop("MySlider Progress " & Uuid)
Dim NewWidth As Double = _Value / MaxValue * (ActualWidth - 16)
Dim NewWidth As Double = _Value / MaxValue * (ActualWidth - ShapeDot.Width)
LineFore.Width = Math.Max(0, NewWidth + If(NewWidth < 0.5, 0, 0.5))
LineBack.Width = Math.Max(0, ActualWidth - 16 - NewWidth + If(ActualWidth - 16 - NewWidth < 0.5, 0, 0.5))
LineBack.Width = Math.Max(0, ActualWidth - ShapeDot.Width - NewWidth + If(ActualWidth - ShapeDot.Width - NewWidth < 0.5, 0, 0.5))
SetLeft(ShapeDot, NewWidth)
End Sub
@@ -79,32 +79,36 @@
Private Sub DragStart(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
e.Handled = True '防止 ScrollViewer 失焦问题
DragControl = Me
RefreshColor()
FrmMain.DragDoing()
AniStart({
AaScaleTransform(ShapeDot, 0.8 - CType(ShapeDot.RenderTransform, ScaleTransform).ScaleX, 75,, New AniEaseOutFluent)
AaScaleTransform(ShapeDot, 1.3 - CType(ShapeDot.RenderTransform, ScaleTransform).ScaleX, 40,, New AniEaseOutFluent)
}, "MySlider Scale " & Uuid)
'更新 Popup
If GetHintText IsNot Nothing Then
TextHint.Text = GetHintText.DynamicInvoke(Value)
Popup.IsOpen = True
AniStop("MySlider KeyPopup " & Uuid)
End If
RefreshPopup()
AniStop("MySlider KeyPopup " & Uuid)
End Sub
Public Sub DragDoing()
Dim Percent As Double = MathRange((Mouse.GetPosition(PanMain).X - 8) / (ActualWidth - 16), 0, 1)
Dim Percent As Double = MathRange((Mouse.GetPosition(PanMain).X - ShapeDot.Width / 2) / (ActualWidth - ShapeDot.Width), 0, 1)
Dim NewValue As Integer = Percent * MaxValue
If Not NewValue = Value Then
Value = NewValue
End If
'更新 Popup
If GetHintText IsNot Nothing Then TextHint.Text = GetHintText.DynamicInvoke(NewValue)
RefreshPopup()
End Sub
Public Sub DragStop()
RefreshColor()
AniStart({
AaScaleTransform(ShapeDot, 1 - CType(ShapeDot.RenderTransform, ScaleTransform).ScaleX, 200,, New AniEaseOutFluent)
}, "MySlider Scale " & Uuid)
If GetHintText IsNot Nothing Then Popup.IsOpen = False
Popup.IsOpen = False
End Sub
Public Sub RefreshPopup()
If GetHintText Is Nothing Then Exit Sub
Popup.IsOpen = True
TextHint.Text = GetHintText.DynamicInvoke(Value)
Dim typeface As New Typeface(TextHint.FontFamily, TextHint.FontStyle, TextHint.FontWeight, TextHint.FontStretch)
Dim formattedText As New FormattedText(TextHint.Text, Thread.CurrentThread.CurrentCulture, TextHint.FlowDirection, typeface, TextHint.FontSize, TextHint.Foreground, DPI)
TextHint.Width = formattedText.Width '使用手动测量的宽度修复 #1057
End Sub
'指向动画
@@ -113,28 +117,39 @@
Try
'判断当前颜色
Dim ColorName As String
Dim ForegroundName As String, DotFillName As String
Dim AnimationTime As Integer
If IsEnabled Then
If IsMouseOver OrElse (Not IsNothing(DragControl) AndAlso DragControl.Equals(Me)) Then
ColorName = "ColorBrush3"
AnimationTime = 100
If Not IsNothing(DragControl) AndAlso DragControl.Equals(Me) Then
ForegroundName = "ColorBrush3"
DotFillName = "ColorBrush3"
AnimationTime = 40
ElseIf IsMouseOver Then
ForegroundName = "ColorBrush3"
DotFillName = "ColorBrush3"
AnimationTime = 40
Else
ColorName = "ColorBrush1"
AnimationTime = 200
ForegroundName = "ColorBrushBg0"
DotFillName = "ColorBrushBg0"
AnimationTime = 100
End If
Else
ColorName = "ColorBrushGray4"
ForegroundName = "ColorBrushGray5"
DotFillName = "ColorBrushGray5"
AnimationTime = 200
End If
'触发颜色动画
If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
'有动画
AniStart({AaColor(Me, BorderBrushProperty, ColorName, AnimationTime)}, "MySlider Color " & Uuid)
AniStart({
AaColor(Me, BorderBrushProperty, ForegroundName, AnimationTime),
AaColor(ShapeDot, Ellipse.FillProperty, DotFillName, AnimationTime)
}, "MySlider Color " & Uuid)
Else
'无动画
AniStop("MySlider Color " & Uuid)
SetResourceReference(BorderBrushProperty, ColorName)
SetResourceReference(BorderBrushProperty, ForegroundName)
ShapeDot.SetResourceReference(Ellipse.FillProperty, DotFillName)
End If
Catch ex As Exception
@@ -167,8 +182,7 @@
End If
'更新 Popup
If GetHintText IsNot Nothing Then
TextHint.Text = GetHintText.DynamicInvoke(Value)
Popup.IsOpen = True
RefreshPopup()
AniStop("MySlider KeyPopup " & Uuid)
AniStart(AaCode(Sub() Popup.IsOpen = False, 700 * AniSpeed), "MySlider KeyPopup " & Uuid)
End If
+10 -19
View File
@@ -212,35 +212,26 @@
If IsEnabled Then
If ValidateResult = "" OrElse Not IsTextChanged Then
If IsFocused Then
ForeColorName = "ColorBrush4"
BackColorName = "ColorBrush9"
AnimationTime = 60
ElseIf IsMouseOver Then
ForeColorName = "ColorBrush3"
BackColorName = "ColorBrush7"
AnimationTime = 10
ElseIf IsMouseOver Then
ForeColorName = "ColorBrush4"
BackColorName = "ColorBrush7"
AnimationTime = 100
Else '未选中
ForeColorName = "ColorBrushBg0"
BackColorName = "ColorBrushHalfWhite"
AnimationTime = 100
Else
ForeColorName = "ColorBrush1"
BackColorName = "ColorBrushHalfWhite"
AnimationTime = 200
End If
Else
ForeColorName = "ColorBrushRedLight"
BackColorName = "ColorBrushRedBack"
AnimationTime = 200
'If IsFocused OrElse IsMouseOver Then
' ForeColorName = "ColorBrushRedLight"
' BackColorName = "ColorBrushRedBack"
' AnimationTime = 100
'Else
' ForeColorName = "ColorBrushRedDark"
' BackColorName = "ColorBrushHalfWhite"
' AnimationTime = 200
'End If
End If
Else
ForeColorName = "ColorBrushGray4"
BackColorName = "ColorBrushHalfWhite"
ForeColorName = "ColorBrushGray5"
BackColorName = "ColorBrushGray6"
AnimationTime = 200
End If
'触发颜色动画
+7 -4
View File
@@ -4,13 +4,16 @@
xmlns:local="clr-namespace:PCL"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Name="WindMain" x:Class="FormMain" Style="{StaticResource MyWindow}"
AllowDrop="True" Topmost="True" Title="Plain Craft Launcher 2 " AllowsTransparency="True" MinHeight="450" MinWidth="760" ScrollViewer.VerticalScrollBarVisibility="Disabled" Icon="/Plain Craft Launcher 2;component/Images/icon.ico" Left="-10000" WindowStyle="None" ResizeMode="CanMinimize" Background="{x:Null}" d:DesignWidth="870" d:DesignHeight="520" Width="850" Height="500" RenderTransformOrigin="0.5,0.5">
AllowDrop="True" Topmost="True" Title="Plain Craft Launcher 2 " AllowsTransparency="True" MinHeight="470" MinWidth="780" ScrollViewer.VerticalScrollBarVisibility="Disabled" Icon="/Plain Craft Launcher 2;component/Images/icon.ico" WindowStyle="None" ResizeMode="CanMinimize" Background="{x:Null}" d:DesignWidth="870" d:DesignHeight="520" Width="850" Height="500" RenderTransformOrigin="0.5,0.5">
<Window.TaskbarItemInfo>
<TaskbarItemInfo ThumbnailClipMargin="{Binding Margin, ElementName=PanForm}" />
</Window.TaskbarItemInfo>
<Grid x:Name="PanBack" SnapsToDevicePixels="True" UseLayoutRounding="True" Margin="1" RenderTransformOrigin="0.5,0.5">
<Grid x:Name="PanBack" SnapsToDevicePixels="True" UseLayoutRounding="True" Margin="10" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<ScaleTransform ScaleX="0.95" ScaleY="0.95" />
<TransformGroup>
<RotateTransform x:Name="TransformRotate" Angle="-4" />
<TranslateTransform x:Name="TransformPos" X="0" Y="60" />
</TransformGroup>
</Grid.RenderTransform>
<Rectangle x:Name="ResizerT" Stroke="{x:Null}" StrokeThickness="0.0001" Height="8" VerticalAlignment="Top" Margin="13,0" Cursor="SizeNS">
<Rectangle.Fill>
@@ -160,7 +163,7 @@
</Border>
</Border>
</Grid>
<StackPanel x:Name="PanHint" UseLayoutRounding="True" SnapsToDevicePixels="True" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="0,0,0,25" IsHitTestVisible="False" Grid.RowSpan="2" />
<StackPanel x:Name="PanHint" IsHitTestVisible="False" UseLayoutRounding="True" SnapsToDevicePixels="True" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="0,0,0,25" Grid.RowSpan="2" />
<StackPanel HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="1" Margin="15">
<local:MyExtraButton x:Name="BtnExtraBack" HorizontalAlignment="Right" VerticalAlignment="Center" ToolTip="返回顶部" Visibility="Collapsed"
Logo="M858.496 188.9024 173.1072 188.9024c-30.2848 0-54.8352-24.5504-54.8352-54.8352L118.272 106.6496c0-30.2848 24.5504-54.8352 54.8352-54.8352l685.3888 0c30.2848 0 54.8352 24.5504 54.8352 54.8352l0 27.4176C913.3312 164.352 888.7808 188.9024 858.496 188.9024L858.496 188.9024zM150.6048 550.8608c0 0 300.0064-240.3584 303.0272-243.328 13.9776-13.5936 31.1808-21.8624 48.8192-24.7552 1.7152-0.3072 3.4304-0.5888 5.1456-0.768 2.7392-0.3072 5.4528-0.3584 8.192-0.3328 2.7392-0.0256 5.4272 0.0256 8.1664 0.3328 1.7408 0.1792 3.4304 0.4864 5.1456 0.768 17.664 2.8928 34.8672 11.1616 48.8192 24.7552 3.0464 2.944 303.0016 243.328 303.0016 243.328 32.384 31.5136 29.6192 63.9744-2.7392 95.5136-32.3328 31.5392-75.648 2.9696-108.0064-28.544l-185.8816-147.1232 0 485.8368c0 30.3104-24.5248 54.8608-54.8352 54.8608l-27.392 0c-30.2848 0-54.8352-24.5504-54.8352-54.8608L447.232 470.7072l-185.8304 147.0976c-32.3584 31.5392-75.6992 60.1344-108.032 28.5696C121.0368 614.8352 118.272 582.3744 150.6048 550.8608L150.6048 550.8608zM150.6048 550.8608" />
+118 -54
View File
@@ -10,11 +10,31 @@ Public Class FormMain
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
'统计更新日志条目
#If BETA Then
If LastVersion < 270 Then 'Release 2.4.3
If LastVersion < 281 Then 'Release 2.4.9
FeatureCount += 1
BugCount += 5
If LastVersion = 279 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复进入 Mod、整合包下载页时报错的 Bug"))
End If
If LastVersion < 279 Then 'Release 2.4.8
FeatureCount += 1
BugCount += 10
End If
If LastVersion < 276 Then 'Release 2.4.7
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "增加 在游戏启动前执行命令 设置"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在百宝箱添加了清理 MC 日志、崩溃报告的按钮"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化界面动画,修改部分配色"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 Mod 中文搜索"))
FeatureCount += 25
BugCount += 56
End If
If LastVersion < 272 Then 'Release 2.4.4
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在版本设置页导出启动脚本、打开存档文件夹等"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 Mod、整合包下载的版本检查与显示"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修改部分配色,让整体边框变得更淡"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法从下载页安装最新 MC 版本的整合包的 Bug"))
If LastVersion <= 267 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 LiteLoader 的 Bug"))
FeatureCount += 6
BugCount += 15
FeatureCount += 13
BugCount += 23
End If
If LastVersion < 268 Then 'Release 2.4.2
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "暂时关闭了联机功能"))
@@ -106,6 +126,42 @@ Public Class FormMain
'3:BUG+ IMP* FEAT-
'2:BUG* IMP-
'1:BUG-
If LastVersion < 282 Then 'Snapshot 2.4.9
FeatureCount += 1
BugCount += 5
If LastVersion = 280 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复进入 Mod、整合包下载页时报错的 Bug"))
End If
If LastVersion < 280 Then 'Snapshot 2.4.8
FeatureCount += 1
BugCount += 10
End If
If LastVersion < 278 Then 'Snapshot 2.4.7
If LastVersion = 277 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复设置背景音乐可能导致无法启动 PCL 的 Bug"))
BugCount += 2
End If
If LastVersion < 278 Then 'Snapshot 2.4.7
If LastVersion = 277 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复设置背景音乐可能导致无法启动 PCL 的 Bug"))
BugCount += 2
End If
If LastVersion < 277 Then 'Snapshot 2.4.6
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在百宝箱添加了清理 MC 日志、崩溃报告的按钮"))
FeatureCount += 8
BugCount += 21
End If
If LastVersion < 275 Then 'Snapshot 2.4.5
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "增加 在游戏启动前执行命令 设置"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化界面动画,修改部分配色"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 Mod 中文搜索"))
FeatureCount += 17
BugCount += 35
End If
If LastVersion < 273 Then 'Snapshot 2.4.4
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在版本设置页导出启动脚本、打开存档文件夹等"))
If LastVersion = 271 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法同时开启多个 Minecraft 客户端的 Bug"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法从下载页安装最新 MC 版本的整合包的 Bug"))
FeatureCount += 7
BugCount += 8
End If
If LastVersion < 271 Then 'Snapshot 2.4.3
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 Mod、整合包下载的版本检查与显示"))
If LastVersion <= 267 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 LiteLoader 的 Bug"))
@@ -267,7 +323,7 @@ Public Class FormMain
'输出更新日志
RunInNewThread(Sub()
If MyMsgBox(Content, "PCL2 已更新至 " & VersionDisplayName, "确定", "完整更新日志") = 2 Then
OpenWebsite("https://afdian.net/@LTCat?tab=feed")
OpenWebsite("https://afdian.net/a/LTCat?tab=feed")
End If
End Sub, "UpdateLog Output")
End Sub
@@ -284,6 +340,7 @@ Public Class FormMain
FrmMain = Me
FrmLaunchLeft = New PageLaunchLeft
FrmLaunchRight = New PageLaunchRight
ToolTipService.ShowDurationProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(2333333))
'版本号改变
Dim LastVersion As Integer = Setup.Get("SystemLastVersionReg")
If LastVersion < VersionCode Then
@@ -329,7 +386,6 @@ Public Class FormMain
Setup.Load("UiHiddenPageDownload")
BackgroundRefresh(False, True)
MusicRefreshPlay(False, True)
JavaListInit()
'扩展按钮
BtnExtraDownload.ShowCheck = AddressOf BtnExtraDownload_ShowCheck
BtnExtraBack.ShowCheck = AddressOf BtnExtraBack_ShowCheck
@@ -346,12 +402,8 @@ Public Class FormMain
Resizer.addResizerRightDown(ResizerRB)
Resizer.addResizerRightUp(ResizerRT)
Resizer.addResizerUp(ResizerT)
'#If DEBUG Then
' MinWidth = 200
' MinHeight = 150
'#End If
'PLC 彩蛋
If RandomInteger(1, 1000) = 23 Then
If RandomInteger(1, 1000) = 233 Then
ShapeTitleLogo.Data = New GeometryConverter().ConvertFromString("M26,29 v-25 h5 a7,7 180 0 1 0,14 h-5 M80,6.5 a10,11.5 180 1 0 0,18 M47,2.5 v24.5 h12 M98,2 v27 M107,2 v27")
End If
'加载窗口
@@ -368,16 +420,16 @@ Public Class FormMain
Dim HwndSource As Interop.HwndSource = PresentationSource.FromVisual(Me)
HwndSource.AddHook(New Interop.HwndSourceHook(AddressOf WndProc))
AniStart({
AaCode(Sub() AniControlEnabled -= 1, 50),
AaOpacity(Me, Setup.Get("UiLauncherTransparent") / 1000 + 0.4, 300, 100),
AaScaleTransform(PanBack, 0.05, 500, 100, New AniEaseOutBack(AniEasePower.Weak)),
AaCode(Sub()
PanBack.RenderTransform = Nothing
'If OsVersion > New Version(10, 1, 0, 0) Then RectForm.RadiusX = 5 : RectForm.RadiusY = 5 'Win11 下圆角
IsWindowLoadFinished = True
Log("[System] DPI:" & DPI & ",工作区尺寸:" & My.Computer.Screen.WorkingArea.Width & " x " & My.Computer.Screen.WorkingArea.Height & ",系统版本:" & OsVersion.ToString)
End Sub, , True)
}, "Form Show")
AaCode(Sub() AniControlEnabled -= 1, 50),
AaOpacity(Me, Setup.Get("UiLauncherTransparent") / 1000 + 0.4, 250, 100),
AaDouble(Sub(i) TransformPos.Y += i, -TransformPos.Y, 600, 100, New AniEaseOutBack(AniEasePower.Weak)),
AaDouble(Sub(i) TransformRotate.Angle += i, -TransformRotate.Angle, 500, 100, New AniEaseOutBack(AniEasePower.Weak)),
AaCode(Sub()
PanBack.RenderTransform = Nothing
IsWindowLoadFinished = True
Log($"[System] DPI:{DPI},系统版本:{OsVersion},PCL 位置:{PathWithName}")
End Sub, , True)
}, "Form Show")
'Timer 启动
AniStartRun()
TimerMainStartRun()
@@ -396,6 +448,7 @@ Reopen:
End Select
End If
Try
JavaListInit() '延后到同意协议后再执行,避免在初次启动时进行进程操作
Thread.Sleep(200)
DlClientListMojangLoader.Start(1)
RunCountSub()
@@ -525,25 +578,34 @@ Reopen:
End If
End If
'关闭
RunInUiWait(Sub()
IsHitTestVisible = False
If PanBack.RenderTransform Is Nothing Then
PanBack.RenderTransform = New ScaleTransform
AniStart({
AaOpacity(Me, -Opacity, 100, 100),
AaScaleTransform(PanBack, -0.05, 200,, New AniEaseInBack),
AaCode(Sub()
IsHitTestVisible = False
Top = -10000
ShowInTaskbar = False
End Sub, 225),
AaCode(AddressOf EndProgramForce, 250)
}, "Form Close")
Else
EndProgramForce()
End If
Log("[System] 收到关闭指令")
End Sub)
RunInUiWait(
Sub()
IsHitTestVisible = False
If PanBack.RenderTransform Is Nothing Then
Dim TransformPos As New TranslateTransform(0, 0)
Dim TransformRotate As New RotateTransform(0)
Dim TransformScale As New ScaleTransform(1, 1)
PanBack.RenderTransform = New TransformGroup() With {.Children = New TransformCollection({TransformRotate, TransformPos, TransformScale})}
AniStart({
AaOpacity(Me, -Opacity, 140, 40, New AniEaseOutFluent(AniEasePower.Weak)),
AaDouble(Sub(i)
TransformScale.ScaleX += i
TransformScale.ScaleY += i
End Sub, 0.88 - TransformScale.ScaleX, 180),
AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 180, 0, New AniEaseOutFluent(AniEasePower.Weak)),
AaDouble(Sub(i) TransformRotate.Angle += i, 0.6 - TransformRotate.Angle, 180, 0, New AniEaseInoutFluent(AniEasePower.Weak)),
AaCode(Sub()
IsHitTestVisible = False
Top = -10000
ShowInTaskbar = False
End Sub, 210),
AaCode(AddressOf EndProgramForce, 230)
}, "Form Close")
Else
EndProgramForce()
End If
Log("[System] 收到关闭指令")
End Sub)
End Sub
Private Shared IsLogShown As Boolean = False
Public Shared Sub EndProgramForce(Optional ReturnCode As Result = Result.Success)
@@ -556,7 +618,7 @@ Reopen:
If ReturnCode = Result.Exception Then
If Not IsLogShown Then
FeedbackInfo()
Log("请在 https://jinshuju.net/f/rP4b6E?x_field_1=crash 提交错误报告,以便于作者解决此问题!")
Log("请在 https://github.com/Hex-Dragon/PCL2/issues 提交错误报告,以便于作者解决此问题!")
IsLogShown = True
ShellOnly(Path & "PCL\Log1.txt")
End If
@@ -616,7 +678,7 @@ Reopen:
Exit Sub
ElseIf e.Key = Key.Escape Then
Dim Msg As Object = PanMsg.Children(0)
If Msg.Btn3.Visibility = Visibility.Visible Then
If TypeOf Msg Is MyMsgText AndAlso Msg.Btn3.Visibility = Visibility.Visible Then
Msg.Btn3_Click()
ElseIf Msg.Btn2.Visibility = Visibility.Visible Then
Msg.Btn2_Click()
@@ -704,7 +766,7 @@ Reopen:
Dim AuthlibServer As String = Net.WebUtility.UrlDecode(Str.Substring("authlib-injector:yggdrasil-server:".Length))
Log("[System] Authlib 拖拽:" & AuthlibServer)
If Not String.IsNullOrEmpty(New ValidateHttp().Validate(AuthlibServer)) Then
Hint("输入的 Authlib 验证服务器不符合网址格式(" & AuthlibServer & ")!", HintType.Critical)
Hint($"输入的 Authlib 验证服务器不符合网址格式({AuthlibServer})!", HintType.Critical)
Exit Sub
End If
If McVersionCurrent Is Nothing Then
@@ -713,7 +775,7 @@ Reopen:
End If
If AuthlibServer = "https://littleskin.cn/api/yggdrasil" Then
'LittleSkin
If MyMsgBox("是否要在版本 " & McVersionCurrent.Name & " 中开启 LittleSkin 登录?" & vbCrLf &
If MyMsgBox($"是否要在版本 {McVersionCurrent.Name} 中开启 LittleSkin 登录?" & vbCrLf &
"你可以在 版本设置 → 设置 → 服务器选项 中修改登录方式。", "第三方登录开启确认", "确定", "取消") = 2 Then
Exit Sub
End If
@@ -723,8 +785,8 @@ Reopen:
Setup.Set("VersionServerAuthName", "LittleSkin 登录", Version:=McVersionCurrent)
Else
'第三方 Authlib 服务器
If MyMsgBox("是否要在版本 " & McVersionCurrent.Name & " 中开启第三方登录?" & vbCrLf &
"登录服务器:" & AuthlibServer & vbCrLf & vbCrLf &
If MyMsgBox($"是否要在版本 {McVersionCurrent.Name} 中开启第三方登录?" & vbCrLf &
$"登录服务器:{AuthlibServer}" & vbCrLf & vbCrLf &
"你可以在 版本设置 → 设置 → 服务器选项 中修改登录方式。", "第三方登录开启确认", "确定", "取消") = 2 Then
Exit Sub
End If
@@ -757,7 +819,8 @@ Reopen:
If FilePathList.Count > 1 Then
'必须要求全部为 jar 文件
For Each File In FilePathList
If File.Split(".").Last.ToLower <> "jar" Then
Dim Extension As String = File.Split(".").Last.ToLower
If Not {"jar", "litemod", "disabled"}.Contains(Extension) Then
Hint("一次请只拖入一个文件!", HintType.Critical)
Exit Sub
End If
@@ -767,9 +830,10 @@ Reopen:
Dim FilePath As String = FilePathList.First
Log("[System] 接受文件拖拽:" & FilePath, LogLevel.Developer)
RunInNewThread(Sub()
Dim Extension As String = FilePath.Split(".").Last.ToLower
'Mod 安装
If FilePath.Split(".").Last.ToLower = "jar" Then
Log("[System] 文件为 jar 格式,尝试作为 Mod 安装")
If {"jar", "litemod", "disabled"}.Contains(Extension) Then
Log("[System] 文件为 jar/litemod 格式,尝试作为 Mod 安装")
'获取并检查目标版本
Dim TargetVersion As McVersion = McVersionCurrent
If PageCurrent = PageType.VersionSetup Then TargetVersion = PageVersionLeft.Version
@@ -778,7 +842,7 @@ Reopen:
Hint("若要安装 Mod,请先选择一个可以安装 Mod 的版本!")
ElseIf Not (PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod) Then
'未处于 Mod 管理页面
If MyMsgBox("是否要将这些文件作为 Mod 安装到 " & TargetVersion.Name & "?", "Mod 安装确认", "确定", "取消") = 1 Then GoTo Install
If MyMsgBox($"是否要将这些文件作为 Mod 安装到 {TargetVersion.Name}?", "Mod 安装确认", "确定", "取消") = 1 Then GoTo Install
Else
'处于 Mod 管理页面
Install:
@@ -787,9 +851,9 @@ Install:
CopyFile(ModFile, TargetVersion.PathIndie & "mods\" & GetFileNameFromPath(ModFile))
Next
If FilePathList.Count = 1 Then
Hint("已安装 " & GetFileNameFromPath(FilePathList.First) & "!", HintType.Finish)
Hint($"已安装 {GetFileNameFromPath(FilePathList.First)}!", HintType.Finish)
Else
Hint("已安装 " & FilePathList.Count & " 个 Mod!", HintType.Finish)
Hint($"已安装 {FilePathList.Count} 个 Mod!", HintType.Finish)
End If
'刷新列表
If PageCurrent = PageType.VersionSetup AndAlso PageCurrentSub = PageSubType.VersionMod Then
@@ -802,12 +866,12 @@ Install:
Exit Sub
End If
'安装整合包
If {"zip", "rar"}.Contains(FilePath.Split(".").Last.ToLower) Then '部分压缩包是 zip 格式但后缀为 rar,总之试一试
If {"zip", "rar"}.Contains(Extension) Then '部分压缩包是 zip 格式但后缀为 rar,总之试一试
Log("[System] 文件为压缩包,尝试作为整合包安装")
If ModpackInstall(FilePath, ShowHint:=False) Then Exit Sub
End If
'RAR 处理
If FilePath.Split(".").Last.ToLower = "rar" Then
If Extension = "rar" Then
Hint("PCL2 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试!")
Exit Sub
End If
@@ -1062,7 +1126,7 @@ Install:
''' <summary>
''' 上层页面的编号堆栈,用于返回。
''' </summary>
Private ReadOnly PageStack As New List(Of PageStackData)
Public PageStack As New List(Of PageStackData)
Public Class PageStackData
Public Page As PageType
+130 -119
View File
@@ -10,12 +10,12 @@ Public Module ModBase
#Region "声明"
'下列版本信息由更新器自动修改
Public Const VersionBaseName As String = "2.4.3" '不含分支前缀的显示用版本名
Public Const VersionStandardCode As String = "2.4.3." & VersionBranchCode '标准格式的四段式版本号
Public Const VersionBaseName As String = "2.4.9" '不含分支前缀的显示用版本名
Public Const VersionStandardCode As String = "2.4.9." & VersionBranchCode '标准格式的四段式版本号
#If BETA Then
Public Const VersionCode As Integer = 270 'Release
Public Const VersionCode As Integer = 281 'Release
#Else
Public Const VersionCode As Integer = 271 'Snapshot
Public Const VersionCode As Integer = 282 'Snapshot
#End If
'自动生成的版本信息
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -79,11 +79,15 @@ Public Module ModBase
''' </summary>
Public OsVersion As Version = Environment.OSVersion.Version
''' <summary>
''' 程序的缓存文件夹路径,以“\”结尾。
''' 系统盘盘符,以 \ 结尾。例如 “C:\”。
''' </summary>
Public OsDrive As String = Environment.GetLogicalDrives().First.ToUpper.First & ":\"
''' <summary>
''' 程序的缓存文件夹路径,以 \ 结尾。
''' </summary>
Public PathTemp As String = If(Setup.Get("SystemSystemCache") = "", IO.Path.GetTempPath() & "PCL\", Setup.Get("SystemSystemCache")).ToString.Replace("/", "\").TrimEnd("\") & "\"
''' <summary>
''' AppData 中的 PCL 文件夹路径,以“\”结尾。
''' AppData 中的 PCL 文件夹路径,以 \ 结尾。
''' </summary>
Public PathAppdata As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\PCL\"
@@ -739,11 +743,12 @@ Public Module ModBase
''' 从文件路径或者 Url 获取不包含路径的文件名。不包含文件名将会抛出异常。
''' </summary>
Public Function GetFileNameFromPath(FilePath As String) As String
If FilePath.EndsWith("\") OrElse FilePath.EndsWith("/") Then Throw New Exception("不包含文件名:" & FilePath)
If Not (FilePath.Contains("\") OrElse FilePath.Contains("/")) Then Return FilePath
If FilePath.Contains("?") Then FilePath = Left(FilePath, FilePath.LastIndexOf("?")) '去掉网络参数后的 ?
GetFileNameFromPath = Mid(FilePath, FilePath.LastIndexOfAny({"\", "/"}) + 2)
If GetFileNameFromPath = "" Then Throw New Exception("不包含文件名:" & FilePath)
FilePath = FilePath.Replace("/", "\")
If FilePath.EndsWith("\") Then Throw New Exception("不包含文件名:" & FilePath)
Dim FileName As String = FilePath.Split("\").Last.Split("?").First '去掉网络参数后的 ?
If FileName.Length = 0 Then Throw New Exception("不包含文件名:" & FilePath)
If FileName.Length > 250 Then Throw New PathTooLongException("文件名过长:" & FilePath)
Return FileName
End Function
''' <summary>
''' 从文件路径或者 Url 获取不包含路径与扩展名的文件名。不包含文件名将会抛出异常。
@@ -789,7 +794,7 @@ Public Module ModBase
''' 读取文件,如果失败则返回空字符串。
''' </summary>
''' <param name="FilePath">文件完整或相对路径。</param>
Public Function ReadFile(FilePath As String) As String
Public Function ReadFile(FilePath As String, Optional Encoding As Encoding = Nothing) As String
Try
'还原文件路径
If Not FilePath.Contains(":\") Then FilePath = Path & FilePath
@@ -799,7 +804,7 @@ Public Module ModBase
ReDim FileBytes(ReadStream.Length - 1)
ReadStream.Read(FileBytes, 0, ReadStream.Length)
End Using
ReadFile = DecodeBytes(FileBytes)
ReadFile = If(Encoding Is Nothing, DecodeBytes(FileBytes), Encoding.GetString(FileBytes))
Else
Log("[System] 欲读取的文件不存在,已返回空字符串:" & FilePath)
Return ""
@@ -1223,7 +1228,7 @@ Re:
Return Nothing
Catch ex As Exception
Log(ex, "检查文件出错")
Return GetString(ex)
Return GetExceptionSummary(ex)
End Try
End Function
End Class
@@ -1262,15 +1267,17 @@ Re:
End Function
''' <summary>
''' 删除文件夹。失败会抛出异常。
''' 删除文件夹,返回删除的文件个数。通过参数选择是否抛出异常。
''' </summary>
Public Sub DeleteDirectory(Path As String, Optional IgnoreIssue As Boolean = False)
If Not Directory.Exists(Path) Then Exit Sub
Public Function DeleteDirectory(Path As String, Optional IgnoreIssue As Boolean = False) As Integer
If Not Directory.Exists(Path) Then Return 0
Dim DeletedCount As Integer = 0
Dim Temp As String()
Temp = Directory.GetFiles(Path)
For Each str As String In Temp
Try
File.Delete(str)
DeletedCount += 1
Catch ex As Exception
If IgnoreIssue Then
Log(ex, "删除单个文件可忽略地失败")
@@ -1292,13 +1299,16 @@ Re:
Throw
End If
End Try
'这个也不靠谱,目录不是空的警告
'My.Computer.FileSystem.DeleteDirectory(Path, FileIO.DeleteDirectoryOption.DeleteAllContents)
End Sub
Return DeletedCount
End Function
''' <summary>
''' 复制文件夹,失败会抛出异常。
''' </summary>
Public Sub CopyDirectory(FromPath As String, ToPath As String)
FromPath = FromPath.Replace("/", "\")
If Not FromPath.EndsWith("\") Then FromPath &= "\"
ToPath = ToPath.Replace("/", "\")
If Not ToPath.EndsWith("\") Then ToPath &= "\"
For Each File In EnumerateFiles(FromPath)
CopyFile(File.FullName, File.FullName.Replace(FromPath, ToPath))
Next
@@ -1307,15 +1317,7 @@ Re:
''' 遍历文件夹中的所有文件。
''' </summary>
Public Function EnumerateFiles(Directory As String) As List(Of FileInfo)
Dim Dir As New DirectoryInfo(Directory)
Dim ResultList As New List(Of FileInfo)
'添加文件
ResultList.AddRange(Dir.EnumerateFiles)
'添加文件夹中的文件
For Each SubDir In Dir.EnumerateDirectories
ResultList.AddRange(EnumerateFiles(SubDir.FullName))
Next
Return ResultList
Return New DirectoryInfo(Directory).EnumerateFiles("*", SearchOption.AllDirectories).ToList
End Function
#End Region
@@ -1325,59 +1327,101 @@ Re:
Public vbRQ As Char = Convert.ToChar(8221)
''' <summary>
''' 提取 Exception 摘要。
''' 提取 Exception 的具体描述与堆栈。
''' </summary>
''' <param name="IsLine">输出是否强制为单行,单行模型下不会输出调用堆栈。</param>
Public Function GetString(Ex As Exception, Optional IsLine As Boolean = True, Optional ShowAllTrace As Boolean = False) As String
''' <param name="ShowAllTrace">是否必须显示所有堆栈。通常用于判定堆栈信息。</param>
Public Function GetExceptionDetail(Ex As Exception, Optional ShowAllTrace As Boolean = False) As String
If Ex Is Nothing Then Return "无可用错误信息!"
Dim Desc As New List(Of String)
'自动错误判断
Dim RealEx = Ex
Do Until RealEx.InnerException Is Nothing
RealEx = RealEx.InnerException
'获取最底层的异常
Dim InnerEx As Exception = Ex
Do Until InnerEx.InnerException Is Nothing
InnerEx = InnerEx.InnerException
Loop
If TypeOf RealEx Is TypeLoadException OrElse TypeOf RealEx Is MissingMethodException OrElse TypeOf RealEx Is NotImplementedException OrElse TypeOf RealEx Is TypeInitializationException Then
Desc.Add("系统环境存在问题,请尝试重装 .Net Framework 4.6.2 后再试")
ElseIf TypeOf RealEx Is UnauthorizedAccessException Then
Desc.Add("PCL2 权限不足,请尝试右键 PCL2,选择以管理员身份运行")
ElseIf TypeOf RealEx Is OutOfMemoryException Then
Desc.Add("电脑运行内存不足,PCL2 无法继续运行")
'获取各级错误的描述与堆栈信息
Dim DescList As New List(Of String)
Dim StackList As New List(Of String)
Do Until Ex Is Nothing
DescList.Add(Ex.Message.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, vbCrLf))
If Ex.StackTrace IsNot Nothing Then
For Each St As String In Ex.StackTrace.Split(vbCrLf)
If ShowAllTrace OrElse St.ToLower.Contains("pcl") Then StackList.Add(St.Replace(vbCr, String.Empty).Replace(vbLf, String.Empty))
Next
End If
Ex = Ex.InnerException
Loop
DescList = DescList.Distinct.ToList
Dim Desc As String = Join(DescList, vbCrLf & "→ ")
Dim Stack As String = If(StackList.Count > 0, vbCrLf & Join(StackList, vbCrLf), "")
'常见错误
Dim CommonReason As String = Nothing
If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then
CommonReason = "PCL2 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。"
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
CommonReason = "PCL2 的权限不足。请尝试右键 PCL2,选择以管理员身份运行。"
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
CommonReason = "你的电脑运行内存不足,导致 PCL2 无法继续运行。请在关闭一部分不需要的程序后再试。"
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
End If
If IsLine Then
'无内部错误的快速处理
If Ex.InnerException Is Nothing Then
If Desc.Count = 0 Then
Return Ex.Message.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, " ")
Else
Return Desc.First
End If
End If
'构造输出信息
Do Until Ex Is Nothing
Desc.Add(Ex.Message.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, " "))
Ex = Ex.InnerException
Loop
Desc.Reverse() '让最深层错误在最左边
GetString = Join(Desc, " → ")
'获取错误类型
Dim TypeDesc As String = If(InnerEx.GetType.FullName = "System.Exception", "", vbCrLf & "错误类型:" & InnerEx.GetType.FullName)
'构造输出信息
If CommonReason Is Nothing Then
Return Desc & Stack & TypeDesc
Else
Dim Stack As New List(Of String)
'逐级追加描述与堆栈
Do Until Ex Is Nothing
Desc.Add(Ex.Message.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, vbCrLf))
If Ex.StackTrace IsNot Nothing Then
For Each St As String In Ex.StackTrace.Split(vbCrLf)
If ShowAllTrace OrElse St.ToLower.Contains("pcl") Then Stack.Add(St.Replace(vbCr, String.Empty).Replace(vbLf, String.Empty))
Next
End If
Ex = Ex.InnerException
Loop
'构造输出信息
Dim TypeName As String = RealEx.GetType.FullName
GetString = Join(Desc, vbCrLf & "Caused By: ") & If(Stack.Count > 0, vbCrLf & Join(Stack, vbCrLf), "") & If(TypeName = "System.Exception", "", vbCrLf & "错误类型:" & TypeName)
Dim Result As String = DescList.First & vbCrLf & CommonReason & vbCrLf & "————————————" & vbCrLf
DescList(0) = "详细错误信息:"
Return Result & Join(DescList, vbCrLf & "→ ") & Stack & TypeDesc
End If
End Function
''' <summary>
''' 提取 Exception 描述,汇总到一行。
''' </summary>
Public Function GetExceptionSummary(Ex As Exception) As String
If Ex Is Nothing Then Return "无可用错误信息!"
'获取最底层的异常
Dim InnerEx As Exception = Ex
Do Until InnerEx.InnerException Is Nothing
InnerEx = InnerEx.InnerException
Loop
'获取各级错误的描述
Dim DescList As New List(Of String)
Do Until Ex Is Nothing
DescList.Add(Ex.Message.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr & vbCr, vbCr).Replace(vbCr, " "))
Ex = Ex.InnerException
Loop
DescList = DescList.Distinct.ToList
'常见错误
Dim Desc As String = Join(DescList, vbCrLf & "→ ")
Dim CommonReason As String = Nothing
If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then
CommonReason = "PCL2 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。"
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
CommonReason = "PCL2 的权限不足。请尝试右键 PCL2,选择以管理员身份运行。"
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
CommonReason = "你的电脑运行内存不足,导致 PCL2 无法继续运行。请在关闭一部分不需要的程序后再试。"
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
CommonReason = "你的网络环境不佳,导致难以连接到服务器。请重试,或尝试使用 VPN。"
End If
'构造输出信息
If CommonReason IsNot Nothing Then
Return DescList.First & ":" & CommonReason
Else
DescList.Reverse() '让最深层错误在最左边
Return Join(DescList, " → ")
End If
End Function
''' <summary>
''' 返回一个枚举对应的字符串。
''' </summary>
@@ -1899,32 +1943,8 @@ NextElement:
Using Program As New Process() With {.StartInfo = Info}
Program.Start()
Program.WaitForExit(Timeout)
If Not Program.HasExited Then Program.Kill()
Return Program.StandardOutput.ReadToEnd & Program.StandardError.ReadToEnd
' Dim Result As New StringBuilder()
' AddHandler process.OutputDataReceived, Function(sender As Object, e As DataReceivedEventArgs)
' Try
' If e.Data IsNot Nothing Then Result.AppendLine(e.Data)
' Finally
' End Try
' Return Nothing
' End Function
' AddHandler process.ErrorDataReceived, Function(sender As Object, e As DataReceivedEventArgs)
' Try
' If e.Data IsNot Nothing Then Result.AppendLine(e.Data)
' Finally
' End Try
' Return Nothing
' End Function
' process.Start()
' process.BeginOutputReadLine()
' process.BeginErrorReadLine()
' If process.WaitForExit(Timeout) Then
' process.Close()
' Return Result.ToString
' Else
' process.Close()
' Throw New TimeoutException("程序执行超时,已有返回值:" & Result.ToString)
' End If
End Using
End Function
@@ -2293,10 +2313,6 @@ Retry:
''' </summary>
Assert = 6
End Enum
''' <summary>
''' 记录程序是否递交了错误提示,以确保运行测试正确。
''' </summary>
Public IsErrorTriggered As Boolean = False
Private LogList As New StringBuilder
Private LogWritter As StreamWriter
Public Sub LogStart()
@@ -2392,20 +2408,16 @@ Retry:
If ModeDebug Then Hint("[调试模式] " & Text, HintType.Info, False)
#End If
Case LogLevel.Hint
IsErrorTriggered = True
Hint(Text, HintType.Critical, False)
Case LogLevel.Msgbox
IsErrorTriggered = True
MyMsgBox(Text, Title)
MyMsgBox(Text, Title, IsWarn:=True)
Case LogLevel.Feedback
IsErrorTriggered = True
If CanFeedback(False) Then
If MyMsgBox(Text & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", Title, "反馈", "取消") = 1 Then Feedback(False, True)
If MyMsgBox(Text & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", Title, "反馈", "取消", IsWarn:=True) = 1 Then Feedback(False, True)
Else
MyMsgBox(Text & vbCrLf & vbCrLf & "将 PCL2 更新至最新版或许可以解决这个问题……", Title)
MyMsgBox(Text & vbCrLf & vbCrLf & "将 PCL2 更新至最新版或许可以解决这个问题……", Title, IsWarn:=True)
End If
Case LogLevel.Assert
IsErrorTriggered = True
Dim Time As Long = GetTimeTick()
If CanFeedback(False) Then
If MsgBox(Text & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", MsgBoxStyle.Critical + MsgBoxStyle.YesNo, Title) = MsgBoxResult.Yes Then Feedback(False, True)
@@ -2429,13 +2441,12 @@ Retry:
Public Sub Log(Ex As Exception, Desc As String, Optional Level As LogLevel = LogLevel.Debug, Optional Title As String = "出现错误")
On Error Resume Next
If TypeOf Ex Is ThreadInterruptedException Then Exit Sub
IsErrorTriggered = True
'获取错误信息
Dim ExFull As String = Desc & ":" & GetString(Ex, False)
Dim ExFull As String = Desc & ":" & GetExceptionDetail(Ex)
'输出日志
Dim AppendText As String = "[" & GetTimeNow() & "] " & Desc & ":" & GetString(Ex, False, True) & vbCrLf '减轻同步锁占用
Dim AppendText As String = "[" & GetTimeNow() & "] " & Desc & ":" & GetExceptionDetail(Ex, True) & vbCrLf '减轻同步锁占用
If ModeDebug Then
SyncLock LogListLock
LogList.Append(AppendText)
@@ -2453,27 +2464,27 @@ Retry:
Case LogLevel.Normal
#If DEBUG Then
Case LogLevel.Developer
Dim ExLine As String = Desc & ":" & GetString(Ex, True)
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
Hint("[开发者模式] " & ExLine, HintType.Info, False)
Case LogLevel.Debug
Dim ExLine As String = Desc & ":" & GetString(Ex, True)
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
Hint("[调试模式] " & ExLine, HintType.Info, False)
#Else
Case LogLevel.Developer
Case LogLevel.Debug
Dim ExLine As String = Desc & ":" & GetString(Ex, True)
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
If ModeDebug Then Hint("[调试模式] " & ExLine, HintType.Info, False)
#End If
Case LogLevel.Hint
Dim ExLine As String = Desc & ":" & GetString(Ex, True)
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
Hint(ExLine, HintType.Critical, False)
Case LogLevel.Msgbox
MyMsgBox(ExFull, Title)
MyMsgBox(ExFull, Title, IsWarn:=True)
Case LogLevel.Feedback
If CanFeedback(False) Then
If MyMsgBox(ExFull & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", Title, "反馈", "取消") = 1 Then Feedback(False, True)
If MyMsgBox(ExFull & vbCrLf & vbCrLf & "是否反馈此问题?如果不反馈,这个问题可能永远无法得到解决!", Title, "反馈", "取消", IsWarn:=True) = 1 Then Feedback(False, True)
Else
MyMsgBox(ExFull & vbCrLf & vbCrLf & "将 PCL2 更新至最新版或许可以解决这个问题……", Title)
MyMsgBox(ExFull & vbCrLf & vbCrLf & "将 PCL2 更新至最新版或许可以解决这个问题……", Title, IsWarn:=True)
End If
Case LogLevel.Assert
Dim Time As Long = GetTimeTick()
@@ -236,7 +236,9 @@
''' </summary>
Public ReadOnly Property IsAborted As Boolean
Get
Return LastRunningThread Is Nothing OrElse Not ReferenceEquals(Thread.CurrentThread, LastRunningThread)
Return LastRunningThread Is Nothing OrElse
Not ReferenceEquals(Thread.CurrentThread, LastRunningThread) OrElse
State = LoadState.Aborted
End Get
End Property
''' <summary>
+11 -7
View File
@@ -412,7 +412,7 @@ RequestFinished:
Throw
Catch ex As WebException
If ex.Status = WebExceptionStatus.Timeout Then
Throw New TimeoutException("连接服务器超时,请检查你的网络环境是否良好(" & Url & ")", ex)
Throw New WebException("连接服务器超时,请检查你的网络环境是否良好(" & Url & ")", ex)
Else
'获取请求失败的返回
Dim Res As String = ""
@@ -1183,10 +1183,10 @@ SourceBreak:
Next
End SyncLock
End SyncLock
Dim IsTimeoutString As String = GetString(ex, False).ToLower.Replace(" ", "")
Dim IsTimeoutString As String = GetExceptionSummary(ex).ToLower.Replace(" ", "")
Dim IsTimeout As Boolean = IsTimeoutString.Contains("由于连接方在一段时间后没有正确答复或连接的主机没有反应") OrElse
IsTimeoutString.Contains("超时") OrElse IsTimeoutString.Contains("timeout") OrElse IsTimeoutString.Contains("timedout")
Log("[Download] " & LocalName & " " & Info.Uuid & If(IsTimeout, "#:超时(" & (Timeout * 0.001) & "s)", "#:出错," & GetString(ex, False)))
Log("[Download] " & LocalName & " " & Info.Uuid & If(IsTimeout, "#:超时(" & (Timeout * 0.001) & "s)", "#:出错," & GetExceptionDetail(ex)))
Info.State = NetState.Error
''使用该下载源的线程是否没有速度
''下载超时也会导致没有速度,容易误判下载失败,所以已弃用此方法
@@ -1653,7 +1653,7 @@ NextElement:
Retry:
Try
Log("[Download] 复制已存在的文件(" & LocalPath & ")")
FileIO.FileSystem.CopyFile(LocalPath, File.LocalPath, True)
CopyFile(LocalPath, File.LocalPath)
File.Finish(False)
Catch ex As Exception
RetryCount += 1
@@ -1697,12 +1697,16 @@ Retry:
SyncLock LockState
If State > LoadState.Loading Then Exit Sub
If ExList Is Nothing OrElse ExList.Count = 0 Then ExList = New List(Of Exception) From {New Exception("未知错误!")}
[Error] = ExList(0)
'寻找第一个不是 404 的下载源
Dim UsefulExs = ExList.Where(Function(e) Not e.Message.Contains("(404)")).ToList
[Error] = If(UsefulExs.Count > 0, UsefulExs(0), ExList(0))
'获取实际失败的文件
SyncLock FilesLock
For Each File In Files
If File.State = NetState.Error Then
[Error] = New Exception("文件下载失败:" & File.LocalPath & "(第一下载源:" & File.Sources(0).Url & ")", ExList(0))
[Error] = New Exception("文件下载失败:" & File.LocalPath & vbCrLf & Join(
File.Sources.Select(Function(s) If(s.Ex Is Nothing, s.Url, s.Ex.Message & "(" & s.Url & ")")).ToList(),
vbCrLf), [Error])
Exit For
End If
Next
@@ -1719,7 +1723,7 @@ Retry:
'在退出同步锁后再进行日志输出
Dim ErrOutput As New List(Of String)
For Each Ex As Exception In ExList
ErrOutput.Add(GetString(Ex, False))
ErrOutput.Add(GetExceptionDetail(Ex))
Next
Log("[Download] " & Join(ArrayNoDouble(ErrOutput.ToArray), vbCrLf))
End Sub
@@ -15,6 +15,8 @@ End Class
''' </summary>
Public Class ValidateNullable
Inherits Validate
Public Sub New()
End Sub
Public Overrides Function Validate(Str As String) As String
If IsNothing(Str) OrElse String.IsNullOrEmpty(Str) Then Return Nothing
Return ""
@@ -26,6 +28,8 @@ End Class
''' </summary>
Public Class ValidateNullOrEmpty
Inherits Validate
Public Sub New()
End Sub
Public Overrides Function Validate(Str As String) As String
If IsNothing(Str) OrElse String.IsNullOrEmpty(Str) Then Return "输入内容不能为空!"
Return ""
@@ -37,6 +41,8 @@ End Class
''' </summary>
Public Class ValidateNullOrWhiteSpace
Inherits Validate
Public Sub New()
End Sub
Public Overrides Function Validate(Str As String) As String
If IsNothing(Str) OrElse String.IsNullOrWhiteSpace(Str) Then Return "输入内容不能为空!"
Return ""
@@ -161,6 +167,8 @@ Public Class ValidateExceptSame
Public Property Excepts As ObjectModel.Collection(Of String) = New ObjectModel.Collection(Of String)
Public Property ErrorMessage As String
Public Property IgnoreCase As Boolean = False
Public Sub New()
End Sub
Public Sub New(Excepts As ObjectModel.Collection(Of String), Optional ErrorMessage As String = "输入内容不能为 %!", Optional IgnoreCase As Boolean = False)
Me.Excepts = Excepts
Me.ErrorMessage = ErrorMessage
@@ -197,6 +205,8 @@ Public Class ValidateFolderName
Public Property UseMinecraftCharCheck As Boolean = True
Public Property IgnoreCase As Boolean = True
Private ReadOnly PathIgnore As IEnumerable(Of DirectoryInfo)
Public Sub New()
End Sub
Public Sub New(Path As String, Optional UseMinecraftCharCheck As Boolean = True, Optional IgnoreCase As Boolean = True)
Me.Path = Path
Me.IgnoreCase = IgnoreCase
@@ -221,7 +231,7 @@ Public Class ValidateFolderName
Dim CharactCheck As String = New ValidateExcept(IO.Path.GetInvalidFileNameChars() & If(UseMinecraftCharCheck, "!;", ""), "文件夹名不可包含 % 字符!").Validate(Str)
If Not CharactCheck = "" Then Return CharactCheck
'检查特殊字符串
Dim InvalidStrCheck As String = New ValidateExceptSame({"CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}, "文件夹名不可为 %!").Validate(Str)
Dim InvalidStrCheck As String = New ValidateExceptSame({"CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}, "文件夹名不可为 %!", True).Validate(Str)
If Not InvalidStrCheck = "" Then Return InvalidStrCheck
'检查文件夹重名
Dim Arr As New List(Of String)
@@ -240,6 +250,61 @@ Public Class ValidateFolderName
End Function
End Class
''' <summary>
''' 对文件名的粗略的特化检测。
''' </summary>
Public Class ValidateFileName
Inherits Validate
Public Property Name As String
Public Property UseMinecraftCharCheck As Boolean = True
Public Property IgnoreCase As Boolean = True
Public Property ParentFolder As String = Nothing
Public Property RequireParentFolderExists = True
Public Sub New()
End Sub
Public Sub New(Name As String, Optional UseMinecraftCharCheck As Boolean = True, Optional IgnoreCase As Boolean = True)
Me.Name = Name
Me.IgnoreCase = IgnoreCase
Me.UseMinecraftCharCheck = UseMinecraftCharCheck
End Sub
Public Overrides Function Validate(Str As String) As String
Try
'检查是否为空
Dim LengthCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
If Not LengthCheck = "" Then Return LengthCheck
'检查空格
If Str.StartsWith(" ") Then Return "文件名不能以空格开头!"
If Str.EndsWith(" ") Then Return "文件名不能以空格结尾!"
'检查长度
LengthCheck = New ValidateLength(1, 253).Validate(Str & If(ParentFolder, ""))
If Not LengthCheck = "" Then Return LengthCheck
'检查尾部小数点
If Str.EndsWith(".") Then Return "文件名不能以小数点结尾!"
'检查特殊字符
Dim CharactCheck As String = New ValidateExcept(IO.Path.GetInvalidFileNameChars() & If(UseMinecraftCharCheck, "!;", ""), "文件名不可包含 % 字符!").Validate(Str)
If Not CharactCheck = "" Then Return CharactCheck
'检查特殊字符串
Dim InvalidStrCheck As String = New ValidateExceptSame({"CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}, "文件名不可为 %!", True).Validate(Str)
If Not InvalidStrCheck = "" Then Return InvalidStrCheck
'检查文件重名
If ParentFolder IsNot Nothing Then
Dim DirInfo As New DirectoryInfo(ParentFolder)
If DirInfo.Exists Then
Dim SameNameCheck = New ValidateExceptSame(DirInfo.EnumerateFiles("*").Select(Function(f) f.Name),
"不可与现有文件重名!", IgnoreCase).Validate(Str)
If Not SameNameCheck = "" Then Return SameNameCheck
Else
If RequireParentFolderExists Then Return $"父文件夹不存在:{ParentFolder}"
End If
End If
Return ""
Catch ex As Exception
Log(ex, "检查文件名出错")
Return "错误:" & ex.Message
End Try
End Function
End Class
''' <summary>
''' 要求输入一个可用的文件夹路径。
''' </summary>
@@ -88,7 +88,7 @@
If FilePath.Contains("crash-") Then
AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(FilePath, ReadFile(FilePath).Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Split(vbCr)))
Else
AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(FilePath, File.ReadAllLines(FilePath, Encoding.UTF8)))
AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(FilePath, ReadFile(FilePath, Encoding.UTF8).Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Split(vbCr)))
End If
Catch ex As Exception
Log(ex, "读取可能的崩溃日志文件失败(" & FilePath & ")")
@@ -135,7 +135,7 @@
If TargetFile.Name.StartsWith("crash-") Then
AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(TargetFile.FullName, ReadFile(TargetFile.FullName).Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Split(vbCr)))
Else
AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(TargetFile.FullName, File.ReadAllLines(TargetFile.FullName, Encoding.UTF8)))
AnalyzeRawFiles.Add(New KeyValuePair(Of String, String())(TargetFile.FullName, ReadFile(TargetFile.FullName, Encoding.UTF8).Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Split(vbCr)))
End If
End If
Catch ex As Exception
@@ -174,10 +174,17 @@
TargetType = AnalyzeFileType.CrashReport
DirectFile = LogFile
ElseIf FileName = "latest.log" OrElse FileName = "latest log.txt" OrElse
FileName = "debug.log" OrElse FileName = "debug log.txt" OrElse FileName = "游戏崩溃前的输出.txt" OrElse
FileName = "rawoutput.log" OrElse FileName = "启动器日志.txt" OrElse FileName = "PCL2 启动器日志.txt" OrElse FileName = "log1.txt" Then
FileName = "debug.log" OrElse FileName = "debug log.txt" OrElse
FileName = "游戏崩溃前的输出.txt" OrElse FileName = "rawoutput.log" Then
TargetType = AnalyzeFileType.MinecraftLog
If DirectFile Is Nothing Then DirectFile = LogFile
ElseIf FileName = "启动器日志.txt" OrElse FileName = "PCL2 启动器日志.txt" OrElse FileName = "log1.txt" Then
If LogFile.Value.Any(Function(s) s.Contains("以下为游戏输出的最后一段内容")) Then
TargetType = AnalyzeFileType.MinecraftLog
If DirectFile Is Nothing Then DirectFile = LogFile
Else
TargetType = AnalyzeFileType.ExtraLog
End If
ElseIf FileName.EndsWith(".log") OrElse FileName.EndsWith(".txt") Then
TargetType = AnalyzeFileType.ExtraLog
Else
@@ -322,6 +329,7 @@
显卡不支持OpenGL
使用OpenJ9
Java版本过高
Java版本不兼容
显卡驱动不支持导致无法设置像素格式
路径包含中文且存在编码问题导致找不到或无法加载主类
Intel驱动不兼容导致EXCEPTION_ACCESS_VIOLATION 'https://bugs.mojang.com/browse/MC-32606
@@ -455,10 +463,9 @@ Done:
If LogMc.Contains("The driver does not appear to support OpenGL") Then AppendReason(CrashReason.显卡不支持OpenGL)
If LogMc.Contains("java.lang.ClassCastException: java.base/jdk") Then AppendReason(CrashReason.使用JDK)
If LogMc.Contains("java.lang.ClassCastException: class jdk.") Then AppendReason(CrashReason.使用JDK)
If LogMc.Contains("Cannot read field ""ofTelemetry"" because ""net.optifine.Config.gameSettings"" is null") Then AppendReason(CrashReason.OptiFine与Forge不兼容)
If LogMc.Contains("TRANSFORMER/net.optifine/net.optifine.reflect.Reflector.<clinit>(Reflector.java") Then AppendReason(CrashReason.OptiFine与Forge不兼容)
If LogMc.Contains("Open J9 is not supported") OrElse LogMc.Contains("OpenJ9 is incompatible") OrElse LogMc.Contains(".J9VMInternals.") Then AppendReason(CrashReason.使用OpenJ9)
If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本过高)
If LogMc.Contains("java.lang.NoSuchFieldException: ucp") Then AppendReason(CrashReason.Java版本过高)
If LogMc.Contains("because module java.base does not export") Then AppendReason(CrashReason.Java版本过高)
If LogMc.Contains("java.lang.ClassNotFoundException: jdk.nashorn.api.scripting.NashornScriptEngineFactory") Then AppendReason(CrashReason.Java版本过高)
If LogMc.Contains("java.lang.ClassNotFoundException: java.lang.invoke.LambdaMetafactory") Then AppendReason(CrashReason.Java版本过高)
@@ -473,6 +480,8 @@ Done:
If LogMc.Contains("A potential solution has been determined:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf))
If LogMc.Contains("Maybe try a lower resolution resourcepack?") Then AppendReason(CrashReason.材质过大或显卡配置不足)
If LogMc.Contains("java.lang.NoSuchMethodError: net.minecraft.world.server.ChunkManager$ProxyTicketManager.shouldForceTicks(J)Z") AndAlso LogMc.Contains("OptiFine") Then AppendReason(CrashReason.OptiFine导致无法加载世界)
If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本不兼容)
If LogMc.Contains("java.lang.UnsupportedClassVersionError: net/fabricmc/loader/impl/launch/knot/KnotClient : Unsupported major.minor version") Then AppendReason(CrashReason.Java版本不兼容)
If LogMc.Contains("Could not reserve enough space") Then
If LogMc.Contains("for 1048576KB object heap") Then
AppendReason(CrashReason.使用32位Java导致JVM无法分配足够多的内存)
@@ -487,11 +496,11 @@ Done:
'找不到或无法加载主类
If (RegexCheck(LogMc, "^[^\n.]+.\w+.[^\n]+\n\[$") OrElse RegexCheck(LogMc, "^\[[^\]]+\] [^\n.]+.\w+.[^\n]+\n\[")) AndAlso
Not (LogMc.Contains("at net.") OrElse LogMc.Contains("/INFO]")) AndAlso
LogHs Is Nothing AndAlso LogCrash Is Nothing Then
LogHs Is Nothing AndAlso LogCrash Is Nothing AndAlso LogMc.Length < 500 Then
AppendReason(CrashReason.路径包含中文且存在编码问题导致找不到或无法加载主类)
End If
'Mod 导致的崩溃
If LogMc.Contains("Mixin prepare failed ") OrElse LogMc.Contains("mixin.injection.throwables.") OrElse LogMc.Contains(".mixins.json] FAILED during )") Then
If LogMc.Contains("Mixin prepare failed ") OrElse LogMc.Contains("Mixin apply failed ") OrElse LogMc.Contains("mixin.injection.throwables.") OrElse LogMc.Contains(".mixins.json] FAILED during )") Then
Dim ModId As String = RegexSeek(LogMc, "(?<=in )[^./ ]+(?=.mixins.json.+failed injection check)")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= failed .+ in )[^./ ]+(?=.mixins.json)")
If ModId Is Nothing Then ModId = RegexSeek(LogMc, "(?<= in config \[)[^./ ]+(?=.mixins.json\] FAILED during )")
@@ -499,7 +508,6 @@ Done:
AppendReason(CrashReason.ModMixin失败, TryAnalyzeModName(If(ModId, "").TrimEnd((vbCrLf & " ").ToCharArray)))
End If
If LogMc.Contains("Caught exception from ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogMc, "[^\n]+?(?)"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
If LogMc.Contains("Failed to create mod instance.") Then AppendReason(CrashReason.Mod初始化失败, TryAnalyzeModName(If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModID: )[^,]+"), If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModId )[^\n]+(?= for )"), "")).TrimEnd(vbCrLf)))
End If
'虚拟机日志分析
@@ -529,6 +537,7 @@ Done:
End If
End If
If LogCrash.Contains("Multiple entries with same key: ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Multiple entries with same key: )[^=]+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
If LogCrash.Contains("due to errors, provided by ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=due to errors, provided by ')[^']+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
If LogCrash.Contains("LoaderExceptionModCrash: Caught exception from ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=LoaderExceptionModCrash: Caught exception from )[^\n]+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
If LogCrash.Contains("Failed loading config file ") Then AppendReason(CrashReason.Mod配置文件导致游戏崩溃, {TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Failed loading config file .+ for modid )[^\n]+"), "").TrimEnd(vbCrLf)).First, If(RegexSeek(LogCrash, "(?<=Failed loading config file ).+(?= of type)"), "").TrimEnd(vbCrLf)})
End If
@@ -542,6 +551,8 @@ Done:
'游戏日志分析
If LogMc IsNot Nothing Then
If LogMc.Contains("]: Warnings were found!") Then AppendReason(CrashReason.Fabric报错, If(RegexSeek(LogMc, "(?<=\]: Warnings were found! ?[\n]+)[\w\W]+?(?=[\n]+\[)"), "").Trim(vbCrLf.ToCharArray))
'Mixin 失败可以导致大量 Mod 实例创建失败
If LogMc.Contains("Failed to create mod instance.") Then AppendReason(CrashReason.Mod初始化失败, TryAnalyzeModName(If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModID: )[^,]+"), If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModId )[^\n]+(?= for )"), "")).TrimEnd(vbCrLf)))
End If
'崩溃报告分析
@@ -731,7 +742,9 @@ Redo:
Case "RawOutput.log"
FileName = "游戏崩溃前的输出.txt"
End Select
CopyFile(OutputFile, TempFolder & "Report\" & FileName)
If File.Exists(OutputFile) Then
WriteFile(TempFolder & "Report\" & FileName, SecretFilter(ReadFile(OutputFile)))
End If
Next
'导出报告
Compression.ZipFile.CreateFromDirectory(TempFolder & "Report\", FileAddress)
@@ -771,11 +784,13 @@ Redo:
Case CrashReason.内存不足
ResultString = "Minecraft 内存不足,导致其无法继续运行。\n这很可能是由于你为游戏分配的内存不足,或是游戏的配置要求过高。\n\n你可以在启动设置中增加为游戏分配的内存,删除配置要求较高的材质、Mod、光影。\n如果这依然不奏效,请在开始游戏前尽量关闭其他软件,或者……换台电脑?\h"
Case CrashReason.使用OpenJ9
ResultString = "游戏因为使用 Open J9 而崩溃了。\n请在启动设置的 Java 选择一项中改用非 OpenJ9 的 Java 8,然后再启动游戏。\n如果你没有安装 JRE 8,你可以从网络中下载、安装一个。"
ResultString = "游戏因为使用 Open J9 而崩溃了。\n请在启动设置的 Java 选择一项中改用非 OpenJ9 的 Java,然后再启动游戏。"
Case CrashReason.使用JDK
ResultString = "游戏似乎因为使用 JDK,或 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用 JRE 8(Java 8),然后再启动游戏。\n如果你没有安装 JRE 8,你可以从网络中下载、安装一个。"
Case CrashReason.Java版本过高
ResultString = "游戏似乎因为你所使用的 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用较低版本的 Java,然后再启动游戏。\n如果没有,可以从网络中下载、安装一个。"
Case CrashReason.Java版本不兼容
ResultString = "游戏不兼容你当前使用的 Java。\n如果没有合适的 Java,可以从网络中下载、安装一个。"
Case CrashReason.使用32位Java导致JVM无法分配足够多的内存
If Environment.Is64BitOperatingSystem Then
ResultString = "你似乎正在使用 32 位 Java,这会导致 Minecraft 无法使用 1GB 以上的内存,进而造成崩溃。\n\n请在启动设置的 Java 选择一项中改用 64 位的 Java 再启动游戏,然后再启动游戏。\n如果你没有安装 64 位的 Java,你可以从网络中下载、安装一个。"
@@ -610,7 +610,7 @@
Try
Result = NetGetCodeByDownload("http://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" & Loader.Input & ".html")
Catch ex As Exception
If GetString(ex).Contains("(404)") Then
If GetExceptionSummary(ex).Contains("(404)") Then
Throw New Exception("没有可用版本")
Else
Throw
@@ -967,7 +967,7 @@
Public CategoryId As Integer = 0 '421: Mod(?), 4780: Fabric
Public IsModPack As Boolean = False
Public GameVersion As String = Nothing
Public PageSize As String = 50
Public PageSize As Integer = 50
Public SearchFilter As String = Nothing
Public Index As Integer? = Nothing
Public ModLoader As Integer? = Nothing
@@ -1254,6 +1254,12 @@
''' CurseForge 工程列表获取事件。
''' </summary>
Public Sub DlCfProjectSub(Task As LoaderTask(Of DlCfProjectRequest, DlCfProjectResult))
'拒绝 1.13- Quilt(这个版本根本没有 Quilt)
If Not Task.Input.IsModPack AndAlso
If(Task.Input.ModLoader, 0) = 5 AndAlso VersionSortInteger(If(Task.Input.GameVersion, "1.15"), "1.14") = -1 Then
Throw New Exception("Quilt 不支持 Minecraft " & Task.Input.GameVersion)
End If
Dim RawFilter As String = If(Task.Input.SearchFilter, "").Trim
Task.Input.SearchFilter = RawFilter
RawFilter = RawFilter.ToLower
@@ -1264,11 +1270,11 @@
If Task.Input.IsModPack Then Throw New Exception("整合包搜索仅支持英文")
ReleaseCfDatabase()
'构造搜索请求
Dim SearchEntries As New List(Of SearchEntry(Of String))
Dim SearchEntries As New List(Of SearchEntry(Of DlCfDbEntry))
For Each Entry In DlCfProjectDb.Values
If If(Entry.ChineseName, "").Contains("动态的树") Then Continue For '傻逼 Mod 的附属太多了
SearchEntries.Add(New SearchEntry(Of String) With {
.Item = Entry.ChineseName,
If Entry.ChineseName.Contains("动态的树") Then Continue For '傻逼 Mod 的附属太多了
SearchEntries.Add(New SearchEntry(Of DlCfDbEntry) With {
.Item = Entry,
.SearchSource = New List(Of KeyValuePair(Of String, Double)) From {
New KeyValuePair(Of String, Double)(Entry.ChineseName & Entry.CurseForgeId, 1)
}
@@ -1278,20 +1284,21 @@
Dim SearchResults = Search(SearchEntries, Task.Input.SearchFilter, 3)
If SearchResults.Count = 0 Then Throw New Exception("无搜索结果,请尝试搜索英文名称")
Dim SearchResult As String = ""
For i = 0 To SearchResults.Count - 1
For i = 0 To Math.Min(4, SearchResults.Count - 1) '就算全是准确的,也最多只要 5 个
If Not SearchResults(i).AbsoluteRight AndAlso i >= Math.Min(2, SearchResults.Count - 1) Then Exit For '把 3 个结果拼合以提高准确度
SearchResult += SearchResults(i).Item.Replace(" - ", "§").Split("§").First.Replace(" (", "|").Split("|").Last.TrimEnd(")") & " "
SearchResult += SearchResults(i).Item.CurseForgeId.Replace("-", " ") & " "
SearchResult += SearchResults(i).Item.ChineseName.Replace(" (", "|").Split("|").Last.TrimEnd(") ").Replace(" - ", "§").Split("§").First & " "
Next
Log("[Download] CurseForge 工程列表中文搜索原始关键词:" & SearchResult, LogLevel.Developer)
Log("[Download] CurseForge 中文搜索原始关键词:" & SearchResult, LogLevel.Developer)
'去除常见连接词
Dim RealFilter As String = ""
For Each Word In SearchResult.Split(" ")
If {"the", "of", "a", "mod"}.Contains(Word.ToLower) Then Continue For
If {"the", "of", "a", "mod"}.Contains(Word.ToLower) OrElse Val(Word) > 0 Then Continue For
If SearchResult.Split(" ").Count > 3 AndAlso {"ftb"}.Contains(Word.ToLower) Then Continue For
RealFilter += Word & " "
RealFilter += Word.TrimStart("{[(").TrimEnd("}])") & " "
Next
Task.Input.SearchFilter = RealFilter
Log("[Download] CurseForge 工程列表中文搜索最终关键词:" & RealFilter, LogLevel.Developer)
Log("[Download] CurseForge 中文搜索最终关键词:" & RealFilter, LogLevel.Developer)
End If
'驼峰英文请求关键字处理
Dim SpacedKeywords = RegexReplace(Task.Input.SearchFilter, "$& ", "([A-Z]+|[a-z]+?)(?=[A-Z]+[a-z]+[a-z ]*)")
@@ -1301,8 +1308,9 @@
Dim RightKeywords As New List(Of String)
For Each Keyword In AllPossibleKeywords.Split(" ")
If Keyword.Trim = "" Then Continue For
If Keyword = "forge" OrElse Keyword = "fabric" OrElse Keyword = "for" OrElse Keyword = "mod" Then 'https://github.com/Hex-Dragon/PCL2/issues/208
Log("[Download] 已跳过搜索关键词 " & Keyword, LogLevel.Developer)
If {"forge", "fabric", "for", "mod",
"forge/fabric", "fabric/forge", "fabric/quilt", "quilt/fabric"}.Contains(Keyword) Then 'https://github.com/Hex-Dragon/PCL2/issues/208
Log("[Download] 已跳过搜索关键词:" & Keyword, LogLevel.Developer)
Continue For
End If
RightKeywords.Add(Keyword)
@@ -1381,18 +1389,25 @@
Private Sub ReleaseCfDatabase()
If DlCfProjectDb IsNot Nothing Then Exit Sub
DlCfProjectDb = New Dictionary(Of String, DlCfDbEntry)
Dim i As Integer = 0
For Each Line In DecodeBytes(GetResources("ModData")).Split(vbLf)
Dim Entry = New DlCfDbEntry
Dim SplitedLine = Line.Split("|")
Entry.CurseForgeId = SplitedLine(0)
Entry.WikiId = SplitedLine(1)
Entry.ChineseName = SplitedLine(2)
Entry.MCBBS = If(SplitedLine.Count = 4, SplitedLine(3), Nothing)
If Entry.ChineseName.Contains("*") Then '处理 *
Entry.ChineseName = Entry.ChineseName.Replace("*", " (" &
String.Join(" ", Entry.CurseForgeId.Split("-").Select(Function(w) w.Substring(0, 1).ToUpper & w.Substring(1, w.Length - 1))) & ")")
End If
DlCfProjectDb.Add(Entry.CurseForgeId, Entry)
i += 1
If Line = "" Then Continue For
For Each EntryData As String In Line.Split("¨")
Dim Entry = New DlCfDbEntry
Dim SplitedLine = EntryData.Split("|")
Entry.CurseForgeId = SplitedLine(0)
Entry.WikiId = i
If SplitedLine.Count >= 2 Then
Entry.ChineseName = SplitedLine(1)
Entry.MCBBS = If(SplitedLine.Count >= 3, SplitedLine(2), Nothing)
If Entry.ChineseName.Contains("*") Then '处理 *
Entry.ChineseName = Entry.ChineseName.Replace("*", " (" &
String.Join(" ", Entry.CurseForgeId.Split("-").Select(Function(w) w.Substring(0, 1).ToUpper & w.Substring(1, w.Length - 1))) & ")")
End If
End If
DlCfProjectDb(Entry.CurseForgeId) = Entry
Next
Next
End Sub
Public Class DlCfDbEntry
@@ -1401,9 +1416,9 @@
''' </summary>
Public WikiId As Integer
''' <summary>
''' 中文译名。若为 Nothing 或空字符串则使用英文名。
''' 中文译名。若为空字符串则使用英文名。
''' </summary>
Public ChineseName As String
Public ChineseName As String = ""
''' <summary>
''' MCBBS 发布帖编号(例如 195107)。若为 Nothing 则没有发布帖。
''' </summary>
@@ -1487,7 +1502,7 @@
Dim Versions As New List(Of String)
For Each Version In Data("gameVersions").Select(Function(t) t.ToString.Trim.ToLower)
If Version.StartsWith("1.") OrElse Version.Contains("w") Then
Versions.Add(Version)
Versions.Add(Version.Replace("-snapshot", " 快照"))
ElseIf Version = "forge" OrElse Version = "fabric" OrElse Version = "quilt" OrElse Version = "rift" Then
ModLoaders.Add(Version.First.ToString.ToUpper & Version.Substring(1))
End If
@@ -1648,9 +1663,10 @@ ExitSub:
#Region "DlSource | 镜像下载源"
Public Function DlSourceResourceGet(MojangBase As String) As String()
Return {MojangBase.Replace("http://resources.download.minecraft.net", "https://download.mcbbs.net/assets"),
MojangBase = MojangBase.Replace("http://resources.download.minecraft.net", "https://resources.download.minecraft.net")
Return {MojangBase.Replace("https://resources.download.minecraft.net", "https://download.mcbbs.net/assets"),
MojangBase,
MojangBase.Replace("http://resources.download.minecraft.net", "https://bmclapi2.bangbang93.com/assets")
MojangBase.Replace("https://resources.download.minecraft.net", "https://bmclapi2.bangbang93.com/assets")
}
End Function
@@ -4,22 +4,75 @@ Public Module ModLaunch
#Region "开始"
Public Class McLaunchOptions
''' <summary>
''' 强制指定在启动后进入的服务器 IP。
''' 默认值:Nothing。使用版本设置的值。
''' </summary>
Public ServerIp As String = Nothing
''' <summary>
''' 将启动脚本保存到该地址,然后取消启动。这同时会改变启动时的提示等。
''' 默认值:Nothing。不保存。
''' </summary>
Public SaveBatch As String = Nothing
''' <summary>
''' 强行指定启动的 MC 版本。
''' 默认值:Nothing。使用 McVersionCurrent。
''' </summary>
Public Version As McVersion = Nothing
End Class
''' <summary>
''' 尝试启动 Minecraft。必须在 UI 线程调用。
''' 返回是否实际开始了启动(如果没有,则一定弹出了错误提示)。
''' </summary>
Public Function McLaunchStart(Optional Options As McLaunchOptions = Nothing) As Boolean
Options = If(Options, New McLaunchOptions)
'预检查
If Not RunInUi() Then
Throw New Exception("McLaunchStart 必须在 UI 线程调用!")
End If
If McLaunchLoader.State = LoadState.Loading Then
Hint("已有游戏正在启动中!", HintType.Critical)
Return False
End If
'强制切换需要启动的版本
If Options.Version IsNot Nothing AndAlso McVersionCurrent <> Options.Version Then
McLaunchLog("在启动前切换到版本 " & Options.Version.Name)
'检查版本
Options.Version.Load()
If Options.Version.State = McVersionState.Error Then
Hint("无法启动 Minecraft:" & Options.Version.Info, HintType.Critical)
Return False
End If
'切换版本
McVersionCurrent = Options.Version
Setup.Set("LaunchVersionSelect", McVersionCurrent.Name)
FrmLaunchLeft.RefreshButtonsUI()
FrmLaunchLeft.RefreshPage(False, False)
End If
FrmMain.AprilGiveup()
'禁止进入版本选择页面(否则就可以在启动中切换 McVersionCurrent 了)
FrmMain.PageStack = FrmMain.PageStack.Where(Function(p) p.Page <> FormMain.PageType.VersionSelect).ToList
'实际启动加载器
McLaunchLoader.Start(Options, IsForceRestart:=True)
Return True
End Function
''' <summary>
''' 记录启动日志。
''' </summary>
Public Sub McLaunchLog(Text As String)
RunInUi(Sub()
FrmLaunchRight.LabLog.Text += vbCrLf & "[" & GetTimeNow() & "] " & Text
End Sub)
Text = SecretFilter(Text)
RunInUi(Sub() FrmLaunchRight.LabLog.Text += vbCrLf & "[" & GetTimeNow() & "] " & Text)
Log("[Launch] " & Text)
End Sub
'启动状态切换
Public McLaunchLoader As New LoaderTask(Of String, Object)("Loader Launch", AddressOf McLaunchStart) With {.OnStateChanged = AddressOf McLaunchState}
Public McLaunchLoader As New LoaderTask(Of McLaunchOptions, Object)("Loader Launch", AddressOf McLaunchStart) With {.OnStateChanged = AddressOf McLaunchState}
Public McLaunchLoaderReal As LoaderCombo(Of Object)
Public McLaunchProcess As Process
Public McLaunchWatcher As Watcher
Private Sub McLaunchState(Loader As LoaderTask(Of String, Object))
Private Sub McLaunchState(Loader As LoaderTask(Of McLaunchOptions, Object))
Select Case McLaunchLoader.State
Case LoadState.Finished, LoadState.Failed, LoadState.Waiting, LoadState.Aborted
FrmLaunchLeft.PageChangeToLogin()
@@ -28,7 +81,13 @@ Public Module ModLaunch
FrmLaunchRight.LabLog.Text = ""
End Select
End Sub
Private Sub McLaunchStart(Loader As LoaderTask(Of String, Object))
''' <summary>
''' 指定启动中断时的提示文本。若不为 Nothing 则会显示为绿色。
''' </summary>
Private AbortHint As String = Nothing
'实际的启动方法
Private Sub McLaunchStart(Loader As LoaderTask(Of McLaunchOptions, Object))
'开始动画
RunInUiWait(AddressOf FrmLaunchLeft.PageChangeToLaunching)
'预检测(预检测的错误将直接抛出)
@@ -48,10 +107,10 @@ Public Module ModLaunch
}) With {.ProgressWeight = 2, .Show = False, .Block = False},
McLoginLoader,
New LoaderCombo(Of String)("补全文件", DlClientFix(McVersionCurrent, False, AssetsIndexExistsBehaviour.DownloadInBackground, True)) With {.ProgressWeight = 15, .Show = False, .Block = True},
New LoaderTask(Of Integer, String)("提供参数中的服务器 IP", Sub(InnerLoader As LoaderTask(Of Integer, String)) InnerLoader.Output = Loader.Input) With {.ProgressWeight = 0.01, .Show = False},
New LoaderTask(Of String, List(Of McLibToken))("获取启动参数", AddressOf McLaunchArgumentMain) With {.ProgressWeight = 2},
New LoaderTask(Of List(Of McLibToken), Integer)("解压文件", AddressOf McLaunchNatives) With {.ProgressWeight = 2},
New LoaderTask(Of Integer, Integer)("预启动处理", AddressOf McLaunchPrerun) With {.ProgressWeight = 1},
New LoaderTask(Of Integer, Integer)("执行自定义命令", AddressOf McLaunchCustom) With {.ProgressWeight = 1},
New LoaderTask(Of Integer, Process)("启动进程", AddressOf McLaunchRun) With {.ProgressWeight = 2},
New LoaderTask(Of Process, Integer)("等待游戏窗口出现", AddressOf McLaunchWait) With {.ProgressWeight = 1},
New LoaderTask(Of Integer, Integer)("结束处理", AddressOf McLaunchEnd) With {.ProgressWeight = 1}
@@ -59,6 +118,7 @@ Public Module ModLaunch
If McLoginLoader.State = LoadState.Finished Then McLoginLoader.State = LoadState.Waiting '要求重启登录主加载器,它会自行决定是否启动副加载器
'等待加载器执行并更新 UI
McLaunchLoaderReal = LaunchLoader
AbortHint = Nothing
LaunchLoader.Start()
'任务栏进度条
LoaderTaskbarAdd(LaunchLoader)
@@ -72,7 +132,11 @@ Public Module ModLaunch
Case LoadState.Finished
Hint(McVersionCurrent.Name & " 启动成功!", HintType.Finish)
Case LoadState.Aborted
Hint("已取消启动!", HintType.Info)
If AbortHint Is Nothing Then
Hint(If(Loader.Input.SaveBatch Is Nothing, "已取消启动!", "已取消导出启动脚本!"), HintType.Info)
Else
Hint(AbortHint, HintType.Finish)
End If
Case LoadState.Failed
Throw LaunchLoader.Error
Case Else
@@ -84,7 +148,7 @@ NextInner:
If CurrentEx.Message.StartsWith("$") Then
'若有以 $ 开头的错误信息,则以此为准显示提示
'若错误信息为 $$,则不提示
If Not CurrentEx.Message = "$$" Then MyMsgBox(CurrentEx.Message.TrimStart("$"), "启动失败")
If Not CurrentEx.Message = "$$" Then MyMsgBox(CurrentEx.Message.TrimStart("$"), If(Loader.Input.SaveBatch Is Nothing, "启动失败", "导出启动脚本失败"))
Throw
ElseIf CurrentEx.InnerException IsNot Nothing Then
'检查下一级错误
@@ -92,8 +156,8 @@ NextInner:
GoTo NextInner
Else
'没有特殊处理过的错误信息
McLaunchLog("错误:" & GetString(ex, False))
Log(ex, "Minecraft 启动失败", LogLevel.Msgbox, "启动失败")
McLaunchLog("错误:" & GetExceptionDetail(ex))
Log(ex, If(Loader.Input.SaveBatch Is Nothing, "Minecraft 启动失败", "导出启动脚本失败"), LogLevel.Msgbox, If(Loader.Input.SaveBatch Is Nothing, "启动失败", "导出启动脚本失败"))
Throw
End If
End Try
@@ -104,6 +168,7 @@ NextInner:
#Region "预检测"
Private Sub McLaunchPrecheck()
If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(100, 2000))
'检查路径
If McVersionCurrent.PathIndie.Contains("!") OrElse McVersionCurrent.PathIndie.Contains(";") Then Throw New Exception("游戏路径中不可包含 ! 或 ;(" & McVersionCurrent.PathIndie & ")")
If McVersionCurrent.Path.Contains("!") OrElse McVersionCurrent.Path.Contains(";") Then Throw New Exception("游戏路径中不可包含 ! 或 ;(" & McVersionCurrent.Path & ")")
@@ -116,15 +181,16 @@ NextInner:
RunInUiWait(Sub()
Dim LoginInput As McLoginData = McLoginInput()
CheckResult = McLoginAble(LoginInput)
If LoginInput.Type = McLoginType.Legacy AndAlso '离线登录
If CheckResult = "" AndAlso
LoginInput.Type = McLoginType.Legacy AndAlso '离线登录
Not RegexCheck(CType(LoginInput, McLoginLegacy).UserName, "^[0-9A-Za-z_]+$") AndAlso
McVersionCurrent.Version.McCodeMain >= 18 Then 'MC 1.18 以上
CheckResult = "用户名中不可包含除数字、英文、下划线以外的特殊字符!"
CheckResult = "玩家名只能由数字、英文和下划线组成,不能包含中文或特殊字符!"
End If
End Sub)
If CheckResult <> "" Then Throw New ArgumentException(CheckResult)
'求赞助
If ThemeCheckGold() Then Exit Sub
#If BETA Then
RunInNewThread(Sub()
Select Case Setup.Get("SystemLaunchCount")
Case 20, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000
@@ -132,10 +198,11 @@ NextInner:
"如果觉得 PCL2 还算好用的话,也可以考虑小小地赞助一下作者呢 qwq……" & vbCrLf &
"毕竟一个人开发也不容易(小声)……",
"求赞助啦……", "这就赞助!", "但是我拒绝") = 1 Then
OpenWebsite("https://afdian.net/@LTCat/plan")
OpenWebsite("https://afdian.net/a/LTCat/plan")
End If
End Select
End Sub, "Donate")
#End If
End Sub
#End Region
@@ -492,7 +559,7 @@ SkipLogin:
McLoginRequestValidate(Data)
GoTo LoginFinish
Catch ex As Exception
Dim AllMessage = GetString(ex)
Dim AllMessage = GetExceptionSummary(ex)
McLaunchLog("验证登录失败:" & AllMessage)
If (AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout")) AndAlso Not AllMessage.Contains("403") Then
McLaunchLog("已触发超时登录失败")
@@ -507,7 +574,7 @@ Refresh:
McLoginRequestRefresh(Data, NeedRefresh)
GoTo LoginFinish
Catch ex As Exception
McLaunchLog("刷新登录失败:" & GetString(ex))
McLaunchLog("刷新登录失败:" & GetExceptionSummary(ex))
End Try
Data.Progress = If(NeedRefresh, 0.85, 0.45)
End If
@@ -516,7 +583,7 @@ Refresh:
If Data.IsAborted Then Throw New ThreadInterruptedException
NeedRefresh = McLoginRequestLogin(Data)
Catch ex As Exception
McLaunchLog("登录失败:" & GetString(ex))
McLaunchLog("登录失败:" & GetExceptionSummary(ex))
Throw
End Try
If NeedRefresh Then
@@ -599,7 +666,7 @@ LoginFinish:
Names.Insert(0, Input.UserName)
Setup.Set("LoginLegacyName", Join(Names.ToArray, "¨"))
Catch ex As Exception
Dim AllMessage As String = GetString(ex)
Dim AllMessage As String = GetExceptionSummary(ex)
Log(ex, "登录失败原始错误信息", LogLevel.Normal)
Dim ThrowEx As Exception = ex
If AllMessage.Contains("403") Then
@@ -607,7 +674,7 @@ LoginFinish:
ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") OrElse AllMessage.Contains("网络请求失败") Then
ThrowEx = New Exception("$登录失败:连接登录服务器超时。" & vbCrLf & "请检查 HiPer 联机模块的连接状况是否良好,或选择其他登录方式!")
End If
McLaunchLog("登录失败:" & GetString(ThrowEx))
McLaunchLog("登录失败:" & GetExceptionSummary(ThrowEx))
Throw ThrowEx
End Try
End Sub
@@ -737,7 +804,7 @@ LoginFinish:
McLaunchLog("登录成功(Login, " & Data.Input.Token & ")")
Return NeedRefresh
Catch ex As Exception
Dim AllMessage As String = GetString(ex)
Dim AllMessage As String = GetExceptionSummary(ex)
Log(ex, "登录失败原始错误信息", LogLevel.Normal)
If AllMessage.Contains("410") AndAlso AllMessage.Contains("Migrated") Then
Throw New Exception("$登录失败:该 Mojang 账号已迁移至微软账号,请在上方的登录方式中选择 微软 并再次尝试登录!")
@@ -784,10 +851,13 @@ LoginFinish:
If OsVersion <= New Version(10, 0, 17763, 0) Then
SystemBrowser:
'Windows 7 或老版 Windows 10 登录
MyMsgBox("PCL2 即将打开登录网页。登录后会转到一个空白页面(这代表登录成功了),请将该空白页面的网址复制到 PCL2。" & vbCrLf &
"如果网络环境不佳,登录网页可能一直加载不出来,此时请尝试使用 VPN 或加速器,然后再试。", "登录说明", "开始", ForceWait:=True)
OpenWebsite(FormLoginOAuth.LoginUrl1)
Dim Result As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {New ValidateRegex("(?<=code\=)[^&]+", "返回网址应以 https://login.live.com/oauth20_desktop.srf?code= 开头")}, "https://login.live.com/oauth20_desktop.srf?code=XXXXXX", "输入登录返回码", "确定", "取消")
Dim Result As String =
MyMsgBoxInput("等待网页登录",
"在登录成功后,网页会变成一片空白,请将该空白页面的网址复制到下面的框中。" & vbCrLf &
"如果网络环境不佳,登录网页可能一直加载不出来,此时请尝试使用 VPN 或加速器,然后再试。",
ValidateRules:=New ObjectModel.Collection(Of Validate) From {New ValidateRegex("(?<=code\=)[^&]+", "返回网址应以 https://login.live.com/oauth20_desktop.srf?code= 开头")},
HintText:="https://login.live.com/oauth20_desktop.srf?code=XXXXXX")
If Result Is Nothing Then
McLaunchLog("微软登录已在步骤 1 被取消")
Throw New ThreadInterruptedException("$$")
@@ -944,7 +1014,7 @@ SystemBrowser:
Try
Result = NetRequestMuity("https://api.minecraftservices.com/authentication/login_with_xbox", "POST", Request, "application/json", 2)
Catch ex As Net.WebException
Dim Message As String = GetString(ex)
Dim Message As String = GetExceptionSummary(ex)
If Message.Contains("(429)") Then
Log(ex, "微软登录第 5 步汇报 429")
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
@@ -968,13 +1038,22 @@ SystemBrowser:
Try
Result = NetRequestMuity("https://api.minecraftservices.com/minecraft/profile", "GET", "", "application/json", 2, New Dictionary(Of String, String) From {{"Authorization", "Bearer " & AccessToken}})
Catch ex As Net.WebException
Dim Message As String = GetString(ex)
Dim Message As String = GetExceptionSummary(ex)
If Message.Contains("(429)") Then
Log(ex, "微软登录第 6 步汇报 429")
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
ElseIf Message.Contains("(404)") Then
Log(ex, "微软登录第 6 步汇报 404")
Throw New Exception("$你可能没有在购买后去 Minecraft 官网创建游戏档案,或者没有购买 Minecraft。")
RunInNewThread(Sub()
Select Case MyMsgBox("你可能没有在 Minecraft 官网创建档案,或者没有购买 Minecraft。" & vbCrLf &
"如果你已经购买了游戏,请在官网上创建档案后再试。", "登录失败", "创建档案", "购买 Minecraft", "取消")
Case 1
OpenWebsite("https://www.minecraft.net/zh-hans/msaprofile/mygames/editprofile")
Case 2
OpenWebsite("https://www.minecraft.net/store/checkout/minecraft-java-bedrock-edition-pc")
End Select
End Sub, "Login Failed: Create Profile")
Throw New Exception("$$")
Else
Throw
End If
@@ -1068,7 +1147,7 @@ SystemBrowser:
MinVer = New Version(1, 17, 0, 0)
ElseIf (McVersionCurrent.ReleaseTime >= New Date(2021, 5, 11) AndAlso McVersionCurrent.Version.McCodeMain = 99) OrElse
(McVersionCurrent.Version.McCodeMain >= 17 AndAlso McVersionCurrent.Version.McCodeMain <> 99) Then
'21w19a+:至少 Java 16
'1.17+ (21w19a+):至少 Java 16
MinVer = New Version(1, 16, 0, 0)
ElseIf McVersionCurrent.ReleaseTime.Year >= 2017 Then 'Minecraft 1.12 与 1.11 的分界线正好是 2017 年,太棒了
'1.12+:至少 Java 8
@@ -1103,6 +1182,9 @@ SystemBrowser:
ElseIf McVersionCurrent.Version.McCodeMain <= 15 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then
'1.15:Java 8 - 15
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 15, 999, 999)
ElseIf VersionSortBoolean(McVersionCurrent.Version.ForgeVersion, "34.0.0") AndAlso VersionSortBoolean("36.2.25", McVersionCurrent.Version.ForgeVersion) Then
'1.16.X,Forge 34.X ~ 36.2.25:最高 Java 8u320
MaxVer = New Version(1, 8, 0, 320)
ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 AndAlso McVersionCurrent.Version.HasOptiFine Then '#305
'1.18+:若安装了 OptiFine,最高 Java 18
MaxVer = New Version(1, 18, 999, 999)
@@ -1112,30 +1194,31 @@ SystemBrowser:
'Fabric 检测
If McVersionCurrent.Version.HasFabric Then
If McVersionCurrent.Version.McCodeMain >= 15 AndAlso McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain <> -1 Then
'1.15 - 1.16:Java 8 - 18
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 18, 999, 999)
'1.15 - 1.16:Java 8 - 19
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 19, 999, 999)
ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 Then
'1.18+:Java 17 - 18
MinVer = New Version(1, 17, 0, 0) : MaxVer = New Version(1, 18, 999, 999)
'1.18+:Java 17 - 19
MinVer = New Version(1, 17, 0, 0) : MaxVer = New Version(1, 19, 999, 999)
End If
End If
'统一通行证检测
If Setup.Get("LoginType") = McLoginType.Nide Then
'至少 Java 8.101 (1.8.0.101)
'至少 Java 8u101
MinVer = If(New Version(1, 8, 0, 101) > MinVer, New Version(1, 8, 0, 101), MinVer)
End If
'选择 Java
McLaunchLog("Java 版本需求:最低 " & MinVer.ToString & ",最高 " & MaxVer.ToString)
McLaunchJavaSelected = JavaSelect(MinVer, MaxVer, McVersionCurrent)
If Task.IsAborted Then Exit Sub '中断加载会导致 JavaSelect 异常地返回空值,误判找不到 Java
McLaunchJavaSelected = JavaSelect("$$", MinVer, MaxVer, McVersionCurrent)
If Task.IsAborted Then Exit Sub
If McLaunchJavaSelected IsNot Nothing Then
McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
Exit Sub
End If
'无合适的 Java
If Task.IsAborted Then Exit Sub '中断加载会导致 JavaSelect 异常地返回空值,误判找不到 Java
McLaunchLog("无合适的 Java,取消启动")
If MinVer >= New Version(1, 17, 0, 0) Then
'缺少 Java 17
@@ -1165,26 +1248,23 @@ SystemBrowser:
''' </summary>
Public Function ExtractJavaWrapper() As String
Dim WrapperPath As String = GetJavaWrapperDir() & "\JavaWrapper.jar"
If Not File.Exists(WrapperPath) OrElse New FileInfo(WrapperPath).Length <> 16818 Then
WriteFile(WrapperPath, GetResources("JavaWrapper"))
Log("[Java] 已自动释放 Java Wrapper:" & WrapperPath)
End If
WriteFile(WrapperPath, GetResources("JavaWrapper"))
Log("[Java] 已释放 Java Wrapper:" & WrapperPath)
Return WrapperPath
End Function
''' <summary>
''' 获取 Java Wrapper 所在的文件夹,不以 \ 结尾。
''' </summary>
Public Function GetJavaWrapperDir() As String
Dim WrapperPath As String = PathAppdata.TrimEnd("\")
If Encoding.UTF8.GetByteCount(WrapperPath) <> WrapperPath.Length Then
Log("[Java] AppData 路径中包含非 ASCII 字符,换用 Temp 目录")
WrapperPath = PathTemp.TrimEnd("\")
If Encoding.UTF8.GetByteCount(PathTemp) <> PathTemp.Length Then
Log("[Java] Temp 路径中包含非 ASCII 字符,换用 C 盘根目录")
WrapperPath = "C:\PCL"
End If
If Encoding.UTF8.GetByteCount(PathAppdata) = PathAppdata.Length Then
Return PathAppdata.TrimEnd("\")
ElseIf Encoding.UTF8.GetByteCount(PathTemp) = PathTemp.Length Then
Log("[Java] Wrapper:AppData 路径中包含非 ASCII 字符,换用 Temp 目录")
Return PathTemp.TrimEnd("\")
Else
Log("[Java] Wrapper:AppData 路径与 Temp 路径中均包含非 ASCII 字符,换用 ProgramData 目录")
Return OsDrive & "ProgramData\PCL"
End If
Return WrapperPath
End Function
'主方法,合并 Jvm、Game、Replace 三部分的参数数据
@@ -1228,7 +1308,7 @@ SystemBrowser:
'全屏
If Setup.Get("LaunchArgumentWindowType") = 0 Then Arguments += " --fullscreen"
'进服
Dim Server As String = If(String.IsNullOrEmpty(Loader.Input), Setup.Get("VersionServerEnter", McVersionCurrent), Loader.Input)
Dim Server As String = If(String.IsNullOrEmpty(McLaunchLoader.Input.ServerIp), Setup.Get("VersionServerEnter", McVersionCurrent), McLaunchLoader.Input.ServerIp)
If Server.Length > 0 Then
If Server.Contains(":") Then
'包含端口号
@@ -1247,7 +1327,7 @@ SystemBrowser:
Arguments += " " & If(ArgumentGame = "", Setup.Get("LaunchAdvanceGame"), ArgumentGame)
'输出
McLaunchLog("Minecraft 启动参数:")
McLaunchLog(Arguments.Replace(McLoginLoader.Output.AccessToken, McLoginLoader.Output.AccessToken.Substring(0, 22) & "[数据删除]" & McLoginLoader.Output.AccessToken.Substring(30)))
McLaunchLog(Arguments)
McLaunchArgument = Arguments
End Sub
@@ -1579,7 +1659,7 @@ NextVersion:
File.Delete(FilePath)
Catch ex As UnauthorizedAccessException
McLaunchLog("删除原 dll 访问被拒绝,这通常代表有一个 MC 正在运行,跳过解压:" & FilePath)
McLaunchLog("实际的错误信息:" & GetString(ex))
McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
Exit For
End Try
End If
@@ -1599,7 +1679,7 @@ NextVersion:
File.Delete(FileName)
Catch ex As UnauthorizedAccessException
McLaunchLog("删除多余文件访问被拒绝,跳过删除步骤")
McLaunchLog("实际的错误信息:" & GetString(ex))
McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
Exit Sub
End Try
Next
@@ -1756,10 +1836,14 @@ NextVersion:
Else
PackFormat = 9
End If
Case 19
PackFormat = 9
Case 19, 99 '99 是快照版
If McVersionCurrent.Version.McCodeSub <= 2 Then
PackFormat = 9
Else
PackFormat = 12
End If
Case Else
PackFormat = 10
PackFormat = 13
End Select
McLaunchLog("正在构建自定义皮肤资源包,格式为:" & PackFormat)
'准备文件
@@ -1829,6 +1913,60 @@ IgnoreCustomSkin:
Log(ex, "离线皮肤资源包设置失败", LogLevel.Hint)
End Try
End Sub
Private Sub McLaunchCustom(Loader As LoaderTask(Of Integer, Integer))
'获取自定义命令
Dim CustomCommand As String = Setup.Get("VersionAdvanceRun", Version:=McVersionCurrent)
If CustomCommand <> "" Then CustomCommand = ArgumentReplace(CustomCommand)
'输出 bat
Try
Dim CmdString As String =
"@echo off" & vbCrLf &
"title 启动 - " & McVersionCurrent.Name & vbCrLf &
"echo 游戏正在启动,请稍候。" & vbCrLf &
"set APPDATA=""" & PathMcFolder & """" & vbCrLf &
"cd /D """ & PathMcFolder & """" & vbCrLf &
CustomCommand & vbCrLf &
"""" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf &
"echo 游戏已退出。" & vbCrLf &
"pause"
WriteFile(If(McLaunchLoader.Input.SaveBatch, Path & "PCL\LatestLaunch.bat"), SecretFilter(CmdString),
Encoding:=If(Encoding.Default.Equals(Encoding.UTF8), Encoding.UTF8, Encoding.GetEncoding("GB18030")))
If McLaunchLoader.Input.SaveBatch IsNot Nothing Then
McLaunchLog("导出启动脚本完成,强制结束启动过程")
AbortHint = "导出启动脚本成功!"
OpenExplorer("/select,""" & McLaunchLoader.Input.SaveBatch & """")
Loader.Parent.Abort()
Exit Sub '导出脚本完成
End If
Catch ex As Exception
Log(ex, "输出启动脚本失败")
If McLaunchLoader.Input.SaveBatch IsNot Nothing Then Throw ex '直接触发启动失败
End Try
'执行自定义命令
If CustomCommand <> "" Then
McLaunchLog("正在执行自定义命令:" & CustomCommand)
Try
Dim Cmd As New Process
Cmd.StartInfo.FileName = "cmd.exe"
Cmd.StartInfo.Arguments = "/c """ & CustomCommand & """"
Cmd.StartInfo.WorkingDirectory = Path
Cmd.StartInfo.UseShellExecute = False
Cmd.StartInfo.CreateNoWindow = True
Cmd.Start()
If Setup.Get("VersionAdvanceRunWait", Version:=McVersionCurrent) Then
Do Until Cmd.HasExited OrElse Loader.IsAborted
Thread.Sleep(10)
Loop
End If
Catch ex As Exception
Log(ex, "执行自定义命令失败", LogLevel.Hint)
End Try
End If
End Sub
Private Sub McLaunchRun(Loader As LoaderTask(Of Integer, Process))
@@ -1861,22 +1999,6 @@ IgnoreCustomSkin:
Loader.Output = GameProcess
McLaunchProcess = GameProcess
'输出 bat
Try
Dim CmdString As String =
"@echo off" & vbCrLf &
"title 启动 - " & McVersionCurrent.Name & vbCrLf &
"echo 游戏正在启动,请稍候。" & vbCrLf &
"set APPDATA=""" & PathMcFolder & """" & vbCrLf &
"cd /D """ & PathMcFolder & """" & vbCrLf &
"""" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf &
"echo 游戏已退出。" & vbCrLf &
"pause"
WriteFile(Path & "PCL\LatestLaunch.bat", CmdString, Encoding:=Encoding.GetEncoding("GB18030"))
Catch ex As Exception
Log(ex, "输出启动脚本失败")
End Try
'进程优先级处理
Try
If GameProcess.HasExited Then Exit Try '可能在启动游戏进程的同时刚好取消了启动
@@ -1912,7 +2034,7 @@ IgnoreCustomSkin:
McLaunchLog("")
McLaunchLog("~ 登录参数 ~")
McLaunchLog("玩家用户名:" & McLoginLoader.Output.Name)
McLaunchLog("AccessToken:" & McLoginLoader.Output.AccessToken.Substring(0, 22) & "[数据删除]" & McLoginLoader.Output.AccessToken.Substring(30))
McLaunchLog("AccessToken:" & McLoginLoader.Output.AccessToken)
McLaunchLog("ClientToken:" & McLoginLoader.Output.ClientToken)
McLaunchLog("UUID:" & McLoginLoader.Output.Uuid)
McLaunchLog("登录方式:" & McLoginLoader.Output.Type)
@@ -1970,6 +2092,45 @@ IgnoreCustomSkin:
End Sub
''' <summary>
''' 在启动结束时,对 PCL 约定的替换标记进行处理。
''' </summary>
Private Function ArgumentReplace(Raw As String) As String
If Raw Is Nothing Then Return Nothing
'路径替换
Raw = Raw.Replace("{minecraft}", PathMcFolder)
Raw = Raw.Replace("{verpath}", McVersionCurrent.Path)
Raw = Raw.Replace("{verindie}", McVersionCurrent.PathIndie)
Raw = Raw.Replace("{java}", McLaunchJavaSelected.PathFolder)
'普通替换
Raw = Raw.Replace("{user}", McLoginLoader.Output.Name)
Raw = Raw.Replace("{uuid}", McLoginLoader.Output.Uuid)
Select Case McLoginLoader.Input.Type
Case McLoginType.Legacy
If PageLinkHiper.HiperState = LoadState.Finished Then
Raw = Raw.Replace("{login}", "联机离线")
Else
Raw = Raw.Replace("{login}", "离线")
End If
Case McLoginType.Mojang
Raw = Raw.Replace("{login}", "Mojang 正版")
Case McLoginType.Ms
Raw = Raw.Replace("{login}", "微软正版")
Case McLoginType.Nide
Raw = Raw.Replace("{login}", "统一通行证")
Case McLoginType.Auth
Raw = Raw.Replace("{login}", "Authlib-Injector")
End Select
Raw = Raw.Replace("{name}", McVersionCurrent.Name)
If {"unknown", "old", "pending"}.Contains(McVersionCurrent.Version.McName.ToLower) Then
Raw = Raw.Replace("{version}", McVersionCurrent.Name)
Else
Raw = Raw.Replace("{version}", McVersionCurrent.Version.McName)
End If
Raw = Raw.Replace("{path}", Path)
Return Raw
End Function
#End Region
End Module
@@ -6,11 +6,11 @@ Public Module ModMinecraft
'列表初始化
Public JavaListCacheVersion As Integer = 1
Public JavaListCacheVersion As Integer = 2
''' <summary>
''' 目前所有可用的 Java。
''' </summary>
Public JavaList As List(Of JavaEntry)
Public JavaList As New List(Of JavaEntry)
''' <summary>
''' 初始化 Java 列表,但除非没有 Java,否则不进行检查。
''' </summary>
@@ -72,7 +72,7 @@ Public Module ModMinecraft
End Get
End Property
''' <summary>
''' Javaw.exe 文件所在文件夹的路径,以 \ 结尾且只含有 \。
''' Javaw.exe 文件所在文件夹的路径,以 \ 结尾。
''' </summary>
Public PathFolder As String
''' <summary>
@@ -125,7 +125,7 @@ Public Module ModMinecraft
Public Overrides Function ToString() As String
Dim VersionString = Version.ToString
If VersionString.StartsWith("1.") Then VersionString = Mid(VersionString, 3)
Return If(IsJre, "Java ", "JDK ") & VersionCode & " (" & VersionString & ")," & If(Is64Bit, "64", "32") & " 位" & If(IsUserImport, ",手动导入", "") & ":" & PathFolder
Return If(IsJre, "JRE ", "JDK ") & VersionCode & " (" & VersionString & ")," & If(Is64Bit, "64", "32") & " 位" & If(IsUserImport, ",手动导入", "") & ":" & PathFolder
End Function
'构造
@@ -156,7 +156,8 @@ Public Module ModMinecraft
End If
IsJre = Not File.Exists(PathFolder & "javac.exe")
'运行 -version
Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 8000).ToLower
Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 15000).ToLower
If Output = "" Then Throw New Exception("尝试运行该 Java 失败")
If ModeDebug Then Log("[Java] Java 检查输出:" & PathFolder & "java.exe" & vbCrLf & Output)
'获取详细信息
Dim VersionString = If(RegexSeek(Output, "(?<=version "")[^""]+"), If(RegexSeek(Output, "(?<=openjdk )[0-9]+"), "")).Replace("_", ".").Split("-").First
@@ -174,10 +175,11 @@ Public Module ModMinecraft
End If
Is64Bit = Output.Contains("64-bit")
If Version.Minor <= 4 OrElse Version.Minor >= 25 Then Throw New Exception("分析详细信息失败,获取的版本为 " & Version.ToString)
'无论如何不允许使用 JRE 16,它完全是炸的,安 OptiFine、Forge 和启动 MC 都会炸
If IsJre AndAlso VersionCode = 16 Then Throw New Exception("由于 JRE 16 对 Minecraft 的兼容性很差,因此不再允许使用")
Catch ex As Exception
Log("[Java] 检查失败的 Java 输出:" & PathFolder & "java.exe" & vbCrLf & If(Output, "无程序输出"))
ex = New Exception("检查 Java 详细信息失败(" & If(PathJavaw, "Nothing") & ")", ex)
Throw ex
Throw New Exception("检查 Java 失败(" & If(PathJavaw, "Nothing") & ")", ex)
End Try
IsChecked = True
End Sub
@@ -225,7 +227,7 @@ Public Module ModMinecraft
JavaSearchFolder(Disk.Name, JavaPreList, False)
Next
'查找 APPDATA 文件夹中的 Java
JavaSearchFolder(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), JavaPreList, False)
JavaSearchFolder(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\", JavaPreList, False)
'查找启动器目录中的 Java
JavaSearchFolder(Path, JavaPreList, False, IsFullSearch:=True)
'查找所选 Minecraft 文件夹中的 Java
@@ -281,7 +283,10 @@ Public Module ModMinecraft
'确保可用并获取详细信息,转入正式列表
Dim NewJavaList As New List(Of JavaEntry)
For Each Entry In JavaPreList
For Each Entry In ArrayNoDouble(JavaPreList.ToList,
Function(a As KeyValuePair(Of String, Boolean), b As KeyValuePair(Of String, Boolean))
Return a.Key.ToLower = b.Key.ToLower '#794
End Function)
NewJavaList.Add(New JavaEntry(Entry.Key, Entry.Value))
Next
NewJavaList = Sort(JavaCheckList(NewJavaList), AddressOf JavaSorter)
@@ -412,7 +417,8 @@ Wait:
''' 最小与最大版本在与输入相同时也会通过。
''' 必须在工作线程调用。
''' </summary>
Public Function JavaSelect(Optional MinVersion As Version = Nothing, Optional MaxVersion As Version = Nothing, Optional RelatedVersion As McVersion = Nothing) As JavaEntry
Public Function JavaSelect(CancelException As String, Optional MinVersion As Version = Nothing, Optional MaxVersion As Version = Nothing,
Optional RelatedVersion As McVersion = Nothing) As JavaEntry
Try
Dim AllowedJavaList As New List(Of JavaEntry)
@@ -425,6 +431,8 @@ Wait:
For Each Entry In JavaPreList
TargetJavaList.Add(New JavaEntry(Entry.Key, Entry.Value))
Next
'检查特定的 Java
If TargetJavaList.Count > 0 Then
TargetJavaList = JavaCheckList(TargetJavaList)
Log("[Java] 检查后找到 " & TargetJavaList.Count & " 个特定目录下的 Java")
@@ -439,6 +447,8 @@ RetryGet:
Case LoadState.Aborted
Throw New ThreadInterruptedException("Java 搜索加载器已中断")
End Select
'生成完整的 Java 列表
Dim AllJavaList As New List(Of JavaEntry)
AllJavaList.AddRange(TargetJavaList)
AllJavaList.AddRange(JavaList)
@@ -458,64 +468,95 @@ RetryGet:
GoTo RetryGet
End If
'检查用户指定的 Java
Dim UserSetup As String = Setup.Get("LaunchArgumentJavaSelect")
If RelatedVersion IsNot Nothing Then
Dim UserSetupVersion As String = Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)
If UserSetupVersion <> "使用全局设置" Then UserSetup = UserSetupVersion
End If
If UserSetup <> "" Then
Dim UserJava As JavaEntry
#Region "检查用户指定的 Java"
Dim UserJava As JavaEntry = Nothing
'获取版本独立设置中指定的 Java
If RelatedVersion IsNot Nothing AndAlso Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion) <> "使用全局设置" Then
Try
UserJava = JavaEntry.FromJson(GetJson(UserSetup))
Catch ex As Exception
Setup.Set("LaunchArgumentJavaSelect", "")
Log(ex, "获取储存的 Java 失败")
GoTo UserPass
End Try
For Each Java In AllowedJavaList
If Java.PathFolder = UserJava.PathFolder Then
'直接使用指定的 Java
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
GoTo UserPass
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)))
'确保版本独立设置中指定的 Java 在 Java 列表中(#978)
If Not JavaList.Any(Function(j) j.PathFolder = UserJava.PathFolder) Then
UserJava = Nothing
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
Log("版本独立设置中指定的 Java 不在主 Java 列表中,此设置已重置", LogLevel.Debug)
Exit Try
End If
Next
Log("[Java] 发现用户指定的不兼容 Java:" & UserJava.ToString)
'弹窗要求选择
Dim Requirement As String = ""
If (MinVersion Is Nothing OrElse MinVersion.Minor = 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 99) Then
Requirement = "最高兼容到 Java " & MaxVersion.Minor & If(MaxVersion.MinorRevision < 99, "." & MaxVersion.MinorRevision & "." & MaxVersion.Revision, "")
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion Is Nothing OrElse MaxVersion.Minor >= 99) Then
Requirement = "至少需要 Java " & MinVersion.Minor & If(MinVersion.MinorRevision > 0 OrElse MinVersion.Revision > 0, "." & MinVersion.MinorRevision & "." & MinVersion.Revision, "")
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 99) Then
Dim Left As String = MinVersion.Minor & If(MinVersion.MinorRevision > 0 OrElse MinVersion.Revision > 0, "." & MinVersion.MinorRevision & "." & MinVersion.Revision, "")
Dim Right As String = MaxVersion.Minor & If(MaxVersion.MinorRevision < 99, "." & MaxVersion.MinorRevision & "." & MaxVersion.Revision, "")
Requirement = "需要 Java " & If(Left = Right, Left, Left & " ~ " & Right)
End If
If Setup.Get("LaunchAdvanceJava") Then
'直接跳过弹窗
Hint("设置中指定了使用 Java " & UserJava.VersionCode & ",但当前版本" & Requirement & ",这可能会导致游戏崩溃!", HintType.Critical)
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
ElseIf MyMsgBox("你在启动设置中指定了使用 Java " & UserJava.VersionCode & ",但当前版本" & Requirement & "。" & vbCrLf &
"如果强制使用该 Java,可能会导致游戏崩溃。" & vbCrLf &
vbCrLf &
" - 指定的 Java:" & UserJava.ToString,
"Java 兼容性警告", "让 PCL2 自动选择", "强制使用该 Java") = 2 Then
'强制使用指定的 Java
Log("[Java] 已强制使用用户指定的不兼容 Java")
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
End If
Catch ex As Exception
UserJava = Nothing
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
Log(ex, "版本独立设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
End Try
End If
'获取全局设置中指定的 Java
If UserJava Is Nothing AndAlso Setup.Get("LaunchArgumentJavaSelect") <> "" Then
Try
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("LaunchArgumentJavaSelect")))
Catch ex As Exception
UserJava = Nothing
Setup.Reset("LaunchArgumentJavaSelect")
Log(ex, "设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
End Try
End If
'确保指定的 Java 可用
If UserJava Is Nothing Then GoTo ExitUserJavaCheck
If AllowedJavaList.Any(Function(j) j.PathFolder = UserJava.PathFolder) Then
Log("[Java] 使用用户指定的 Java:" & UserJava.PathFolder)
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
GoTo UserPass
End If
'指定的 Java 不可用,弹窗要求选择
Log("[Java] 发现用户指定的不兼容 Java:" & UserJava.ToString)
Dim Requirement As String = ""
Dim ShowRevision As Boolean = False
If (MinVersion Is Nothing OrElse MinVersion.Minor = 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 999) Then
ShowRevision = MaxVersion.MinorRevision < 999
Requirement = "最高兼容到 Java " & MaxVersion.Minor & If(ShowRevision, "." & MaxVersion.MajorRevision & "." & MaxVersion.MinorRevision, "")
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion Is Nothing OrElse MaxVersion.Minor >= 999) Then
ShowRevision = MinVersion.MinorRevision > 0 OrElse MinVersion.MajorRevision > 0
Requirement = "至少需要 Java " & MinVersion.Minor & If(ShowRevision, "." & MinVersion.MajorRevision & "." & MinVersion.MinorRevision, "")
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 999) Then
ShowRevision = MinVersion.MinorRevision > 0 OrElse MinVersion.MajorRevision > 0 OrElse MaxVersion.MinorRevision < 999
Dim Left As String = MinVersion.Minor & If(ShowRevision, "." & MinVersion.MajorRevision & "." & MinVersion.MinorRevision, "")
Dim Right As String = MaxVersion.Minor & If(ShowRevision, "." & MaxVersion.MajorRevision & "." & MaxVersion.MinorRevision, "")
Requirement = "需要 Java " & If(Left = Right, Left, Left & " ~ " & Right)
End If
Dim JavaCurrent As String = UserJava.VersionCode & If(ShowRevision, "." & UserJava.Version.MajorRevision & "." & UserJava.Version.MinorRevision, "")
If Setup.Get("LaunchAdvanceJava") Then
'直接跳过弹窗
Hint("设置中指定了使用 Java " & JavaCurrent & ",但当前版本" & Requirement & ",这可能会导致游戏崩溃!", HintType.Critical)
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
Else
Select Case MyMsgBox("你在设置中手动指定了使用 Java " & JavaCurrent & ",但当前" & Requirement & "。" & vbCrLf &
"如果强制使用该 Java,可能会导致出现异常。" & vbCrLf &
vbCrLf &
" - 指定的 Java:" & UserJava.ToString,
"Java 兼容性警告", "让 PCL2 自动选择", "强制使用该 Java", "取消")
Case 1 '让 PCL2 自动选择
Case 2 '强制使用指定的 Java
Log("[Java] 已强制使用用户指定的不兼容 Java")
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
Case 3 '取消启动
Throw New Exception(CancelException)
End Select
End If
ExitUserJavaCheck:
#End Region
'若依然未找到适合的 Java,直接返回
If AllowedJavaList.Count = 0 Then Return Nothing
'检查特定的 Java
'优先使用特定目录下的 Java
For Each Java In AllowedJavaList
If TargetJavaList.Contains(Java) Then
'直接使用指定的 Java
AllowedJavaList = New List(Of JavaEntry) From {Java}
Log("[Java] 使用特定目录下的 Java:" & Java.ToString)
Log("[Java] 优先使用特定目录下的 Java:" & Java.ToString)
GoTo UserPass
End If
Next
@@ -528,8 +569,11 @@ UserPass:
Dim SelectedJava = AllowedJavaList.First
Try
SelectedJava.Check()
Catch ex As ThreadInterruptedException
Throw
Catch ex As Exception
Log(ex, "找到的 Java 已无法使用,尝试进行搜索")
AllowedJavaList = New List(Of JavaEntry)
JavaSearchLoader.Start(IsForceRestart:=True)
GoTo RetryGet
End Try
@@ -542,6 +586,7 @@ UserPass:
Log(ex, "查找符合条件的 Java 时出现加载器中断")
Return Nothing
Catch ex As Exception
If ex.Message = "$$" Then Throw ex
Log(ex, "查找符合条件的 Java 失败", LogLevel.Feedback)
Return Nothing
End Try
@@ -558,11 +603,19 @@ UserPass:
If UserSetupVersion <> "使用全局设置" Then UserSetup = UserSetupVersion
End If
If UserSetup <> "" Then
Dim UserJava = JavaEntry.FromJson(GetJson(UserSetup))
Dim UserJava As JavaEntry = Nothing
Try
UserJava = JavaEntry.FromJson(GetJson(UserSetup))
Catch ex As Exception
Log(ex, "版本指定的 Java 信息已损坏,已重置版本设置中指定的 Java")
Setup.Set("VersionArgumentJavaSelect", "使用全局设置", Version:=RelatedVersion)
GoTo NoUserJava
End Try
For Each Java In JavaList
If Java.PathFolder = UserJava.PathFolder Then Return UserJava.Is64Bit
Next
End If
NoUserJava:
'检查列表
For Each Java In JavaList
If Java.Is64Bit Then Return True
@@ -571,7 +624,6 @@ UserPass:
Catch ex As Exception
Log(ex, "检查 Java 类别时出错", LogLevel.Feedback)
Setup.Set("LaunchArgumentJavaSelect", "")
Setup.Set("VersionArgumentJavaSelect", "", Version:=RelatedVersion)
Return True
End Try
End Function
@@ -598,7 +650,7 @@ UserPass:
'4. Java 大版本
If Left.VersionCode <> Right.VersionCode Then
' Java 7 8 9 10 11 12 13 14 15 16 17 18 19 20...
Dim Weight = {0, 1, 2, 3, 4, 5, 6, 14, 29, 10, 11, 12, 13, 9, 8, 7, 15, 30, 29, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}
Dim Weight = {0, 1, 2, 3, 4, 5, 6, 14, 29, 10, 11, 12, 13, 9, 8, 7, 15, 31, 30, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}
Return Weight.ElementAtOrDefault(Left.VersionCode) >= Weight.ElementAtOrDefault(Right.VersionCode)
End If
'5. 最次级版本号更接近 51
@@ -615,7 +667,7 @@ UserPass:
MyMsgBox("PCL2 未找到 Java 7。" & vbCrLf &
"请自行百度安装 Java 7,安装后在 PCL2 的 设置 → 启动设置 → 游戏 Java 中通过搜索或导入,确保安装的 Java 已列入 Java 列表。",
"未找到 Java")
Case 8
Case 8 '291
If Is32BitSystem Then
OpenWebsite("https://wwa.lanzoui.com/i7RyXq0jbub")
Else
@@ -654,17 +706,10 @@ UserPass:
Public Name As String
Public Path As String
Public Type As McFolderType
Public VersionCount As Integer
Public Overrides Function Equals(obj As Object) As Boolean
If Not (TypeOf obj Is McFolder) Then
Return False
End If
If Not (TypeOf obj Is McFolder) Then Return False
Dim folder = DirectCast(obj, McFolder)
Return Name = folder.Name AndAlso
Path = folder.Path AndAlso
Type = folder.Type AndAlso
VersionCount = folder.VersionCount
Return Name = folder.Name AndAlso Path = folder.Path AndAlso Type = folder.Type
End Function
Public Overrides Function ToString() As String
Return Path
@@ -746,15 +791,6 @@ UserPass:
End If
For Each Folder As McFolder In CacheMcFolderList
#Region "获取可用版本数"
If Directory.Exists(Folder.Path & "versions\") Then
Folder.VersionCount = New DirectoryInfo(Folder.Path & "versions\").GetDirectories.Count
'减去隐藏版本的个数
For Each Dir As DirectoryInfo In New DirectoryInfo(Folder.Path & "versions\").GetDirectories
If ReadIni(Dir.FullName & "\PCL\Setup.ini", "Hide", "False") Then Folder.VersionCount -= 1
Next
End If
#End Region
#Region "更新 launcher_profiles.json"
McFolderLauncherProfilesJsonCreate(Folder.Path)
#End Region
@@ -800,7 +836,7 @@ UserPass:
#Region "版本处理"
Public Const McVersionCacheVersion As Integer = 24
Public Const McVersionCacheVersion As Integer = 25
Private _McVersionCurrent As McVersion
Private _McVersionLast = 0 '为 0 以保证与 Nothing 不相同,使得 UI 显示可以正常初始化
@@ -816,6 +852,8 @@ UserPass:
_McVersionCurrent = value '由于有可能是 Nothing,导致无法初始化,才得这样弄一圈
_McVersionLast = value
If value Is Nothing Then Exit Property
'重置缓存的 Mod 文件夹
PageDownloadCfDetail.CachedFolder = Nothing
'统一通行证重判
If AniControlEnabled = 0 AndAlso
Setup.Get("VersionServerNide", Version:=value) <> Setup.Get("CacheNideServer") AndAlso
@@ -936,6 +974,7 @@ UserPass:
''' </summary>
Public ReadOnly Property Modable As Boolean
Get
If Not IsLoaded Then Load()
Return Version.HasFabric OrElse Version.HasForge OrElse Version.HasLiteLoader OrElse
DisplayType = McVersionCardType.API '#223
End Get
@@ -1271,7 +1310,7 @@ Recheck:
'检查文件夹
If Not Directory.Exists(Path) Then
State = McVersionState.Error
Info = "该文件夹不存在"
Info = "未找到版本 " & Name
Return False
End If
'检查权限
@@ -1307,7 +1346,7 @@ Recheck:
Catch ex As Exception
Log(ex, "依赖版本检查出错(" & Name & ")")
State = McVersionState.Error
Info = "未知错误:" & GetString(ex)
Info = "未知错误:" & GetExceptionSummary(ex)
Return False
End Try
@@ -1319,7 +1358,6 @@ Recheck:
''' </summary>
Public Function Load() As McVersion
Try
Directory.CreateDirectory(Path & "PCL")
'检查版本,若出错则跳过数据确定阶段
If Not Check() Then GoTo ExitDataLoad
#Region "确定版本分类"
@@ -1424,9 +1462,11 @@ ExitDataLoad:
'确定版本显示种类
DisplayType = ReadIni(Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto)
'写入缓存
WriteIni(Path & "PCL\Setup.ini", "State", State)
WriteIni(Path & "PCL\Setup.ini", "Info", Info)
WriteIni(Path & "PCL\Setup.ini", "Logo", Logo)
If Directory.Exists(Path) Then
WriteIni(Path & "PCL\Setup.ini", "State", State)
WriteIni(Path & "PCL\Setup.ini", "Info", Info)
WriteIni(Path & "PCL\Setup.ini", "Logo", Logo)
End If
If State <> McVersionState.Error Then
WriteIni(Path & "PCL\Setup.ini", "ReleaseTime", ReleaseTime.ToString("yyyy-MM-dd HH:mm:ss"))
WriteIni(Path & "PCL\Setup.ini", "VersionFabric", Version.FabricVersion)
@@ -1439,7 +1479,7 @@ ExitDataLoad:
WriteIni(Path & "PCL\Setup.ini", "VersionOriginalSub", Version.McCodeSub)
End If
Catch ex As Exception
Info = "未知错误:" & GetString(ex)
Info = "未知错误:" & GetExceptionSummary(ex)
Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png"
State = McVersionState.Error
Log(ex, "加载版本失败(" & Name & ")", LogLevel.Feedback)
@@ -1454,6 +1494,14 @@ ExitDataLoad:
Dim version = TryCast(obj, McVersion)
Return version IsNot Nothing AndAlso Path = version.Path
End Function
Public Shared Operator =(a As McVersion, b As McVersion) As Boolean
If a Is Nothing AndAlso b Is Nothing Then Return True
If a Is Nothing OrElse b Is Nothing Then Return False
Return a.Path = b.Path
End Operator
Public Shared Operator <>(a As McVersion, b As McVersion) As Boolean
Return Not (a = b)
End Operator
End Class
Public Enum McVersionState
@@ -1621,7 +1669,7 @@ ExitDataLoad:
If Name.StartsWith("2.0") Then
Return "这个秘密计划了两年的更新将游戏推向了一个新高度!"
ElseIf Name.StartsWith("20w14inf") OrElse Name = "20w14∞" Then
Return "我们加入了 20 亿个新的世界,让无限的想象变成了现实!"
Return "我们加入了 20 亿个新的维度,让无限的想象变成了现实!"
ElseIf Name = "15w14a" Then
Return "作为一款全年龄向的游戏,我们需要和平,需要爱与拥抱。"
ElseIf Name = "1.rv-pre1" Then
@@ -1761,7 +1809,8 @@ OnLoaded:
Version.State = ReadIni(Version.Path & "PCL\Setup.ini", "State", Version.State)
Version.IsStar = ReadIni(Version.Path & "PCL\Setup.ini", "IsStar", False)
Version.DisplayType = ReadIni(Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto)
If Version.State <> McVersionState.Error Then
If Version.State <> McVersionState.Error AndAlso
ReadIni(Version.Path & "PCL\Setup.ini", "VersionOriginal", "Unknown") <> "Unknown" Then '旧版本可能没有这一项,导致 Version 不加载(#643)
Dim VersionInfo As New McVersionInfo With {
.FabricVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionFabric", ""),
.ForgeVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionForge", ""),
@@ -1889,16 +1938,23 @@ OnLoaded:
'将每个大版本下的最常规版本加入
For Each Code As Integer In ExistVersion
If NewerVersion.ContainsKey(Code & "-" & McVersionState.OptiFine) Then
If NewerVersion.ContainsKey(Code & "-" & McVersionState.OptiFine) AndAlso NewerVersion.ContainsKey(Code & "-" & McVersionState.Original) Then
'同时存在 OptiFine 与原版
Dim OriginalVersion As McVersion = NewerVersion(Code & "-" & McVersionState.Original)
Dim OptiFineVersion As McVersion = NewerVersion(Code & "-" & McVersionState.OptiFine)
If NewerVersion.ContainsKey(Code & "-" & McVersionState.Original) AndAlso Not NewerVersion(Code & "-" & McVersionState.Original).Version.McName = OptiFineVersion.InheritVersion Then
'同时存在 OptiFine 与原版,但 OptiFine 不是该版的依赖版本,则一定为两个不同版本,且原版较新
VersionUseful.Add(NewerVersion(Code & "-" & McVersionState.Original))
VersionList.Remove(NewerVersion(Code & "-" & McVersionState.Original))
If OriginalVersion.Version.McCodeSub > OptiFineVersion.Version.McCodeSub Then
'仅在原版比 OptiFine 更新时才加入原版
VersionUseful.Add(OriginalVersion)
VersionList.Remove(OriginalVersion)
End If
VersionUseful.Add(OptiFineVersion)
VersionList.Remove(OptiFineVersion)
Else
ElseIf NewerVersion.ContainsKey(Code & "-" & McVersionState.OptiFine) Then
'没有原版,直接加入 OptiFine
VersionUseful.Add(NewerVersion(Code & "-" & McVersionState.OptiFine))
VersionList.Remove(NewerVersion(Code & "-" & McVersionState.OptiFine))
ElseIf NewerVersion.ContainsKey(Code & "-" & McVersionState.Original) Then
'没有 OptiFine,直接加入原版
VersionUseful.Add(NewerVersion(Code & "-" & McVersionState.Original))
VersionList.Remove(NewerVersion(Code & "-" & McVersionState.Original))
End If
@@ -2777,7 +2833,7 @@ NextVersion:
If File.Exists AndAlso (Token.Size = 0 OrElse Token.Size = File.Length) AndAlso
(Not CheckHash OrElse Token.Hash Is Nothing OrElse Token.Hash = GetAuthSHA1(Token.LocalPath)) Then Continue For
'文件不存在,添加下载
Result.Add(New NetFile(DlSourceResourceGet("http://resources.download.minecraft.net/" & Left(Token.Hash, 2) & "/" & Token.Hash), Token.LocalPath, New FileChecker(ActualSize:=If(Token.Size = 0, -1, Token.Size), Hash:=Token.Hash)))
Result.Add(New NetFile(DlSourceResourceGet("https://resources.download.minecraft.net/" & Left(Token.Hash, 2) & "/" & Token.Hash), Token.LocalPath, New FileChecker(ActualSize:=If(Token.Size = 0, -1, Token.Size), Hash:=Token.Hash)))
Next
Catch ex As Exception
Log(ex, "获取版本缺失的资源文件下载列表失败")
@@ -3502,10 +3558,16 @@ VersionFindFail:
'获取 Mod 文件夹下的可用文件列表
Dim ModFileList As New List(Of FileInfo)
If Directory.Exists(Loader.Input) Then
For Each File As FileInfo In New DirectoryInfo(Loader.Input).EnumerateFiles("*.*", SearchOption.AllDirectories)
Dim DirName As String = File.DirectoryName.ToLower
If DirName.StartsWith(Loader.Input & "memory_repo") OrElse DirName.StartsWith(".") OrElse
((DirName & "\") <> Loader.Input AndAlso DirName.Contains("voxel")) Then Continue For
Dim RawName As String = Loader.Input.ToLower
For Each File As FileInfo In EnumerateFiles(Loader.Input)
If File.DirectoryName.ToLower & "\" <> RawName Then
'仅当 Forge 1.13- 且文件夹名与版本号相同时,才加载该子文件夹下的 Mod
If Not (PageVersionLeft.Version IsNot Nothing AndAlso PageVersionLeft.Version.Version.HasForge AndAlso
PageVersionLeft.Version.Version.McCodeMain < 13 AndAlso
File.Directory.Name = "1." & PageVersionLeft.Version.Version.McCodeMain & "." & PageVersionLeft.Version.Version.McCodeSub) Then
Continue For
End If
End If
If McMod.IsModFile(File.FullName) Then ModFileList.Add(File)
Next
End If
@@ -3661,7 +3723,7 @@ VersionFindFail:
End If
Next
Catch ex As Exception
Result.Add("检查 Mod 时出错:" & GetString(ex) & vbCrLf & " - " & ModEntity.FileName)
Result.Add("检查 Mod 时出错:" & GetExceptionSummary(ex) & vbCrLf & " - " & ModEntity.FileName)
Log(ex, "检查 Mod 时出错")
End Try
Next
@@ -3721,7 +3783,7 @@ VersionFindFail:
End Sub
''' <summary>
''' 比较两个版本名的排序,若 Left 较新则返回 True。无法比较两个 Pre 的大小。
''' 比较两个版本名的排序,若 Left 较新或相同则返回 True(Left >= Right)。无法比较两个 Pre 的大小。
''' 支持的格式范例:未知版本, 1.13.2, 1.7.10-pre4, 1.8_pre, 1.14 Pre-Release 2, 1.14.4 C6
''' </summary>
Public Function VersionSortBoolean(Left As String, Right As String) As Boolean
@@ -3737,8 +3799,8 @@ VersionFindFail:
If Left = "未知版本" AndAlso Right = "未知版本" Then Return 0
If Left <> "未知版本" AndAlso Right = "未知版本" Then Return -1
End If
Dim Lefts = RegexSearch(Left.ToLower, "[a-z]+|[0-9]+")
Dim Rights = RegexSearch(Right.ToLower, "[a-z]+|[0-9]+")
Dim Lefts = RegexSearch(Left.ToLower.Replace("快照", "snapshot"), "[a-z]+|[0-9]+")
Dim Rights = RegexSearch(Right.ToLower.Replace("快照", "snapshot"), "[a-z]+|[0-9]+")
Dim i As Integer = 0
While True
'两边均缺失,感觉是一个东西
@@ -3820,46 +3882,5 @@ NextEntry:
Return "".PadLeft(Account.Count, "*")
End If
End Function
''' <summary>
''' 对 PCL 约定的替换标记进行处理。
''' </summary>
Public Function ArgumentReplace(Raw As String) As String
If Raw Is Nothing Then Return Nothing
Raw = Raw.Replace("{user}", If(IsNothing(McLoginLoader.Output), "尚未登录", McLoginLoader.Output.Name))
If IsNothing(McLoginLoader.Input) Then
Raw = Raw.Replace("{login}", "尚未登录")
Else
Select Case McLoginLoader.Input.Type
Case McLoginType.Legacy
If PageLinkHiper.HiperState = LoadState.Finished Then
Raw = Raw.Replace("{login}", "联机离线")
Else
Raw = Raw.Replace("{login}", "离线")
End If
Case McLoginType.Mojang
Raw = Raw.Replace("{login}", "Mojang 正版")
Case McLoginType.Ms
Raw = Raw.Replace("{login}", "微软正版")
Case McLoginType.Nide
Raw = Raw.Replace("{login}", "统一通行证")
Case McLoginType.Auth
Raw = Raw.Replace("{login}", "Authlib-Injector")
End Select
End If
If McVersionCurrent Is Nothing Then
Raw = Raw.Replace("{name}", "无可用版本")
Raw = Raw.Replace("{version}", "无可用版本")
Else
Raw = Raw.Replace("{name}", McVersionCurrent.Name)
If Not McVersionCurrent.IsLoaded Then McVersionCurrent.Load()
If {"unknown", "old", "pending"}.Contains(McVersionCurrent.Version.McName.ToLower) Then
Raw = Raw.Replace("{version}", McVersionCurrent.Name)
Else
Raw = Raw.Replace("{version}", McVersionCurrent.Version.McName)
End If
End If
Raw = Raw.Replace("{path}", Path)
Return Raw
End Function
End Module
@@ -12,7 +12,7 @@
''' <summary>
''' 安装一个给定的整合包文件,返回是否安装成功。必须在工作线程执行。
''' </summary>
Public Function ModpackInstall(File As String, Optional VersionName As String = Nothing, Optional ShowHint As Boolean = True) As Boolean
Public Function ModpackInstall(File As String, Optional VersionName As String = Nothing, Optional ShowHint As Boolean = True, Optional Logo As String = Nothing) As Boolean
Log("[ModPack] 整合包安装请求:" & If(File, "null"))
Dim Archive As Compression.ZipArchive = Nothing
Dim ArchiveBaseFolder As String = ""
@@ -54,7 +54,7 @@
If FullNames(1) = "mmc-pack.json" Then PackType = 2 : Exit Try 'MMC 整合包
Next
Catch ex As Exception
If GetString(ex, False, True).Contains("Error.WinIOError") Then
If GetExceptionDetail(ex, True).Contains("Error.WinIOError") Then
Log(ex, "打开整合包文件失败", If(ShowHint, LogLevel.Hint, LogLevel.Normal))
Return False
ElseIf File.ToLower.EndsWith(".rar") Then
@@ -69,7 +69,7 @@
Select Case PackType
Case 0
Log("[ModPack] 整合包种类:CurseForge")
InstallPackCurseForge(File, Archive, ArchiveBaseFolder, VersionName)
InstallPackCurseForge(File, Archive, ArchiveBaseFolder, VersionName, Logo)
Case 1
Log("[ModPack] 整合包种类:HMCL")
InstallPackHMCL(File, Archive, ArchiveBaseFolder)
@@ -156,7 +156,7 @@ Retry:
''' 获取安装 CurseForge 整合包的加载器,若失败或跳过则返回 Nothing。
''' 加载器以安装目标版本文件夹为输入。
''' </summary>
Private Function InstallPackCurseForgeLoader(FileAddress As String, Archive As Compression.ZipArchive, ArchiveBaseFolder As String, VersionName As String) As LoaderCombo(Of String)
Private Function InstallPackCurseForgeLoader(FileAddress As String, Archive As Compression.ZipArchive, ArchiveBaseFolder As String, VersionName As String, Optional Logo As String = Nothing) As LoaderCombo(Of String)
'读取 Json 文件
Dim Json As JObject
Try
@@ -206,7 +206,7 @@ Retry:
Task.Progress = 0.5
'复制结果
If Directory.Exists(InstallTemp & ArchiveBaseFolder & OverrideHome) Then
My.Computer.FileSystem.CopyDirectory(InstallTemp & ArchiveBaseFolder & OverrideHome, PathMcFolder & "versions\" & VersionName)
CopyDirectory(InstallTemp & ArchiveBaseFolder & OverrideHome, PathMcFolder & "versions\" & VersionName)
Else
Log("[ModPack] 整合包中未找到 override 目录,已跳过")
End If
@@ -242,8 +242,13 @@ Retry:
'跳过重复的 Mod(疑似 CurseForge Bug)
If FileList.ContainsKey(ModJson("id").ToObject(Of Integer)) Then Continue For
'根据 modules 判断是资源包还是 Mod
Dim ModuleNames = CType(ModJson("modules"), JArray).Select(Function(l) l("name").ToString).ToList
Dim IsResourcePack As Boolean = Not ModuleNames.Contains("META-INF") AndAlso ModuleNames.Contains("pack.mcmeta")
Dim IsResourcePack As Boolean
If ModJson("modules").Any Then 'modules 可能返回 null(#1006)
Dim ModuleNames = CType(ModJson("modules"), JArray).Select(Function(l) l("name").ToString).ToList
IsResourcePack = Not ModuleNames.Contains("META-INF") AndAlso ModuleNames.Contains("pack.mcmeta")
Else
IsResourcePack = False
End If
'实际的添加
FileList.Add(ModJson("id"), New DlCfFile(ModJson, False).GetDownloadFile(
PathMcFolder & "versions\" & VersionName & "\" & If(IsResourcePack, "resourcepacks", "mods") & "\", False))
@@ -280,9 +285,18 @@ Retry:
Loaders.Add(New LoaderCombo(Of String)("整合包安装", InstallLoaders) With {.Show = False, .Block = False, .ProgressWeight = InstallExpectTime})
Loaders.Add(New LoaderCombo(Of String)("游戏安装", MergeLoaders) With {.Show = False, .ProgressWeight = MergeExpectTime})
Loaders.Add(New LoaderCombo(Of String)("下载游戏支持库文件", LoadersLib) With {.ProgressWeight = 8})
Loaders.Add(New LoaderTask(Of String, String)("清理安装文件",
Loaders.Add(New LoaderTask(Of String, String)("最终整理文件",
Sub(Task As LoaderTask(Of String, String))
Dim Target As String = PathMcFolder & "versions\" & VersionName & "\原始整合包.zip"
'设置图标
Dim VersionFolder As String = PathMcFolder & "versions\" & VersionName & "\"
If Logo IsNot Nothing AndAlso File.Exists(Logo) Then
File.Copy(Logo, VersionFolder & "PCL\Logo.png", True)
WriteIni(VersionFolder & "PCL\Setup.ini", "Logo", "PCL\Logo.png")
WriteIni(VersionFolder & "PCL\Setup.ini", "LogoCustom", "True")
Log("[Download] 已设置整合包 Logo:" & Logo)
End If
'删除原始整合包文件
Dim Target As String = VersionFolder & "原始整合包.zip"
If Not Setup.Get("ToolDownloadKeepModpack") AndAlso File.Exists(Target) Then
Log("[Download] 根据设置要求删除原始整合包文件:" & Target)
File.Delete(Target)
@@ -304,7 +318,7 @@ Retry:
Dim Loader As New LoaderCombo(Of String)(LoaderName, Loaders) With {.OnStateChanged = AddressOf McInstallState}
Return Loader
End Function
Private Sub InstallPackCurseForge(FileAddress As String, Archive As Compression.ZipArchive, ArchiveBaseFolder As String, Optional VersionName As String = Nothing)
Private Sub InstallPackCurseForge(FileAddress As String, Archive As Compression.ZipArchive, ArchiveBaseFolder As String, Optional VersionName As String = Nothing, Optional Logo As String = Nothing)
'获取版本名
Dim ShowRibble As Boolean = VersionName Is Nothing
@@ -320,13 +334,12 @@ Retry:
Dim PackName As String = If(Json("name"), "")
Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
If Validate.Validate(PackName) <> "" Then PackName = ""
VersionName = MyMsgBoxInput(PackName, New ObjectModel.Collection(Of Validate) From {Validate},
Title:="输入版本名", Button2:="取消")
VersionName = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
If String.IsNullOrEmpty(VersionName) Then Exit Sub
End If
'启动加载器
Dim Loader = InstallPackCurseForgeLoader(FileAddress, Archive, ArchiveBaseFolder, VersionName)
Dim Loader = InstallPackCurseForgeLoader(FileAddress, Archive, ArchiveBaseFolder, VersionName, Logo)
If Loader Is Nothing Then Exit Sub
Loader.Start(PathMcFolder & "versions\" & VersionName & "\")
LoaderTaskbarAdd(Loader)
@@ -349,8 +362,7 @@ Retry:
Dim PackName As String = If(Json("name"), "")
Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
If Validate.Validate(PackName) <> "" Then PackName = ""
Dim VersionName As String = MyMsgBoxInput(PackName, New ObjectModel.Collection(Of Validate) From {Validate},
Title:="输入版本名", Button2:="取消")
Dim VersionName As String = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
If VersionName Is Nothing Then Exit Sub
'解压与配置文件
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
@@ -361,7 +373,7 @@ Retry:
Task.Progress = 0.5
'复制结果
If Directory.Exists(InstallTemp & ArchiveBaseFolder & "minecraft") Then
My.Computer.FileSystem.CopyDirectory(InstallTemp & ArchiveBaseFolder & "minecraft", PathMcFolder & "versions\" & VersionName)
CopyDirectory(InstallTemp & ArchiveBaseFolder & "minecraft", PathMcFolder & "versions\" & VersionName)
Else
Log("[ModPack] 整合包中未找到 minecraft override 目录,已跳过")
End If
@@ -445,8 +457,7 @@ Retry:
Dim PackName As String = If(RegexSeek(PackInstance, "(?<=\nname\=)[^\n]+"), "")
Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
If Validate.Validate(PackName) <> "" Then PackName = ""
Dim VersionName As String = MyMsgBoxInput(PackName, New ObjectModel.Collection(Of Validate) From {Validate},
Title:="输入版本名", Button2:="取消")
Dim VersionName As String = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
If VersionName Is Nothing Then Exit Sub
'解压与配置文件
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
@@ -457,7 +468,7 @@ Retry:
Task.Progress = 0.5
'复制结果
If Directory.Exists(InstallTemp & ArchiveBaseFolder & ".minecraft") Then
My.Computer.FileSystem.CopyDirectory(InstallTemp & ArchiveBaseFolder & ".minecraft", PathMcFolder & "versions\" & VersionName)
CopyDirectory(InstallTemp & ArchiveBaseFolder & ".minecraft", PathMcFolder & "versions\" & VersionName)
Else
Log("[ModPack] 整合包中未找到 override .minecraft 目录,已跳过")
End If
@@ -533,8 +544,7 @@ Retry:
Dim PackName As String = If(Json("name"), "")
Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
If Validate.Validate(PackName) <> "" Then PackName = ""
Dim VersionName As String = MyMsgBoxInput(PackName, New ObjectModel.Collection(Of Validate) From {Validate},
Title:="输入版本名", Button2:="取消")
Dim VersionName As String = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
If VersionName Is Nothing Then Exit Sub
'解压与配置文件
Dim InstallTemp As String = PathTemp & "PackInstall\" & RandomInteger(0, 100000) & "\"
@@ -545,7 +555,7 @@ Retry:
Task.Progress = 0.5
'复制结果
If Directory.Exists(InstallTemp & ArchiveBaseFolder & "overrides") Then
My.Computer.FileSystem.CopyDirectory(InstallTemp & ArchiveBaseFolder & "overrides", PathMcFolder & "versions\" & VersionName)
CopyDirectory(InstallTemp & ArchiveBaseFolder & "overrides", PathMcFolder & "versions\" & VersionName)
Else
Log("[ModPack] 整合包中未找到 overrides 目录,已跳过")
End If
@@ -616,9 +626,8 @@ Retry:
If TargetFolder.Contains("!") OrElse TargetFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Critical) : Exit Sub
If Directory.GetFileSystemEntries(TargetFolder).Length > 0 Then Hint("请选择一个空文件夹作为安装目标!", HintType.Critical) : Exit Sub
'要求显示名称
Dim NewName As String = MyMsgBoxInput(GetFolderNameFromPath(TargetFolder), New ObjectModel.Collection(Of Validate) From {
New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})
},, "输入它在列表中的显示名称",, "取消")
Dim NewName As String = MyMsgBoxInput("输入显示名称", "输入该文件夹在左边栏列表中显示的名称。", GetFolderNameFromPath(TargetFolder),
New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
'解压
Hint("正在解压压缩包……")
@@ -6,13 +6,13 @@
Public HasRunningMinecraft As Boolean = False
Private Sub WatcherStateChanged()
Dim IsRunning As Boolean = False
Dim IsCrashed As Boolean = False
Dim TriggerLauncherShutdown As Boolean = True
For Each Watcher In McWatcherList
If Watcher.State = Watcher.MinecraftState.Loading OrElse Watcher.State = Watcher.MinecraftState.Running Then
IsRunning = True
Exit For
ElseIf Watcher.State = Watcher.MinecraftState.Crashed Then
IsCrashed = True
ElseIf Watcher.State = Watcher.MinecraftState.Crashed OrElse Watcher.State = Watcher.MinecraftState.Canceled Then
TriggerLauncherShutdown = False
End If
Next
If IsWatcherRunning = IsRunning Then Exit Sub
@@ -20,7 +20,7 @@
If IsWatcherRunning Then
MinecraftStart()
Else
MinecraftStop(IsCrashed)
MinecraftStop(TriggerLauncherShutdown)
End If
End Sub
Private Sub MinecraftStart()
@@ -28,7 +28,7 @@
HasRunningMinecraft = True
FrmMain.BtnExtraShutdown.ShowRefresh()
End Sub
Private Sub MinecraftStop(HasMinecraftCrashed As Boolean)
Private Sub MinecraftStop(TriggerLauncherShutdown As Boolean)
McLaunchLog("[全局] 已无运行中的 Minecraft")
HasRunningMinecraft = False
FrmMain.BtnExtraShutdown.ShowRefresh()
@@ -42,10 +42,10 @@
Select Case Setup.Get("LaunchArgumentVisible")
Case 2
'直接关闭
If HasMinecraftCrashed Then
RunInUi(Sub() FrmMain.Hidden = False)
Else
If TriggerLauncherShutdown Then
RunInUi(Sub() FrmMain.EndProgram(False))
Else
RunInUi(Sub() FrmMain.Hidden = False)
End If
Case 3
'恢复
@@ -73,7 +73,7 @@
'更改列表
Dim NewWatcherList As New List(Of Watcher)
For Each Watch In McWatcherList
If Watch.State = MinecraftState.Crashed OrElse Watch.State = MinecraftState.Ended Then Continue For
If Watch.State = MinecraftState.Crashed OrElse Watch.State = MinecraftState.Ended OrElse Watch.State = MinecraftState.Canceled Then Continue For
NewWatcherList.Add(Watch)
Next
NewWatcherList.Add(Me)
@@ -90,8 +90,7 @@
'初始化时钟
RunInNewThread(Sub()
Try
MinecraftBeforeLaunch = GetAllMinecraftWindowHandle(False).Keys.ToList
Do Until State = MinecraftState.Ended OrElse State = MinecraftState.Crashed OrElse Loader.State = LoadState.Aborted
Do Until State = MinecraftState.Ended OrElse State = MinecraftState.Crashed OrElse State = MinecraftState.Canceled OrElse Loader.State = LoadState.Aborted
TimerWindow()
TimerLog()
'设置窗口标题
@@ -128,6 +127,7 @@
Running
Crashed
Ended
Canceled
End Enum
'日志
@@ -250,77 +250,72 @@
Private IsWindowAppeared As Boolean = False
Private IsWindowFinished As Boolean = False
Private WindowHandle As IntPtr
Private MinecraftBeforeLaunch As List(Of IntPtr)
Private Sub TimerWindow()
Try
If GameProcess.HasExited Then Exit Sub
If Not IsWindowFinished Then
'获取全部窗口,检查是否有新增的
Dim MinecraftWindows = GetAllMinecraftWindowHandle(True)
For Each Window In MinecraftBeforeLaunch
If MinecraftWindows.ContainsKey(Window) Then MinecraftWindows.Remove(Window)
Next
If MinecraftWindows.Count = 0 Then Exit Sub
'已找到窗口
If MinecraftWindows.Values(0) Then
'已找到 Minecraft 窗口
WindowHandle = MinecraftWindows.Keys(0)
WatcherLog("Minecraft 窗口已加载:" & WindowHandle.ToInt64)
IsWindowFinished = True
'最大化
If Setup.Get("LaunchArgumentWindowType") = 4 Then
RunInNewThread(Sub()
Try
'如果最大化导致屏幕渲染大小不对,那是 MC 的 Bug,不是我的 Bug
'……虽然我很想这样说,但总有人反馈,算了
Thread.Sleep(1000)
ShowWindow(WindowHandle, 3)
Catch ex As Exception
Log(ex, "最大化 Minecraft 窗口时出现错误")
End Try
End Sub, "MinecraftWindowMaximize")
End If
ElseIf Not IsWindowAppeared Then
'已找到 FML 窗口
WatcherLog("FML 窗口已加载:" & MinecraftWindows.Keys(0).ToInt64)
If IsWindowFinished Then Exit Sub
'获取全部窗口,检查是否有新增的
Dim MinecraftWindow = TryGetMinecraftWindow()
If MinecraftWindow Is Nothing Then Exit Sub
Dim MinecraftWindowName = MinecraftWindow.Value.Value, MinecraftWindowHandle = MinecraftWindow.Value.Key
'已找到窗口
If Not MinecraftWindowName.StartsWith("FML") Then
'已找到 Minecraft 窗口
WindowHandle = MinecraftWindowHandle
WatcherLog("Minecraft 窗口已加载:" & MinecraftWindowName & "(" & MinecraftWindowHandle.ToInt64 & ")")
IsWindowFinished = True
'最大化
If Setup.Get("LaunchArgumentWindowType") = 4 Then
RunInNewThread(Sub()
Try
'如果最大化导致屏幕渲染大小不对,那是 MC 的 Bug,不是我的 Bug
'……虽然我很想这样说,但总有人反馈,算了
Thread.Sleep(2000)
ShowWindow(WindowHandle, 3)
Catch ex As Exception
Log(ex, "最大化 Minecraft 窗口时出现错误")
End Try
End Sub, "MinecraftWindowMaximize")
End If
IsWindowAppeared = True
ElseIf Not IsWindowAppeared Then
'已找到 FML 窗口
WatcherLog("FML 窗口已加载:" & MinecraftWindowName & "(" & MinecraftWindowHandle.ToInt64 & ")")
End If
IsWindowAppeared = True
Catch ex As Exception
Log(ex, "检查 Minecraft 窗口失败", LogLevel.Feedback)
End Try
End Sub
''' <summary>
''' 获取所有 Minecraft 窗口句柄。
''' Value: 是否为 Minecraft 窗口,而不是 FML 窗口。
''' 获取可能是当前进程对应的 Minecraft 窗口的句柄和标题。
''' Nothing 代表未找到。
''' </summary>
''' <param name="CanUseFml">是否包含 FML 窗口</param>
Private Function GetAllMinecraftWindowHandle(CanUseFml As Boolean) As Dictionary(Of IntPtr, Boolean)
Dim AllList As New Dictionary(Of IntPtr, Boolean)
EnumWindows(Sub(hwnd As IntPtr, lParam As Integer)
'检查类名
Dim str As New StringBuilder(512)
GetClassName(hwnd, str, str.Capacity)
Dim ClassName As String = str.ToString
If Not (ClassName = "GLFW30" OrElse ClassName = "LWJGL" OrElse ClassName = "SunAwtFrame") Then Exit Sub
'检查窗口标题名
str = New StringBuilder(512)
GetWindowText(hwnd, str, str.Capacity)
Dim WindowText As String = str.ToString
If CanUseFml AndAlso WindowText.StartsWith("FML") Then
AllList.Add(hwnd, False)
ElseIf Not (WindowText.StartsWith("GLFW") OrElse WindowText = "PopupMessageWindow") Then
'有的 Mod 可以修改窗口标题,不能检测是否为 Minecraft 打头
'部分版本会搞个 GLFW message window 出来所以得反选
AllList.Add(hwnd, True)
End If
'If WindowText.StartsWith("Minecraft") Then
' AllList.Add(hwnd, True)
'ElseIf CanUseFml AndAlso WindowText.StartsWith("FML") Then
' AllList.Add(hwnd, False)
'End If
End Sub, 0)
Return AllList
Private Function TryGetMinecraftWindow() As KeyValuePair(Of IntPtr, String)?
TryGetMinecraftWindow = Nothing
EnumWindows(
Sub(hwnd As IntPtr, lParam As Integer)
If TryGetMinecraftWindow IsNot Nothing Then Exit Sub
'检查类名
Dim str As New StringBuilder(512)
GetClassName(hwnd, str, str.Capacity)
Dim ClassName As String = str.ToString
If Not (ClassName = "GLFW30" OrElse ClassName = "LWJGL" OrElse ClassName = "SunAwtFrame") Then Exit Sub
'获取窗口标题名
str = New StringBuilder(512)
GetWindowText(hwnd, str, str.Capacity)
Dim WindowText As String = str.ToString
'有的 Mod 可以修改窗口标题,所以不能检测是否为 Minecraft 打头,这并不准确
'部分版本会搞个 GLFW message window 出来所以得反选
If Not (WindowText.StartsWith("FML") OrElse (WindowText <> "PopupMessageWindow") AndAlso Not WindowText.StartsWith("GLFW")) Then Exit Sub
'获取窗口关联的进程
Dim ProcessId As Integer
GetWindowThreadProcessId(hwnd, ProcessId)
Dim WindowProcess = Process.GetProcessById(ProcessId)
If WindowProcess.StartTime < GameProcess.StartTime Then Exit Sub '需要是此后启动的进程
'返回
TryGetMinecraftWindow = New KeyValuePair(Of IntPtr, String)(hwnd, WindowText)
End Sub, 0)
Return TryGetMinecraftWindow
End Function
Private Delegate Sub EnumWindowsSub(hwnd As IntPtr, lParam As Integer)
Private Declare Function EnumWindows Lib "user32" (hWnd As EnumWindowsSub, lParam As Integer) As Boolean
@@ -328,6 +323,7 @@
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (hWnd As Integer, str As StringBuilder, maxCount As Integer) As Integer
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (hWnd As Integer, str As String) As Boolean
Private Declare Function ShowWindow Lib "user32" (hWnd As IntPtr, cmdWindow As UInteger) As Boolean
Private Declare Function GetWindowThreadProcessId Lib "user32" (hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
'崩溃处理
Private Sub Crashed()
@@ -356,7 +352,7 @@
'强制关闭
Public Sub Kill()
State = MinecraftState.Ended
State = MinecraftState.Canceled
WatcherLog("尝试强制结束 Minecraft 进程")
Try
If Not GameProcess.HasExited Then GameProcess.Kill()
+7 -26
View File
@@ -31,10 +31,10 @@
'执行
If Type = "打开文件" Then
Dim Info As New ProcessStartInfo With {
.Arguments = If(Data.Length >= 2, Data(1), ""),
.FileName = Location,
.WorkingDirectory = WorkingDir
}
.Arguments = If(Data.Length >= 2, Data(1), ""),
.FileName = Location,
.WorkingDirectory = WorkingDir
}
Process.Start(Info)
Else '打开帮助
PageOtherHelp.EnterHelpPage(Location)
@@ -45,28 +45,9 @@
End Try
End Sub)
Case "启动游戏"
'初始化与前置条件检测
If Not (FrmLaunchLeft.BtnLaunch.IsEnabled AndAlso FrmLaunchLeft.BtnLaunch.Visibility = Visibility.Visible AndAlso FrmLaunchLeft.BtnLaunch.IsHitTestVisible) Then
Hint("已有游戏正在启动中!", HintType.Critical) : Exit Sub
If McLaunchStart(New McLaunchOptions With {.ServerIp = If(Data.Length >= 2, Data(1), Nothing), .Version = New McVersion(Data(0))}) Then
Hint("正在启动 " & Data(0) & "……")
End If
If Not Directory.Exists(PathMcFolder & "versions\" & Data(0)) Then
Hint("未在当前 Minecraft 文件夹找到版本 " & Data(0) & "!", HintType.Critical) : Exit Sub
End If
Dim ButtonVersion As New McVersion(Data(0))
ButtonVersion.Load()
If ButtonVersion.State = McVersionState.Error Then
Hint("无法启动 " & Data(0) & ":" & ButtonVersion.Info, HintType.Critical) : Exit Sub
End If
'实际启动
McVersionCurrent = ButtonVersion
Setup.Set("LaunchVersionSelect", McVersionCurrent.Name)
FrmLaunchLeft.PageLaunchLeft_Loaded()
FrmLaunchLeft.RefreshButtonsUI()
FrmMain.AprilGiveup()
FrmLaunchLeft.LaunchButtonClick(If(Data.Length >= 2, Data(1), ""))
FrmMain.PageChange(FormMain.PageType.Launch)
Case "复制文本"
ClipboardSet(Join(Data, "|"))
@@ -86,7 +67,7 @@
MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL2 不支持其他乱七八糟的协议。", "事件执行失败")
Exit Sub
End If
PageOtherTest.StartCustomDownload(Data(0))
PageOtherTest.StartCustomDownload(Data(0), GetFileNameFromPath(Data(0)))
Case Else
MyMsgBox("未知的事件类型:" & Type & vbCrLf & "请检查事件类型填写是否正确,或者 PCL2 是否为最新版本。", "事件执行失败")
+9 -9
View File
@@ -187,7 +187,8 @@
''' </summary>
Private Sub MusicStartPlay(Address As String, Optional IsFirstLoad As Boolean = False)
Log("[Music] 播放开始:" & Address)
RunInNewThread(Sub() MusicLoop(Address, IsFirstLoad), "Music", ThreadPriority.BelowNormal)
MusicCurrent = Address
RunInNewThread(Sub() MusicLoop(IsFirstLoad), "Music", ThreadPriority.BelowNormal)
End Sub
'播放与暂停
@@ -237,15 +238,14 @@
''' <summary>
''' 在 MusicUuid 不变的前提下,持续播放某地址的音乐,且在播放结束后随机播放下一曲。
''' </summary>
Private Sub MusicLoop(Address As String, Optional IsFirstLoad As Boolean = False)
MusicCurrent = Address
Private Sub MusicLoop(Optional IsFirstLoad As Boolean = False)
Dim CurrentWave As NAudio.Wave.WaveOut = Nothing
Dim Reader As NAudio.Wave.WaveStream = Nothing
Try
'开始播放
CurrentWave = New NAudio.Wave.WaveOut()
MusicNAudio = CurrentWave
Reader = New NAudio.Wave.AudioFileReader(Address)
Reader = New NAudio.Wave.AudioFileReader(MusicCurrent)
CurrentWave.Init(Reader)
CurrentWave.Play()
'第一次打开的暂停
@@ -265,13 +265,13 @@
If CurrentWave.PlaybackState = NAudio.Wave.PlaybackState.Stopped AndAlso MusicAllList.Count > 0 Then MusicStartPlay(DequeueNextMusicAddress)
Catch ex As Exception
If ex.Message.Contains("Got a frame at sample rate") OrElse ex.Message.Contains("does not support changes to") Then
Hint("播放音乐失败(" & GetFileNameFromPath(Address) & "):PCL2 不支持播放音频属性在中途发生变化的音乐", HintType.Critical)
ElseIf Not (Address.ToLower.EndsWith(".wav") OrElse Address.ToLower.EndsWith(".mp3") OrElse Address.ToLower.EndsWith(".flac")) Then
Hint("播放音乐失败(" & GetFileNameFromPath(Address) & "):PCL2 可能不支持此音乐格式,请将格式转换为 .wav、.mp3 或 .flac 后再试", HintType.Critical)
Hint("播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & "):PCL2 不支持播放音频属性在中途发生变化的音乐", HintType.Critical)
ElseIf Not (MusicCurrent.ToLower.EndsWith(".wav") OrElse MusicCurrent.ToLower.EndsWith(".mp3") OrElse MusicCurrent.ToLower.EndsWith(".flac")) Then
Hint("播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & "):PCL2 可能不支持此音乐格式,请将格式转换为 .wav、.mp3 或 .flac 后再试", HintType.Critical)
Else
Log(ex, "播放音乐失败(" & GetFileNameFromPath(Address) & ")", LogLevel.Hint)
Log(ex, "播放音乐失败(" & GetFileNameFromPath(MusicCurrent) & ")", LogLevel.Hint)
End If
Log(ex, "播放音乐失败(" & Address & ")", LogLevel.Developer)
Log(ex, "播放音乐失败(" & MusicCurrent & ")", LogLevel.Developer)
If MusicAllList.Count > 1 Then
Thread.Sleep(1000)
MusicStartPlay(DequeueNextMusicAddress)
@@ -12,7 +12,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("Minecraft 启动器 (制作:龙腾猫跃)")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Plain Craft Launcher 2")>
<Assembly: AssemblyCopyright("Copyright © 龙腾猫跃 2016-2022. All Rights Reserved.")>
<Assembly: AssemblyCopyright("Copyright © 龙腾猫跃 2016-2023. All Rights Reserved.")>
<Assembly: AssemblyConfiguration("PCL2 Config Mark")>
<Assembly: ComVisible(False)>
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
' 方法是按如下所示使用“*”
<Assembly: AssemblyVersion("2.4.3.0")>
<Assembly: AssemblyFileVersion("2.4.3.0")>
<Assembly: AssemblyVersion("2.4.9.0")>
<Assembly: AssemblyFileVersion("2.4.9.0")>
<Assembly: NeutralResourcesLanguage("")>
@@ -380,7 +380,7 @@ Public Module ModDownloadLib
End Sub
Private Sub McDownloadOptiFineInstall(BaseMcFolderHome As String, Target As String, Task As LoaderTask(Of List(Of NetFile), Boolean))
'选择 Java
Dim Java = JavaSelect(New Version(1, 8, 0, 0))
Dim Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
If Java Is Nothing Then
JavaMissing(17)
Throw New Exception("未找到用于安装 OptiFine 的 Java")
@@ -563,7 +563,7 @@ Public Module ModDownloadLib
If Directory.Exists(BaseMcFolder & "versions\" & DownloadInfo.Inherit) Then
DeleteDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit)
End If
My.Computer.FileSystem.CreateDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\")
Directory.CreateDirectory(BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\")
McFolderLauncherProfilesJsonCreate(BaseMcFolder)
CopyFile(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json",
BaseMcFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json")
@@ -575,10 +575,10 @@ Public Module ModDownloadLib
Task.Progress = 0.96
'复制文件
File.Delete(BaseMcFolder & "launcher_profiles.json")
My.Computer.FileSystem.CopyDirectory(BaseMcFolder, McFolder, True)
CopyDirectory(BaseMcFolder, McFolder)
Task.Progress = 0.98
'清理文件
My.Computer.FileSystem.DeleteFile(Target)
File.Delete(Target)
DeleteDirectory(BaseMcFolderHome)
Catch ex As Exception
Throw New Exception("安装新版 OptiFine 版本失败", ex)
@@ -1097,7 +1097,7 @@ Public Module ModDownloadLib
Private Sub ForgeInjector(Target As String, Task As LoaderTask(Of Boolean, Boolean), McFolder As String)
'选择 Java
Dim Java = JavaSelect(New Version(1, 8, 0, 60))
Dim Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
If Java Is Nothing Then
JavaMissing(17)
Throw New Exception("未找到用于安装 Forge 的 Java")
@@ -1175,9 +1175,14 @@ Public Module ModDownloadLib
outputWaitHandle.WaitOne(10000)
errorWaitHandle.WaitOne(10000)
process.Dispose()
If LastResults.Last = "true" Then Exit Sub
'检查是否安装成功:最后两行中是否有 true(true 可能在倒数第二行,见 #832)
If LastResults.Last = "true" OrElse (LastResults.Count >= 2 AndAlso LastResults(LastResults.Count - 2) = "true") Then Exit Sub
Log(Join(LastResults, vbCrLf))
Throw New Exception("Forge 安装器出错,末行为 " & LastResults.Last)
Dim LastLines As String = ""
For i As Integer = Math.Max(0, LastResults.Count - 5) To LastResults.Count - 1 '最后 5 行
LastLines &= vbCrLf & LastResults(i)
Next
Throw New Exception("Forge 安装器出错,日志结束部分为:" & LastLines)
End Using
End Using
End SyncLock
@@ -1404,7 +1409,7 @@ Public Module ModDownloadLib
'清理文件
Try
If Installer IsNot Nothing Then Installer.Dispose()
If File.Exists(InstallerAddress) Then My.Computer.FileSystem.DeleteFile(InstallerAddress)
If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress)
Catch ex As Exception
Log(ex, "安装 Forge 清理文件时出错")
End Try
@@ -1435,7 +1440,7 @@ Public Module ModDownloadLib
'解压支持库文件
Installer.Dispose()
ZipFile.ExtractToDirectory(InstallerAddress, InstallerAddress & "_unrar\")
My.Computer.FileSystem.CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\", True)
CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\")
DeleteDirectory(InstallerAddress & "_unrar\")
Else
'旧版格式
@@ -1458,7 +1463,7 @@ Public Module ModDownloadLib
Try
'清理文件
If Installer IsNot Nothing Then Installer.Dispose()
If File.Exists(InstallerAddress) Then My.Computer.FileSystem.DeleteFile(InstallerAddress)
If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress)
If Directory.Exists(InstallerAddress & "_unrar\") Then DeleteDirectory(InstallerAddress & "_unrar\")
Catch ex As Exception
Log(ex, "非新版方式安装 Forge 清理文件时出错")
@@ -1822,7 +1827,7 @@ Public Module ModDownloadLib
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '清空缓存(合并安装会先生成文件夹,这会在刷新时误判为可以使用缓存)
Hint(Loader.Name & "成功!", HintType.Finish)
Case LoadState.Failed
Hint(Loader.Name & "失败:" & GetString(Loader.Error), HintType.Critical)
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
Case LoadState.Aborted
Hint(Loader.Name & "已取消!", HintType.Info)
Case LoadState.Loading
@@ -1839,7 +1844,7 @@ Public Module ModDownloadLib
Case LoadState.Finished
Hint(Loader.Name & "成功!", HintType.Finish)
Case LoadState.Failed
Hint(Loader.Name & "失败:" & GetString(Loader.Error), HintType.Critical)
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
Case LoadState.Aborted
Hint(Loader.Name & "已取消!", HintType.Info)
Case LoadState.Loading
@@ -1889,11 +1894,19 @@ Public Module ModDownloadLib
''' 如果出现已知问题且已提示用户,则返回 Nothing。出现异常则直接抛出。
''' </summary>
Public Function McInstallLoader(Request As McInstallRequest, Optional DontFixLibraries As Boolean = False) As List(Of LoaderBase)
'获取缓存目录
Dim PathInstallTemp As String
If PathTemp.Contains(" ") AndAlso Request.ForgeEntry IsNot Nothing Then
PathInstallTemp = OsDrive & "ProgramData\PCL\Install\"
Else
PathInstallTemp = PathTemp & "Install\"
End If
'清理缓存
Try
'清理缓存
If Not IsInstallTempCleared Then
IsInstallTempCleared = True
DeleteDirectory(PathTemp & "Install\", True)
DeleteDirectory(PathInstallTemp, True)
Log("[Download] 已清理合并安装缓存")
End If
Catch ex As Exception
@@ -1902,10 +1915,11 @@ Public Module ModDownloadLib
'获取参数
Dim OutputFolder As String = PathMcFolder & "versions\" & Request.TargetVersionName & "\"
Dim TempMcFolder As String = PathTemp & "Install\" & Request.TargetVersionName & "\"
Dim TempMcFolder As String = PathInstallTemp & Request.TargetVersionName.GetHashCode() & "\"
If Directory.Exists(TempMcFolder) Then DeleteDirectory(TempMcFolder)
Dim OptiFineFolder As String = Nothing
If Request.OptiFineVersion IsNot Nothing Then
If Request.OptiFineVersion.Contains("_HD_U") Then Request.OptiFineVersion = "HD_U_" & Request.OptiFineVersion.Split("_HD_U").Last '#735
Request.OptiFineEntry = New DlOptiFineListEntry With {
.NameDisplay = Request.MinecraftName & " " & Request.OptiFineVersion.Replace("HD_U_", "").Replace("_", ""),
.Inherit = Request.MinecraftName,
@@ -1981,8 +1995,8 @@ Public Module ModDownloadLib
LoaderList.Add(New LoaderTask(Of String, String)("安装游戏", Sub(Task As LoaderTask(Of String, String))
InstallMerge(OutputFolder, OutputFolder, OptiFineFolder, OptiFineAsMod, ForgeFolder, Request.ForgeVersion, FabricFolder, LiteLoaderFolder)
Task.Progress = 0.3
If Directory.Exists(TempMcFolder & "libraries") Then My.Computer.FileSystem.CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries", True)
If Directory.Exists(TempMcFolder & "mods") Then My.Computer.FileSystem.CopyDirectory(TempMcFolder & "mods", PathMcFolder & "mods", True)
If Directory.Exists(TempMcFolder & "libraries") Then CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries")
If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", PathMcFolder & "mods")
End Sub) With {.ProgressWeight = 2, .Block = True})
'补全文件
If Not DontFixLibraries AndAlso
@@ -21,7 +21,7 @@
<!--<Rectangle Height="45" Width="45" RadiusX="4" RadiusY="4" Fill="White" Grid.Column="1" Grid.Row="1" IsHitTestVisible="False" SnapsToDevicePixels="True" UseLayoutRounding="False" Grid.RowSpan="3" />-->
<Border Height="45" Width="45" Grid.Column="1" Grid.Row="1" IsHitTestVisible="False" SnapsToDevicePixels="True" UseLayoutRounding="True" Grid.RowSpan="3">
<Border.Clip>
<RectangleGeometry Rect="0,0,45,45" RadiusX="4" RadiusY="4" />
<RectangleGeometry Rect="0,0,45,45" RadiusX="6" RadiusY="6" />
</Border.Clip>
<Image x:Name="PathLogo" RenderOptions.BitmapScalingMode="HighQuality" />
</Border>
@@ -3,7 +3,6 @@
#Region "Logo"
'Public CacheLogo As Boolean = True '是否缓存 Logo:通过下载量确定是否为默认页
Private _Logo As String = ""
Public Property Logo As String
Get
@@ -157,7 +156,7 @@ RetryStart:
Dim Ani As New List(Of AniData)
If IsMouseOver Then
Ani.AddRange({
AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrush9"), Time),
AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrushBg1"), Time),
AaOpacity(RectBack, 1 - RectBack.Opacity, Time,, New AniEaseOutFluent)
})
If IsMouseDown Then
@@ -13,16 +13,12 @@
</Grid.RowDefinitions>
<local:MyCard Margin="0,0,0,25" x:Name="CardIntro">
<StackPanel Margin="22,22,22,19" x:Name="PanIntro">
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnIntroCf" Grid.Column="0" MinWidth="140" Text="查看 CurseForge" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnIntroWiki" Grid.Column="1" MinWidth="140" Text="查看百科" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnIntroMCBBS" Grid.Column="2" MinWidth="140" Text="查看 MCBBS" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
</Grid>
<StackPanel Orientation="Horizontal" Height="35">
<local:MyButton x:Name="BtnIntroCf" MinWidth="140" Text="查看 CurseForge" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnIntroWiki" MinWidth="140" Text="查看百科" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnIntroMCBBS" MinWidth="140" Text="查看 MCBBS" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnIntroCopy" MinWidth="140" Text="复制名称" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
</StackPanel>
</StackPanel>
</local:MyCard>
<StackPanel Grid.Row="1" Grid.RowSpan="2" Name="PanMain" Grid.IsSharedSizeScope="True" />
@@ -96,7 +96,7 @@
PanMain.Children.Add(NewCard)
'确定卡片是否展开
If Pair.Key = TopVersion Then
MyCard.StackInstall(NewStack, 8, Pair.Key)
MyCard.StackInstall(NewStack, If(Project.IsModPack, 9, 8), Pair.Key)
Else
NewCard.IsSwaped = True
End If
@@ -157,24 +157,26 @@
Dim PackName As String = Project.ChineseName.Replace(".zip", "").Replace(".rar", "").Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":")
Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
If Validate.Validate(PackName) <> "" Then PackName = ""
Dim VersionName As String = MyMsgBoxInput(PackName, New ObjectModel.Collection(Of Validate) From {Validate},
Title:="输入版本名", Button2:="取消")
Dim VersionName As String = MyMsgBoxInput("输入版本名称", "", PackName, New ObjectModel.Collection(Of Validate) From {Validate})
If String.IsNullOrEmpty(VersionName) Then Exit Sub
'构造步骤加载器
Dim Loaders As New List(Of LoaderBase)
Dim Target As String = PathMcFolder & "versions\" & VersionName & "\原始整合包.zip"
Dim LogoFileAddress As String = PathTemp & "CFLogo\" & GetHash(CfItem.Logo) & ".png"
Loaders.Add(New LoaderDownload("下载整合包文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 10, .Block = True})
Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包",
Sub()
If Not ModpackInstall(Target, VersionName) Then Throw New Exception("整合包安装出现异常!")
If Not ModpackInstall(Target, VersionName, Logo:=If(IO.File.Exists(LogoFileAddress), LogoFileAddress, Nothing)) Then
Throw New Exception("整合包安装出现异常!")
End If
End Sub) With {.ProgressWeight = 0.1})
'启动
Dim Loader As New LoaderCombo(Of String)(LoaderName, Loaders) With {.OnStateChanged = Sub(MyLoader)
Select Case MyLoader.State
Case LoadState.Failed
Hint(MyLoader.Name & "失败:" & GetString(MyLoader.Error), HintType.Critical)
Hint(MyLoader.Name & "失败:" & GetExceptionSummary(MyLoader.Error), HintType.Critical)
Case LoadState.Aborted
Hint(MyLoader.Name & "已取消!", HintType.Info)
Case LoadState.Loading
@@ -203,7 +205,7 @@
Dim DefaultFolder As String = Nothing
If Not Project.IsModPack Then
'获取 Mod 所需的加载器种类
Dim AllowForge As Boolean? = Nothing, AllowFabric As Boolean? = Nothing 'FUTURE: Quilt 支持
Dim AllowForge As Boolean? = Nothing, AllowFabric As Boolean? = Nothing
If File.ModLoaders.Count > 0 Then '从文件中获取
AllowForge = False : AllowFabric = False
For Each LoaderType In File.ModLoaders
@@ -228,7 +230,7 @@
If Not Version.IsLoaded Then Version.Load()
If Not Version.Modable Then Return False
If File.GameVersion.Any(Function(v) v.Contains(".")) AndAlso
Not File.GameVersion.Any(Function(v) v.Contains(".") AndAlso v.Split(".")(1) = Version.Version.McCodeMain) Then Return False
Not File.GameVersion.Any(Function(v) v.Contains(".") AndAlso v.Split(".")(1) = Version.Version.McCodeMain.ToString) Then Return False
If AllowForge Is Nothing OrElse AllowFabric Is Nothing Then Return True
If AllowForge AndAlso Version.Version.HasForge Then Return True
If AllowFabric AndAlso Version.Version.HasFabric Then Return True
@@ -255,7 +257,7 @@
If SuitableVersions.Count = 0 Then
DefaultFolder = PathMcFolder
If NeedLoad Then
Hint("当前 MC 文件夹中未找到适合这个 Mod 的游戏版本")
Hint("当前 MC 文件夹中没有找到适合这个 Mod 的版本!")
Else
Log("[Download] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置")
End If
@@ -321,5 +323,8 @@
Private Sub BtnIntroMCBBS_Click(sender As Object, e As EventArgs) Handles BtnIntroMCBBS.Click
OpenWebsite("https://www.mcbbs.net/thread-" & Project.MCBBS & "-1-1.html")
End Sub
Private Sub BtnIntroCopy_Click(sender As Object, e As EventArgs) Handles BtnIntroCopy.Click
ClipboardSet(CfItem.LabTitle.Text)
End Sub
End Class
@@ -18,8 +18,9 @@
</StackPanel.RenderTransform>
<local:MyCard Title="安装预览" Margin="0,15,0,0" UseAnimation="False">
<StackPanel Margin="25,37,25,15">
<local:MyHint Text="你尚未选择安装 Fabric API,这会导致大多数 Mod 无法使用!" Margin="0,1,0,7" x:Name="HintFabricAPI" />
<local:MyHint Text="你尚未选择安装 OptiFabric,这会导致 OptiFine 无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabric" />
<local:MyHint Text="你尚未选择安装 Fabric API,这会导致大多数 Mod 无法使用!" Margin="0,1,0,7" x:Name="HintFabricAPI" IsWarn="True" />
<local:MyHint Text="你尚未选择安装 OptiFabric,这会导致 OptiFine 无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabric" IsWarn="True" />
<local:MyHint Text="安装结束后,请在 Mod 下载中搜索 OptiFabric Origins 并下载,否则 OptiFine 会无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabricOld" IsWarn="False" />
<Grid Margin="0,0,0,11">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
@@ -131,7 +131,7 @@
End Sub
'页面切换触发
Public Sub MinecraftSelected(sender As MyListItem, e As Object)
Public Sub MinecraftSelected(sender As MyListItem, e As MouseButtonEventArgs)
SelectedMinecraftId = sender.Title
SelectedMinecraftJsonUrl = sender.Tag("url").ToString
SelectedMinecraftIcon = sender.Logo
@@ -382,7 +382,18 @@
End If
'主警告
HintFabricAPI.Visibility = If(SelectedFabric IsNot Nothing AndAlso SelectedFabricApi Is Nothing, Visibility.Visible, Visibility.Collapsed)
HintOptiFabric.Visibility = If(SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso SelectedOptiFabric Is Nothing, Visibility.Visible, Visibility.Collapsed)
If SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso SelectedOptiFabric Is Nothing Then
If SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15") Then
HintOptiFabric.Visibility = Visibility.Collapsed
HintOptiFabricOld.Visibility = Visibility.Visible
Else
HintOptiFabric.Visibility = Visibility.Visible
HintOptiFabricOld.Visibility = Visibility.Collapsed
End If
Else
HintOptiFabric.Visibility = Visibility.Collapsed
HintOptiFabricOld.Visibility = Visibility.Collapsed
End If
End Sub
''' <summary>
''' 清空已选择的项目。
@@ -627,6 +638,8 @@
If Versions.Count = 0 Then Exit Sub
'排序
Versions = Sort(Versions, Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean
If Not Left.IsPreview AndAlso Right.IsPreview Then Return True
If Left.IsPreview AndAlso Not Right.IsPreview Then Return False
Return VersionSortBoolean(Left.NameDisplay, Right.NameDisplay)
End Function)
'可视化
@@ -991,6 +1004,7 @@
If SelectedFabric Is Nothing AndAlso SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine 与 Fabric"
If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
If SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine"
If SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15") Then Return "不兼容老版本 Fabric,请手动下载 OptiFabric Origins"
If LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
If LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFabric.State, Object).Error.Message
For Each Version In DlOptiFabricLoader.Output
@@ -1049,7 +1063,10 @@
#Region "安装"
Private Sub BtnSelectStart_Click(sender As Object, e As EventArgs) Handles BtnSelectStart.Click
Private Sub TextSelectName_KeyUp(sender As Object, e As KeyEventArgs) Handles TextSelectName.KeyUp
If e.Key = Key.Enter AndAlso BtnSelectStart.IsEnabled Then BtnSelectStart_Click()
End Sub
Private Sub BtnSelectStart_Click() Handles BtnSelectStart.Click
'确认版本隔离
If (SelectedForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) AndAlso
(Setup.Get("LaunchArgumentIndie") = 0 OrElse Setup.Get("LaunchArgumentIndie") = 2) Then
@@ -9,7 +9,7 @@
LogoScale="0.87" Logo="M1091.291429 0H78.935771C35.34848 0.035109 0.029257 35.354331 0 78.935771v863.331475c0 43.534629 35.401143 78.994286 78.935771 78.994285H1091.291429c43.534629 0 78.994286-35.401143 78.994285-78.994285V78.871406C1170.156983 35.319223 1134.849463 0.064366 1091.291429 0z m-8.835658 87.771429v78.754377H87.771429v-78.760229h994.684342zM87.771429 933.425737V254.232869h994.684342v679.140205H87.771429v0.058515zM724.95104 340.00896l-206.19264 547.605943a43.903269 43.903269 0 0 1-82.154057-31.012572l206.139977-547.547428a43.944229 43.944229 0 0 1 82.20672 30.954057zM369.558674 545.909029l-85.489371 85.489371 85.489371 85.542034a43.885714 43.885714 0 0 1-62.025143 62.083657l-116.554605-116.560457a43.8272 43.8272 0 0 1 0-62.025143l116.560457-116.49024a43.885714 43.885714 0 0 1 62.019291 61.966629z m610.567315-37.566172a43.885714 43.885714 0 0 1 0 62.083657l-116.560458 116.560457a43.768686 43.768686 0 0 1-62.019291 0 43.885714 43.885714 0 0 1 0-62.083657l85.547886-85.547885-85.547886-85.542035a43.897417 43.897417 0 0 1 62.083657-62.083657l116.496092 116.618972z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="1" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="1" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -21,7 +21,7 @@
<!--Logo="M469.333333 213.333333V128a42.666667 42.666667 0 1 1 85.333334 0v85.333333h127.829333C847.722667 213.333333 981.333333 347.029333 981.333333 512.149333v319.936A106.496 106.496 0 0 1 874.730667 938.666667h-85.461334c-48.661333 0-107.221333-29.290667-136.469333-68.266667l-64-85.333333c-6.144-8.170667-23.957333-17.066667-34.24-17.066667h-85.12c-10.282667 0-28.096 8.896-34.24 17.066667l-64 85.333333c-29.226667 38.976-87.808 68.266667-136.469333 68.266667H149.269333A106.496 106.496 0 0 1 42.666667 832.085333V512.149333C42.666667 347.029333 176.277333 213.333333 341.504 213.333333H469.333333z m213.162667 85.333334H341.504A213.333333 213.333333 0 0 0 128 512.149333v319.936c0 11.818667 9.450667 21.248 21.269333 21.248h85.461334c21.802667 0 55.082667-16.64 68.202666-34.133333l64-85.333333c22.272-29.696 65.408-51.2 102.506667-51.2h85.12c37.098667 0 80.213333 21.504 102.506667 51.2l64 85.333333c13.12 17.493333 46.4 34.133333 68.202666 34.133333h85.461334a21.162667 21.162667 0 0 0 21.269333-21.248V512.149333A213.333333 213.333333 0 0 0 682.496 298.666667zM362.666667 469.333333h42.666666a42.666667 42.666667 0 1 1 0 85.333334h-42.666666v42.666666a42.666667 42.666667 0 1 1-85.333334 0v-42.666666h-42.666666a42.666667 42.666667 0 1 1 0-85.333334h42.666666v-42.666666a42.666667 42.666667 0 1 1 85.333334 0v42.666666z m341.333333-21.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m0 213.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m-106.666667-106.666666a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z m213.333334 0a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z">-->
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="4" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="4" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -30,7 +30,7 @@
<!--Logo="M12 0l-11 6v12.131l11 5.869 11-5.869v-12.066l-11-6.065zm-1 21.2l-6.664-3.555 4.201-2.801c1.08-.719-.066-2.359-1.243-1.575l-4.294 2.862v-7.901l8 4.363v8.607zm-6.867-14.63l6.867-3.746v4.426c0 1.323 2 1.324 2 0v-4.415l6.91 3.811-7.905 4.218-7.872-4.294zm8.867 6.03l8-4.269v7.8l-4.263-2.842c-1.181-.785-2.323.855-1.245 1.574l4.172 2.781-6.664 3.556v-8.6z">-->
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="5" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="5" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -39,7 +39,7 @@
<!--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.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="6" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="6" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -47,7 +47,7 @@
LogoScale="1.02" Logo="M826.453333 170.666667c-100.266667-93.866667-248.96-76.373333-256-75.52a31.786667 31.786667 0 0 0-26.666666 22.613333c-1.066667 3.2-101.546667 330.666667-426.666667 445.013333a29.013333 29.013333 0 0 0-7.893333 4.48l-1.493334 1.066667a29.44 29.44 0 0 0-5.973333 6.613333 31.786667 31.786667 0 0 0-3.626667 7.68 5.333333 5.333333 0 0 1 0 1.493334 30.506667 30.506667 0 0 0 0 8.96c7.466667 116.266667 45.013333 204.586667 112 262.826666a303.36 303.36 0 0 0 194.773334 71.466667h11.52a32.426667 32.426667 0 0 0 27.093333-19.626667 694.186667 694.186667 0 0 1 159.36-234.666666l-7.68 55.466666A31.786667 31.786667 0 0 0 621.44 768h4.48a32.213333 32.213333 0 0 0 31.786667-27.733333l15.573333-112.426667 112.426667 8.32a32 32 0 1 0 4.693333-64l-56.96-4.266667c36.48-25.813333 74.026667-50.56 112-75.52l51.626667-34.133333a31.573333 31.573333 0 0 0 14.08-24.746667c6.186667-115.2-21.76-203.306667-84.693334-262.826666zM620.8 573.013333l-1.706667 1.493334a219.093333 219.093333 0 0 0-87.466666-116.693334 222.933333 222.933333 0 0 0-95.146667-33.28c18.986667-21.333333 36.266667-42.666667 51.626667-64a198.613333 198.613333 0 0 1 202.453333 158.08c-20.053333 14.506667-39.893333 29.44-59.52 45.226667a29.866667 29.866667 0 0 0-10.24 9.173333z m-228.693333 292.266667a238.72 238.72 0 0 1-141.44-55.893333 213.333333 213.333333 0 0 1-34.986667-39.466667 123.946667 123.946667 0 0 0 44.373333 8.106667 168.533333 168.533333 0 0 0 69.12-16.213334 29.44 29.44 0 0 0 7.04-4.266666l106.666667-85.333334a32 32 0 1 0-39.893333-49.92L298.666667 704a78.293333 78.293333 0 0 1-69.546667 1.706667c-32.426667-17.066667-52.693333-61.653333-62.506667-93.44a709.333333 709.333333 0 0 0 202.453334-123.733334 187.52 187.52 0 0 1 128 21.333334 171.946667 171.946667 0 0 1 68.906666 109.653333 756.48 756.48 0 0 0-173.866666 245.76zM810.666667 438.4l-64 42.666667A256 256 0 0 0 529.706667 298.666667a810.666667 810.666667 0 0 0 69.12-140.8c37.973333-1.066667 123.946667 4.053333 183.68 59.946666 45.866667 42.666667 67.84 108.8 65.493333 195.84z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="7" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="7" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -55,7 +55,7 @@
LogoScale="1.06" Logo="M517.41 186.99l22.45 83.78h-55.04l-18.76-70.02c-2.85-10.63-13.78-16.95-24.42-14.1-10.63 2.85-16.95 13.78-14.1 24.42l16 59.71H388.5l-12.31-45.95c-10.45-38.99 12.69-79.08 51.69-89.52s79.08 12.68 89.53 51.68z M538.58 98c40.37 0 73.1 32.73 73.1 73.1v79.74h-53.16V171.1c0-11.01-8.93-19.94-19.94-19.94-11.01 0-19.94 8.93-19.94 19.94v79.74h-53.16V171.1c0-40.37 32.73-73.1 73.1-73.1z M512 224.26c191.58 0 346.88 155.3 346.88 346.88v61.8c0 28.85 3.33 59.94 9.98 93.27l1.29 6.28c12.43 59.1-21.15 118.2-78.28 137.78C691.18 904.75 597.9 922 512 922c-83.94 0-174.95-16.47-273.01-49.41l-6.85-2.32c-56.4-19.32-89.85-77.16-78.74-135.5l0.46-2.27c7.51-35.71 11.27-68.89 11.27-99.55v-61.8c0-189.66 152.21-343.77 341.14-346.83l5.73-0.06z m-4.64 66.49c-151.21 2.45-273.32 124.58-275.75 275.8l-0.04 4.59v61.8l-0.04 5.93c-0.45 33.74-4.7 69.49-12.65 107.3-5.53 26.27 9.4 52.53 34.79 61.23 94.08 32.23 180.19 48.15 258.32 48.15s164.25-15.92 258.32-48.15c25.39-8.7 40.32-34.97 34.79-61.23-7.95-37.81-12.2-73.56-12.65-107.3l-0.04-5.93v-61.8c0-153.33-123.05-277.91-275.79-280.39l-4.64-0.04-4.62 0.04z M500.66 717.38l-53.28-87.19c-3.83-6.26-1.85-14.44 4.41-18.27 0.76-0.46 1.56-0.85 2.39-1.15L512 589.74l57.82 21.03c6.9 2.51 10.46 10.13 7.95 17.03-0.3 0.83-0.69 1.63-1.15 2.39l-53.28 87.19c-3.83 6.26-12.01 8.24-18.27 4.41-1.8-1.1-3.31-2.61-4.41-4.41z M684.77 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z M339.23 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="8" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="8" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -64,7 +64,7 @@
LogoScale="0.97" 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.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="10" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="10" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -72,7 +72,7 @@
LogoScale="0.98" 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="11" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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" />
<local:MyIconButton Tag="11" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" 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>
@@ -95,21 +95,30 @@
DlFabricListLoader.Start(IsForceRestart:=True)
DlFabricApiLoader.Start(IsForceRestart:=True)
DlOptiFabricLoader.Start(IsForceRestart:=True)
ItemInstall.Checked = True
Case FormMain.PageSubType.DownloadMod
If FrmDownloadMod IsNot Nothing Then FrmDownloadMod.PageLoaderRestart()
ItemMod.Checked = True
Case FormMain.PageSubType.DownloadPack
If FrmDownloadPack IsNot Nothing Then FrmDownloadPack.PageLoaderRestart()
ItemPack.Checked = True
Case FormMain.PageSubType.DownloadClient
DlClientListLoader.Start(IsForceRestart:=True)
ItemClient.Checked = True
Case FormMain.PageSubType.DownloadOptiFine
DlOptiFineListLoader.Start(IsForceRestart:=True)
ItemOptiFine.Checked = True
Case FormMain.PageSubType.DownloadForge
DlForgeListLoader.Start(IsForceRestart:=True)
ItemForge.Checked = True
Case FormMain.PageSubType.DownloadLiteLoader
DlLiteLoaderListLoader.Start(IsForceRestart:=True)
ItemLiteLoader.Checked = True
Case FormMain.PageSubType.DownloadFabric
DlFabricListLoader.Start(IsForceRestart:=True)
ItemFabric.Checked = True
End Select
Hint("正在刷新……", Log:=False)
End Sub
'点击返回
@@ -14,7 +14,7 @@
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2.5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
@@ -33,7 +33,7 @@
<local:MyComboBoxItem Tag="4487" Content="FTB" Margin="15,0,0,0" ToolTip="该整合包由 FTB 官方发布" />
<local:MyComboBoxItem Tag="4480" Content="基于地图" Margin="15,0,0,0" ToolTip="该整合包基于已有的 Minecraft 游戏地图运行" />
<local:MyComboBoxItem Tag="4479" Content="硬核" />
<local:MyComboBoxItem Tag="4471" Content="科幻" />
<local:MyComboBoxItem Tag="4474" Content="科幻" />
<local:MyComboBoxItem Tag="4483" Content="战斗" />
<local:MyComboBoxItem Tag="4478" Content="任务" />
<local:MyComboBoxItem Tag="4484" Content="多人" />
@@ -77,7 +77,7 @@
<local:MyButton x:Name="BtnSearchRun" Text="搜索" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ColorType="Highlight" />
<local:MyButton x:Name="BtnSearchReset" Text="重置条件" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
<local:MyButton x:Name="BtnSearchInstall" Text="安装已有整合包" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2"
ToolTip="在当前选择的 Minecraft 文件夹下安装整合包" ToolTipService.ShowDuration="2333333" />
ToolTip="在当前选择的 Minecraft 文件夹下安装整合包" />
</Grid>
</StackPanel>
</local:MyCard>
@@ -72,7 +72,7 @@
Private Sub BtnSearchReset_Click(sender As Object, e As EventArgs) Handles BtnSearchReset.Click
TextSearchName.Text = ""
TextSearchVersion.SelectedIndex = 0
TextSearchVersion.Text = "全部"
TextSearchVersion.Text = ""
ComboSearchTag.SelectedIndex = 0
Loader.LastFinishedTime = 0 '要求强制重新开始
End Sub
@@ -256,20 +256,20 @@ UnknownType:
RadioLoginType5.Visibility = Visibility.Visible
RadioLoginType0.Visibility = Visibility.Visible
Case 1 '仅正版
If RadioLoginType5.Checked Then
If Setup.Get("CacheMsAccess") = "" Then
Type = PageType.Ms
Else
Type = PageType.MsSkin
End If
Setup.Set("LoginType", McLoginType.Ms)
Else
If RadioLoginType1.Checked Then
If Setup.Get("CacheMojangAccess") = "" Then
Type = PageType.Mojang
Else
Type = PageType.MojangSkin
End If
Setup.Set("LoginType", McLoginType.Mojang)
Else
If Setup.Get("CacheMsAccess") = "" Then
Type = PageType.Ms
Else
Type = PageType.MsSkin
End If
Setup.Set("LoginType", McLoginType.Ms)
End If
PanType.Visibility = Visibility.Visible
PanTypeOne.Visibility = Visibility.Collapsed
@@ -352,10 +352,10 @@ UnknownType:
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
ElseIf GetExceptionSummary(ex).Contains("429") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
@@ -400,10 +400,10 @@ Finish:
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
ElseIf GetExceptionSummary(ex).Contains("429") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
@@ -470,7 +470,7 @@ UseDefault:
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
ElseIf GetExceptionSummary(ex).Contains("429") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
Else
@@ -522,10 +522,10 @@ UseDefault:
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
ElseIf GetExceptionSummary(ex).Contains("429") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
@@ -570,10 +570,10 @@ Finish:
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
ElseIf GetExceptionSummary(ex).Contains("429") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
@@ -601,26 +601,23 @@ Finish:
FrmMain.PageChange(FormMain.PageType.VersionSelect)
End Sub
'启动按钮
Private Sub BtnLaunch_Click() Handles BtnLaunch.Click
LaunchButtonClick()
End Sub
Public Sub LaunchButtonClick(Optional ServerIp As String = "")
If BtnLaunch.IsEnabled AndAlso BtnLaunch.Visibility = Visibility.Visible AndAlso BtnLaunch.IsHitTestVisible Then
If BtnLaunch.Text = "启动游戏" Then
McLaunchLoader.Start(ServerIp, IsForceRestart:=True)
ElseIf BtnLaunch.Text = "下载游戏" Then
FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
End If
'愚人节处理
If IsAprilEnabled AndAlso Not IsAprilGiveup Then
ThemeUnlock(12, False, "隐藏主题 滑稽彩 已解锁!")
IsAprilGiveup = True
FrmLaunchLeft.AprilScaleTrans.ScaleX = 1
FrmLaunchLeft.AprilScaleTrans.ScaleY = 1
FrmLaunchLeft.AprilPosTrans.X = 0
FrmLaunchLeft.AprilPosTrans.Y = 0
FrmMain.BtnExtraApril.ShowRefresh()
End If
Public Sub LaunchButtonClick() Handles BtnLaunch.Click
If Not BtnLaunch.IsEnabled Then Exit Sub
'愚人节处理
If IsAprilEnabled AndAlso Not IsAprilGiveup Then
ThemeUnlock(12, False, "隐藏主题 滑稽彩 已解锁!")
IsAprilGiveup = True
FrmLaunchLeft.AprilScaleTrans.ScaleX = 1
FrmLaunchLeft.AprilScaleTrans.ScaleY = 1
FrmLaunchLeft.AprilPosTrans.X = 0
FrmLaunchLeft.AprilPosTrans.Y = 0
FrmMain.BtnExtraApril.ShowRefresh()
End If
'实际的启动
If BtnLaunch.Text = "启动游戏" Then
McLaunchStart()
ElseIf BtnLaunch.Text = "下载游戏" Then
FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
End If
End Sub
Private BtnLaunchState As Integer = 0
@@ -728,7 +725,7 @@ ExitRefresh:
'初始化页面
LabLaunchingName.Text = McVersionCurrent.Name
LabLaunchingStage.Text = "初始化"
LabLaunchingTitle.Text = "正在启动游戏"
LabLaunchingTitle.Text = If(McLaunchLoader.Input Is Nothing OrElse McLaunchLoader.Input.SaveBatch Is Nothing, "正在启动游戏", "正在导出启动脚本")
LabLaunchingProgress.Text = "0.00 %"
LabLaunchingProgress.Opacity = 1
LabLaunchingDownload.Visibility = Visibility.Visible
@@ -789,7 +786,7 @@ ExitRefresh:
If ActualProgress <= ShowProgress Then ShowProgress = ActualProgress '原来或处理后变得比实际进度高,直接回退
If IsLaunched Then ShowProgress = 1 '如果已经完成了,就不卖关子了
'文本
LabLaunchingTitle.Text = If(IsLaunched, "已启动游戏", "正在启动游戏")
LabLaunchingTitle.Text = If(IsLaunched, "已启动游戏", If(McLaunchLoader.Input.SaveBatch Is Nothing, "正在启动游戏", "正在导出启动脚本"))
LabLaunchingProgress.Text = StrFillNum(ShowProgress * 100, 2) & " %"
Dim HasLaunchDownloader As Boolean = False
Try
@@ -27,7 +27,7 @@
<StackPanel Margin="20,40,18,18">
<local:MyListItem Title="联机反馈与交流" Info="加入联机模块官方 QQ 群反馈联机异常,或询问联机功能的使用方式"
Type="Clickable" PaddingRight="20" Logo="pack://application:,,,/images/Blocks/RedstoneBlock.png"
EventType="打开网页" EventData="https://shimowendang.com/docs/KrkEVXz1K0frowAJ#anchor-7qQG" />
EventType="打开网页" EventData="https://shimo.im/docs/KrkEVXz1K0frowAJ#anchor-7qQG" />
<local:MyListItem Title="违法违规举报" Info="投诉、举报联机使用者的各类违法违规行为"
Type="Clickable" EventType="打开网页" EventData="https://shimo.im/docs/rGrd8pY8xWkt6ryW#anchor-7x6P"
PaddingRight="20" Logo="pack://application:,,,/images/Blocks/RedstoneBlock.png" />
@@ -145,9 +145,9 @@ Reopen:
Try
CertRaw = NetRequestOnce("https://cert.mcer.cn/" & Cert & ".yml", "GET", "", "")
Catch ex As Exception
If GetString(ex).Contains("(404)") Then
If GetExceptionSummary(ex).Contains("(404)") Then
Throw New CertOutdatedException '索引码无效或已过期
ElseIf GetString(ex).Contains("too many requests") Then
ElseIf GetExceptionSummary(ex).Contains("too many requests") Then
Throw New Exception("你的尝试太频繁了,请暂时啥都别点,等两分钟后再试……")
Else
Throw
@@ -709,14 +709,14 @@ FinishMcbFileCheck:
'创建房间
Private Sub BtnSelectCreate_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnSelectCreate.MouseLeftButtonUp
'获取端口号
Dim PortInput As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {
New ValidateInteger(2, 65535),
New ValidateExceptSame({"55555", "55557"}, "端口不能为 %!")
}, "在 MC 的暂停画面选择【对局域网开放】", "输入端口号", "确定", "取消")
If PortInput Is Nothing Then Exit Sub
'开始
RoomCreate(Val(PortInput))
''获取端口号
'Dim PortInput As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {
' New ValidateInteger(2, 65535),
' New ValidateExceptSame({"55555", "55557"}, "端口不能为 %!")
' }, "在 MC 的暂停画面选择【对局域网开放】", "输入端口号", "确定", "取消")
'If PortInput Is Nothing Then Exit Sub
''开始
'RoomCreate(Val(PortInput))
End Sub
Private Sub RoomCreate(Port As Integer)
'记录信息
@@ -728,34 +728,34 @@ FinishMcbFileCheck:
'加入房间
Private Sub BtnSelectJoin_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnSelectJoin.MouseLeftButtonUp
'获取信息
Dim Code As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {New ValidateLength(8, 99)}, "",
"输入联机码", "确定", "取消")
If Code Is Nothing Then Exit Sub
'记录信息
If Not Code.EndsWith(RequestVersion) OrElse Not Code.StartsWith("P") Then GoTo WrongCode
Dim Ip As String, Port As Integer
Try
Dim IpAndPort As Long = RadixConvert(Code.Substring(1, Code.Length - 2).ToUpper, 36, 10)
'IpAndPort = HostPort + IpParts(0) * 65536 + IpParts(1) * 65536 * 256 + IpParts(2) * 65536 * 256 * 256 + IpParts(3) * 65536 * 256 * 256 * 256
Ip = Math.Floor(IpAndPort / (65536L * 256 * 256 * 256))
IpAndPort = IpAndPort Mod (65536L * 256 * 256 * 256)
Ip = Math.Floor(IpAndPort / (65536L * 256 * 256)) & "." & Ip
IpAndPort = IpAndPort Mod (65536L * 256 * 256)
Ip = Math.Floor(IpAndPort / (65536L * 256)) & "." & Ip
IpAndPort = IpAndPort Mod (65536L * 256)
Ip = Math.Floor(IpAndPort / (65536L)) & "." & Ip
Port = IpAndPort Mod 65536
Catch
GoTo WrongCode
End Try
'启动
RoomJoin(Ip, Port)
Exit Sub
WrongCode:
If Not Code.StartsWith("P") AndAlso Code.Length >= 49 Then Hint("你输入的可能是 IOI 的联机码,请在左侧的联机方式中选择 IOI!", HintType.Critical) : Exit Sub
If Code.StartsWith("P") AndAlso Not Code.EndsWith(RequestVersion) Then Hint("你的 PCL2 版本与房主的 PCL2 版本不一致!", HintType.Critical) : Exit Sub
Hint("你输入的联机码无效!", HintType.Critical)
' '获取信息
' Dim Code As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {New ValidateLength(8, 99)}, "",
' "输入联机码", "确定", "取消")
' If Code Is Nothing Then Exit Sub
' '记录信息
' If Not Code.EndsWith(RequestVersion) OrElse Not Code.StartsWith("P") Then GoTo WrongCode
' Dim Ip As String, Port As Integer
' Try
' Dim IpAndPort As Long = RadixConvert(Code.Substring(1, Code.Length - 2).ToUpper, 36, 10)
' 'IpAndPort = HostPort + IpParts(0) * 65536 + IpParts(1) * 65536 * 256 + IpParts(2) * 65536 * 256 * 256 + IpParts(3) * 65536 * 256 * 256 * 256
' Ip = Math.Floor(IpAndPort / (65536L * 256 * 256 * 256))
' IpAndPort = IpAndPort Mod (65536L * 256 * 256 * 256)
' Ip = Math.Floor(IpAndPort / (65536L * 256 * 256)) & "." & Ip
' IpAndPort = IpAndPort Mod (65536L * 256 * 256)
' Ip = Math.Floor(IpAndPort / (65536L * 256)) & "." & Ip
' IpAndPort = IpAndPort Mod (65536L * 256)
' Ip = Math.Floor(IpAndPort / (65536L)) & "." & Ip
' Port = IpAndPort Mod 65536
' Catch
' GoTo WrongCode
' End Try
' '启动
' RoomJoin(Ip, Port)
' Exit Sub
'WrongCode:
' If Not Code.StartsWith("P") AndAlso Code.Length >= 49 Then Hint("你输入的可能是 IOI 的联机码,请在左侧的联机方式中选择 IOI!", HintType.Critical) : Exit Sub
' If Code.StartsWith("P") AndAlso Not Code.EndsWith(RequestVersion) Then Hint("你的 PCL2 版本与房主的 PCL2 版本不一致!", HintType.Critical) : Exit Sub
' Hint("你输入的联机码无效!", HintType.Critical)
End Sub
Private Sub RoomJoin(Ip As String, Port As Integer)
'记录信息
@@ -799,7 +799,7 @@ WrongCode:
LabLoadDesc.Text = RealException.Message.TrimStart("$") & vbCrLf &
"点击镐子重试,或者点击灰色的 × 取消。"
Else
LabLoadDesc.Text = LoadStep & "失败:" & GetString(RealException) & vbCrLf &
LabLoadDesc.Text = LoadStep & "失败:" & GetExceptionSummary(RealException) & vbCrLf &
"点击镐子重试,或者点击灰色的 × 取消。"
End If
Log(Loader.Error, "HiPer 联机尝试失败")
@@ -28,8 +28,8 @@
<!--<local:MyListItem Type="Clickable" PaddingRight="60" Height="40" Title="00ll00" Info="已连接,1100 ms" Logo="pack://application:,,,/images/Blocks/Grass.png">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton ToolTip="刷新" ToolTipService.Placement="Bottom" ToolTipService.HorizontalOffset="-10" ToolTipService.VerticalOffset="5" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" 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" />
<local:MyIconButton ToolTip="断开" ToolTipService.Placement="Bottom" ToolTipService.HorizontalOffset="-10" ToolTipService.VerticalOffset="5" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" 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 ToolTip="刷新" ToolTipService.Placement="Bottom" ToolTipService.HorizontalOffset="-10" ToolTipService.VerticalOffset="5" ToolTipService.InitialShowDelay="200" 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" />
<local:MyIconButton ToolTip="断开" ToolTipService.Placement="Bottom" ToolTipService.HorizontalOffset="-10" ToolTipService.VerticalOffset="5" ToolTipService.InitialShowDelay="200" LogoScale="0.85" 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" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>-->
@@ -979,70 +979,70 @@ Done:
'正向与反向连接
Public Shared Sub BtnLeftCreate_Click() Handles BtnLeftCreate.Click
'获取信息
Dim Code As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {New ValidateLength(9, 99999)}, "", "输入对方的联机码", "确定", "取消")
If Code Is Nothing Then Exit Sub
'检查
If Code.StartsWith("P") AndAlso Code.Length < 48 Then
Hint("你输入的可能是 HiPer 的联机码,请在左侧的联机方式中选择 HiPer!", HintType.Critical) : Exit Sub
End If
Dim Id As String, DisplayName As String
Try '解密失败检查
Id = "12D3" & Code.Substring(0, 48)
DisplayName = SecretDecrypt(Code.Substring(48))
Catch
Hint("你输入的联机码有误!", HintType.Critical)
Exit Sub
End Try
If Id = IoiId Then '自我连接检查
Hint("我连我自己?搁这卡 Bug 呢?", HintType.Critical)
Exit Sub
End If
'开始
Dim User As New LinkUserIoi(Id, DisplayName)
User.RelativeThread = RunInNewThread(Sub()
Dim WaitCount As Integer = 0
Try
'加入列表
If UserList.ContainsKey(Id) Then
Hint(UserList(Id).DisplayName & " 已在列表中,无需再次连接!")
Exit Sub
Else
UserList.Add(Id, User)
End If
'发送 portsub 请求(0% -> 80%)
SendPortsubRequest(User)
'构建 Socket(81% -> 82%)
Dim ClientSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) With {.ReceiveTimeout = 1000000000, .SendTimeout = 1000000000}
ClientSocket.Connect(New IPEndPoint(IPAddress.Parse(User.Ports(55557)), 55557))
User.BindSocket(ClientSocket)
User.Progress = 0.82
'发送 connect 请求(83% -> 85%)
SendConnectRequest(User)
User.Progress = 0.85
'等待对方向自己请求
Log("[IOI] 加入成功,等待反向请求")
Do While User.Progress < 0.9999
User.Progress += 0.0002
If User.Progress > 0.98 AndAlso User.Progress < 0.9999 Then Throw New Exception("对方未回应连接请求!")
Thread.Sleep(100)
Loop
Hint("已连接到 " & User.DisplayName & "!", HintType.Finish)
Catch ex As ThreadInterruptedException
Log("[IOI] 已中断主动发起的连接(" & User.DisplayName & ")")
Catch ex As InvalidOperationException
'API 返回的错误
NetRequestOnce("http://127.0.0.1:55555/api/link?id=" & Id & "&password=" & IoiPassword, "DELETE", "", "", 500)
User.Dispose()
If InitLoader.State = LoadState.Finished Then Log("与 " & DisplayName & " 建立连接失败:" & ex.Message, LogLevel.Msgbox)
Catch ex As Exception
'常规错误
NetRequestOnce("http://127.0.0.1:55555/api/link?id=" & Id & "&password=" & IoiPassword, "DELETE", "", "", 500)
User.Dispose()
If ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is ThreadInterruptedException Then Exit Sub
If InitLoader.State = LoadState.Finished Then Log(ex, "与 " & DisplayName & " 建立连接失败", LogLevel.Msgbox)
End Try
End Sub, "Link Create " & DisplayName)
''获取信息
'Dim Code As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {New ValidateLength(9, 99999)}, "", "输入对方的联机码", "确定", "取消")
'If Code Is Nothing Then Exit Sub
''检查
'If Code.StartsWith("P") AndAlso Code.Length < 48 Then
' Hint("你输入的可能是 HiPer 的联机码,请在左侧的联机方式中选择 HiPer!", HintType.Critical) : Exit Sub
'End If
'Dim Id As String, DisplayName As String
'Try '解密失败检查
' Id = "12D3" & Code.Substring(0, 48)
' DisplayName = SecretDecrypt(Code.Substring(48))
'Catch
' Hint("你输入的联机码有误!", HintType.Critical)
' Exit Sub
'End Try
'If Id = IoiId Then '自我连接检查
' Hint("我连我自己?搁这卡 Bug 呢?", HintType.Critical)
' Exit Sub
'End If
''开始
'Dim User As New LinkUserIoi(Id, DisplayName)
'User.RelativeThread = RunInNewThread(Sub()
' Dim WaitCount As Integer = 0
' Try
' '加入列表
' If UserList.ContainsKey(Id) Then
' Hint(UserList(Id).DisplayName & " 已在列表中,无需再次连接!")
' Exit Sub
' Else
' UserList.Add(Id, User)
' End If
' '发送 portsub 请求(0% -> 80%)
' SendPortsubRequest(User)
' '构建 Socket(81% -> 82%)
' Dim ClientSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) With {.ReceiveTimeout = 1000000000, .SendTimeout = 1000000000}
' ClientSocket.Connect(New IPEndPoint(IPAddress.Parse(User.Ports(55557)), 55557))
' User.BindSocket(ClientSocket)
' User.Progress = 0.82
' '发送 connect 请求(83% -> 85%)
' SendConnectRequest(User)
' User.Progress = 0.85
' '等待对方向自己请求
' Log("[IOI] 加入成功,等待反向请求")
' Do While User.Progress < 0.9999
' User.Progress += 0.0002
' If User.Progress > 0.98 AndAlso User.Progress < 0.9999 Then Throw New Exception("对方未回应连接请求!")
' Thread.Sleep(100)
' Loop
' Hint("已连接到 " & User.DisplayName & "!", HintType.Finish)
' Catch ex As ThreadInterruptedException
' Log("[IOI] 已中断主动发起的连接(" & User.DisplayName & ")")
' Catch ex As InvalidOperationException
' 'API 返回的错误
' NetRequestOnce("http://127.0.0.1:55555/api/link?id=" & Id & "&password=" & IoiPassword, "DELETE", "", "", 500)
' User.Dispose()
' If InitLoader.State = LoadState.Finished Then Log("与 " & DisplayName & " 建立连接失败:" & ex.Message, LogLevel.Msgbox)
' Catch ex As Exception
' '常规错误
' NetRequestOnce("http://127.0.0.1:55555/api/link?id=" & Id & "&password=" & IoiPassword, "DELETE", "", "", 500)
' User.Dispose()
' If ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is ThreadInterruptedException Then Exit Sub
' If InitLoader.State = LoadState.Finished Then Log(ex, "与 " & DisplayName & " 建立连接失败", LogLevel.Msgbox)
' End Try
' End Sub, "Link Create " & DisplayName)
End Sub
Private Shared Sub SendPortsubBack(User As LinkUserIoi, TargetVersion As Integer)
Try
@@ -1076,38 +1076,38 @@ Done:
'创建房间
Private Sub LinkCreate() Handles BtnCreate.Click
If MyMsgBox("请先进入 MC 并暂停游戏,在暂停页面选择对局域网开放,然后在下一个窗口输入 MC 显示的端口号。" & vbCrLf & "若使用服务端开服,则直接在下一个窗口输入服务器配置中的端口号即可。", "提示", "继续", "取消") = 2 Then Exit Sub
'获取端口号
Dim Port As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {
New ValidateInteger(0, 65535),
New ValidateExceptSame({"55555", "55557"}, "端口不能为 %!"),
New ValidateExceptSame(RoomListForMe.Select(AddressOf RoomEntry.SelectPort), "端口 % 已创建过房间,请在删除该房间后继续!")
}, "", "输入端口号", "确定", "取消")
If Port Is Nothing Then Exit Sub
'获取显示名称
Dim DisplayName As String = MyMsgBoxInput(GetPlayerName() & " 的房间 - " & Port, New ObjectModel.Collection(Of Validate) From {
New ValidateNullOrWhiteSpace(), New ValidateLength(1, 40), New ValidateFilter()
}, "", "输入房间名(建议包含游戏版本等信息)", "确定", "取消")
If DisplayName Is Nothing Then Exit Sub
DisplayName = DisplayName.Trim
'开始
RunInThread(Sub()
Try
'请求
Dim Result As JObject = GetJson(NetRequestOnce("http://127.0.0.1:55555/api/port?proto=tcp&port=" & Port & "&password=" & IoiPassword, "PUT", "", "", 100000))
If Result("msg") IsNot Nothing Then Throw New InvalidOperationException(Result("msg").ToString)
'成功
RoomListForMe.Add(New RoomEntry(Port, DisplayName))
Hint("房间 " & DisplayName & " 已创建!", HintType.Finish)
SendUpdateRequestToAllUsers()
Catch ex As InvalidOperationException
'API 返回的错误
Log("创建房间失败:" & ex.Message, LogLevel.Msgbox)
Catch ex As Exception
'常规错误
Log(ex, "创建房间失败", LogLevel.Msgbox)
End Try
End Sub)
'If MyMsgBox("请先进入 MC 并暂停游戏,在暂停页面选择对局域网开放,然后在下一个窗口输入 MC 显示的端口号。" & vbCrLf & "若使用服务端开服,则直接在下一个窗口输入服务器配置中的端口号即可。", "提示", "继续", "取消") = 2 Then Exit Sub
''获取端口号
'Dim Port As String = MyMsgBoxInput("", New ObjectModel.Collection(Of Validate) From {
' New ValidateInteger(0, 65535),
' New ValidateExceptSame({"55555", "55557"}, "端口不能为 %!"),
' New ValidateExceptSame(RoomListForMe.Select(AddressOf RoomEntry.SelectPort), "端口 % 已创建过房间,请在删除该房间后继续!")
' }, "", "输入端口号", "确定", "取消")
'If Port Is Nothing Then Exit Sub
''获取显示名称
'Dim DisplayName As String = MyMsgBoxInput(GetPlayerName() & " 的房间 - " & Port, New ObjectModel.Collection(Of Validate) From {
' New ValidateNullOrWhiteSpace(), New ValidateLength(1, 40), New ValidateFilter()
' }, "", "输入房间名(建议包含游戏版本等信息)", "确定", "取消")
'If DisplayName Is Nothing Then Exit Sub
'DisplayName = DisplayName.Trim
''开始
'RunInThread(Sub()
' Try
' '请求
' Dim Result As JObject = GetJson(NetRequestOnce("http://127.0.0.1:55555/api/port?proto=tcp&port=" & Port & "&password=" & IoiPassword, "PUT", "", "", 100000))
' If Result("msg") IsNot Nothing Then Throw New InvalidOperationException(Result("msg").ToString)
' '成功
' RoomListForMe.Add(New RoomEntry(Port, DisplayName))
' Hint("房间 " & DisplayName & " 已创建!", HintType.Finish)
' SendUpdateRequestToAllUsers()
' Catch ex As InvalidOperationException
' 'API 返回的错误
' Log("创建房间失败:" & ex.Message, LogLevel.Msgbox)
' Catch ex As Exception
' '常规错误
' Log(ex, "创建房间失败", LogLevel.Msgbox)
' End Try
' End Sub)
End Sub
Private Shared Sub SendUpdateRequestToAllUsers()
For i = 0 To UserList.Count - 1
@@ -1123,18 +1123,18 @@ Done:
End Sub
'修改房间名称
Private Shared Sub BtnRoomEdit_Click(sender As MyIconButton, e As EventArgs)
Dim Room As RoomEntry = sender.Tag
'获取房间名
Dim DisplayName As String = MyMsgBoxInput(Room.DisplayName, New ObjectModel.Collection(Of Validate) From {
New ValidateNullOrWhiteSpace(),
New ValidateLength(1, 40)
}, "", "输入房间名(建议包含游戏版本等信息)", "确定", "取消")
If DisplayName Is Nothing Then Exit Sub
DisplayName = DisplayName.Trim
'修改
Room.DisplayName = DisplayName
FrmLinkIoi.RefreshUi()
SendUpdateRequestToAllUsers()
'Dim Room As RoomEntry = sender.Tag
''获取房间名
'Dim DisplayName As String = MyMsgBoxInput(Room.DisplayName, New ObjectModel.Collection(Of Validate) From {
' New ValidateNullOrWhiteSpace(),
' New ValidateLength(1, 40)
' }, "", "输入房间名(建议包含游戏版本等信息)", "确定", "取消")
'If DisplayName Is Nothing Then Exit Sub
'DisplayName = DisplayName.Trim
''修改
'Room.DisplayName = DisplayName
'FrmLinkIoi.RefreshUi()
'SendUpdateRequestToAllUsers()
End Sub
'加入房间
Private Shared Sub BtnRoom_Click(sender As MyListItem, e As EventArgs)
@@ -12,7 +12,7 @@
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton ToolTip="关闭联机模块" Loaded="BtnHiperStop_Loaded" Click="BtnHiperStop_Click"
ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.VerticalOffset="-2" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.7"
ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.VerticalOffset="-2" ToolTipService.InitialShowDelay="200" LogoScale="0.7"
Logo="M576 512l277.333333 277.333333-64 64-277.333333-277.333333L234.666667 853.333333 170.666667 789.333333l277.333333-277.333333L170.666667 234.666667 234.666667 170.666667l277.333333 277.333333L789.333333 170.666667 853.333333 234.666667 576 512z" />
</x:Array>
</local:MyListItem.Buttons>
@@ -22,7 +22,7 @@
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton ToolTip="关闭联机模块" Loaded="BtnIoiStop_Loaded" Click="BtnIoiStop_Click"
ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.VerticalOffset="-2" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.7"
ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.VerticalOffset="-2" ToolTipService.InitialShowDelay="200" LogoScale="0.7"
Logo="M576 512l277.333333 277.333333-64 64-277.333333-277.333333L234.666667 853.333333 170.666667 789.333333l277.333333-277.333333L170.666667 234.666667 234.666667 170.666667l277.333333 277.333333L789.333333 170.666667 853.333333 234.666667 576 512z" />
</x:Array>
</local:MyListItem.Buttons>
@@ -32,7 +32,7 @@
LogoScale="0.85" Logo="M940.4 463.7L773.3 174.2c-17.3-30-49.2-48.4-83.8-48.4H340.2c-34.6 0-66.5 18.5-83.8 48.4L89.2 463.7c-17.3 30-17.3 66.9 0 96.8L256.4 850c17.3 30 49.2 48.4 83.8 48.4h349.2c34.6 0 66.5-18.5 83.8-48.4l167.2-289.5c17.3-29.9 17.3-66.8 0-96.8z m-94.6 96.8L725.9 768.1c-17.3 30-49.2 48.4-83.8 48.4H387.5c-34.6 0-66.5-18.5-83.8-48.4L183.9 560.5c-17.3-30-17.3-66.9 0-96.8l119.8-207.5c17.3-30 49.2-48.4 83.8-48.4h254.6c34.6 0 66.5 18.5 83.8 48.4l119.8 207.5c17.3 30 17.3 66.9 0.1 96.8z M522.3 321.2c-2.5-0.1-5-0.2-7.5-0.2-119.9 0-214 110.3-186.3 235 15.8 70.9 71.5 126.6 142.4 142.4 17.5 3.9 34.7 5.4 51.4 4.7 102.1-3.9 183.6-87.9 183.6-191 0.1-103-81.5-187-183.6-190.9z m68.6 269.1c-18.5 18-43 28.9-68.6 30.7l-6 0.3c-30.2 0.4-58.6-11.4-79.7-33-19.5-20.1-30.7-47-30.9-75-0.3-29.6 11.1-57.4 32-78.3 20.6-20.6 48-32 77.2-32 2.5 0 5 0.1 7.5 0.3 26.7 1.8 51.5 13.2 70.5 32.5 19.6 20 30.8 46.9 31.2 74.9 0.2 30.2-11.5 58.6-33.2 79.6z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="5" ToolTip="初始化设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
<local:MyIconButton Tag="5" ToolTip="初始化设置" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
@@ -173,6 +173,7 @@ Public Class PageLinkLeft
If MyMsgBox("是否要初始化联机页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupLink) Then FrmSetupLink = New PageSetupLink
FrmSetupLink.Reset()
ItemSetup.Checked = True
End If
End Sub
@@ -7,7 +7,7 @@
LogoScale="0.97" Logo="M520.6 620.3c-11.3-0.6-20.1-4-26.9-10.5-6.6-6.3-8.1-11-10.1-20.8-1.9-9.5-1.5-16.7-1-24.9l0.3-5.3c0.5-9.9 3.5-19.6 8.8-28.1 5.7-9 12.5-17.2 20.8-25.1 8.6-8 17.7-15.7 27-22.9 9.4-7.2 18.7-14.8 27.7-22.7 9-7.9 16.2-15.8 22.1-24.3 6.2-9 9.3-18.8 9.3-29.4 1.2-20.3-6.5-37.7-22.8-51.3-16-13.3-37.4-20-63.5-20-13.7 0-26.3 3.3-37.4 10-10.9 6.5-20.2 14.5-27.7 23.8-7.5 9.2-13.5 19-17.9 29.2-4.5 10.6-6.7 19.4-6.7 26.8 0 9.2-3.3 16-10.1 20.8-6.9 4.8-14.6 7.3-22.8 7.3h-1.3c-9-0.3-17-3.3-24.6-9.2-7.3-5.6-11.1-14.6-11.6-27.5-0.6-11.5 1.9-26.1 7.2-43.5 5.4-17.4 14.8-34.4 28.1-50.5 13.4-16.3 31.2-30.4 52.8-41.8 21.6-11.4 49.2-17.2 81.9-17.2 26.4 0 49.6 3.9 69.1 11.7 19.4 7.7 35.4 18.2 47.5 31.1l1.6 1.7c11.8 12.6 20.3 21.7 29.4 44.4 11.6 28.9 7.1 52.1 5.5 58.5-5.8 22.6-12.6 37.7-22.7 50.4-11.7 14.6-24.9 28.2-39.2 40.4-14 11.7-39.2 33.3-39.2 33.3-13.3 11.4-19.4 22.1-18.6 32.9V587c0.5 8.7-2.4 16.1-8.8 22.8-6.2 6.4-14.8 10-26.2 10.5zM519 766.1c-13 0-23.6-4.2-32.2-12.9-8.7-8.7-13-19-13-31.4 0-12.9 4.2-23.5 12.9-32.2 8.7-8.7 19.2-12.9 32.2-12.9 13 0 23.5 4.2 32.2 12.9s12.9 19.2 12.9 32.2c0 12.4-4.2 22.7-12.9 31.4-8.6 8.6-19.2 12.9-32.1 12.9z M515 928.3c-228.1 0-413.7-185.6-413.7-413.7S286.9 100.9 515 100.9s413.7 185.6 413.7 413.7c0.1 228.1-185.5 413.7-413.7 413.7z m0-747.4c-184 0-333.7 149.7-333.7 333.7S331 848.3 515 848.3s333.7-149.7 333.7-333.7S699 180.9 515 180.9z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="0" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" 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" />
<local:MyIconButton Tag="0" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" 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>
@@ -114,7 +114,9 @@
Select Case Val(sender.Tag)
Case FormMain.PageSubType.OtherHelp
RefreshHelp()
ItemHelp.Checked = True
End Select
Hint("正在刷新……", Log:=False)
End Sub
Public Shared Sub RefreshHelp()
Setup.Set("SystemHelpVersion", 0) '强制重新解压文件
@@ -125,9 +127,13 @@
'打开网页
Public Shared Sub TryFeedback() Handles ItemFeedback.Click
If Not CanFeedback(True) Then Exit Sub
If MyMsgBox("是否要打开反馈列表网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
"提醒", "打开", "取消") = 2 Then Exit Sub
Feedback(True, False)
Select Case MyMsgBox("是否要打开反馈列表网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
"反馈提示", "提交新反馈", "查看反馈列表", "取消")
Case 1
Feedback(True, False)
Case 2
OpenWebsite("https://github.com/Hex-Dragon/PCL2/issues/")
End Select
End Sub
Public Shared Sub TryVote() Handles ItemVote.Click
If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
@@ -164,9 +164,8 @@
Dim SplitedNames As String() = NewFolder.TrimEnd("\").Split("\")
Dim DefaultName As String = If(SplitedNames.Last = ".minecraft", If(SplitedNames.Count >= 3, SplitedNames(SplitedNames.Count - 2), ""), SplitedNames.Last)
If DefaultName.Length > 40 Then DefaultName = DefaultName.Substring(0, 39)
Dim NewName As String = MyMsgBoxInput(DefaultName, New ObjectModel.Collection(Of Validate) From {
New ValidateNullOrWhiteSpace, New ValidateLength(1, 40), New ValidateExcept({">", "|"})
},, "输入显示名称",, "取消")
Dim NewName As String = MyMsgBoxInput("输入显示名称", "输入该文件夹在左边栏列表中显示的名称。", DefaultName,
New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
'添加文件夹
AddFolder(NewFolder, NewName, True)
@@ -315,8 +314,8 @@
Public Sub Delete_Click(sender As Object, e As RoutedEventArgs)
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
Dim DeleteText As String = If((Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1, "清空", "删除")
If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久消失,且不可恢复!", "删除警告", "取消", "继续") = 1 Then Exit Sub
If MyMsgBox(DeleteText & "这个文件夹会导致该文件夹中的所有文件永久消失,且不可恢复!" & vbCrLf & "这是最后一次警告!", "删除警告", DeleteText, "取消",, True) = 2 Then Exit Sub
If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久丢失,且不可恢复!", "删除警告", "取消", "确认", "取消") <> 2 Then Exit Sub
If MyMsgBox("如果你在该文件夹中存放了除 MC 以外的其他文件,这些文件也会被一同删除!" & vbCrLf & "继续删除会导致该文件夹中的所有文件永久丢失,请在仔细确认后再继续!" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这是最后一次警告!", "删除警告", "确认" & DeleteText, "取消", IsWarn:=True) <> 1 Then Exit Sub
'移出列表
If Folder.Type = McFolderType.Custom Then
Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
@@ -357,8 +356,9 @@
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
Try
'获取输入
Dim NewName As String = MyMsgBoxInput(Folder.Name, New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})},
, "输入新名称",, "取消")
Dim NewName As String =
MyMsgBoxInput("输入新名称", "", Folder.Name,
New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})})
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
'修改自定义名
Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
@@ -13,7 +13,7 @@
<StackPanel Margin="20,17">
<TextBlock Name="LabEmptyTitle" Margin="0,0,0,9" HorizontalAlignment="Center" Text="无可用版本" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Name="LabEmptyContent" Margin="10,15,10,5" Text="未找到任何版本的游戏,请先下载任意版本的游戏。&#xA;若有已存在的游戏,请在左边的列表中选择“添加文件夹”,选择 .minecraft 文件夹将其导入。" TextWrapping="Wrap" />
<TextBlock Name="LabEmptyContent" Margin="10,15,10,5" Text="未找到任何版本的游戏,请先下载任意版本的游戏。&#xa;若有已存在的游戏,请在左边的列表中选择“添加文件夹”,选择 .minecraft 文件夹将其导入。" TextWrapping="Wrap" />
<local:MyButton Height="35" HorizontalAlignment="Center" x:Name="BtnEmptyDownload" MinWidth="140" Text="下载游戏" Margin="0,10,0,0" Padding="13,0" ColorType="Highlight" />
</StackPanel>
</local:MyCard>
@@ -9,7 +9,7 @@
PageLoaderInit(Load, PanLoad, PanAllBack, Nothing, McVersionListLoader, AddressOf McVersionListUI, AutoRun:=False)
End Sub
Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click
If McModLoader.State = LoadState.Failed Then
If McVersionListLoader.State = LoadState.Failed Then
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
End If
End Sub
@@ -17,11 +17,11 @@
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:MyRadioBox Text="随机" x:Name="RadioSkinType0" Height="22" Tag="LaunchSkinType/0" Grid.Column="0" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Bottom" ToolTip="在 Steve 和 Alex 中随机选择一个皮肤" />
<local:MyRadioBox Text="随机" x:Name="RadioSkinType0" Height="22" Tag="LaunchSkinType/0" Grid.Column="0" ToolTipService.Placement="Bottom" ToolTip="在 Steve 和 Alex 中随机选择一个皮肤" />
<local:MyRadioBox Text="Steve" x:Name="RadioSkinType1" Height="22" Tag="LaunchSkinType/1" Grid.Column="1" />
<local:MyRadioBox Text="Alex" x:Name="RadioSkinType2" Height="22" Tag="LaunchSkinType/2" Grid.Column="2" />
<local:MyRadioBox Text="正版皮肤" x:Name="RadioSkinType3" Height="22" Tag="LaunchSkinType/3" Grid.Column="3" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Bottom" ToolTip="使用某个正版玩家的皮肤" />
<local:MyRadioBox Text="自定义" x:Name="RadioSkinType4" Height="22" Tag="LaunchSkinType/4" Grid.Column="4" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Bottom" ToolTip="以资源包的形式加载自定义皮肤。&#xA;使用此方式更换的皮肤在多人游戏中仅自己可见,且会替换游戏中所有的角色。" />
<local:MyRadioBox Text="正版皮肤" x:Name="RadioSkinType3" Height="22" Tag="LaunchSkinType/3" Grid.Column="3" ToolTipService.Placement="Bottom" ToolTip="使用某个正版玩家的皮肤" />
<local:MyRadioBox Text="自定义" x:Name="RadioSkinType4" Height="22" Tag="LaunchSkinType/4" Grid.Column="4" ToolTipService.Placement="Bottom" ToolTip="以资源包的形式加载自定义皮肤。&#xa;使用此方式更换的皮肤在多人游戏中仅自己可见,且会替换游戏中所有的角色。" />
</Grid>
<Grid x:Name="PanSkinID" Margin="0,14,0,2" Visibility="Collapsed">
<Grid.ColumnDefinitions>
@@ -40,7 +40,7 @@
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnSkinSave" Text="保存皮肤" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Row="1" />
<local:MyButton x:Name="BtnSkinCache" Text="刷新缓存" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ToolTip="刷新并重新下载 PCL 当前显示的皮肤" ToolTipService.ShowDuration="2333333" Grid.Row="1" Grid.Column="1" />
<local:MyButton x:Name="BtnSkinCache" Text="刷新缓存" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ToolTip="刷新并重新下载 PCL 当前显示的皮肤" Grid.Row="1" Grid.Column="1" />
</Grid>
</Grid>
<Grid x:Name="PanSkinChange" Margin="0,14,0,2" Height="35" Visibility="Collapsed">
@@ -78,9 +78,9 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="游戏窗口标题" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentTitle" Grid.Row="0" Grid.ColumnSpan="2" Tag="LaunchArgumentTitle" Grid.Column="1" ToolTip="自定义游戏窗口的标题,若留空则不进行更改。&#x0a;支持以下替换标记:&#x0a; - {user}:玩家名字&#x0a; - {login}:玩家的登录方式&#x0a; - {name}:游戏版本名&#x0a; - {time}:当前的系统时间&#x0a; - {version}:游戏对应的原版版本号&#x0a; - {path}:PCL 可执行文件所在路径,以 \ 结尾" ToolTipService.ShowDuration="2333333" HintText="默认" MaxLength="100" />
<local:MyTextBox x:Name="TextArgumentTitle" Grid.Row="0" Grid.ColumnSpan="2" Tag="LaunchArgumentTitle" Grid.Column="1" ToolTip="自定义游戏窗口的标题,若留空则不进行更改。&#xa;支持以下替换标记:&#xa; · {user}:玩家名字&#xa; · {login}:玩家的登录方式&#xa; · {name}:游戏版本名&#xa; · {time}:当前的系统时间&#xa; · {version}:游戏对应的原版版本号" HintText="默认" MaxLength="100" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="自定义信息" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchArgumentInfo" Text="Plain Craft Launcher 2" Grid.Column="1" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角" ToolTipService.ShowDuration="2333333">
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchArgumentInfo" Text="Plain Craft Launcher 2" Grid.Column="1" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角">
<local:MyTextBox.ValidateRules>
<local:ValidateExcept>
<local:ValidateExcept.Excepts>
@@ -93,7 +93,7 @@
</local:MyTextBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本隔离" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentIndie" Grid.Row="4" Grid.ColumnSpan="2" Tag="LaunchArgumentIndie" Grid.Column="1">
<local:MyComboBoxItem Content="关闭" ToolTip="所有版本均使用同一档案,存档、Mod、资源包等均为公用。&#xA;若存在不同版本的 Forge,可能会由于 Mod 与版本冲突导致未知问题。" />
<local:MyComboBoxItem Content="关闭" ToolTip="所有版本均使用同一档案,存档、Mod、资源包等均为公用。&#xa;若存在不同版本的 Forge,可能会由于 Mod 与版本冲突导致未知问题。" />
<local:MyComboBoxItem Content="仅隔离可安装 Mod 的版本" IsSelected="True" ToolTip="每个 LiteLoader、Forge、Fabric 版本均互相独立以避免 Mod 冲突,未安装 Mod API 的其他版本则不会被隔离。" />
<local:MyComboBoxItem Content="仅隔离非正式版" ToolTip="将 Minecraft 快照、预发布版、远古版本、愚人节版本与其他版本进行隔离。" />
<local:MyComboBoxItem Content="隔离非正式版与可安装 Mod 的版本" />
@@ -124,9 +124,9 @@
</Grid.ColumnDefinitions>
<local:MyComboBox x:Name="ComboArgumentWindowType" Tag="LaunchArgumentWindowType">
<local:MyComboBoxItem Content="全屏" />
<local:MyComboBoxItem Content="默认大小" IsSelected="True" ToolTip="以 854×480 的默认窗口大小启动 Minecraft" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.ShowDuration="2333333" />
<local:MyComboBoxItem Content="默认大小" IsSelected="True" ToolTip="以 854×480 的默认窗口大小启动 Minecraft" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" />
<local:MyComboBoxItem Content="与启动器窗口大小一致" />
<local:MyComboBoxItem Content="自定义大小" ToolTip="请注意 1.12.2 及更老的部分 Forge 存在 Bug,会导致高度设定无效" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.ShowDuration="2333333" />
<local:MyComboBoxItem Content="自定义大小" ToolTip="请注意 1.12.2 及更老的部分 Forge 存在 Bug,会导致高度设定无效" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" />
<local:MyComboBoxItem Content="最大化" />
<local:MyComboBoxItem Content="保持游戏默认" />
</local:MyComboBox>
@@ -137,14 +137,14 @@
</local:MyTextBox>
<TextBlock x:Name="LabArgumentWindowMiddle" Visibility="Collapsed" Grid.Column="2" Text=" × " VerticalAlignment="Center" FontSize="18" />
<local:MyTextBox Padding="0,0,5,0" Visibility="Collapsed" Grid.Column="3" Width="60" HorizontalContentAlignment="Center" x:Name="TextArgumentWindowHeight" Tag="LaunchArgumentWindowHeight" Text="480"
ToolTip="请注意 Forge 1.12.2 存在 Bug,会导致高度设定无效,其他版本无此问题" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.ShowDuration="2333333">
ToolTip="请注意 Forge 1.12.2 存在 Bug,会导致高度设定无效,其他版本无此问题" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5">
<local:MyTextBox.ValidateRules>
<local:ValidateInteger Min="1" Max="9999" />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
</Grid>
<TextBlock VerticalAlignment="Center" Grid.Row="12" HorizontalAlignment="Left" Text="游戏 Java" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentJava" Grid.ColumnSpan="2" Grid.Row="12" Grid.Column="1" ToolTip="若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL2 会尽量优先选择它" ToolTipService.ShowDuration="2333333">
<local:MyComboBox x:Name="ComboArgumentJava" Grid.ColumnSpan="2" Grid.Row="12" Grid.Column="1" ToolTip="若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL2 会尽量优先选择它">
<ComboBoxItem Content="加载中……" IsSelected="True" />
<!--<local:MyComboBoxItem Content="Java 8 (1.8.0_171),64 位:C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" IsSelected="True" ToolTip="C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" />-->
</local:MyComboBox>
@@ -223,14 +223,14 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="JVM 参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="0" Grid.ColumnSpan="2" Tag="LaunchAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,在没有确定把握的情况下请不要尝试修改。&#xA;你可以通过点击左侧选项卡的初始化按钮来恢复到默认设置。" ToolTipService.ShowDuration="2333333" Text="-XX:+UseG1GC -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -Dfml.ignoreInvalidMinecraftCertificates=True -Dfml.ignorePatchDiscrepancies=True -Dlog4j2.formatMsgNoLookups=true" />
<local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="0" Grid.ColumnSpan="2" Tag="LaunchAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,在没有确定把握的情况下请不要尝试修改。&#xa;你可以通过点击左侧选项卡的初始化按钮来恢复到默认设置。" Text="-XX:+UseG1GC -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -Dfml.ignoreInvalidMinecraftCertificates=True -Dfml.ignorePatchDiscrepancies=True -Dlog4j2.formatMsgNoLookups=true" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="额外参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xA;例如输入 --demo 则会以试玩模式启动游戏。" ToolTipService.ShowDuration="2333333" />
<StackPanel Margin="0,10,0,4" Orientation="Horizontal" Grid.Row="3" Grid.ColumnSpan="2">
<local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xa;例如输入 --demo 则会以试玩模式启动游戏。" />
<StackPanel Margin="0,12,0,4" Orientation="Horizontal" Grid.Row="3" Grid.ColumnSpan="2">
<local:MyCheckBox Text="忽略 Java 兼容性警告" x:Name="CheckAdvanceJava" Tag="LaunchAdvanceJava" Margin="0,0,60,0"
ToolTip="如果在设置中手动选择了与当前版本不兼容的 Java,则自动跳过兼容性警告弹窗,强制使用手动选择的 Java。" ToolTipService.ShowDuration="2333333" />
ToolTip="如果在设置中手动选择了与当前版本不兼容的 Java,则自动跳过兼容性警告弹窗,强制使用手动选择的 Java。" />
<local:MyCheckBox Text="关闭文件校验" x:Name="CheckAdvanceAssets" Tag="LaunchAdvanceAssets"
ToolTip="在启动时不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。&#xA;如果你没有修改相关文件,请勿勾选此项。&#xA;更推荐在版本设置中关闭特定版本的校验,而不是在这里关闭所有版本的校验。" ToolTipService.ShowDuration="2333333" />
ToolTip="在启动时不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。&#xa;如果你没有修改相关文件,请勿勾选此项。&#xa;更推荐在版本设置中关闭特定版本的校验,而不是在这里关闭所有版本的校验。" />
</StackPanel>
</Grid>
</local:MyCard>
@@ -304,6 +304,7 @@
}, "SetupLaunch Ram TextRight")
Else
'不需要动画
AniStop("SetupLaunch Ram TextRight")
LabRamGame.Margin = New Thickness(TotalWidth - LabGameWidth, 3, 0, 0)
LabRamGameTitle.Margin = New Thickness(TotalWidth - LabGameTitleWidth, 0, 0, 5)
End If
@@ -316,6 +317,7 @@
}, "SetupLaunch Ram TextRight")
Else
'不需要动画
AniStop("SetupLaunch Ram TextRight")
LabRamGame.Margin = New Thickness(2 + RectUsedWidth, 3, 0, 0)
LabRamGameTitle.Margin = New Thickness(2 + RectUsedWidth, 0, 0, 5)
End If
@@ -8,14 +8,14 @@
LogoScale="1" Logo="M924.009688 527.92367C875.975633 601.905321 808.729835 663.317138 733.564477 712.920073 726.302532 832.878385 665.670459 944.569541 567.084624 1015.075229 558.826862 1020.965578 549.065982 1024 539.239339 1024 533.048367 1024 526.829211 1022.806899 520.929468 1020.373725 505.663413 1014.023046 494.709431 1000.278899 491.966239 983.941872 484.67611 940.755376 465.361028 892.899817 436.876917 844.546349 404.954422 853.283229 373.980771 860.385468 344.970569 865.420917 342.227376 865.92822 339.484183 866.144294 336.75978 866.144294 324.142972 866.144294 311.920734 861.174606 302.855046 852.061945L172.807046 721.685138C161.768514 710.637211 156.789431 694.863853 159.466862 679.466275 164.502312 650.390312 171.576367 619.341505 180.27567 587.362642 132.100697 558.822165 84.376661 539.450716 41.302899 532.151193 25.00345 529.370422 11.287486 518.41644 4.98378 503.103413-1.319927 487.809174 0.662312 470.316624 10.254092 456.826128 80.581284 357.958459 191.971817 297.185468 311.591927 289.857761 361.053945 214.495119 422.31545 147.061431 496.081028 98.895853 636.030826 7.54378 802.350972 0 974.730569 0 1001.223046 0 1022.680073 21.494606 1022.680073 48.034055 1022.680073 213.997211 1015.061138 387.72022 924.009688 527.92367ZM558.122275 918.528C601.506055 876.187009 631.784514 822.328367 645.81989 763.744294 602.680367 785.86833 558.563817 804.553982 515.067303 819.989138 533.358385 853.161101 548.023193 886.267303 558.122275 918.528ZM106.566459 465.807266C138.705028 475.915743 171.717284 490.627523 204.804697 508.937394 220.192881 465.337541 238.803376 421.117651 260.871046 377.865394 202.493651 391.947743 148.822899 422.282569 106.566459 465.807266ZM548.398972 179.444257C395.794789 279.09167 294.681835 493.94378 258.522422 671.678239L352.749211 766.121101C530.00455 729.877138 744.283596 628.510532 843.667963 475.474202 912.557798 369.39156 924.742459 236.562789 926.527413 96.387523 786.699743 98.172477 654.227963 110.385321 548.398972 179.444257ZM687.071119 416.617688C642.93578 416.617688 607.161541 380.74011 607.161541 336.492037 607.161541 292.234569 642.93578 256.37578 687.071119 256.37578 731.206459 256.37578 766.971303 292.234569 766.971303 336.492037 766.971303 380.74011 731.206459 416.617688 687.071119 416.617688ZM67.222312 858.008661C77.171083 825.118532 107.646826 801.171963 143.702899 801.171963 187.838239 801.171963 223.603083 837.040147 223.603083 881.297615 223.603083 917.438239 199.722275 948.017321 166.926092 957.975486L52.46356 992.763303C50.998018 993.204844 49.438532 993.458495 47.813284 993.458495 38.973064 993.458495 31.823853 986.290495 31.823853 977.431486 31.823853 975.806239 32.058716 974.237358 32.519046 972.771817L67.222312 858.008661Z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="0" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
<local:MyIconButton Tag="0" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemUI" IsScaleAnimationEnabled="False" Tag="1" PaddingRight="38" Height="36" VerticalAlignment="Top" Title="个性化" Logo="M10.5 24h-7c-1.4 0-2.5-1.14-2.5-2.5v-11.64c-.662-.473-1-1.201-1-1.941 0-.376.089-.75.289-1.129 1.065-1.898 2.153-3.783 3.265-5.654.462-.737 1.211-1.136 2.045-1.136.635 0 .972.204 1.445.479.662.386 9 5.352 12.512 7.441.087.052 3.366 1.988 3.449 2.045.663.49.995 1.197.995 1.934 0 .375-.092.745-.295 1.13-1.064 1.899-2.153 3.784-3.265 5.655-.577.92-1.615 1.29-2.496 1.088-.392.234-5.826 3.75-6.252 3.968-.413.212-.762.26-1.192.26m-7.5-10.763v8.263c0 .274.221.5.5.5h4.588c-1.72-2.906-3.417-5.827-5.088-8.763m1.606-1.238c.053.092 5.681 9.797 5.726 9.859.108.139.299.181.455.098.164-.092 5.081-3.251 5.081-3.251-.639-.377-8.144-4.851-11.262-6.706m.659-9.829c-.913 1.456-3.199 5.525-3.235 5.61-.07.171-.008.366.149.464.201.12 16.023 9.547 16.177 9.571.151.022.297-.045.377-.174.942-1.584 3.206-5.55 3.232-5.601.069-.172.007-.367-.15-.465-.201-.12-15.983-9.499-16.09-9.546-.18-.074-.365-.002-.46.141m1.557 2.695c1.104 0 2 .897 2 2 0 1.104-.896 2-2 2s-2-.896-2-2c0-1.103.896-2 2-2" Type="RadioBox">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="1" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
<local:MyIconButton Tag="1" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
@@ -23,7 +23,7 @@
LogoScale="0.87" Logo="M1091.291429 0H78.935771C35.34848 0.035109 0.029257 35.354331 0 78.935771v863.331475c0 43.534629 35.401143 78.994286 78.935771 78.994285H1091.291429c43.534629 0 78.994286-35.401143 78.994285-78.994285V78.871406C1170.156983 35.319223 1134.849463 0.064366 1091.291429 0z m-8.835658 87.771429v78.754377H87.771429v-78.760229h994.684342zM87.771429 933.425737V254.232869h994.684342v679.140205H87.771429v0.058515zM724.95104 340.00896l-206.19264 547.605943a43.903269 43.903269 0 0 1-82.154057-31.012572l206.139977-547.547428a43.944229 43.944229 0 0 1 82.20672 30.954057zM369.558674 545.909029l-85.489371 85.489371 85.489371 85.542034a43.885714 43.885714 0 0 1-62.025143 62.083657l-116.554605-116.560457a43.8272 43.8272 0 0 1 0-62.025143l116.560457-116.49024a43.885714 43.885714 0 0 1 62.019291 61.966629z m610.567315-37.566172a43.885714 43.885714 0 0 1 0 62.083657l-116.560458 116.560457a43.768686 43.768686 0 0 1-62.019291 0 43.885714 43.885714 0 0 1 0-62.083657l85.547886-85.547885-85.547886-85.542035a43.897417 43.897417 0 0 1 62.083657-62.083657l116.496092 116.618972z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="2" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
<local:MyIconButton Tag="2" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
@@ -31,7 +31,7 @@
LogoScale="0.75" Logo="M512 817c-48.601 0-88-39.399-88-88s39.399-88 88-88 88 39.399 88 88-39.399 88-88 88zM237.671 565.74C308.335 474.58 397.369 429 504.774 429c118.433 0 214.225 55.421 287.377 166.264l-53.407 30.369c-13.84 7.87-31.362 4.367-41.114-8.219-50.291-64.911-114.577-97.367-192.856-97.367-86.851 0-156.835 40.318-209.95 120.953l-47.995-28.02c-15.263-8.91-20.412-28.507-11.502-43.77a32 32 0 0 1 2.344-3.47zM107.691 419.47C205.24 278.491 337.805 208 505.379 208c178.77 0 317.694 80.224 416.772 240.672l-56.54 31.73c-13.686 7.68-30.922 4.303-40.697-7.975C735.581 360.213 629.07 303.009 505.38 300.815 373.997 298.485 261.637 362.88 168.3 494l-50.116-28.505c-15.362-8.738-20.732-28.275-11.994-43.637a32 32 0 0 1 1.5-2.387z" >
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="3" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
<local:MyIconButton Tag="3" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
@@ -147,21 +147,25 @@
If MyMsgBox("是否要初始化启动页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupLaunch) Then FrmSetupLaunch = New PageSetupLaunch
FrmSetupLaunch.Reset()
ItemLaunch.Checked = True
End If
Case FormMain.PageSubType.SetupUI
If MyMsgBox("是否要初始化个性化页的所有设置?该操作不可撤销。" & vbCrLf & "(背景图片与音乐、自定义主页等外部文件不会被删除)", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupUI) Then FrmSetupUI = New PageSetupUI
FrmSetupUI.Reset()
ItemUI.Checked = True
End If
Case FormMain.PageSubType.SetupSystem
If MyMsgBox("是否要初始化启动器页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupSystem) Then FrmSetupSystem = New PageSetupSystem
FrmSetupSystem.Reset()
ItemSystem.Checked = True
End If
Case FormMain.PageSubType.SetupLink
If MyMsgBox("是否要初始化联机页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupLink) Then FrmSetupLink = New PageSetupLink
FrmSetupLink.Reset()
ItemLink.Checked = True
End If
End Select
End Sub
@@ -2,6 +2,7 @@
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"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d" x:Class="PageSetupSystem"
d:DesignWidth="800" d:DesignHeight="800">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
@@ -33,7 +34,7 @@
</local:MyComboBox>
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Mod 命名风格" Margin="0,0,25,0" />
<local:MyComboBox Grid.Row="2" x:Name="ComboDownloadTranslate" Grid.ColumnSpan="2" Tag="ToolDownloadTranslate" Grid.Column="1"
ToolTip="决定下载的 Mod 的默认文件名中,中文译名应该放在哪个位置" ToolTipService.ShowDuration="2333333">
ToolTip="决定下载的 Mod 的默认文件名中,中文译名应该放在哪个位置">
<local:MyComboBoxItem Content="译名位于文件名开头:[遗物] relics-0.1.14" IsSelected="True" />
<local:MyComboBoxItem Content="译名位于文件名开头:遗物-relics-0.1.14" />
<local:MyComboBoxItem Content="译名位于文件名末尾:relics-0.1.14-遗物" />
@@ -41,11 +42,11 @@
</local:MyComboBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="最大线程数" Margin="0,0,25,0" />
<local:MySlider x:Name="SliderDownloadThread" Grid.Row="4" Tag="ToolDownloadThread" MaxValue="255" Value="63" Grid.Column="1"
ToolTipService.ShowDuration="2333333" ToolTip="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。&#xA;一般而言,64 线程已可以保证足够的下载速度。" />
ToolTip="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。&#xa;一般而言,64 线程已可以保证足够的下载速度。" />
<TextBlock VerticalAlignment="Center" Grid.Row="5" HorizontalAlignment="Left" Text="速度限制" Margin="0,0,25,0" />
<local:MySlider x:Name="SliderDownloadSpeed" Grid.Row="5" Tag="ToolDownloadSpeed" MaxValue="42" Value="42" Grid.Column="1" />
<TextBlock VerticalAlignment="Top" Grid.Row="6" HorizontalAlignment="Left" Text="目标文件夹" Margin="0,5,25,5" />
<TextBlock Margin="0,5" HorizontalAlignment="Left" Text="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。&#xA;在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" />
<TextBlock Margin="0,5" HorizontalAlignment="Left" Text="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。&#xa;在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" />
<local:MyCheckBox Margin="0,2,0,4" Text="安装 CurseForge 整合包时保留原始压缩包" Grid.Row="7" Height="22" Grid.ColumnSpan="2"
x:Name="CheckDownloadKeepModpack" Tag="ToolDownloadKeepModpack"
ToolTip="安装 CurseForge 整合包后,在版本文件夹下保留用于安装的 原始整合包.zip 文件" />
@@ -101,7 +102,7 @@
<local:MyComboBoxItem Content="关闭所有公告" />
</local:MyComboBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="缓存文件夹" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextSystemCache" Grid.Row="4" Grid.ColumnSpan="2" Tag="SystemSystemCache" Grid.Column="1" ToolTip="PCL2 的下载、皮肤等缓存文件的存储位置,留空即为默认值,重启后生效" ToolTipService.ShowDuration="2333333" HintText="默认">
<local:MyTextBox x:Name="TextSystemCache" Grid.Row="4" Grid.ColumnSpan="2" Tag="SystemSystemCache" Grid.Column="1" ToolTip="PCL2 的下载、皮肤等缓存文件的存储位置。&#xa;不推荐路径中带有空格。&#xa;留空即为默认值,重启 PCL2 后生效。" HintText="默认">
<local:MyTextBox.ValidateRules>
<local:ValidateNullable />
<local:ValidateFolderPath UseMinecraftCharCheck="False" />
@@ -150,9 +151,9 @@
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:MyCheckBox Grid.Column="0" Text="禁止在下载时复制已存在的文件" Height="22" x:Name="CheckDebugSkipCopy" Tag="SystemDebugSkipCopy" ToolTip="在下载时不直接复制已经存在的文件,而是重新下载每个文件。&#x0a;只建议在测试下载速度时开启。" />
<local:MyCheckBox Grid.Column="1" Text="调试模式" Height="22" x:Name="CheckDebugMode" Tag="SystemDebugMode" ToolTip="显示调试信息与更多错误信息。&#x0a;这会导致启动器性能略有下降,若无特殊需要不建议开启。" />
<local:MyCheckBox Grid.Column="2" Text="添加延迟" Height="22" x:Name="CheckDebugDelay" Tag="SystemDebugDelay" ToolTip="在各个环节添加随机的延迟,拖慢加载速度,以测试部分功能是否正常运行。&#x0a;这会严重影响启动器运行,若无特殊需要不建议开启。" />
<local:MyCheckBox Grid.Column="0" Text="禁止在下载时复制已存在的文件" Height="22" x:Name="CheckDebugSkipCopy" Tag="SystemDebugSkipCopy" ToolTip="在下载时不直接复制已经存在的文件,而是重新下载每个文件。&#xa;只建议在测试下载速度时开启。" />
<local:MyCheckBox Grid.Column="1" Text="调试模式" Height="22" x:Name="CheckDebugMode" Tag="SystemDebugMode" ToolTip="显示调试信息与更多错误信息。&#xa;这会导致启动器性能略有下降,若无特殊需要不建议开启。" />
<local:MyCheckBox Grid.Column="2" Text="添加延迟" Height="22" x:Name="CheckDebugDelay" Tag="SystemDebugDelay" ToolTip="在各个环节添加随机的延迟,拖慢加载速度,以测试部分功能是否正常运行。&#xa;这会严重影响启动器运行,若无特殊需要不建议开启。" />
</Grid>
</StackPanel>
</local:MyCard>
@@ -161,13 +161,25 @@
Hint("请在所有下载任务完成后再清理缓存!", HintType.Critical)
Exit Sub
End If
If MyMsgBox("你确定要清理缓存吗?" & vbCrLf & "在清理缓存后,PCL2 会被强制关闭,以避免缓存缺失带来的异常。", "清理缓存", "确定", "取消") = 2 Then
Exit Sub
If PathTemp = IO.Path.GetTempPath() & "PCL\" Then
If MyMsgBox("你确定要清理缓存吗?" & vbCrLf & "在清理缓存后,PCL2 会被强制关闭,以避免缓存缺失带来的异常。", "清理确认", "确定", "取消") = 2 Then
Exit Sub
End If
Else
If MyMsgBox("你已将缓存文件夹手动修改为:" & PathTemp & vbCrLf &
"清理缓存将删除你所设置的这一文件夹中的所有内容,且无法恢复!" & vbCrLf &
"请在继续前,确认其中没有除了 PCL2 缓存以外的重要文件!" & vbCrLf & vbCrLf &
"在清理缓存后,PCL2 会被强制关闭,以避免缓存缺失带来的异常。", "清理确认", "永久删除该文件夹", "取消", IsWarn:=True) = 2 Then
Exit Sub
End If
End If
If IsClearingCache Then Exit Sub
IsClearingCache = True
Try
Dim TotalSize As ULong = DeleteCacheDirectory(PathTemp)
DeleteDirectory(PathTemp, True)
TotalSize += DeleteCacheDirectory(OsDrive & "ProgramData\PCL\")
DeleteDirectory(OsDrive & "ProgramData\PCL\", True)
If TotalSize <= 0 Then
Hint("没有可清理的缓存!")
Else
@@ -16,10 +16,10 @@
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="{DynamicResource ColorObject9}" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObjectBg1}" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0.02"/>
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0.98"/>
<GradientStop Color="{DynamicResource ColorObject9}" Offset="1"/>
<GradientStop Color="{DynamicResource ColorObjectBg1}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
@@ -91,11 +91,11 @@
Card.Children.Clear()
Card.Children.Add(GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""0"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"))
Dim Tb As TextBlock = GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" TextWrapping=""Wrap"" HorizontalAlignment=""Left"" ToolTipService.ShowDuration=""2333333"" ToolTip=""单击复制错误详情"" Grid.Column=""1"" Grid.Row=""0"" Margin=""0,0,0,5"" />")
Tb.Text = GetString(Loader.Error, False)
AddHandler Tb.MouseDown, Sub(sender As TextBlock, e As EventArgs)
ClipboardSet(sender.Text, False)
Hint("已复制错误详情!", HintType.Finish)
End Sub
Tb.Text = GetExceptionDetail(Loader.Error)
AddHandler Tb.MouseLeftButtonDown, Sub(sender As TextBlock, e As EventArgs)
ClipboardSet(sender.Text, False)
Hint("已复制错误详情!", HintType.Finish)
End Sub
Card.Children.Add(Tb)
''删除取消按钮
'For Each Element As FrameworkElement In CType(Card.Parent, Panel).Children
@@ -33,7 +33,7 @@
<Path Stretch="Uniform" Data="F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z" Width="16" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="5" Fill="{DynamicResource ColorBrush3}" Margin="0,7.5,14,0" VerticalAlignment="Top" Height="6" />
<TextBlock Text="摸鱼一时爽,一直摸鱼一直爽" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="5" />
</Grid>
<local:MyIconButton Logo="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" Height="20" Margin="0,10,10,0" ToolTipService.Placement="Top" ToolTipService.HorizontalOffset="-10" ToolTip="取消" ToolTipService.ShowDuration="2333333" LogoScale="1.1" HorizontalAlignment="Right" VerticalAlignment="Top" />
<local:MyIconButton Logo="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" Height="20" Margin="0,10,10,0" ToolTipService.Placement="Top" ToolTipService.HorizontalOffset="-10" ToolTip="取消" LogoScale="1.1" HorizontalAlignment="Right" VerticalAlignment="Top" />
</local:MyCard> -->
</StackPanel>
</local:MyScrollViewer>
@@ -9,7 +9,7 @@
LogoScale="1.02" Logo="M292.693 787.627c0 30.72-24.746 55.466-55.466 55.466s-55.467-24.746-55.467-55.466 24.747-55.467 55.467-55.467c30.72-0.853 55.466 24.747 55.466 55.467z M1000.96 241.493c-2.56-5.973-4.267-11.946-6.827-17.92-0.853-6.826-4.266-12.8-8.533-17.92-7.68-9.386-18.773-15.36-31.573-15.36-6.827 0-13.654 1.707-19.627 5.12l-15.36 15.36-17.067 17.067-21.333 21.333L749.227 381.44c-14.507 14.507-38.4 14.507-52.907 0l-54.613-54.613c-14.507-14.507-14.507-38.4 0-52.907l132.266-132.267 14.507-14.506 20.48-20.48 16.213-16.214c3.414-5.973 5.12-11.946 5.12-19.626 0-12.8-5.973-24.747-16.213-32.427-5.973-4.267-11.947-6.827-18.773-7.68-5.12-2.56-10.24-4.267-16.214-5.973-36.693-12.8-76.8-19.627-117.76-19.627-7.68 0-14.506 0-22.186 0.853-188.587 11.947-337.92 168.107-337.92 360.96 0 16.214 0.853 32.427 3.413 48.64L56.32 663.04c-73.387 74.24-73.387 193.707 0 267.093l33.28 33.28c73.387 73.387 193.707 73.387 267.093 0l240.64-241.493c21.334 4.267 42.667 5.973 64 5.973 190.294 0 346.454-146.773 360.107-333.653 0.853-8.533 0.853-17.92 0.853-27.307 0.854-44.373-6.826-86.186-21.333-125.44zM658.773 639.147c-28.16 0-54.613-4.267-79.36-11.094-4.266 7.68-10.24 14.507-16.213 21.334l-258.56 258.56c-43.52 43.52-115.2 43.52-158.72 0l-29.013-29.014c-43.52-44.373-43.52-115.2 0-158.72l212.48-212.48 46.08-46.08c5.973-5.973 12.8-11.093 19.626-15.36-8.533-26.453-12.8-54.613-12.8-83.626v-1.707c0-152.747 123.734-275.627 276.48-275.627 18.774 0 37.547 1.707 55.467 5.974L597.333 207.36c-52.053 52.053-52.053 137.387 0 189.44l29.867 29.867c52.053 52.053 137.387 52.053 189.44 0L930.987 312.32c2.56 16.213 4.266 33.28 4.266 50.347 0 152.746-123.733 276.48-276.48 276.48z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="1" ToolTip="初始化" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
<local:MyIconButton Tag="1" ToolTip="初始化" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
@@ -17,7 +17,7 @@
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.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="2" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" 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" />
<local:MyIconButton Tag="2" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" 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>
@@ -3,15 +3,15 @@
''' <summary>
''' 当前显示设置的 MC 版本。
''' </summary>
Public Shared Version As McVersion
Public Shared Version As McVersion = Nothing
Public Sub RefreshModDisabled() Handles Me.Loaded
If Version IsNot Nothing AndAlso Version.Modable Then
ItemMod.Visibility = Visibility.Visible
ItemModDisabled.Visibility = Visibility.Collapsed
ItemMod.Height = 36
ItemModDisabled.Height = 0
Else
ItemMod.Visibility = Visibility.Collapsed
ItemModDisabled.Visibility = Visibility.Visible
ItemMod.Height = 0
ItemModDisabled.Height = 36
End If
End Sub
@@ -90,12 +90,15 @@
Public Sub Refresh(sender As Object, e As EventArgs) '由边栏按钮匿名调用
'强制刷新
If FrmVersionMod IsNot Nothing Then FrmVersionMod.RefreshList(True) '没有 Else,还没加载刷个鬼的新
ItemMod.Checked = True
Hint("正在刷新……", Log:=False)
End Sub
Public Sub Reset(sender As Object, e As EventArgs)
If MyMsgBox("是否要初始化该版本的版本独立设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmVersionSetup) Then FrmVersionSetup = New PageVersionSetup
FrmVersionSetup.Reset()
ItemSetup.Checked = True
End If
End Sub
@@ -22,7 +22,7 @@
<local:MyButton x:Name="BtnManageOpen" Grid.Column="0" MinWidth="140" Text="打开 Mod 文件夹" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnManageEnabled" Grid.Column="1" MinWidth="140" Text="全部启用" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnManageDisabled" Grid.Column="2" MinWidth="140" Text="全部禁用" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnManageCheck" Grid.Column="3" MinWidth="140" Text="检查 Mod" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ToolTip="快速检查 Mod 的版本要求、重复、前置缺失等问题。&#xA;结果仅供参考,由于部分 Mod 标注的信息有误,可能并不准确。" Visibility="Collapsed" />
<local:MyButton x:Name="BtnManageCheck" Grid.Column="3" MinWidth="140" Text="检查 Mod" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ToolTip="快速检查 Mod 的版本要求、重复、前置缺失等问题。&#xa;结果仅供参考,由于部分 Mod 标注的信息有误,可能并不准确。" Visibility="Collapsed" />
</Grid>
</StackPanel>
</local:MyCard>
@@ -39,7 +39,7 @@
<StackPanel Margin="20,17">
<TextBlock Margin="0,0,0,9" HorizontalAlignment="Center" Text="未找到 Mod" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Margin="10,15,10,0" Text="要安装 Mod,请直接将 Mod 文件拖入 PCL2 窗口。&#xA;如果你确定你已经安装了 Mod,但仍然看到了这条提示,那么你的版本隔离设置可能有误。请尝试在启动设置中调整版本隔离选项。" TextWrapping="Wrap" />
<TextBlock Margin="10,15,10,0" Text="要安装 Mod,请直接将 Mod 文件拖入 PCL2 窗口。&#xa;如果你确定你已经安装了 Mod,但仍然看到了这条提示,那么你的版本隔离设置可能有误。请尝试在启动设置中调整版本隔离选项。" TextWrapping="Wrap" />
<local:MyButton Height="35" HorizontalAlignment="Center" x:Name="BtnHintOpen" MinWidth="140" Text="打开 Mod 文件夹" Margin="0,15,0,0" Padding="13,0" ColorType="Highlight" />
</StackPanel>
</local:MyCard>
@@ -23,6 +23,7 @@
Public Sub RefreshList(Optional ForceReload As Boolean = False)
If McModLoader.State = LoadState.Loading Then Exit Sub
If LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then
Log("[System] 已刷新 Mod 列表")
PanBack.ScrollToHome()
SearchBox.Text = ""
End If
@@ -59,6 +60,7 @@
PanEmpty.Visibility = Visibility.Collapsed
End If
SearchBox.Text = ""
'建立 StackPanel
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, If(List.Count > 0, 20, 0)), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0)}
For Each ModEntity As McMod In List
@@ -212,39 +214,38 @@
''' </summary>
Private Sub BtnManageChange_Click(sender As MyButton, e As EventArgs) Handles BtnManageEnabled.Click, BtnManageDisabled.Click
Dim IsSuccessful As Boolean = True
Try
Dim IsDisable As Boolean = sender.Text.Contains("禁用")
For Each ModEntity In McModLoader.Output
Dim NewPath As String = Nothing
If ModEntity.State = McMod.McModState.Fine And IsDisable Then
'禁用
NewPath = ModEntity.Path & ".disabled"
ElseIf ModEntity.State = McMod.McModState.Disabled AndAlso Not IsDisable Then
'启用
NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count)
Else
Continue For
End If
'重命名
Try
If File.Exists(ModEntity.Path) Then
File.Delete(NewPath)
FileSystem.Rename(ModEntity.Path, NewPath)
Else
Throw New FileNotFoundException("未找到文件:" & ModEntity.Path)
End If
Catch ex As Exception
Log(ex, "全局状态改变中重命名 Mod 失败")
IsSuccessful = False
End Try
Next
Catch ex As Exception
Log(ex, "改变全部 Mod 状态失败", LogLevel.Msgbox)
IsSuccessful = False
Finally
If Not IsSuccessful Then Hint("由于文件被占用,部分 Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
RefreshList()
End Try
Dim SuccessfulCount As Integer = 0
Dim IsDisable As Boolean = sender.Text.Contains("禁用")
For Each ModEntity In McModLoader.Output
Dim NewPath As String = Nothing
If ModEntity.State = McMod.McModState.Fine And IsDisable Then
'禁用
NewPath = ModEntity.Path & ".disabled"
ElseIf ModEntity.State = McMod.McModState.Disabled AndAlso Not IsDisable Then
'启用
NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count)
Else
SuccessfulCount += 1
Continue For
End If
'重命名
Try
If File.Exists(NewPath) AndAlso Not File.Exists(ModEntity.Path) Then Continue For '因为未知原因 Mod 的状态已经切换完了
File.Delete(NewPath)
FileSystem.Rename(ModEntity.Path, NewPath)
SuccessfulCount += 1
Catch ex As FileNotFoundException
Log(ex, "未找到需要重命名的 Mod(" & If(ex.FileName, "null") & ")", LogLevel.Feedback)
RefreshList()
Exit Sub
Catch ex As Exception
Log(ex, "全局状态改变中重命名 Mod 失败")
IsSuccessful = False
End Try
Next
If Not IsSuccessful Then Hint("由于文件被占用,部分 Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
Log("[System] 已确认 " & SuccessfulCount & "/" & McModLoader.Output.Count & " 个 Mod 的状态与要求一致")
RefreshList()
End Sub
#End Region
@@ -267,7 +268,7 @@
Case McMod.McModState.Disabled
NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count)
Case McMod.McModState.Unavaliable
MyMsgBox("无法读取此 Mod 的信息。" & vbCrLf & vbCrLf & "详细的错误信息:" & GetString(ModEntity.FileUnavailableReason, False), "Mod 读取失败")
MyMsgBox("无法读取此 Mod 的信息。" & vbCrLf & vbCrLf & "详细的错误信息:" & GetExceptionDetail(ModEntity.FileUnavailableReason), "Mod 读取失败")
Exit Sub
End Select
'重命名
@@ -383,15 +384,15 @@
ModSearchName = ModSearchName.Replace("++", "+").Replace("pti+Fine", "ptiFine")
'显示
If ModEntity.Url Is Nothing Then
If MyMsgBox(Join(ContentLines, vbCrLf), ModEntity.Name, "确定", "百科搜索") = 2 Then
If MyMsgBox(Join(ContentLines, vbCrLf), ModEntity.Name, "百科搜索", "返回") = 1 Then
OpenWebsite("https://www.mcmod.cn/s?key=" & ModSearchName & "&site=all&filter=0")
End If
Else
Select Case MyMsgBox(Join(ContentLines, vbCrLf), ModEntity.Name, "确定", "百科搜索", "打开官网")
Select Case MyMsgBox(Join(ContentLines, vbCrLf), ModEntity.Name, "打开官网", "百科搜索", "返回")
Case 1
OpenWebsite(ModEntity.Url)
Case 2
OpenWebsite("https://www.mcmod.cn/s?key=" & ModSearchName & "&site=all&filter=0")
Case 3
OpenWebsite(ModEntity.Url)
End Select
End If
@@ -22,7 +22,7 @@
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="4" Margin="0,0,0,9" HorizontalAlignment="Center" Text="该版本不可使用 Mod" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle Grid.Row="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="2" Grid.ColumnSpan="4" Margin="10,15,10,5" Text="你需要先安装 Forge 或 Fabric 才能使用 Mod,请在下载页面重新安装这些版本。&#xA;如果你已经安装过了 Forge 或 Fabric,那么你很可能选择了错误的版本,请点击版本选择按钮切换版本,并注意 Forge 在版本选择列表中的图标为铁砧,Fabric 的图标为丝绸。" TextWrapping="Wrap" />
<TextBlock Grid.Row="2" Grid.ColumnSpan="4" Margin="10,15,10,5" Text="你需要先安装 Forge 或 Fabric 等 Mod 加载器才能使用 Mod,请在下载页面重新安装这些版本。&#xa;如果你已经安装过了 Mod 加载器,那么你很可能选择了错误的版本,请点击版本选择按钮切换版本,并注意 Forge 在版本选择列表中的图标为铁砧,Fabric 的图标为丝绸。" TextWrapping="Wrap" />
<local:MyButton Grid.Row="3" Grid.Column="1" Height="35" HorizontalAlignment="Center" x:Name="BtnDownload" MinWidth="140" Text="转到下载页面" Margin="10,10,10,0" Padding="13,0" ColorType="Highlight" />
<local:MyButton Grid.Row="3" Grid.Column="2" Height="35" HorizontalAlignment="Center" x:Name="BtnVersion" MinWidth="140" Text="版本选择" Margin="10,10,10,0" Padding="13,0" />
</Grid>
@@ -7,10 +7,12 @@
d:DesignWidth="800" d:DesignHeight="800" Grid.IsSharedSizeScope="True">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10">
<local:MyCard Margin="0,15" Title="个性化" x:Name="PanDisplay">
<local:MyCard Margin="0,15" Title="">
<Grid Margin="10,7" Name="PanDisplayItem" />
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="个性化" x:Name="PanDisplay">
<StackPanel Margin="25,40,25,15">
<Grid Margin="-7,-3,0,12" Name="PanDisplayItem" />
<Grid x:Name="PanDisplayIcon" Margin="0,0,0,11" HorizontalAlignment="Stretch">
<Grid x:Name="PanDisplayIcon" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
@@ -20,7 +22,7 @@
<RowDefinition Height="9" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本图标" Margin="0,0,25,0" />
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="图标" Margin="0,0,25,0" />
<local:MyComboBox Grid.Column="1" x:Name="ComboDisplayLogo">
<local:MyComboBoxItem Content="自动" IsSelected="True" Tag="" />
<local:MyComboBoxItem Content="自定义..." x:Name="ItemDisplayLogoCustom" />
@@ -36,29 +38,29 @@
<local:MyComboBoxItem Content="鸡蛋" Tag="pack://application:,,,/images/Blocks/Egg.png" />
<local:MyComboBoxItem Content="布料(Fabric)" Tag="pack://application:,,,/images/Blocks/Fabric.png" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本分类" Margin="0,0,25,0" />
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="分类" Margin="0,0,25,0" />
<local:MyComboBox Grid.Column="1" Grid.Row="2" x:Name="ComboDisplayType">
<local:MyComboBoxItem Content="自动" IsSelected="True" />
<local:MyComboBoxItem Content="从版本列表中隐藏" ToolTip="该版本默认将不会在版本列表中显示。&#xA;在版本列表页面按下 F11,即可查看所有隐藏的版本。" ToolTipService.ShowDuration="2333333" />
<local:MyComboBoxItem Content="从版本列表中隐藏" ToolTip="该版本默认将不会在版本列表中显示。&#xa;在版本列表页面按下 F11,即可查看所有隐藏的版本。" />
<local:MyComboBoxItem Content="可安装 Mod 的版本" />
<local:MyComboBoxItem Content="常规版本" />
<local:MyComboBoxItem Content="不常用版本" />
<local:MyComboBoxItem Content="愚人节版本" />
</local:MyComboBox>
</Grid>
<Grid Margin="0,0,0,7" Height="35">
<Grid Margin="0,15,0,7" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnDisplayRename" Text="重命名版本" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnDisplayDesc" Text="更改描述" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
<local:MyButton x:Name="BtnDisplayRename" Text="修改版本名" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnDisplayDesc" Text="修改版本描述" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
<local:MyButton x:Name="BtnDisplayStar" Text="加入收藏夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="管理" x:Name="PanManage">
<local:MyCard Margin="0,0,0,15" Title="快捷方式" x:Name="PanFolder">
<StackPanel Margin="25,40,25,15">
<Grid Margin="0,2,0,7" Height="35">
<Grid.ColumnDefinitions>
@@ -66,8 +68,22 @@
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnManageFolder" Text="打开版本文件夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnManageCheck" Text="补全文件" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" ToolTip="校验版本依赖文件是否完整,并重新下载 Assets 索引与缺失、校验失败的文件。&#xa;若游戏缺失音效,请尝试此项。" ToolTipService.ShowDuration="2333333" />
<local:MyButton x:Name="BtnFolderVersion" Text="版本文件夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnFolderSaves" Text="存档文件夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
<local:MyButton x:Name="BtnFolderMods" Text="Mod 文件夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="高级管理" x:Name="PanManage">
<StackPanel Margin="25,40,25,15">
<Grid Margin="0,2,0,7" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnManageScript" Text="导出启动脚本" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnManageCheck" Text="补全文件" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" ToolTip="校验版本依赖文件是否完整,并重新下载 Assets 索引与缺失、校验失败的文件。&#xa;若游戏缺失音效,请尝试此项。" />
<local:MyButton x:Name="BtnManageDelete" Text="删除版本" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2" ColorType="Red" />
</Grid>
</StackPanel>
@@ -27,6 +27,7 @@
'刷新设置项目
ComboDisplayType.SelectedIndex = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto)
BtnDisplayStar.Text = If(PageVersionLeft.Version.IsStar, "从收藏夹中移除", "加入收藏夹")
BtnFolderMods.Visibility = If(PageVersionLeft.Version.Modable, Visibility.Visible, Visibility.Collapsed)
'刷新版本显示
PanDisplayItem.Children.Clear()
ItemVersion = PageSelectRight.McVersionListItem(PageVersionLeft.Version)
@@ -49,7 +50,7 @@
AniControlEnabled -= 1
End Sub
#Region "设置临时接口"
#Region "卡片:个性化"
'版本分类
Private Sub ComboDisplayType_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayType.SelectionChanged
@@ -67,6 +68,7 @@
Catch ex As Exception
Log(ex, "修改版本分类失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
End Try
Reload() '更新 “打开 Mod 文件夹” 按钮
Else
'改为隐藏
Try
@@ -85,11 +87,12 @@
End Try
End If
End Sub
'更改描述
Private Sub BtnDisplayDesc_Click(sender As Object, e As EventArgs) Handles BtnDisplayDesc.Click
Try
Dim OldInfo As String = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "CustomInfo")
Dim NewInfo As String = MyMsgBoxInput(OldInfo, New ObjectModel.Collection(Of Validate), "留空即为使用默认描述", "更改描述",, "取消")
Dim NewInfo As String = MyMsgBoxInput("更改描述", "修改版本的描述文本,留空则使用 PCL2 的默认描述。", OldInfo, New ObjectModel.Collection(Of Validate), "默认描述")
If NewInfo IsNot Nothing AndAlso OldInfo <> NewInfo Then WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "CustomInfo", NewInfo)
PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
Reload()
@@ -98,6 +101,7 @@
Log(ex, "版本 " & PageVersionLeft.Version.Name & " 描述更改失败", LogLevel.Msgbox)
End Try
End Sub
'重命名版本
Private Sub BtnDisplayRename_Click(sender As Object, e As EventArgs) Handles BtnDisplayRename.Click
Try
@@ -105,7 +109,7 @@
Dim OldName As String = PageVersionLeft.Version.Name
Dim OldPath As String = PageVersionLeft.Version.Path
'修改此部分的同时修改快速安装的版本名检测*
Dim NewName As String = MyMsgBoxInput(OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)},, "重命名版本",, "取消")
Dim NewName As String = MyMsgBoxInput("重命名版本", "", OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)})
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
'获取临时中间名,以防止仅修改大小写的重命名失败
@@ -171,80 +175,7 @@
Log(ex, "重命名版本失败", LogLevel.Msgbox)
End Try
End Sub
'收藏夹
Private Sub BtnDisplayStar_Click(sender As Object, e As EventArgs) Handles BtnDisplayStar.Click
Try
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "IsStar", Not PageVersionLeft.Version.IsStar)
PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
Reload()
McVersionListForceRefresh = True
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "版本 " & PageVersionLeft.Version.Name & " 收藏状态更改失败", LogLevel.Msgbox)
End Try
End Sub
'补全文件
Private Sub BtnManageCheck_Click(sender As Object, e As EventArgs) Handles BtnManageCheck.Click
Try
'重复任务检查
SyncLock LoaderTaskbarLock
For i = 0 To LoaderTaskbar.Count - 1
If LoaderTaskbar(i).Name = PageVersionLeft.Version.Name & " 文件补全" Then
Hint("正在处理中,请稍候!", HintType.Critical)
Exit Sub
End If
Next
End SyncLock
'启动
Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload, False))
Loader.OnStateChanged = Sub()
Select Case Loader.State
Case LoadState.Finished
Hint(Loader.Name & "成功!", HintType.Finish)
Case LoadState.Failed
Hint(Loader.Name & "失败:" & GetString(Loader.Error), HintType.Critical)
Case LoadState.Aborted
Hint(Loader.Name & "已取消!", HintType.Info)
End Select
End Sub
Loader.Start(PageVersionLeft.Version.Name)
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "尝试补全文件失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Msgbox)
End Try
End Sub
'删除版本
Private Sub BtnManageDelete_Click(sender As Object, e As EventArgs) Handles BtnManageDelete.Click
'修改此代码时,同时修改 PageSelectRight 中的代码
Try
Dim IsHintIndie As Boolean = PageVersionLeft.Version.State <> McVersionState.Error AndAlso PageVersionLeft.Version.PathIndie <> PathMcFolder
Select Case MyMsgBox("你确定要删除版本 " & PageVersionLeft.Version.Name & " 吗?" &
If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
"版本删除确认", , "取消",, True)
Case 1
FileIO.FileSystem.DeleteDirectory(PageVersionLeft.Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
Case 2
' DeleteDirectory(PageVersionLeft.Version.Path)
' Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish)
'Case 3
Exit Sub
End Select
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
FrmMain.PageBack()
Catch ex As Exception
Log(ex, "删除版本 " & PageVersionLeft.Version.Name & " 失败", LogLevel.Msgbox)
End Try
End Sub
'打开版本文件夹
Private Sub BtnManageFolder_Click() Handles BtnManageFolder.Click
OpenVersionFolder(PageVersionLeft.Version)
End Sub
Public Shared Sub OpenVersionFolder(Version As McVersion)
OpenExplorer("""" & Version.Path & """")
End Sub
'版本图标
Private Sub ComboDisplayLogo_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
If Not (IsLoad AndAlso AniControlEnabled = 0) Then Exit Sub
@@ -280,6 +211,130 @@
End Try
End Sub
'收藏夹
Private Sub BtnDisplayStar_Click(sender As Object, e As EventArgs) Handles BtnDisplayStar.Click
Try
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "IsStar", Not PageVersionLeft.Version.IsStar)
PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
Reload()
McVersionListForceRefresh = True
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "版本 " & PageVersionLeft.Version.Name & " 收藏状态更改失败", LogLevel.Msgbox)
End Try
End Sub
#End Region
#Region "卡片:快捷方式"
'版本文件夹
Private Sub BtnFolderVersion_Click() Handles BtnFolderVersion.Click
OpenVersionFolder(PageVersionLeft.Version)
End Sub
Public Shared Sub OpenVersionFolder(Version As McVersion)
OpenExplorer("""" & Version.Path & """")
End Sub
'存档文件夹
Private Sub BtnFolderSaves_Click() Handles BtnFolderSaves.Click
Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "saves\"
Directory.CreateDirectory(FolderPath)
OpenExplorer("""" & FolderPath & """")
End Sub
'Mod 文件夹
Private Sub BtnFolderMods_Click() Handles BtnFolderMods.Click
Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "mods\"
Directory.CreateDirectory(FolderPath)
OpenExplorer("""" & FolderPath & """")
End Sub
#End Region
#Region "卡片:管理"
'导出启动脚本
Private Sub BtnManageScript_Click() Handles BtnManageScript.Click
Try
'弹窗要求指定脚本的保存位置
Dim SavePath As String = SelectAs("选择脚本保存位置", "启动 " & PageVersionLeft.Version.Name & ".bat", "批处理文件(*.bat)|*.bat")
If SavePath = "" Then Exit Sub
'检查中断(等玩家选完弹窗指不定任务就结束了呢……)
If McLaunchLoader.State = LoadState.Loading Then
Hint("请在当前启动任务结束后再试!", HintType.Critical)
Exit Sub
End If
'生成脚本
If McLaunchStart(New McLaunchOptions With {.SaveBatch = SavePath, .Version = PageVersionLeft.Version}) Then
If Setup.Get("LoginType") = McLoginType.Legacy Then
Hint("正在导出启动脚本……")
Else
Hint("正在导出启动脚本……(注意,使用脚本启动可能会导致登录失效!)")
End If
End If
Catch ex As Exception
Log(ex, "导出启动脚本失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Msgbox)
End Try
End Sub
'补全文件
Private Sub BtnManageCheck_Click(sender As Object, e As EventArgs) Handles BtnManageCheck.Click
Try
'重复任务检查
SyncLock LoaderTaskbarLock
For i = 0 To LoaderTaskbar.Count - 1
If LoaderTaskbar(i).Name = PageVersionLeft.Version.Name & " 文件补全" Then
Hint("正在处理中,请稍候!", HintType.Critical)
Exit Sub
End If
Next
End SyncLock
'启动
Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload, False))
Loader.OnStateChanged = Sub()
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
Loader.Start(PageVersionLeft.Version.Name)
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "尝试补全文件失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Msgbox)
End Try
End Sub
'删除版本
Private Sub BtnManageDelete_Click(sender As Object, e As EventArgs) Handles BtnManageDelete.Click
'修改此代码时,同时修改 PageSelectRight 中的代码
Try
Dim IsHintIndie As Boolean = PageVersionLeft.Version.State <> McVersionState.Error AndAlso PageVersionLeft.Version.PathIndie <> PathMcFolder
Select Case MyMsgBox("你确定要删除版本 " & PageVersionLeft.Version.Name & " 吗?" &
If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
"版本删除确认", , "取消",, True)
Case 1
FileIO.FileSystem.DeleteDirectory(PageVersionLeft.Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
Case 2
' DeleteDirectory(PageVersionLeft.Version.Path)
' Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish)
'Case 3
Exit Sub
End Select
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
FrmMain.PageBack()
Catch ex As Exception
Log(ex, "删除版本 " & PageVersionLeft.Version.Name & " 失败", LogLevel.Msgbox)
End Try
End Sub
#End Region
End Class
@@ -25,17 +25,11 @@
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<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 x:Name="TextArgumentTitle" Grid.Row="0" Grid.ColumnSpan="2" Tag="VersionArgumentTitle" Grid.Column="1" ToolTip="自定义游戏窗口的标题,若留空则使用全局设置的值。&#x0a;支持以下替换标记:&#x0a; - {user}:玩家名字&#x0a; - {login}:玩家的登录方式&#x0a; - {name}:游戏版本名&#x0a; - {time}:当前的系统时间&#x0a; - {version}:游戏对应的原版版本号&#x0a; - {path}:PCL 可执行文件所在路径,以 \ 结尾" ToolTipService.ShowDuration="2333333" HintText="使用全局设置" MaxLength="100" />
<local:MyTextBox x:Name="TextArgumentTitle" Grid.Row="0" Grid.ColumnSpan="2" Tag="VersionArgumentTitle" Grid.Column="1" ToolTip="自定义游戏窗口的标题,若留空则使用全局设置的值。&#xa;支持以下替换标记:&#xa; · {user}:玩家名字&#xa; · {login}:玩家的登录方式&#xa; · {name}:游戏版本名&#xa; · {time}:当前的系统时间&#xa; · {version}:游戏对应的原版版本号" HintText="使用全局设置" MaxLength="100" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="自定义信息" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="VersionArgumentInfo" Grid.Column="1" HintText="使用全局设置" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角。&#xa;若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333">
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="VersionArgumentInfo" Grid.Column="1" HintText="使用全局设置" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角。&#xa;若留空,则使用全局设置的值。">
<local:MyTextBox.ValidateRules>
<local:ValidateExcept>
<local:ValidateExcept.Excepts>
@@ -46,24 +40,14 @@
</local:ValidateExcept>
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="JVM 参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="4" Grid.ColumnSpan="2" Tag="VersionAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,在没有确定把握的情况下请不要尝试修改。&#xA;若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333" HintText="使用全局设置" />
<TextBlock Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Text="额外参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="6" Grid.ColumnSpan="2" Tag="VersionAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xA;例如输入 --demo 则会以试玩模式启动游戏。&#xA;若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333" HintText="使用全局设置" />
<TextBlock Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本隔离" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentIndie" Grid.Row="8" Grid.ColumnSpan="2" Tag="VersionArgumentIndie" Grid.Column="1">
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本隔离" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentIndie" Grid.Row="4" Grid.ColumnSpan="2" Tag="VersionArgumentIndie" Grid.Column="1">
<local:MyComboBoxItem Content="使用全局设置" IsSelected="True" />
<local:MyComboBoxItem Content="开启" ToolTip="让这个版本与其他版本的存档、Mod 等档案相互独立,互不干涉" />
<local:MyComboBoxItem Content="关闭" ToolTip="与其余未开启隔离的版本均使用同一档案,存档、Mod 等均为公用。&#xA;若存在不同版本的 Forge 或 Fabric,可能会由于 Mod 与版本冲突导致未知问题。" />
<local:MyComboBoxItem Content="关闭" ToolTip="与其余未开启隔离的版本均使用同一档案,存档、Mod 等均为公用。&#xa;若存在不同版本的 Forge 或 Fabric,可能会由于 Mod 与版本冲突导致未知问题。" />
</local:MyComboBox>
<TextBlock Grid.Row="10" VerticalAlignment="Center" HorizontalAlignment="Left" Text="文件校验" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboAdvanceAssets" Grid.Row="10" Grid.ColumnSpan="2" Tag="VersionAdvanceAssets" Grid.Column="1">
<local:MyComboBoxItem Content="使用全局设置" IsSelected="True" />
<local:MyComboBoxItem Content="开启" ToolTip="在启动 Minecraft 时,简单校验并下载缺失或错误的文件。" />
<local:MyComboBoxItem Content="关闭" ToolTip="在启动 Minecraft 时,不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。&#xA;如果你没有修改相关文件,请勿选择此项。" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="12" HorizontalAlignment="Left" Text="游戏 Java" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentJava" Grid.ColumnSpan="2" Grid.Row="12" Grid.Column="1" ToolTip="若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL2 会尽量优先选择它" ToolTipService.ShowDuration="2333333">
<TextBlock VerticalAlignment="Center" Grid.Row="6" HorizontalAlignment="Left" Text="游戏 Java" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentJava" Grid.ColumnSpan="2" Grid.Row="6" Grid.Column="1" ToolTip="若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL2 会尽量优先选择它">
<ComboBoxItem Content="加载中……" IsSelected="True" />
<!--<local:MyComboBoxItem Content="Java 8 (1.8.0_171),64 位:C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" IsSelected="True" ToolTip="C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" />-->
</local:MyComboBox>
@@ -121,8 +105,8 @@
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardServer" Margin="0,0,0,15" Title="服务器选项">
<StackPanel Margin="25,42,25,21">
<local:MyCard x:Name="CardServer" Margin="0,0,0,15" Title="服务器">
<StackPanel Margin="25,42,25,18">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
@@ -166,7 +150,7 @@
<TextBlock Name="LabServerAuthName" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" Text="服务器名称" Margin="0,8,25,0" Visibility="Collapsed" />
<local:MyTextBox x:Name="TextServerAuthName" Grid.Row="3" Grid.ColumnSpan="2" ShowValidateResult="False" Tag="VersionServerAuthName" Grid.Column="1" Margin="0,8,0,0" Visibility="Collapsed" HintText="显示在登录页面的服务器名称" />
<TextBlock VerticalAlignment="Center" Grid.Row="5" HorizontalAlignment="Left" Text="自动进入服务器" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextServerEnter" Grid.ColumnSpan="2" Grid.Row="5" Tag="VersionServerEnter" Grid.Column="1" ToolTip="在打开 Minecraft 后自动进入某服务器。&#xA;用英文冒号间隔 IP 与端口,例如 233.233.233.233:12345。" ToolTipService.ShowDuration="2333333">
<local:MyTextBox x:Name="TextServerEnter" Grid.ColumnSpan="2" Grid.Row="5" Tag="VersionServerEnter" Grid.Column="1" ToolTip="在打开 Minecraft 后自动进入某服务器。&#xa;用英文冒号间隔 IP 与端口,例如 233.233.233.233:12345。">
<local:MyTextBox.ValidateRules>
<local:ValidateExcept>
<local:ValidateExcept.Excepts>
@@ -189,6 +173,40 @@
<local:MyButton x:Name="BtnServerAuthLittle" Height="35" MinWidth="150" Margin="0,12,0,0" Text="设置为 LittleSkin" HorizontalAlignment="Left" ColorType="Highlight" />
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardAdvance" Margin="0,0,0,15" Title="高级启动选项" IsSwaped="True" CanSwap="True">
<Grid Margin="25,40,25,21">
<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="31" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="JVM 参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="0" Grid.ColumnSpan="2" Tag="VersionAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,在没有确定把握的情况下请不要尝试修改。&#xa;若留空,则使用全局设置的值。" HintText="使用全局设置" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="额外参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="2" Grid.ColumnSpan="2" Tag="VersionAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xa;例如输入 --demo 则会以试玩模式启动游戏。&#xa;若留空,则使用全局设置的值。" HintText="使用全局设置" />
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="文件校验" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboAdvanceAssets" Grid.Row="4" Grid.ColumnSpan="2" Tag="VersionAdvanceAssets" Grid.Column="1">
<local:MyComboBoxItem Content="使用全局设置" IsSelected="True" />
<local:MyComboBoxItem Content="开启" ToolTip="在启动 Minecraft 时,简单校验并下载缺失或错误的文件。" />
<local:MyComboBoxItem Content="关闭" ToolTip="在启动 Minecraft 时,不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。&#xa;如果你没有修改相关文件,请勿选择此项。" />
</local:MyComboBox>
<TextBlock Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Text="启动前执行命令" Margin="0,0,25,3" />
<local:MyTextBox x:Name="TextAdvanceRun" Grid.Row="6" Grid.ColumnSpan="2" Tag="VersionAdvanceRun" Grid.Column="1" HintText="" Margin="0,0,0,3"
ToolTip="在 MC 启动前执行特定命令或程序,语法与 Windows 的命令提示符一致。&#xa;&#xa;可以使用以下替换标记实现相对路径(路径均以 \ 结尾):&#xa; · {path}:PCL 的 exe 文件所在的文件夹&#xa; · {minecraft}:.minecraft 文件夹&#xa; · {verpath}:版本文件夹(.minecraft\versions\版本名\)&#xa; · {verindie}:开启版本隔离时等同版本文件夹,未开启时等同 .minecraft 文件夹&#xa; · {java}:游戏运行时的 Java 文件夹&#xa;&#xa;除此之外,也支持以下替换标记:&#xa; · {user}:玩家名字&#xa; · {login}:玩家的登录方式&#xa; · {uuid}:玩家的 UUID&#xa; · {name}:游戏版本名&#xa; · {time}:当前的系统时间&#xa; · {version}:游戏对应的原版版本号&#xa;&#xa;例如:&#xa; · &quot;{verpath}test.exe&quot; :运行版本文件夹下的 test.exe 程序&#xa; · &quot;{java}java.exe&quot; -jar &quot;{verpath}test.jar&quot; :用 Java 运行版本文件夹下的 test.jar&#xa; · notepad &quot;{verindie}option.txt&quot; :使用记事本打开该版本的设置文件&#xa;&#xa;涉及路径的操作最好都打上双引号,以避免路径中的空格导致运行失败。" />
<local:MyCheckBox Grid.Row="7" Grid.Column="1" x:Name="CheckAdvanceRunWait" Tag="VersionAdvanceRunWait" Visibility="Collapsed"
Text="等待命令执行完成后再继续启动" Margin="0,5,0,0" />
</Grid>
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -46,9 +46,6 @@
End If
End If
ComboArgumentIndie.SelectedIndex = Indie
TextAdvanceJvm.Text = Setup.Get("VersionAdvanceJvm", Version:=PageVersionLeft.Version)
TextAdvanceGame.Text = Setup.Get("VersionAdvanceGame", Version:=PageVersionLeft.Version)
ComboAdvanceAssets.SelectedIndex = Setup.Get("VersionAdvanceAssets", Version:=PageVersionLeft.Version)
RefreshJavaComboBox()
'游戏内存
@@ -65,6 +62,13 @@
TextServerAuthName.Text = Setup.Get("VersionServerAuthName", Version:=PageVersionLeft.Version)
TextServerAuthRegister.Text = Setup.Get("VersionServerAuthRegister", Version:=PageVersionLeft.Version)
'高级设置
TextAdvanceJvm.Text = Setup.Get("VersionAdvanceJvm", Version:=PageVersionLeft.Version)
TextAdvanceGame.Text = Setup.Get("VersionAdvanceGame", Version:=PageVersionLeft.Version)
TextAdvanceRun.Text = Setup.Get("VersionAdvanceRun", Version:=PageVersionLeft.Version)
CheckAdvanceRunWait.Checked = Setup.Get("VersionAdvanceRunWait", Version:=PageVersionLeft.Version)
ComboAdvanceAssets.SelectedIndex = Setup.Get("VersionAdvanceAssets", Version:=PageVersionLeft.Version)
Catch ex As Exception
Log(ex, "重载版本独立设置时出错", LogLevel.Feedback)
End Try
@@ -88,6 +92,8 @@
Setup.Reset("VersionAdvanceJvm", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceGame", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceAssets", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceRun", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceRunWait", Version:=PageVersionLeft.Version)
Setup.Reset("VersionArgumentJavaSelect", Version:=PageVersionLeft.Version)
JavaSearchLoader.Start(IsForceRestart:=True)
@@ -105,7 +111,7 @@
Private Shared Sub RadioBoxChange(sender As MyRadioBox, e As Object) Handles RadioRamType0.Check, RadioRamType1.Check, RadioRamType2.Check
If AniControlEnabled = 0 Then Setup.Set(sender.Tag.ToString.Split("/")(0), Val(sender.Tag.ToString.Split("/")(1)), Version:=PageVersionLeft.Version)
End Sub
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextServerEnter.ValidatedTextChanged, TextArgumentInfo.ValidatedTextChanged, TextAdvanceGame.ValidatedTextChanged, TextAdvanceJvm.ValidatedTextChanged, TextServerNide.ValidatedTextChanged, TextServerAuthName.ValidatedTextChanged, TextServerAuthRegister.ValidatedTextChanged, TextServerAuthServer.ValidatedTextChanged, TextArgumentTitle.ValidatedTextChanged
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextServerEnter.ValidatedTextChanged, TextArgumentInfo.ValidatedTextChanged, TextAdvanceGame.ValidatedTextChanged, TextAdvanceJvm.ValidatedTextChanged, TextServerNide.ValidatedTextChanged, TextServerAuthName.ValidatedTextChanged, TextServerAuthRegister.ValidatedTextChanged, TextServerAuthServer.ValidatedTextChanged, TextArgumentTitle.ValidatedTextChanged, TextAdvanceRun.ValidatedTextChanged
If AniControlEnabled = 0 Then
Dim HandledText As String = sender.Text
If sender.Tag = "VersionServerAuthServer" OrElse sender.Tag = "VersionServerAuthRegister" Then HandledText = HandledText.TrimEnd("/")
@@ -118,6 +124,9 @@
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboArgumentIndie.SelectionChanged, ComboAdvanceAssets.SelectionChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex, Version:=PageVersionLeft.Version)
End Sub
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckAdvanceRunWait.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked, Version:=PageVersionLeft.Version)
End Sub
#Region "游戏内存"
@@ -469,4 +478,12 @@ PreFin:
#End Region
#Region "高级设置"
Private Sub TextAdvanceRun_TextChanged(sender As Object, e As TextChangedEventArgs) Handles TextAdvanceRun.TextChanged
CheckAdvanceRunWait.Visibility = If(TextAdvanceRun.Text = "", Visibility.Collapsed, Visibility.Visible)
End Sub
#End Region
End Class
@@ -100,7 +100,7 @@
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Snapshot|AnyCPU'">
<OutputPath>D:\Minecraft\</OutputPath>
<OutputPath>D:\Minecraft\程序\</OutputPath>
<DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile>
<Optimize>true</Optimize>
<WarningLevel>1</WarningLevel>
@@ -119,6 +119,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet>BasicDesignGuidelineRules.ruleset</CodeAnalysisRuleSet>
<DefineConstants>BETA</DefineConstants>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
+4 -4
View File
@@ -18,9 +18,9 @@
<StackPanel Margin="25,40,23,15">
<local:MyHint Text="local:MyHint 代表提示条,它默认是警告样式。" />
<local:MyHint Margin="0,8,0,2" IsWarn="False"
Text="将提示条的 IsWarn 属性改为 False 即可改为提示样式。&#xA;使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
Text="将提示条的 IsWarn 属性改为 False 即可改为提示样式。&#xa;使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
<TextBlock Margin="0,6,0,0"
Text="卡片(local:MyCard)的 Title 属性决定了它的标题。&#xA;为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
Text="卡片(local:MyCard)的 Title 属性决定了它的标题。&#xa;为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
</StackPanel>
</local:MyCard>
@@ -90,7 +90,7 @@
<TextBlock Margin="0,4,0,0"
Text="就像为游戏指定服务器 IP 一样,你也可以在 EventData 的竖线后为程序添加启动参数。" />
<local:MyButton Margin="0,8,0,0" Width="200" Height="35"
Text="定位游戏启动脚本" EventType="打开文件" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL2 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。&#xA;点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
Text="定位游戏启动脚本" EventType="打开文件" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL2 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。&#xa;点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
</StackPanel>
</local:MyCard>
@@ -216,7 +216,7 @@ Image(图片):
- Source:要显示的图片的网址
local:MyHint(提示条):
- Text:设置显示的文本(&#xA; 代表换行)
- Text:设置显示的文本(&#xa; 代表换行)
- IsWarn:设置为 True 代表警告样式,False 代表提示样式
local:MyButton(按钮):
Binary file not shown.
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.