Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2b282c8db | ||
|
|
48214557da | ||
|
|
06b50fa74c | ||
|
|
7cab6b281a | ||
|
|
c28f05aae1 | ||
|
|
f11aedef5d | ||
|
|
63e002780a | ||
|
|
8e5362e2df | ||
|
|
3129edd09f | ||
|
|
45a9bf1096 | ||
|
|
bef94fa743 | ||
|
|
fd329037e7 | ||
|
|
5fb5a3b963 | ||
|
|
5ef1d60e2e | ||
|
|
d091e153a9 |
No files matched your search
@@ -3,9 +3,6 @@ contact_links:
|
||||
- name: 帮助文档反馈
|
||||
url: https://github.com/LTCatt/PCL2Help/issues
|
||||
about: 提交 PCL2 帮助系统(更多 → 帮助)相关的反馈
|
||||
- name: 联机反馈与交流
|
||||
url: https://shimowendang.com/docs/KrkEVXz1K0frowAJ#anchor-7qQG
|
||||
about: 加入联机模块官方 QQ 群反馈联机异常,或询问联机功能的使用方式
|
||||
- name: 提问
|
||||
url: https://github.com/Hex-Dragon/PCL2/discussions/new?category=%E6%8F%90%E9%97%AE
|
||||
about: 我不想提交反馈,只是想问一些问题
|
||||
@@ -349,9 +349,6 @@ ModSetup.vb
|
||||
PageOtherAbout.*
|
||||
PageOtherTest.*
|
||||
PageSetupUI.*
|
||||
# 公开联机代码可能导致安全风险
|
||||
Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb
|
||||
Plain Craft Launcher 2/Pages/PageLink/PageLinkHiPer.xaml.vb
|
||||
# 开发者工具
|
||||
ModDevelop.vb
|
||||
# 不公开底层函数库,以免抄袭
|
||||
|
||||
File renamed without changes.
@@ -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">
|
||||
|
||||
@@ -15,7 +15,6 @@ Public Class Application
|
||||
Log(ex, "开发者模式测试出错", LogLevel.Feedback)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
#End If
|
||||
|
||||
'开始
|
||||
@@ -33,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
|
||||
'制作更新包
|
||||
@@ -50,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
|
||||
@@ -105,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
|
||||
@@ -127,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
|
||||
|
||||
@@ -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
|
||||
@@ -287,14 +289,15 @@
|
||||
End Class
|
||||
Partial Public Module ModAnimation
|
||||
Public Sub AniDispose(Control As MyCard, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
|
||||
If Not Control.IsHitTestVisible Then Exit Sub
|
||||
Control.IsHitTestVisible = False
|
||||
AniStart({
|
||||
If Control.IsHitTestVisible Then
|
||||
Control.IsHitTestVisible = False
|
||||
AniStart({
|
||||
AaScaleTransform(Control, -0.08, 200,, New AniEaseInFluent),
|
||||
AaOpacity(Control, -1, 200,, New AniEaseOutFluent),
|
||||
AaHeight(Control, -Control.ActualHeight, 150, 100, New AniEaseOutFluent),
|
||||
AaCode(Sub()
|
||||
If RemoveFromChildren Then
|
||||
If Control.Parent Is Nothing Then Exit Sub
|
||||
CType(Control.Parent, Object).Children.Remove(Control)
|
||||
Else
|
||||
Control.Visibility = Visibility.Collapsed
|
||||
@@ -302,5 +305,14 @@ Partial Public Module ModAnimation
|
||||
If CallBack IsNot Nothing Then CallBack(Control)
|
||||
End Sub,, True)
|
||||
}, "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
|
||||
End If
|
||||
If CallBack IsNot Nothing Then CallBack(Control)
|
||||
End If
|
||||
End Sub
|
||||
End Module
|
||||
@@ -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),
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,9 +79,10 @@
|
||||
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
|
||||
@@ -91,7 +92,7 @@
|
||||
End If
|
||||
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
|
||||
@@ -113,28 +114,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
|
||||
|
||||
@@ -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
|
||||
'触发颜色动画
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -10,6 +10,23 @@ Public Class FormMain
|
||||
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
|
||||
'统计更新日志条目
|
||||
#If BETA Then
|
||||
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 += 13
|
||||
BugCount += 23
|
||||
End If
|
||||
If LastVersion < 268 Then 'Release 2.4.2
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "暂时关闭了联机功能"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "游戏崩溃的弹窗添加了直接查看日志的选项"))
|
||||
@@ -100,6 +117,35 @@ Public Class FormMain
|
||||
'3:BUG+ IMP* FEAT-
|
||||
'2:BUG* IMP-
|
||||
'1:BUG-
|
||||
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"))
|
||||
FeatureCount += 6
|
||||
BugCount += 15
|
||||
End If
|
||||
If LastVersion < 269 Then 'Snapshot 2.4.2
|
||||
If LastVersion = 267 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法下载 CurseForge 整合包的 Bug"))
|
||||
FeatureCount += 2
|
||||
@@ -272,6 +318,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
|
||||
@@ -317,7 +364,6 @@ Public Class FormMain
|
||||
Setup.Load("UiHiddenPageDownload")
|
||||
BackgroundRefresh(False, True)
|
||||
MusicRefreshPlay(False, True)
|
||||
JavaListInit()
|
||||
'扩展按钮
|
||||
BtnExtraDownload.ShowCheck = AddressOf BtnExtraDownload_ShowCheck
|
||||
BtnExtraBack.ShowCheck = AddressOf BtnExtraBack_ShowCheck
|
||||
@@ -334,12 +380,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
|
||||
'加载窗口
|
||||
@@ -356,16 +398,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()
|
||||
@@ -384,6 +426,7 @@ Reopen:
|
||||
End Select
|
||||
End If
|
||||
Try
|
||||
JavaListInit() '延后到同意协议后再执行,避免在初次启动时进行进程操作
|
||||
Thread.Sleep(200)
|
||||
DlClientListMojangLoader.Start(1)
|
||||
RunCountSub()
|
||||
@@ -513,25 +556,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)
|
||||
@@ -544,7 +596,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
|
||||
@@ -604,7 +656,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()
|
||||
@@ -692,7 +744,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
|
||||
@@ -701,7 +753,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
|
||||
@@ -711,8 +763,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
|
||||
@@ -755,9 +807,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"}.Contains(Extension) Then
|
||||
Log("[System] 文件为 jar/litemod 格式,尝试作为 Mod 安装")
|
||||
'获取并检查目标版本
|
||||
Dim TargetVersion As McVersion = McVersionCurrent
|
||||
If PageCurrent = PageType.VersionSetup Then TargetVersion = PageVersionLeft.Version
|
||||
@@ -766,7 +819,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:
|
||||
@@ -775,9 +828,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
|
||||
@@ -790,12 +843,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
|
||||
@@ -1050,7 +1103,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
|
||||
@@ -1136,7 +1189,7 @@ Install:
|
||||
If MyMsgBox("由于联机提供商要求新联机强制付费,且高度商业化,PCL 将暂时关闭联机功能,不再使用该联机模块。" & vbCrLf &
|
||||
"PCL、HMCL、BakaXL 将合作开发新的跨启动器联机功能,在开发结束后将同步开放,请各位多多理解。",
|
||||
"联机功能已暂时关闭", "查看详情", "确定") = 1 Then
|
||||
OpenWebsite("https://www.bilibili.com/read/cv19553725")
|
||||
OpenWebsite("https://www.bilibili.com/read/cv19845645")
|
||||
End If
|
||||
e.Handled = True
|
||||
End Sub
|
||||
|
||||
@@ -10,12 +10,12 @@ Public Module ModBase
|
||||
#Region "声明"
|
||||
|
||||
'下列版本信息由更新器自动修改
|
||||
Public Const VersionBaseName As String = "2.4.2" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.4.2." & VersionBranchCode '标准格式的四段式版本号
|
||||
Public Const VersionBaseName As String = "2.4.7" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.4.7." & VersionBranchCode '标准格式的四段式版本号
|
||||
#If BETA Then
|
||||
Public Const VersionCode As Integer = 268 'Release
|
||||
Public Const VersionCode As Integer = 276 'Release
|
||||
#Else
|
||||
Public Const VersionCode As Integer = 269 'Snapshot
|
||||
Public Const VersionCode As Integer = 278 '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 获取不包含路径与扩展名的文件名。不包含文件名将会抛出异常。
|
||||
@@ -771,6 +776,8 @@ Public Module ModBase
|
||||
'还原文件路径
|
||||
If Not FromPath.Contains(":\") Then FromPath = Path & FromPath
|
||||
If Not ToPath.Contains(":\") Then ToPath = Path & ToPath
|
||||
'如果复制同一个文件则跳过
|
||||
If FromPath = ToPath Then Exit Sub
|
||||
'读取文件内容
|
||||
Dim FileBytes As Byte()
|
||||
Using ReadStream As New FileStream(FromPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) '支持读取使用中的文件
|
||||
@@ -787,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
|
||||
@@ -797,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 ""
|
||||
@@ -1221,7 +1228,7 @@ Re:
|
||||
Return Nothing
|
||||
Catch ex As Exception
|
||||
Log(ex, "检查文件出错")
|
||||
Return GetString(ex)
|
||||
Return GetExceptionSummary(ex)
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
@@ -1260,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, "删除单个文件可忽略地失败")
|
||||
@@ -1290,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
|
||||
@@ -1305,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
|
||||
@@ -1323,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>
|
||||
@@ -1897,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
|
||||
|
||||
@@ -2291,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()
|
||||
@@ -2390,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)
|
||||
@@ -2427,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)
|
||||
@@ -2451,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>
|
||||
|
||||
@@ -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
|
||||
|
||||
'崩溃报告分析
|
||||
@@ -771,11 +782,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,你可以从网络中下载、安装一个。"
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
McDownloadClientUpdateHint(Version, Json)
|
||||
IsNewClientVersionHinted = True
|
||||
End If
|
||||
McVersionHighest = Version.Split(".")(1)
|
||||
Setup.Set("ToolUpdateReleaseLast", Version)
|
||||
'解析更新提示(Snapshot)
|
||||
Version = Json("latest")("snapshot")
|
||||
@@ -609,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
|
||||
@@ -772,7 +773,7 @@
|
||||
''' </summary>
|
||||
Public IsLegacy As Boolean
|
||||
''' <summary>
|
||||
''' 发布时间,格式为“yyyy/mm/dd HH:mm:ss”。
|
||||
''' 发布时间,格式为“yyyy/mm/dd HH:mm”。
|
||||
''' </summary>
|
||||
Public ReleaseTime As String
|
||||
''' <summary>
|
||||
@@ -966,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
|
||||
@@ -1090,33 +1091,27 @@
|
||||
DateUpdate = Data("dateModified")
|
||||
DownloadCount = Data("downloadCount")
|
||||
IsModPack = Not Website.Contains("/mc-mods/")
|
||||
'获取常见文件
|
||||
'获取 Mod Loader 列表
|
||||
ModLoaders = New List(Of String)
|
||||
For Each File In If(Data("latestFiles"), {})
|
||||
Dim NewFile As New DlCfFile(File, IsModPack)
|
||||
If Not NewFile.IsAvailable Then Continue For
|
||||
ModLoaders.AddRange(NewFile.ModLoaders)
|
||||
Next
|
||||
'获取游戏版本、Mod Loader
|
||||
ModLoaders = ModLoaders.Distinct.ToList
|
||||
'用一个偷懒的方式让 Forge 排在 Fabric 的前面
|
||||
ModLoaders = ModLoaders.Select(Function(s) s.Replace("Forge", "Aorge")).ToList()
|
||||
ModLoaders.Sort()
|
||||
ModLoaders = ModLoaders.Select(Function(s) s.Replace("Aorge", "Forge")).ToList()
|
||||
'获取游戏版本
|
||||
Dim GameVersions As New List(Of Integer)
|
||||
ModLoaders = New List(Of String)
|
||||
For Each File In If(Data("latestFilesIndexes"), {})
|
||||
Dim Version As String = File("gameVersion")
|
||||
If Not Version.Contains("1.") Then Continue For
|
||||
GameVersions.Add(Version.Split(".")(1).Split("-").First)
|
||||
Select Case If(File("modLoader"), "0").ToString
|
||||
Case 1
|
||||
ModLoaders.Add("Forge")
|
||||
Case 2
|
||||
ModLoaders.Add("Cauldron")
|
||||
Case 3
|
||||
ModLoaders.Add("LiteLoader")
|
||||
Case 4
|
||||
ModLoaders.Add("Fabric")
|
||||
End Select
|
||||
FileIndexes.Add(File("fileId"))
|
||||
Next
|
||||
GameVersions = Sort(GameVersions.Distinct.ToList, AddressOf VersionSortBoolean)
|
||||
ModLoaders = ModLoaders.Distinct.ToList
|
||||
ModLoaders.Sort()
|
||||
If GameVersions.Count = 0 Then
|
||||
GameVersionDesc = ""
|
||||
Else
|
||||
@@ -1133,8 +1128,15 @@
|
||||
Next
|
||||
If StartVersion = EndVersion Then
|
||||
SpaVersions.Add("1." & StartVersion)
|
||||
ElseIf StartVersion >= McVersionHighest Then
|
||||
SpaVersions.Add("1." & EndVersion & "+")
|
||||
ElseIf EndVersion <= 7 Then
|
||||
SpaVersions.Add("1." & StartVersion & "-")
|
||||
Exit For
|
||||
ElseIf StartVersion - EndVersion = 1 Then
|
||||
SpaVersions.Add("1." & StartVersion & ", 1." & EndVersion)
|
||||
Else
|
||||
SpaVersions.Add("1." & StartVersion & "-1." & EndVersion)
|
||||
SpaVersions.Add("1." & StartVersion & "~1." & EndVersion)
|
||||
End If
|
||||
Next
|
||||
GameVersionDesc = "[" & Join(SpaVersions, ", ") & "] "
|
||||
@@ -1211,12 +1213,11 @@
|
||||
Dim NewItem As New MyCfItem With {.Tag = Me}
|
||||
NewItem.LabTitle.Text = ChineseName
|
||||
NewItem.LabInfo.Text = Description.Replace(vbCr, "").Replace(vbLf, "")
|
||||
NewItem.LabLeft.Text = If(ModLoaders.Count > 0 AndAlso ShowLoaderDesc, "[" & Join(ModLoaders, " & ") & "] ", "") &
|
||||
If(ShowVersionDesc, GameVersionDesc, "") &
|
||||
NewItem.LabLeft.Text = (If(ModLoaders.Count > 0 AndAlso ShowLoaderDesc, "[" & Join(ModLoaders, "/") & "] ", "") &
|
||||
If(ShowVersionDesc, GameVersionDesc, "")).Replace("] [", " ") &
|
||||
Join(CategoryDesc, ",") & " (" &
|
||||
GetTimeSpanString(DateUpdate - Date.Now) & "更新" &
|
||||
If(DownloadCount > 0,
|
||||
"," & If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载", DownloadCount & " 次下载"), "") & ")"
|
||||
GetTimeSpanString(DateUpdate - Date.Now) & "更新," &
|
||||
If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载", DownloadCount & " 次下载") & ")"
|
||||
If Thumb Is Nothing Then
|
||||
NewItem.Logo = "pack://application:,,,/images/Icons/NoIcon.png"
|
||||
Else
|
||||
@@ -1253,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
|
||||
@@ -1263,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)
|
||||
}
|
||||
@@ -1277,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("|").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 ]*)")
|
||||
@@ -1300,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)
|
||||
@@ -1380,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.Add(Entry.CurseForgeId, Entry)
|
||||
Next
|
||||
Next
|
||||
End Sub
|
||||
Public Class DlCfDbEntry
|
||||
@@ -1400,9 +1416,9 @@
|
||||
''' </summary>
|
||||
Public WikiId As Integer
|
||||
''' <summary>
|
||||
''' 中文译名。若为 Nothing 或空字符串则使用英文名。
|
||||
''' 中文译名。若为空字符串则使用英文名。
|
||||
''' </summary>
|
||||
Public ChineseName As String
|
||||
Public ChineseName As String = ""
|
||||
''' <summary>
|
||||
''' MCBBS 发布帖编号(例如 195107)。若为 Nothing 则没有发布帖。
|
||||
''' </summary>
|
||||
@@ -1432,6 +1448,7 @@
|
||||
Public DisplayName As String
|
||||
Public [Date] As Date
|
||||
Public GameVersion As String()
|
||||
Public ModLoaders As New List(Of String)
|
||||
Public ReleaseType As Integer
|
||||
Public FileName As String
|
||||
Public DownloadCount As Integer
|
||||
@@ -1481,11 +1498,13 @@
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
'获取游戏版本
|
||||
'获取游戏版本与 Mod 加载器列表
|
||||
Dim Versions As New List(Of String)
|
||||
For Each Version In Data("gameVersions")
|
||||
If Version.ToString.StartsWith("1.") OrElse Version.ToString.Contains("w") Then
|
||||
Versions.Add(Version.ToString.Trim.ToLower)
|
||||
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.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
|
||||
Next
|
||||
If Versions.Count > 1 Then
|
||||
@@ -1493,11 +1512,13 @@
|
||||
If IsModPack Then GameVersion = {GameVersion(0)}
|
||||
ElseIf Versions.Count = 1 Then
|
||||
GameVersion = Versions.ToArray
|
||||
'ElseIf Data("gameVersion").Count = 1 AndAlso Not Data("gameVersion")(0).ToString.Contains("1.") Then
|
||||
' GameVersion = {"1.16.4"}
|
||||
Else
|
||||
GameVersion = {"未知版本"}
|
||||
End If
|
||||
'用一个偷懒的方式让 Forge 排在 Fabric 的前面
|
||||
ModLoaders = ModLoaders.Select(Function(s) s.Replace("Forge", "Aorge")).ToList()
|
||||
ModLoaders.Sort()
|
||||
ModLoaders = ModLoaders.Select(Function(s) s.Replace("Aorge", "Forge")).ToList()
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
@@ -1513,10 +1534,14 @@
|
||||
'获取描述信息
|
||||
Dim Info As String = ""
|
||||
If Not IsModPack Then
|
||||
Info += "适用于 " & Join(GameVersion, "、").Replace("-snapshot", " 快照") &
|
||||
If(ModeDebug AndAlso Dependencies.Count > 0, "," & Dependencies.Count & " 个前置,", ",")
|
||||
Info += If(ModLoaders.Count > 0, Join(ModLoaders, "/"), "") &
|
||||
If(GameVersion.Count > 1, If(ModLoaders.Count > 0, " ", "") & Join(GameVersion, "、").Replace("-snapshot", " 快照"), "")
|
||||
If Info <> "" Then Info = "适用于 " & Info & ","
|
||||
Info += If(ModeDebug AndAlso Dependencies.Count > 0, Dependencies.Count & " 个前置 Mod,", "")
|
||||
End If
|
||||
Info += If(DownloadCount > 0, If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载,", DownloadCount & " 次下载,"), "")
|
||||
'If DownloadCount > 0 Then 'DownloadCount 目前的返回内容完全不正确,经常是 0,干脆不显示了
|
||||
' Info += If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载,", DownloadCount & " 次下载,")
|
||||
'End If
|
||||
Info += GetTimeSpanString([Date] - Date.Now) & "更新"
|
||||
Info += If(ReleaseType <> 1, "," & ReleaseTypeString, "")
|
||||
|
||||
@@ -1638,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,74 @@ 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)
|
||||
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 +80,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 +106,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 +117,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 +131,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 +147,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 +155,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 +167,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,10 +180,11 @@ 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)
|
||||
@@ -492,7 +557,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 +572,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 +581,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 +664,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 +672,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 +802,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 +849,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 +1012,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 +1036,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 +1145,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
|
||||
@@ -1078,20 +1155,34 @@ SystemBrowser:
|
||||
MaxVer = New Version(1, 12, 999, 999)
|
||||
End If
|
||||
|
||||
'OptiFine 检测
|
||||
If McVersionCurrent.Version.HasOptiFine Then
|
||||
If McVersionCurrent.Version.McCodeMain <= 7 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then
|
||||
'<1.7:至多 Java 8(Java 9 - 10 未测试)
|
||||
MaxVer = New Version(1, 8, 999, 999)
|
||||
ElseIf McVersionCurrent.Version.McCodeMain >= 8 AndAlso McVersionCurrent.Version.McCodeMain <= 11 Then
|
||||
'1.8 - 1.11:必须恰好 Java 8(Java 9 - 10 未测试)
|
||||
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 8, 999, 999)
|
||||
End If
|
||||
End If
|
||||
|
||||
'Forge 检测
|
||||
If McVersionCurrent.Version.HasForge Then
|
||||
If McVersionCurrent.Version.McName = "1.7.2" Then
|
||||
'1.7.2:必须 Java 7
|
||||
MinVer = New Version(1, 7, 0, 0) : MaxVer = New Version(1, 7, 999, 999)
|
||||
ElseIf McVersionCurrent.Version.McCodeMain <= 12 AndAlso McVersionCurrent.Version.McCodeMain > 0 AndAlso VersionSortBoolean("14.23.5.2855", McVersionCurrent.Version.ForgeVersion) Then
|
||||
'1.12,Forge 14.23.5.2855 及更低:Java 8
|
||||
'<1.12,Forge 14.23.5.2855 及更低:Java 8
|
||||
MaxVer = New Version(1, 8, 999, 999)
|
||||
ElseIf McVersionCurrent.Version.McCodeMain <= 14 AndAlso McVersionCurrent.Version.McCodeMain > 0 AndAlso VersionSortBoolean("28.2.23", McVersionCurrent.Version.ForgeVersion) Then
|
||||
'1.13 - 1.14,Forge 28.2.23 及更低:Java 8 - 10
|
||||
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 10, 999, 999)
|
||||
ElseIf McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then
|
||||
'1.15 - 1.16:Java 8 - 15
|
||||
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)
|
||||
@@ -1101,30 +1192,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 - 15
|
||||
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 15, 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
|
||||
@@ -1150,24 +1242,28 @@ SystemBrowser:
|
||||
Private McLaunchArgument As String
|
||||
|
||||
''' <summary>
|
||||
''' 释放 Java Wrapper 并返回文件路径。
|
||||
''' 释放 Java Wrapper 并返回完整文件路径。
|
||||
''' </summary>
|
||||
Public Function ExtractJavaWrapper() As String
|
||||
Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar"
|
||||
If Encoding.UTF8.GetByteCount(WrapperPath) <> WrapperPath.Length Then
|
||||
Log("[Java] AppData 路径中包含非 ASCII 字符,换用 Temp 目录")
|
||||
WrapperPath = PathTemp & "JavaWrapper.jar"
|
||||
If Encoding.UTF8.GetByteCount(PathTemp) <> PathTemp.Length Then
|
||||
Log("[Java] Temp 路径中包含非 ASCII 字符,换用 C 盘根目录")
|
||||
WrapperPath = "C:\PCL\JavaWrapper.jar"
|
||||
End If
|
||||
End If
|
||||
If Not File.Exists(WrapperPath) OrElse New FileInfo(WrapperPath).Length > 20 * 1024 Then
|
||||
WriteFile(WrapperPath, GetResources("JavaWrapper"))
|
||||
Log("[Java] 已自动释放 Java Wrapper:" & WrapperPath)
|
||||
End If
|
||||
Dim WrapperPath As String = GetJavaWrapperDir() & "\JavaWrapper.jar"
|
||||
WriteFile(WrapperPath, GetResources("JavaWrapper"))
|
||||
Log("[Java] 已释放 Java Wrapper:" & WrapperPath)
|
||||
Return WrapperPath
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 获取 Java Wrapper 所在的文件夹,不以 \ 结尾。
|
||||
''' </summary>
|
||||
Public Function GetJavaWrapperDir() As String
|
||||
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
|
||||
End Function
|
||||
|
||||
'主方法,合并 Jvm、Game、Replace 三部分的参数数据
|
||||
Private Sub McLaunchArgumentMain(Loader As LoaderTask(Of String, List(Of McLibToken)))
|
||||
@@ -1185,7 +1281,7 @@ SystemBrowser:
|
||||
McLaunchLog("旧版 JVM 参数获取成功:")
|
||||
McLaunchLog(Arguments)
|
||||
End If
|
||||
If McVersionCurrent.JsonObject("minecraftArguments") IsNot Nothing Then
|
||||
If Not String.IsNullOrEmpty(McVersionCurrent.JsonObject("minecraftArguments")) Then '有的版本是空字符串
|
||||
McLaunchLog("获取旧版 Game 参数")
|
||||
Arguments += " " & McLaunchArgumentsGameOld(McVersionCurrent)
|
||||
McLaunchLog("旧版 Game 参数获取成功")
|
||||
@@ -1210,7 +1306,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
|
||||
'包含端口号
|
||||
@@ -1270,6 +1366,7 @@ SystemBrowser:
|
||||
|
||||
'添加 Java Wrapper 作为主 Jar
|
||||
If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED")
|
||||
DataList.Insert(0, "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """")
|
||||
DataList.Add("-jar """ & ExtractJavaWrapper() & """")
|
||||
|
||||
'添加 MainClass
|
||||
@@ -1336,6 +1433,7 @@ NextVersion:
|
||||
|
||||
'添加 Java Wrapper 作为主 Jar
|
||||
If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED")
|
||||
DataList.Insert(0, "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """")
|
||||
DataList.Add("-jar """ & ExtractJavaWrapper() & """")
|
||||
|
||||
'将 "-XXX" 与后面 "XXX" 合并到一起
|
||||
@@ -1502,9 +1600,7 @@ NextVersion:
|
||||
GameArguments.Add("${assets_index_name}", McAssetsGetIndexName(Version))
|
||||
|
||||
'支持库参数
|
||||
'Dim LibList As List(Of McLibToken) = McLibListGet(Version,
|
||||
' Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17)) '包含版本 Jar 的条件是不为 1.17+ 的 Forge
|
||||
Dim LibList As List(Of McLibToken) = McLibListGet(Version, True) '如果在 1.19.x Forge 不包含版本 Jar 会导致 #188
|
||||
Dim LibList As List(Of McLibToken) = McLibListGet(Version, True)
|
||||
Loader.Output = LibList
|
||||
Dim CpStrings As New List(Of String)
|
||||
Dim OptiFineCp As String = Nothing
|
||||
@@ -1561,7 +1657,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
|
||||
@@ -1581,7 +1677,7 @@ NextVersion:
|
||||
File.Delete(FileName)
|
||||
Catch ex As UnauthorizedAccessException
|
||||
McLaunchLog("删除多余文件访问被拒绝,跳过删除步骤")
|
||||
McLaunchLog("实际的错误信息:" & GetString(ex))
|
||||
McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
|
||||
Exit Sub
|
||||
End Try
|
||||
Next
|
||||
@@ -1739,9 +1835,13 @@ NextVersion:
|
||||
PackFormat = 9
|
||||
End If
|
||||
Case 19
|
||||
PackFormat = 9
|
||||
If McVersionCurrent.Version.McCodeSub <= 2 Then
|
||||
PackFormat = 9
|
||||
Else
|
||||
PackFormat = 12
|
||||
End If
|
||||
Case Else
|
||||
PackFormat = 10
|
||||
PackFormat = 13
|
||||
End Select
|
||||
McLaunchLog("正在构建自定义皮肤资源包,格式为:" & PackFormat)
|
||||
'准备文件
|
||||
@@ -1811,6 +1911,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"), 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))
|
||||
|
||||
@@ -1843,22 +1997,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 '可能在启动游戏进程的同时刚好取消了启动
|
||||
@@ -1952,6 +2090,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
|
||||
@@ -2327,13 +2383,16 @@ NextVersion:
|
||||
Dim RealVersion As McVersion
|
||||
Dim RequiredJar As String = Version.JsonObject("jar")?.ToString
|
||||
If Version.IsHmclFormatJson OrElse RequiredJar Is Nothing Then
|
||||
'HMCL 项直接使用自身的 Jar
|
||||
'根据 Inherit 获取最深层版本
|
||||
'此外,HMCL 项直接使用自身的 Jar
|
||||
Dim OriginalVersion As McVersion = Version
|
||||
Do Until OriginalVersion.InheritVersion = ""
|
||||
If OriginalVersion.InheritVersion = OriginalVersion.Name Then Exit Do
|
||||
OriginalVersion = New McVersion(PathMcFolder & "versions\" & OriginalVersion.InheritVersion & "\")
|
||||
Loop
|
||||
'1.17+ 的 Forge 不寻找 Inherit
|
||||
If Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17) Then
|
||||
Do Until OriginalVersion.InheritVersion = ""
|
||||
If OriginalVersion.InheritVersion = OriginalVersion.Name Then Exit Do
|
||||
OriginalVersion = New McVersion(PathMcFolder & "versions\" & OriginalVersion.InheritVersion & "\")
|
||||
Loop
|
||||
End If
|
||||
'需要新建对象,否则后面的 Check 会导致 McVersionCurrent 的 State 变回 Original
|
||||
'复现:启动一个 Snapshot 版本
|
||||
RealVersion = New McVersion(OriginalVersion.Path)
|
||||
@@ -2380,6 +2439,11 @@ NextVersion:
|
||||
'转换为 LibToken
|
||||
For Each Library As JObject In AllLibs.Children
|
||||
|
||||
'清理 null 项(BakaXL 会把没有的项序列化为 null,但会被 Newtonsoft 转换为 JValue,导致 Is Nothing = false;这导致了 #409)
|
||||
For i = Library.Properties.Count - 1 To 0 Step -1
|
||||
If Library.Properties(i).Value.Type = JTokenType.Null Then Library.Remove(Library.Properties(i).Name)
|
||||
Next
|
||||
|
||||
'检查是否需要(Rules)
|
||||
If Not McJsonRuleCheck(Library("rules")) Then Continue For
|
||||
|
||||
@@ -2769,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, "获取版本缺失的资源文件下载列表失败")
|
||||
@@ -3494,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
|
||||
@@ -3653,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
|
||||
@@ -3713,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
|
||||
@@ -3729,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
|
||||
'两边均缺失,感觉是一个东西
|
||||
@@ -3812,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
|
||||
@@ -241,8 +241,17 @@ Retry:
|
||||
For Each ModJson In Task.Input
|
||||
'跳过重复的 Mod(疑似 CurseForge Bug)
|
||||
If FileList.ContainsKey(ModJson("id").ToObject(Of Integer)) Then Continue For
|
||||
'根据 modules 判断是资源包还是 Mod
|
||||
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 & "\mods\", False))
|
||||
FileList.Add(ModJson("id"), New DlCfFile(ModJson, False).GetDownloadFile(
|
||||
PathMcFolder & "versions\" & VersionName & "\" & If(IsResourcePack, "resourcepacks", "mods") & "\", False))
|
||||
Task.Progress += 1 / (1 + ModFileList.Count)
|
||||
Next
|
||||
Task.Output = FileList.Values.ToList
|
||||
@@ -276,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)
|
||||
@@ -300,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
|
||||
@@ -316,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)
|
||||
@@ -345,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) & "\"
|
||||
@@ -357,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
|
||||
@@ -441,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) & "\"
|
||||
@@ -453,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
|
||||
@@ -529,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) & "\"
|
||||
@@ -541,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
|
||||
@@ -612,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()
|
||||
|
||||
@@ -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 是否为最新版本。", "事件执行失败")
|
||||
|
||||
@@ -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.2.0")>
|
||||
<Assembly: AssemblyFileVersion("2.4.2.0")>
|
||||
<Assembly: AssemblyVersion("2.4.7.0")>
|
||||
<Assembly: AssemblyFileVersion("2.4.7.0")>
|
||||
<Assembly: NeutralResourcesLanguage("")>
|
||||
@@ -1,8 +1,15 @@
|
||||
Imports System.IO.Compression
|
||||
|
||||
Public Module ModDownloadLib
|
||||
'如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败
|
||||
|
||||
''' <summary>
|
||||
''' 如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败,所以在这里添加一个锁。
|
||||
''' </summary>
|
||||
Private InstallSyncLock As New Object
|
||||
''' <summary>
|
||||
''' 最高的 Minecraft 大版本号,-1 代表尚未获取。
|
||||
''' </summary>
|
||||
Public McVersionHighest As Integer = -1
|
||||
|
||||
#Region "Minecraft 下载"
|
||||
|
||||
@@ -114,7 +121,7 @@ Public Module ModDownloadLib
|
||||
Task.Output = New List(Of NetFile) From {New NetFile(DlSourceLauncherOrMetaGet(JsonAddress), VersionFolder & VersionName & ".json")}
|
||||
End Sub) With {.ProgressWeight = 2, .Show = False})
|
||||
End If
|
||||
Loaders.Add(New LoaderDownload("下载原版 Json 文件", New List(Of NetFile) From {
|
||||
Loaders.Add(New LoaderDownload(McDownloadClientJsonName, New List(Of NetFile) From {
|
||||
New NetFile(DlSourceLauncherOrMetaGet(If(JsonUrl, "")), VersionFolder & VersionName & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True))
|
||||
}) With {.ProgressWeight = 3})
|
||||
|
||||
@@ -159,6 +166,7 @@ Public Module ModDownloadLib
|
||||
|
||||
End Function
|
||||
Private Const McDownloadClientLibName As String = "下载原版支持库文件"
|
||||
Private Const McDownloadClientJsonName As String = "下载原版 Json 文件"
|
||||
|
||||
#End Region
|
||||
|
||||
@@ -372,13 +380,13 @@ 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")
|
||||
End If
|
||||
'添加 Java Wrapper 作为主 Jar
|
||||
Dim Arguments = "-Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & ExtractJavaWrapper() & """ optifine.Installer"
|
||||
Dim Arguments = "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """ -Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & ExtractJavaWrapper() & """ optifine.Installer"
|
||||
If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments
|
||||
'开始启动
|
||||
SyncLock InstallSyncLock
|
||||
@@ -518,27 +526,28 @@ Public Module ModDownloadLib
|
||||
Loaders.Add(New LoaderDownload("下载 OptiFine 主文件", New List(Of NetFile)) With {.ProgressWeight = 8})
|
||||
Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("等待原版下载",
|
||||
Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
||||
'是否已经存在原版文件
|
||||
If ClientDownloadLoader Is Nothing Then Exit Sub
|
||||
'等待原版文件下载完成
|
||||
For Each Loader In ClientDownloadLoader.GetLoaderList
|
||||
If Loader.Name <> McDownloadClientLibName Then Continue For
|
||||
If Loader.State = LoadState.Loading Then
|
||||
Log("[Download] OptiFine 安装正在等待原版文件下载完成")
|
||||
Loader.WaitForExit()
|
||||
End If
|
||||
Exit For
|
||||
Next
|
||||
If ClientDownloadLoader Is Nothing Then Exit Sub
|
||||
Dim TargetLoaders As List(Of LoaderBase) =
|
||||
ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
|
||||
Where(Function(l) l.State <> LoadState.Finished).ToList
|
||||
If TargetLoaders.Count > 0 Then Log("[Download] OptiFine 安装正在等待原版文件下载完成")
|
||||
Do While TargetLoaders.Count > 0 AndAlso Not Task.IsAborted
|
||||
TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
|
||||
Thread.Sleep(50)
|
||||
Loop
|
||||
If Task.IsAborted Then Exit Sub
|
||||
'拷贝原版文件
|
||||
If IsCustomFolder Then
|
||||
Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
|
||||
Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit)
|
||||
If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json")
|
||||
End If
|
||||
If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar")
|
||||
End If
|
||||
If Not IsCustomFolder Then Exit Sub
|
||||
Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
|
||||
Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit)
|
||||
If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".json",
|
||||
McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json")
|
||||
End If
|
||||
If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".jar",
|
||||
McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar")
|
||||
End If
|
||||
End Sub) With {.ProgressWeight = 0.1, .Show = False})
|
||||
|
||||
@@ -554,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")
|
||||
@@ -566,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)
|
||||
@@ -876,8 +885,8 @@ Public Module ModDownloadLib
|
||||
'构造版本 Json
|
||||
Dim VersionJson As New JObject
|
||||
VersionJson.Add("id", VersionName)
|
||||
VersionJson.Add("time", DateTime.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm:ss", Globalization.CultureInfo.CurrentCulture))
|
||||
VersionJson.Add("releaseTime", DateTime.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm:ss", Globalization.CultureInfo.CurrentCulture))
|
||||
VersionJson.Add("time", Date.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm", Globalization.CultureInfo.CurrentCulture))
|
||||
VersionJson.Add("releaseTime", Date.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm", Globalization.CultureInfo.CurrentCulture))
|
||||
VersionJson.Add("type", "release")
|
||||
VersionJson.Add("arguments", GetJson("{""game"":[""--tweakClass"",""" & DownloadInfo.JsonToken("tweakClass").ToString & """]}"))
|
||||
VersionJson.Add("libraries", DownloadInfo.JsonToken("libraries"))
|
||||
@@ -1088,13 +1097,13 @@ 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")
|
||||
End If
|
||||
'添加 Java Wrapper 作为主 Jar
|
||||
Dim Arguments = "-cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & ExtractJavaWrapper() & """ com.bangbang93.ForgeInstaller """ & McFolder
|
||||
Dim Arguments = "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """ -cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & ExtractJavaWrapper() & """ com.bangbang93.ForgeInstaller """ & McFolder
|
||||
If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments
|
||||
'开始启动
|
||||
SyncLock InstallSyncLock
|
||||
@@ -1166,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
|
||||
@@ -1329,27 +1343,26 @@ Public Module ModDownloadLib
|
||||
End If
|
||||
#End Region
|
||||
#Region "原版文件"
|
||||
'是否已经存在原版文件
|
||||
If ClientDownloadLoader Is Nothing Then Exit Sub
|
||||
'等待原版文件下载完成
|
||||
For Each Loader In ClientDownloadLoader.GetLoaderList
|
||||
If Loader.Name <> McDownloadClientLibName Then Continue For
|
||||
If Loader.State = LoadState.Loading Then
|
||||
Log("[Download] Forge 安装正在等待原版文件下载完成")
|
||||
Loader.WaitForExit()
|
||||
End If
|
||||
Exit For
|
||||
Next
|
||||
If ClientDownloadLoader Is Nothing Then Exit Sub
|
||||
Dim TargetLoaders As List(Of LoaderBase) =
|
||||
ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
|
||||
Where(Function(l) l.State <> LoadState.Finished).ToList
|
||||
If TargetLoaders.Count > 0 Then Log("[Download] Forge 安装正在等待原版文件下载完成")
|
||||
Do While TargetLoaders.Count > 0 AndAlso Not Task.IsAborted
|
||||
TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
|
||||
Thread.Sleep(50)
|
||||
Loop
|
||||
If Task.IsAborted Then Exit Sub
|
||||
'拷贝原版文件
|
||||
If IsCustomFolder Then
|
||||
Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
|
||||
Directory.CreateDirectory(McFolder & "versions\" & Inherit)
|
||||
If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".json") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & Inherit & "\" & Inherit & ".json")
|
||||
End If
|
||||
If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & Inherit & "\" & Inherit & ".jar")
|
||||
End If
|
||||
If Not IsCustomFolder Then Exit Sub
|
||||
Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name
|
||||
Directory.CreateDirectory(McFolder & "versions\" & Inherit)
|
||||
If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".json") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & Inherit & "\" & Inherit & ".json")
|
||||
End If
|
||||
If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") Then
|
||||
CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & Inherit & "\" & Inherit & ".jar")
|
||||
End If
|
||||
#End Region
|
||||
End Sub) With {.ProgressWeight = 0.1, .Show = False})
|
||||
@@ -1396,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
|
||||
@@ -1427,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
|
||||
'旧版格式
|
||||
@@ -1450,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 清理文件时出错")
|
||||
@@ -1814,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
|
||||
@@ -1831,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
|
||||
@@ -1881,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
|
||||
@@ -1894,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,
|
||||
@@ -1973,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
|
||||
@@ -192,63 +194,124 @@
|
||||
End Try
|
||||
End Sub
|
||||
'Mod 下载;整合包另存为
|
||||
Public Shared DownloadFolder = Nothing '仅在本次缓存的下载文件夹
|
||||
Public Shared CachedFolder As String = Nothing '仅在本次缓存的下载文件夹
|
||||
Public Sub Save_Click(sender As Object, e As EventArgs)
|
||||
Try
|
||||
Dim Desc As String = If(Project.IsModPack, "整合包", "Mod ")
|
||||
|
||||
'确认默认保存位置
|
||||
Dim DefaultFolder As String = Nothing
|
||||
If Not Project.IsModPack Then
|
||||
DefaultFolder = DownloadFolder
|
||||
If McVersionCurrent IsNot Nothing Then
|
||||
If Not McVersionCurrent.IsLoaded Then McVersionCurrent.Load()
|
||||
If McVersionCurrent.Modable Then
|
||||
Dim File As DlCfFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag
|
||||
RunInNewThread(
|
||||
Sub()
|
||||
Try
|
||||
Dim Desc As String = If(Project.IsModPack, "整合包", "Mod ")
|
||||
'确认默认保存位置
|
||||
Dim DefaultFolder As String = Nothing
|
||||
If Not Project.IsModPack Then
|
||||
'获取 Mod 所需的加载器种类
|
||||
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
|
||||
If LoaderType = "Forge" Then AllowForge = True
|
||||
If LoaderType = "Fabric" Then AllowFabric = True
|
||||
Next
|
||||
ElseIf Project.ModLoaders.Count > 0 Then '从工程中获取
|
||||
AllowForge = False : AllowFabric = False
|
||||
For Each LoaderType In Project.ModLoaders
|
||||
If LoaderType = "Forge" Then AllowForge = True
|
||||
If LoaderType = "Fabric" Then AllowFabric = True
|
||||
Next
|
||||
End If
|
||||
If AllowForge IsNot Nothing AndAlso Not AllowForge AndAlso
|
||||
AllowFabric IsNot Nothing AndAlso Not AllowFabric Then
|
||||
AllowForge = Nothing : AllowFabric = Nothing
|
||||
End If
|
||||
Log("[Download] 允许 Forge:" & If(AllowForge, "未知") & ",允许 Fabric:" & If(AllowFabric, "未知"))
|
||||
'判断某个版本是否符合要求
|
||||
Dim IsVersionSuitable As Func(Of McVersion, Boolean) =
|
||||
Function(Version)
|
||||
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.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
|
||||
Return False
|
||||
End Function
|
||||
'获取 Mod 默认下载位置
|
||||
If CachedFolder IsNot Nothing Then
|
||||
DefaultFolder = CachedFolder
|
||||
Log("[Download] 使用上次下载时的文件夹作为默认下载位置")
|
||||
ElseIf McVersionCurrent IsNot Nothing AndAlso IsVersionSuitable(McVersionCurrent) Then
|
||||
DefaultFolder = McVersionCurrent.PathIndie & "mods\"
|
||||
Directory.CreateDirectory(DefaultFolder)
|
||||
Log("[Download] 使用当前版本的 mods 文件夹作为默认下载位置(" & McVersionCurrent.Name & ")")
|
||||
Else
|
||||
Dim NeedLoad As Boolean = McVersionListLoader.State <> LoadState.Finished
|
||||
If NeedLoad Then
|
||||
Hint("正在查找适合的游戏版本……")
|
||||
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True)
|
||||
End If
|
||||
Dim SuitableVersions As New List(Of McVersion)
|
||||
For Each Version As McVersion In McVersionList.Values.SelectMany(Function(l) l)
|
||||
If IsVersionSuitable(Version) Then SuitableVersions.Add(Version)
|
||||
Next
|
||||
If SuitableVersions.Count = 0 Then
|
||||
DefaultFolder = PathMcFolder
|
||||
If NeedLoad Then
|
||||
Hint("当前 MC 文件夹中没有找到适合这个 Mod 的版本!")
|
||||
Else
|
||||
Log("[Download] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置")
|
||||
End If
|
||||
Else '选择 Mod 数量最多的版本
|
||||
Dim SelectedVersion = SuitableVersions.OrderBy(Function(v)
|
||||
Dim Info As New DirectoryInfo(v.PathIndie & "mods\")
|
||||
Return If(Info.Exists, Info.GetFiles().Length, -1)
|
||||
End Function).LastOrDefault()
|
||||
DefaultFolder = SelectedVersion.PathIndie & "mods\"
|
||||
Directory.CreateDirectory(DefaultFolder)
|
||||
Log("[Download] 使用适合的游戏版本作为默认下载位置(" & SelectedVersion.Name & ")")
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
If String.IsNullOrEmpty(DefaultFolder) Then DefaultFolder = Nothing
|
||||
End If
|
||||
|
||||
'获取基本信息
|
||||
Dim File As DlCfFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag
|
||||
Dim ChineseName As String = If(Project.ChineseName = Project.Name, "",
|
||||
Project.ChineseName.Replace(" (", "Å").Split("Å").First.Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":"))
|
||||
Dim FileName As String
|
||||
Select Case Setup.Get("ToolDownloadTranslate")
|
||||
Case 0
|
||||
FileName = If(ChineseName = "", "", "[" & ChineseName & "] ") & File.FileName
|
||||
Case 1
|
||||
FileName = If(ChineseName = "", "", ChineseName & "-") & File.FileName
|
||||
Case 2
|
||||
FileName = File.FileName & If(ChineseName = "", "", "-" & ChineseName)
|
||||
Case Else
|
||||
FileName = File.FileName
|
||||
End Select
|
||||
Dim Target As String
|
||||
If File.FileName.EndsWith(".litemod") Then
|
||||
Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.litemod"), DefaultFolder)
|
||||
Else
|
||||
Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.jar"), DefaultFolder)
|
||||
End If
|
||||
If Not Target.Contains("\") Then Exit Sub
|
||||
Dim LoaderName As String = Desc & "下载:" & File.DisplayName & " "
|
||||
If Target <> DefaultFolder AndAlso Not Project.IsModPack Then DownloadFolder = GetPathFromFullPath(Target)
|
||||
|
||||
'构造步骤加载器
|
||||
Dim Loaders As New List(Of LoaderBase)
|
||||
Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 6, .Block = True})
|
||||
|
||||
'启动
|
||||
Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
||||
Loader.Start(1)
|
||||
LoaderTaskbarAdd(Loader)
|
||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||
FrmMain.BtnExtraDownload.Ribble()
|
||||
Catch ex As Exception
|
||||
Log(ex, "保存 CurseForge 文件失败", LogLevel.Feedback)
|
||||
End Try
|
||||
'获取基本信息
|
||||
Dim ChineseName As String = If(Project.ChineseName = Project.Name, "",
|
||||
Project.ChineseName.Replace(" (", "Å").Split("Å").First.Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":"))
|
||||
Dim FileName As String
|
||||
Select Case Setup.Get("ToolDownloadTranslate")
|
||||
Case 0
|
||||
FileName = If(ChineseName = "", "", "[" & ChineseName & "] ") & File.FileName
|
||||
Case 1
|
||||
FileName = If(ChineseName = "", "", ChineseName & "-") & File.FileName
|
||||
Case 2
|
||||
FileName = File.FileName & If(ChineseName = "", "", "-" & ChineseName)
|
||||
Case Else
|
||||
FileName = File.FileName
|
||||
End Select
|
||||
RunInUi(
|
||||
Sub()
|
||||
'弹窗要求选择保存位置
|
||||
Dim Target As String
|
||||
If File.FileName.EndsWith(".litemod") Then
|
||||
Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.litemod"), DefaultFolder)
|
||||
Else
|
||||
Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.jar"), DefaultFolder)
|
||||
End If
|
||||
If Not Target.Contains("\") Then Exit Sub
|
||||
'构造步骤加载器
|
||||
Dim LoaderName As String = Desc & "下载:" & File.DisplayName & " "
|
||||
If Target <> DefaultFolder AndAlso Not Project.IsModPack Then CachedFolder = GetPathFromFullPath(Target)
|
||||
Dim Loaders As New List(Of LoaderBase)
|
||||
Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 6, .Block = True})
|
||||
'启动
|
||||
Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
||||
Loader.Start(1)
|
||||
LoaderTaskbarAdd(Loader)
|
||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||
FrmMain.BtnExtraDownload.Ribble()
|
||||
End Sub)
|
||||
Catch ex As Exception
|
||||
Log(ex, "保存 CurseForge 文件失败", LogLevel.Feedback)
|
||||
End Try
|
||||
End Sub, "Download CFDetail Save")
|
||||
End Sub
|
||||
|
||||
Private Sub BtnIntroCf_Click(sender As Object, e As EventArgs) Handles BtnIntroCf.Click
|
||||
@@ -260,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
|
||||
|
||||
'点击返回
|
||||
|
||||
@@ -51,28 +51,17 @@
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="版本" Margin="0,0,25,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="4" Grid.ColumnSpan="2" IsEditable="True" MaxDropDownHeight="320" HintText="全部 (也可自行输入)">
|
||||
<local:MyComboBoxItem Content="" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.19.3" />
|
||||
<local:MyComboBoxItem Content="1.19.2" />
|
||||
<local:MyComboBoxItem Content="1.19.1" />
|
||||
<local:MyComboBoxItem Content="1.19" />
|
||||
<local:MyComboBoxItem Content="1.18.2" />
|
||||
<local:MyComboBoxItem Content="1.18.1" />
|
||||
<local:MyComboBoxItem Content="1.18" />
|
||||
<local:MyComboBoxItem Content="1.17.1" />
|
||||
<local:MyComboBoxItem Content="1.17" />
|
||||
<local:MyComboBoxItem Content="1.16.5" />
|
||||
<local:MyComboBoxItem Content="1.16.4" />
|
||||
<local:MyComboBoxItem Content="1.16.3" />
|
||||
<local:MyComboBoxItem Content="1.16.2" />
|
||||
<local:MyComboBoxItem Content="1.16.1" />
|
||||
<local:MyComboBoxItem Content="1.16" />
|
||||
<local:MyComboBoxItem Content="1.15.2" />
|
||||
<local:MyComboBoxItem Content="1.15" />
|
||||
<local:MyComboBoxItem Content="1.14.4" />
|
||||
<local:MyComboBoxItem Content="1.14" />
|
||||
<local:MyComboBoxItem Content="1.13.2" />
|
||||
<local:MyComboBoxItem Content="1.13" />
|
||||
<local:MyComboBoxItem Content="1.12.2" />
|
||||
<local:MyComboBoxItem Content="1.12" />
|
||||
<local:MyComboBoxItem Content="1.11.2" />
|
||||
<local:MyComboBoxItem Content="1.10.2" />
|
||||
<local:MyComboBoxItem Content="1.9.4" />
|
||||
@@ -83,9 +72,10 @@
|
||||
<local:MyComboBoxItem Content="1.5.2" />
|
||||
</local:MyComboBox>
|
||||
<local:MyComboBox x:Name="ComboSearchLoader" Visibility="Collapsed" Grid.Row="2" Grid.Column="5" MaxDropDownHeight="320" Margin="10,0,0,0">
|
||||
<local:MyComboBoxItem Content="Forge 或 Fabric" IsSelected="True" Tag="0" />
|
||||
<local:MyComboBoxItem Content="任意 Mod 加载器" IsSelected="True" Tag="0" />
|
||||
<local:MyComboBoxItem Content="Forge" Tag="1" />
|
||||
<local:MyComboBoxItem Content="Fabric" Tag="4" />
|
||||
<local:MyComboBoxItem Content="Quilt" Tag="5" />
|
||||
</local:MyComboBox>
|
||||
</Grid>
|
||||
<Grid Margin="0,4,0,6" Height="35">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
'初始化加载器信息
|
||||
Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
|
||||
PageLoaderInit(Load, PanLoad, CardProjects, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
|
||||
McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1)))
|
||||
End Sub
|
||||
Public Shared Loader As New LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)("DlCfProject Mod", AddressOf DlCfProjectSub, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000}
|
||||
Private Shared Function LoaderInput() As DlCfProjectRequest
|
||||
|
||||
@@ -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" />
|
||||
@@ -47,42 +47,21 @@
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="版本" Margin="0,0,25,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="4" IsEditable="True" MaxDropDownHeight="320" HintText="全部 (也可自行输入)">
|
||||
<local:MyComboBoxItem Content="" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.19.3" />
|
||||
<local:MyComboBoxItem Content="1.19.2" />
|
||||
<local:MyComboBoxItem Content="1.19.1" />
|
||||
<local:MyComboBoxItem Content="1.19" />
|
||||
<local:MyComboBoxItem Content="1.18.2" />
|
||||
<local:MyComboBoxItem Content="1.18.1" />
|
||||
<local:MyComboBoxItem Content="1.18" />
|
||||
<local:MyComboBoxItem Content="1.17.1" />
|
||||
<local:MyComboBoxItem Content="1.17" />
|
||||
<local:MyComboBoxItem Content="1.16.5" />
|
||||
<local:MyComboBoxItem Content="1.16.4" />
|
||||
<local:MyComboBoxItem Content="1.16.3" />
|
||||
<local:MyComboBoxItem Content="1.16.2" />
|
||||
<local:MyComboBoxItem Content="1.16.1" />
|
||||
<local:MyComboBoxItem Content="1.16" />
|
||||
<local:MyComboBoxItem Content="1.15.2" />
|
||||
<local:MyComboBoxItem Content="1.15.1" />
|
||||
<local:MyComboBoxItem Content="1.15" />
|
||||
<local:MyComboBoxItem Content="1.14.4" />
|
||||
<local:MyComboBoxItem Content="1.14.3" />
|
||||
<local:MyComboBoxItem Content="1.14.2" />
|
||||
<local:MyComboBoxItem Content="1.14.1" />
|
||||
<local:MyComboBoxItem Content="1.14" />
|
||||
<local:MyComboBoxItem Content="1.13.2" />
|
||||
<local:MyComboBoxItem Content="1.13.1" />
|
||||
<local:MyComboBoxItem Content="1.13" />
|
||||
<local:MyComboBoxItem Content="1.12.2" />
|
||||
<local:MyComboBoxItem Content="1.12.1" />
|
||||
<local:MyComboBoxItem Content="1.12" />
|
||||
<local:MyComboBoxItem Content="1.11.2" />
|
||||
<local:MyComboBoxItem Content="1.11" />
|
||||
<local:MyComboBoxItem Content="1.10.2" />
|
||||
<local:MyComboBoxItem Content="1.10" />
|
||||
<local:MyComboBoxItem Content="1.9.4" />
|
||||
<local:MyComboBoxItem Content="1.9" />
|
||||
<local:MyComboBoxItem Content="1.8.9" />
|
||||
<local:MyComboBoxItem Content="1.8" />
|
||||
<local:MyComboBoxItem Content="1.7.10" />
|
||||
<local:MyComboBoxItem Content="1.7.2" />
|
||||
<local:MyComboBoxItem Content="1.6.4" />
|
||||
@@ -98,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>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
'初始化加载器信息
|
||||
Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
|
||||
PageLoaderInit(Load, PanLoad, CardProjects, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
|
||||
McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1)))
|
||||
End Sub
|
||||
Public Shared Loader As New LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)("DlCfProject ModPack", AddressOf DlCfProjectSub, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000}
|
||||
Private Shared Function LoaderInput() As DlCfProjectRequest
|
||||
@@ -71,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
|
||||
|
||||
@@ -83,12 +83,21 @@
|
||||
'加载
|
||||
Dim Image As New MyBitmap(Address)
|
||||
ImgBack.Tag = Address
|
||||
'大小检查
|
||||
Dim Scale As Integer = Image.Pic.Width / 64
|
||||
If Image.Pic.Width < 32 OrElse Image.Pic.Height < 32 Then
|
||||
ImgFore.Source = Nothing : ImgBack.Source = Nothing
|
||||
Throw New Exception("图片大小不足,长为 " & Image.Pic.Height & ",宽为 " & Image.Pic.Width)
|
||||
End If
|
||||
'头发层(附加层)
|
||||
If Image.Pic.Width >= 64 AndAlso Image.Pic.Height >= 32 Then
|
||||
'如果图片中有透明像素,或是头部颜色和透明区均不一样,则加载附加层
|
||||
If (Image.Pic.GetPixel(1, 1).A = 0 OrElse Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1).A = 0 OrElse Image.Pic.GetPixel(Image.Pic.Width - 2, 2).A = 0) OrElse
|
||||
(Image.Pic.GetPixel(1, 1) <> Image.Pic.GetPixel(41, 9) AndAlso Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1) <> Image.Pic.GetPixel(41, 9) AndAlso Image.Pic.GetPixel(Image.Pic.Width - 2, 2) <> Image.Pic.GetPixel(41, 9)) Then
|
||||
ImgFore.Source = New CroppedBitmap(Image, New Int32Rect(40, 8, 8, 8))
|
||||
If (Image.Pic.GetPixel(1, 1).A = 0 OrElse '如果图片中有任何透明像素(避免纯色白底)
|
||||
Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1).A = 0 OrElse
|
||||
Image.Pic.GetPixel(Image.Pic.Width - 2, Image.Pic.Height / 2 - 2).A = 0) OrElse
|
||||
(Image.Pic.GetPixel(1, 1) <> Image.Pic.GetPixel(Scale * 41, Scale * 9) AndAlso '或是头部颜色和透明区均不一样
|
||||
Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1) <> Image.Pic.GetPixel(Scale * 41, Scale * 9) AndAlso
|
||||
Image.Pic.GetPixel(Image.Pic.Width - 2, Image.Pic.Height / 2 - 2) <> Image.Pic.GetPixel(Scale * 41, Scale * 9)) Then
|
||||
ImgFore.Source = New CroppedBitmap(Image, New Int32Rect(Scale * 40, Scale * 8, Scale * 8, Scale * 8))
|
||||
Else
|
||||
ImgFore.Source = Nothing
|
||||
End If
|
||||
@@ -96,13 +105,8 @@
|
||||
ImgFore.Source = Nothing
|
||||
End If
|
||||
'脸层
|
||||
If Image.Pic.Width >= 32 AndAlso Image.Pic.Height >= 32 Then
|
||||
ImgBack.Source = New CroppedBitmap(Image, New Int32Rect(8, 8, 8, 8))
|
||||
Log("[Skin] 载入头像成功:" & Loader.Name)
|
||||
Else
|
||||
ImgBack.Source = Nothing
|
||||
Throw New Exception("图片大小不足,长为 " & Image.Pic.Height & ",宽为 " & Image.Pic.Width)
|
||||
End If
|
||||
ImgBack.Source = New CroppedBitmap(Image, New Int32Rect(Scale * 8, Scale * 8, Scale * 8, Scale * 8))
|
||||
Log("[Skin] 载入头像成功:" & Loader.Name)
|
||||
Catch ex As Exception
|
||||
Log(ex, "载入头像失败(" & If(Address, "null") & "," & Loader.Name & ")", LogLevel.Hint)
|
||||
End Try
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,952 @@
|
||||
Public Class PageLinkHiper
|
||||
Public Const RequestVersion As Char = "2"
|
||||
|
||||
'记录的启动情况
|
||||
Public Shared IsServerSide As Boolean
|
||||
Private Shared HostIp As String
|
||||
Private Shared HostPort As Integer
|
||||
|
||||
#Region "初始化"
|
||||
|
||||
'加载器初始化
|
||||
Private Sub LoaderInit() Handles Me.Initialized
|
||||
PageLoaderInit(Load, PanLoad, PanContent, PanAlways, InitLoader, AutoRun:=False)
|
||||
'注册自定义的 OnStateChanged
|
||||
AddHandler InitLoader.OnStateChangedUi, AddressOf OnLoadStateChanged
|
||||
End Sub
|
||||
|
||||
Private IsLoad As Boolean = False
|
||||
Private Sub OnLoaded() Handles Me.Loaded
|
||||
If IsLoad Then Exit Sub
|
||||
IsLoad = True
|
||||
'启动监视线程
|
||||
If Not IsWatcherStarted Then RunInNewThread(AddressOf WatcherThread, "Hiper Watcher")
|
||||
'读取索引码
|
||||
Try
|
||||
Dim Time As String = Setup.Get("LinkHiperCertTime")
|
||||
If Time = "" Then
|
||||
Log("[HiPer] 没有缓存凭证")
|
||||
ElseIf Date.Parse(Time) > Date.Now Then
|
||||
TextCert.Text = Setup.Get("LinkHiperCertLast")
|
||||
Log("[HiPer] 缓存凭证尚未过期:" & Time)
|
||||
CurrentSubpage = Subpages.PanSelect
|
||||
Else
|
||||
Log("[HiPer] 缓存凭证已过期:" & Time)
|
||||
LabCertTitle.Text = "输入索引码"
|
||||
LabCertDesc.Text = "你的 HiPer 索引码已经过期,请输入新的索引码。" & vbCrLf & "如果实在没有索引码,可以在左侧选择 IOI 方式联机。"
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log(ex, "读取缓存凭证失败")
|
||||
Setup.Set("LinkHiperCertTime", "")
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "加载步骤"
|
||||
|
||||
Public Shared PathHiper As String = PathAppdata & "联机模块\"
|
||||
Public Shared WithEvents InitLoader As New LoaderCombo(Of Integer)("HiPer 初始化", {
|
||||
New LoaderTask(Of Integer, Integer)("网络环境:连通检测", AddressOf InitPingCheck) With {.Block = False, .ProgressWeight = 0.5},
|
||||
New LoaderTask(Of Integer, Integer)("网络环境:IP 检测", AddressOf InitIpCheck) With {.Block = False, .ProgressWeight = 1},
|
||||
New LoaderTask(Of Integer, Integer)("检查网络环境", AddressOf InitCheck) With {.ProgressWeight = 0.5},
|
||||
New LoaderTask(Of Integer, List(Of NetFile))("获取所需文件", AddressOf InitGetFile) With {.ProgressWeight = 4},
|
||||
New LoaderDownload("下载所需文件", New List(Of NetFile)) With {.ProgressWeight = 4},
|
||||
New LoaderTask(Of Integer, Integer)("启动联机模块", AddressOf InitLaunch) With {.ProgressWeight = 7}
|
||||
})
|
||||
|
||||
'检查网络状态
|
||||
Private Shared Sub InitPingCheck(Task As LoaderTask(Of Integer, Integer))
|
||||
PingTime = 0
|
||||
Try
|
||||
Log("[HiPer] 网络检测:连通检测开始")
|
||||
Dim StartTime = Date.Now.Ticks
|
||||
Dim Result As String = NetGetCodeByClient("https://www.baidu.com/duty/", Encoding.UTF8, 20000, "")
|
||||
Dim DuringTime As Integer = (Date.Now.Ticks - StartTime) / 10000
|
||||
If Result.Contains("百度") Then
|
||||
Log("[HiPer] 网络检测:连通检测成功(" & DuringTime & "ms)")
|
||||
PingTime = DuringTime
|
||||
Else
|
||||
Log("[HiPer] 网络检测:连通检测失败(获取的内容有误)")
|
||||
PingTime = -1
|
||||
End If
|
||||
Catch ex As ThreadInterruptedException
|
||||
Catch ex As Exception
|
||||
Log(ex, "连通检测失败")
|
||||
PingTime = -1
|
||||
End Try
|
||||
End Sub
|
||||
Private Shared Sub InitIpCheck()
|
||||
IpCheckStatus = LoadState.Loading
|
||||
Try
|
||||
Log("[HiPer] 网络检测:IP 地址检测开始")
|
||||
Dim IpCheckResult As String = NetRequestOnce("https://ipinfo.io/json", "GET", "", "application/json", 10000)
|
||||
Dim Country As String = GetJson(IpCheckResult)("country")
|
||||
IpIsInChina = Country = "CN"
|
||||
IpCheckStatus = LoadState.Finished
|
||||
Log("[HiPer] 网络检测:IP 地址检测结果:" & Country)
|
||||
Catch ex As ThreadInterruptedException
|
||||
IpCheckStatus = LoadState.Aborted
|
||||
Catch ex As Exception
|
||||
Log(ex, "IP 地址检测失败")
|
||||
IpCheckStatus = LoadState.Failed
|
||||
IpIsInChina = True
|
||||
End Try
|
||||
End Sub
|
||||
Private Shared PingTime As Integer, IpCheckStatus As LoadState = LoadState.Loading, IpIsInChina As Boolean
|
||||
Private Shared Sub InitCheck(Task As LoaderTask(Of Integer, Integer))
|
||||
'检查协议
|
||||
If Not Setup.Get("LinkEula") Then
|
||||
Reopen:
|
||||
Select Case MyMsgBox("PCL2 的联机服务由速聚授权提供。" & vbCrLf & "在使用前,你需要同意速聚的用户服务协议和隐私政策。", "协议授权", "同意", "拒绝", "查看用户服务协议和隐私政策")
|
||||
Case 1
|
||||
Setup.Set("LinkEula", True)
|
||||
Case 2
|
||||
Throw New Exception("$你拒绝了用户服务协议……")
|
||||
Case 3
|
||||
OpenWebsite("https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzkxMTMyODk3Mg==&action=getalbum&album_id=2585385685407514625&scene=173&from_msgid=2247483720&from_itemidx=1&count=3&nolastread=1#wechat_redirect")
|
||||
GoTo Reopen
|
||||
End Select
|
||||
End If
|
||||
'等待网络环境检查加载器结束
|
||||
SetLoadDesc("正在检查网络环境……", "检查网络环境")
|
||||
Do While Task.State = LoadState.Loading AndAlso Not (PingTime <> 0 AndAlso IpCheckStatus <> LoadState.Loading)
|
||||
Thread.Sleep(50)
|
||||
Loop
|
||||
'获取网络环境检查结果
|
||||
If IpCheckStatus = LoadState.Finished AndAlso Not IpIsInChina Then
|
||||
If MyMsgBox("检测到你的 IP 不在中国,这会导致联机变得非常不稳定。" & vbCrLf &
|
||||
"如果你正开着加速器或者 VPN,请先关闭它们,然后再继续……", "警告", "继续", "取消", IsWarn:=True, ForceWait:=True) = 2 Then
|
||||
Throw New Exception("$请在关闭加速器或者 VPN 后点击重试。")
|
||||
End If
|
||||
Task.Progress = 0.5
|
||||
InitIpCheck() '重新进行检查
|
||||
End If
|
||||
'没有联网
|
||||
If IpCheckStatus = LoadState.Failed AndAlso PingTime = -1 Then
|
||||
Throw New Exception("$PCL2 没法连上网……" & vbCrLf & "如果你改变了网络环境,请重启 PCL2。")
|
||||
End If
|
||||
End Sub
|
||||
|
||||
'获取所需文件
|
||||
Private Shared Sub InitGetFile(Task As LoaderTask(Of Integer, List(Of NetFile)))
|
||||
'初始化
|
||||
SetLoadDesc("正在初始化……", "初始化")
|
||||
Directory.CreateDirectory(PathHiper)
|
||||
WriteFile(PathHiper & "HiPer 联机模块.vbs", "createobject(""wscript.shell"").run """"""" & PathHiper & "HiPer 联机模块.exe"""" v"", 0", Encoding:=Encoding.GetEncoding("GB18030")) '准备启动脚本
|
||||
'获取索引码文件
|
||||
SetLoadDesc("正在获取索引码文件……", "获取索引码文件")
|
||||
Dim Cert As String = RunInUiWait(Function() FrmLinkHiper.TextCert.Text)
|
||||
Log("[Hiper] 联机索引码:" & Cert)
|
||||
If Cert = Setup.Get("LinkHiperCertLast") AndAlso File.Exists(PathHiper & "cert.yml") Then
|
||||
Log("[Hiper] 索引码与上次输入的一致,跳过获取步骤")
|
||||
Else
|
||||
Dim CertRaw As String
|
||||
Try
|
||||
CertRaw = NetRequestOnce("https://cert.mcer.cn/" & Cert & ".yml", "GET", "", "")
|
||||
Catch ex As Exception
|
||||
If GetExceptionSummary(ex).Contains("(404)") Then
|
||||
Throw New CertOutdatedException '索引码无效或已过期
|
||||
ElseIf GetExceptionSummary(ex).Contains("too many requests") Then
|
||||
Throw New Exception("你的尝试太频繁了,请暂时啥都别点,等两分钟后再试……")
|
||||
Else
|
||||
Throw
|
||||
End If
|
||||
End Try
|
||||
If Not CertRaw.Contains("WARNING <<< AUTO SYNC AREA") Then Throw New Exception("获取到的索引码文件内容有误!")
|
||||
WriteFile(PathHiper & "cert.yml", CertRaw)
|
||||
Setup.Set("LinkHiperCertLast", Cert)
|
||||
Setup.Set("LinkHiperCertTime", "")
|
||||
End If
|
||||
Task.Progress = 0.25
|
||||
'获取 CPU 架构
|
||||
SetLoadDesc("正在获取 CPU 架构……", "获取 CPU 架构")
|
||||
Dim Architecture As String
|
||||
Select Case GetType(String).Assembly.GetName().ProcessorArchitecture
|
||||
Case Reflection.ProcessorArchitecture.X86
|
||||
Architecture = "386"
|
||||
Case Reflection.ProcessorArchitecture.Amd64
|
||||
Architecture = "amd64"
|
||||
Case Reflection.ProcessorArchitecture.Arm
|
||||
Architecture = "arm64"
|
||||
Case Else
|
||||
Architecture = "arm64"
|
||||
Log("[Hiper] 当前 CPU 架构为 " & GetStringFromEnum(GetType(String).Assembly.GetName().ProcessorArchitecture) & ",没有最适合的项,这可能会导致联机模块无法启动!", LogLevel.Debug)
|
||||
End Select
|
||||
Log("[Hiper] CPU 架构:" & Architecture)
|
||||
'检查更新:hiper.exe
|
||||
SetLoadDesc("正在检查联机模块本体更新……", "检查联机模块本体更新")
|
||||
Dim RequiredFiles As New List(Of NetFile)
|
||||
Dim Checksums As String = Nothing, ChecksumHiper As String = Nothing
|
||||
If File.Exists(PathHiper & "HiPer 联机模块.exe") Then
|
||||
Try
|
||||
Checksums = NetGetCodeByDownload({
|
||||
"http://mirror.hiper.cn.s2.the.bb/packages.sha1",
|
||||
"http://mirror.hiper.cn.s3.the.bb:175/packages.sha1",
|
||||
"https://gitcode.net/to/hiper/-/raw/master/packages.sha1",
|
||||
"https://cert.mcer.cn/mirror/packages.sha1"
|
||||
})
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取联机模块更新信息失败,将会强制启动联机模块", LogLevel.Hint)
|
||||
GoTo FinishHiperFileCheck
|
||||
End Try
|
||||
ChecksumHiper = RegexSeek(Checksums, "[0-9a-f]{40}(?= windows-" & Architecture & "/hiper.exe)")
|
||||
If ChecksumHiper Is Nothing Then
|
||||
Log("[Hiper] 未找到联机模块更新信息,将会强制启动联机模块", LogLevel.Hint)
|
||||
GoTo FinishHiperFileCheck
|
||||
End If
|
||||
Log("[Hiper] hiper.exe 的所需 SHA1:" & ChecksumHiper)
|
||||
If ChecksumHiper = GetAuthSHA1(PathHiper & "HiPer 联机模块.exe") Then
|
||||
Log("[Hiper] hiper.exe 文件校验通过,无需重新下载")
|
||||
GoTo FinishHiperFileCheck
|
||||
End If
|
||||
End If
|
||||
Log("[Hiper] 需要重新下载 hiper.exe")
|
||||
RequiredFiles.Add(New NetFile({"http://mirror.hiper.cn.s2.the.bb/windows-" & Architecture & "/hiper.exe",
|
||||
"http://mirror.hiper.cn.s3.the.bb:175/windows-" & Architecture & "/hiper.exe",
|
||||
"https://gitcode.net/to/hiper/-/raw/master/windows-" & Architecture & "/hiper.exe?inline=false",
|
||||
"https://cert.mcer.cn/mirror/windows-" & Architecture & "/hiper.exe"},
|
||||
PathHiper & "HiPer 联机模块.exe",
|
||||
New FileChecker(Hash:=ChecksumHiper, MinSize:=1024 * 200))) 'Hash 的默认值即为 Nothing,所以 Checksum 可以为 Nothing
|
||||
FinishHiperFileCheck:
|
||||
Task.Progress = 0.5
|
||||
'检查更新:wintun.dll
|
||||
Dim ChecksumWintun As String = Nothing
|
||||
If File.Exists(PathHiper & "wintun.dll") Then
|
||||
Try
|
||||
If Checksums Is Nothing Then
|
||||
Checksums = NetGetCodeByDownload({
|
||||
"http://mirror.hiper.cn.s2.the.bb/packages.sha1",
|
||||
"http://mirror.hiper.cn.s3.the.bb:175/packages.sha1",
|
||||
"https://gitcode.net/to/hiper/-/raw/master/packages.sha1",
|
||||
"https://cert.mcer.cn/mirror/packages.sha1"
|
||||
})
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取联机模块更新信息失败,将会强制启动联机模块", LogLevel.Hint)
|
||||
GoTo FinishWintunFileCheck
|
||||
End Try
|
||||
ChecksumWintun = RegexSeek(Checksums, "[0-9a-f]{40}(?= windows-" & Architecture & "/wintun.dll)")
|
||||
If ChecksumWintun Is Nothing Then
|
||||
Log("[Hiper] 未找到联机模块更新信息,将会强制启动联机模块", LogLevel.Hint)
|
||||
GoTo FinishWintunFileCheck
|
||||
End If
|
||||
Log("[Hiper] wintun.dll 的所需 SHA1:" & ChecksumWintun)
|
||||
If ChecksumWintun = GetAuthSHA1(PathHiper & "wintun.dll") Then
|
||||
Log("[Hiper] wintun.dll 文件校验通过,无需重新下载")
|
||||
GoTo FinishWintunFileCheck
|
||||
End If
|
||||
End If
|
||||
Log("[Hiper] 需要重新下载 wintun.dll")
|
||||
RequiredFiles.Add(New NetFile({"http://mirror.hiper.cn.s2.the.bb/windows-" & Architecture & "/wintun.dll",
|
||||
"http://mirror.hiper.cn.s3.the.bb:175/windows-" & Architecture & "/wintun.dll",
|
||||
"https://gitcode.net/to/hiper/-/raw/master/windows-" & Architecture & "/wintun.dll?inline=false",
|
||||
"https://cert.mcer.cn/mirror/windows-" & Architecture & "/wintun.dll"},
|
||||
PathHiper & "wintun.dll",
|
||||
New FileChecker(Hash:=ChecksumWintun, MinSize:=1024 * 200))) 'Hash 的默认值即为 Nothing,所以 Checksum 可以为 Nothing
|
||||
FinishWintunFileCheck:
|
||||
Task.Progress = 0.75
|
||||
'检查更新:MCB
|
||||
If Not IsServerSide Then
|
||||
SetLoadDesc("正在检查联机模块组件更新……", "检查联机模块组件更新")
|
||||
Dim ChecksumMcb As String = Nothing
|
||||
If File.Exists(PathHiper & "MCB 联机模块.exe") Then
|
||||
Try
|
||||
Checksums = NetGetCodeByDownload({
|
||||
"http://mirror.hiper.cn.s2.the.bb/utils/minecraft-broadcast/packages.sha1",
|
||||
"http://mirror.hiper.cn.s3.the.bb:175/utils/minecraft-broadcast/packages.sha1",
|
||||
"https://gitcode.net/to/hiper/-/raw/master/utils/minecraft-broadcast/packages.sha1",
|
||||
"https://cert.mcer.cn/mirror/utils/minecraft-broadcast/packages.sha1"
|
||||
})
|
||||
Catch ex As Exception
|
||||
Log(ex, "获取联机模块组件更新信息失败,将会强制启动联机模块组件", LogLevel.Hint)
|
||||
GoTo FinishMcbFileCheck
|
||||
End Try
|
||||
ChecksumMcb = RegexSeek(Checksums, "[0-9a-f]{40}(?= mcb-windows-" & Architecture & ".exe)")
|
||||
If ChecksumMcb Is Nothing Then
|
||||
Log("[Hiper] 未找到联机模块组件更新信息,将会强制启动联机模块组件", LogLevel.Hint)
|
||||
GoTo FinishMcbFileCheck
|
||||
End If
|
||||
Log("[Hiper] mcb.exe 的所需 SHA1:" & ChecksumMcb)
|
||||
If ChecksumMcb = GetAuthSHA1(PathHiper & "MCB 联机模块.exe") Then
|
||||
Log("[Hiper] mcb.exe 文件校验通过,无需重新下载")
|
||||
GoTo FinishMcbFileCheck
|
||||
End If
|
||||
End If
|
||||
Log("[Hiper] 需要重新下载 mcb.exe")
|
||||
RequiredFiles.Add(New NetFile({
|
||||
"http://mirror.hiper.cn.s2.the.bb/utils/minecraft-broadcast/mcb-windows-" & Architecture & ".exe",
|
||||
"http://mirror.hiper.cn.s3.the.bb:175/utils/minecraft-broadcast/mcb-windows-" & Architecture & ".exe",
|
||||
"https://gitcode.net/to/hiper/-/raw/master/utils/minecraft-broadcast/mcb-windows-" & Architecture & ".exe?inline=false",
|
||||
"https://cert.mcer.cn/mirror/utils/minecraft-broadcast/mcb-windows-" & Architecture & ".exe"},
|
||||
PathHiper & "MCB 联机模块.exe",
|
||||
New FileChecker(Hash:=ChecksumMcb, MinSize:=1024 * 200))) 'Hash 的默认值即为 Nothing,所以 Checksum 可以为 Nothing
|
||||
FinishMcbFileCheck:
|
||||
End If
|
||||
'添加 point.yml
|
||||
RequiredFiles.Add(New NetFile({"https://cert.mcer.cn/point.yml"}, PathHiper & "point.yml", New FileChecker(MinSize:=200)))
|
||||
'开始下载
|
||||
SetLoadDesc("正在下载联机模块……", "下载联机模块")
|
||||
Task.Output = RequiredFiles
|
||||
End Sub
|
||||
Public Class CertOutdatedException
|
||||
Inherits Exception
|
||||
End Class
|
||||
'启动联机模块
|
||||
Private Shared Sub InitLaunch(Task As LoaderTask(Of Integer, Integer))
|
||||
'关闭运行中的 HiPer,然后再刷新凭证文件
|
||||
SetLoadDesc("正在关闭运行中的联机模块……", "关闭运行中的联机模块")
|
||||
HiperStop(True)
|
||||
'准备凭证文件
|
||||
SetLoadDesc("正在准备索引码文件……", "准备索引码文件")
|
||||
Dim CertFile As String = ReadFile(PathHiper & "cert.yml")
|
||||
'添加防火墙配置
|
||||
If IsServerSide Then
|
||||
CertFile += ("\n\ninbound:\n port: " & HostPort & "\n proto: tcp\n host: any").Replace("\n", vbCrLf)
|
||||
Else
|
||||
CertFile += ("\n\noutbound:\n port: " & HostPort & "\n proto: tcp\n host: " & HostIp).Replace("\n", vbCrLf)
|
||||
End If
|
||||
CertFile += "\nlogging:\n format: json".Replace("\n", vbCrLf)
|
||||
'更新 point.yml 段
|
||||
Const SyncAreaRegex As String = "(?<=#[ ]*WARNING >>> AUTO SYNC AREA)[\s\S]+?(?=#[ ]*WARNING <<< AUTO SYNC AREA)"
|
||||
CertFile = CertFile.Replace(RegexSeek(CertFile, SyncAreaRegex), RegexSeek(ReadFile(PathHiper & "point.yml"), SyncAreaRegex))
|
||||
WriteFile(PathHiper & "config.yml", CertFile)
|
||||
AllNodes = RegexSearch(CertFile.Replace(vbLf, "cr"), "(?<="")[0-9]+.[0-9]+.[0-9]+.[0-9]+(?=""( )?:( )?cr - "")").Distinct.
|
||||
Where(Function(l) Not (l = "6.6.1.1" OrElse l = "6.6.2.2" OrElse l = "6.6.3.3")).ToList
|
||||
If AllNodes.Count < 2 Then Throw New Exception("$索引码文件格式有误,未找到节点 IP!")
|
||||
Task.Progress = 0.05
|
||||
'尝试启动
|
||||
HiperStart(Task) '启动失败会直接抛出异常
|
||||
Task.Progress = 0.2
|
||||
'检查连接情况
|
||||
SetLoadDesc("正在连接到联机节点 (1/2)……" & If(IpIsInChina, "", vbCrLf & "由于网络不在中国,可能要花费很长时间。"), "检查联机节点")
|
||||
If Not IsServerSide AndAlso HostIp = HiperIp Then Throw New Exception("$还搁这自己连自己?!不是吧?!")
|
||||
Dim PingNodeResults As New List(Of Integer)
|
||||
Dim UnpingedNodes As New List(Of String)(AllNodes)
|
||||
Do Until PingNodeResults.Count >= 2 OrElse Task.IsAborted
|
||||
Dim SelectedNode = RandomOne(UnpingedNodes)
|
||||
Dim PingNode = Ping(SelectedNode, 4000)
|
||||
If PingNode = -1 Then
|
||||
Task.Progress += (If(PingNodeResults.Count = 0, 0.58, 0.88) - Task.Progress) * 0.3
|
||||
Else
|
||||
SetLoadDesc("正在连接到联机节点 (2/2)……" & If(IpIsInChina, "", vbCrLf & "由于网络不在中国,可能要花费很长时间。"), "检查联机节点")
|
||||
Task.Progress = 0.6
|
||||
PingNodeResults.Add(PingNode)
|
||||
UnpingedNodes.Remove(SelectedNode)
|
||||
End If
|
||||
Loop
|
||||
PingNodes = PingNodeResults.Min
|
||||
Task.Progress = 0.9
|
||||
'与房主 Ping 一下看看
|
||||
If Not IsServerSide Then
|
||||
SetLoadDesc("正在连接到房主……", "检查房主")
|
||||
HostPing = -1 '实际上不使用本次 Ping 的结果,因为它真的偏大……
|
||||
Do
|
||||
Dim PingHost = Ping(HostIp, 4000, False)
|
||||
If PingHost = -1 Then
|
||||
Thread.Sleep(500)
|
||||
Else
|
||||
Exit Do
|
||||
End If
|
||||
Loop Until Task.IsAborted
|
||||
'在等待 2 秒后再次触发 Ping,以刷新显示的 Ping
|
||||
RunInNewThread(Sub()
|
||||
Thread.Sleep(2000)
|
||||
TaskPingHost.Start(True, IsForceRestart:=True)
|
||||
End Sub, "HiPer Delayed Ping")
|
||||
End If
|
||||
'刷新完成页面
|
||||
SetLoadDesc("正在加载完成页面……", "加载完成页面")
|
||||
RunInUiWait(AddressOf FrmLinkHiper.WatcherTimer1)
|
||||
End Sub
|
||||
Private Shared PingNodes As Integer, AllNodes As List(Of String)
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "进程管理"
|
||||
|
||||
Private Shared _HiperState As LoadState = LoadState.Waiting
|
||||
Public Shared Property HiperState As LoadState
|
||||
Get
|
||||
Return _HiperState
|
||||
End Get
|
||||
Set(value As LoadState)
|
||||
_HiperState = value
|
||||
RunInUi(Sub() If FrmLinkLeft IsNot Nothing Then CType(FrmLinkLeft.ItemHiper.Buttons(0), MyIconButton).Visibility = If(HiperState = LoadState.Finished OrElse HiperState = LoadState.Loading, Visibility.Visible, Visibility.Collapsed))
|
||||
End Set
|
||||
End Property
|
||||
Public Shared Sub ModuleStopManually() '关闭联机模块按钮
|
||||
HiperExit(False)
|
||||
End Sub
|
||||
|
||||
Private Shared HiperIp As String = Nothing
|
||||
Private Shared HiperProcessId As Integer = -1, McbProcessId As Integer = -1
|
||||
Private Shared HiperCertTime As Date = Date.Now
|
||||
|
||||
''' <summary>
|
||||
''' 若程序正在运行,则结束程序进程,同时初始化状态数据。返回是否关闭了相关进程。
|
||||
''' </summary>
|
||||
Public Shared Function HiperStop(SleepWhenKilled As Boolean) As Boolean
|
||||
HiperStop = False
|
||||
'修改凭证
|
||||
Dim ConfigContent As String = ReadFile(PathHiper & "config.yml")
|
||||
If Not ConfigContent.Contains("enable: false") Then
|
||||
WriteFile(PathHiper & "config.yml", ConfigContent & vbCrLf & "enable: false")
|
||||
End If
|
||||
'关闭所有进程
|
||||
For Each ProcessObject In Process.GetProcesses
|
||||
Dim IsHiper As Boolean = ProcessObject.ProcessName = "HiPer 联机模块"
|
||||
Dim IsMcb As Boolean = ProcessObject.ProcessName = "MCB 联机模块"
|
||||
If Not IsHiper AndAlso Not IsMcb Then Continue For
|
||||
HiperStop = True
|
||||
Try
|
||||
If IsMcb Then
|
||||
ProcessObject.Kill()
|
||||
Log("[HiPer] 已结束进程 PID " & ProcessObject.Id & ":" & ProcessObject.ProcessName)
|
||||
If HiperStop AndAlso SleepWhenKilled Then Thread.Sleep(1000) '等待 1 秒确认进程已退出
|
||||
Else 'IsHiper
|
||||
If SleepWhenKilled Then
|
||||
Thread.Sleep(4000) '等待 4 秒确认进程已退出
|
||||
If Not ProcessObject.HasExited Then
|
||||
ProcessObject.Kill()
|
||||
Log("[HiPer] 已结束进程 PID " & ProcessObject.Id & ":" & ProcessObject.ProcessName)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log(ex, "结束进程失败(" & ProcessObject.Id & "," & ProcessObject.ProcessName & ")")
|
||||
End Try
|
||||
Next
|
||||
'初始化
|
||||
HiperState = LoadState.Waiting
|
||||
HiperProcessId = -1 : McbProcessId = -1
|
||||
HiperCertTime = Nothing
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 启动程序,并等待初始化完成后退出运行,同时更新 HiperIp。
|
||||
''' 若启动失败,则会直接抛出异常。
|
||||
''' 若程序正在运行,则会先停止其运行。
|
||||
''' </summary>
|
||||
Public Shared Sub HiperStart(Task As LoaderTask(Of Integer, Integer))
|
||||
Try
|
||||
SetLoadDesc("正在启动联机模块……", "启动联机模块")
|
||||
PossibleFailReason = Nothing
|
||||
'启动 Hiper
|
||||
Log("[Hiper] 启动 Hiper 进程")
|
||||
DeleteDirectory(PathHiper & "logs") '清理日志
|
||||
Dim HiperInfo = New ProcessStartInfo With {
|
||||
.FileName = "wscript",
|
||||
.Arguments = """" & PathHiper & "HiPer 联机模块.vbs""",
|
||||
.Verb = "runas" '需要管理员权限
|
||||
}
|
||||
Dim HiperVbsProcess As New Process() With {.StartInfo = HiperInfo}
|
||||
HiperVbsProcess.Start()
|
||||
'查找真正的 Hiper 进程
|
||||
SetLoadDesc("联机模块正在启动……", "联机模块加载")
|
||||
Do
|
||||
Dim GotProcesses = Process.GetProcesses.
|
||||
Where(Function(l) l.ProcessName = "HiPer 联机模块" AndAlso Math.Abs((l.StartTime - Date.Now).TotalMinutes) < 1)
|
||||
If GotProcesses.Count > 0 Then
|
||||
HiperProcessId = GotProcesses.First.Id
|
||||
Log("[Hiper] 已发现 Hiper 进程,PID:" & HiperProcessId)
|
||||
Exit Do
|
||||
End If
|
||||
Thread.Sleep(50)
|
||||
Loop While Task.State = LoadState.Loading AndAlso Not Task.IsAborted
|
||||
If HiperProcessId = -1 Then Throw New Exception("联机模块未能成功启动!")
|
||||
HiperState = LoadState.Loading
|
||||
Task.Progress = 0.15
|
||||
'抓取日志
|
||||
Dim LogLine As Integer = 0
|
||||
Do
|
||||
Thread.Sleep(100)
|
||||
If Not File.Exists(PathHiper & "logs\hiper.log") Then Continue Do
|
||||
Dim LogLines As String() = ReadFile(PathHiper & "logs\hiper.log").TrimEnd(vbLf).Split(vbLf)
|
||||
For i = LogLine To LogLines.Count - 1
|
||||
HiperLogLine(LogLines(i), Task)
|
||||
Next
|
||||
LogLine = LogLines.Count
|
||||
Loop While HiperState = LoadState.Loading AndAlso Not Task.IsAborted AndAlso Process.GetProcesses.Any(Function(l) l.Id = HiperProcessId)
|
||||
'输出
|
||||
If HiperState = LoadState.Finished Then
|
||||
Log("[Hiper] Hiper 启动完成")
|
||||
ElseIf PossibleFailReason IsNot Nothing AndAlso PossibleFailReason.Contains("索引码已过期") Then
|
||||
Throw New CertOutdatedException()
|
||||
Else
|
||||
Throw New Exception(If(PossibleFailReason, "联机模块因未知原因启动失败!"))
|
||||
End If
|
||||
'启动 MCB
|
||||
Task.Progress = 0.25
|
||||
If Not IsServerSide Then
|
||||
Try
|
||||
Log("[Hiper] 启动 MCB 进程")
|
||||
Dim McbInfo = New ProcessStartInfo With {
|
||||
.FileName = PathHiper & "MCB 联机模块.exe", .WorkingDirectory = PathHiper,
|
||||
.UseShellExecute = False, .CreateNoWindow = True,
|
||||
.RedirectStandardError = True, .RedirectStandardOutput = True,
|
||||
.Arguments = "-addr " & HostIp & ":" & HostPort & " -motd ""PCL2 联机房间"""
|
||||
}
|
||||
Dim McbProcess As New Process() With {.StartInfo = McbInfo}
|
||||
McbProcess.Start()
|
||||
McbProcessId = McbProcess.Id
|
||||
Catch ex As Exception
|
||||
Throw New Exception("联机模块组件启动失败", ex)
|
||||
End Try
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Try
|
||||
HiperStop(True) '由于启动失败停止进程
|
||||
Catch
|
||||
End Try
|
||||
HiperState = LoadState.Failed
|
||||
Throw
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'Hiper 日志
|
||||
Private Shared Sub HiperLogLine(Content As String, Task As LoaderTask(Of Integer, Integer))
|
||||
|
||||
'检查报错
|
||||
Dim ContentTest As String = Content.ToLower
|
||||
Dim ErrorMessage As String = Nothing
|
||||
Dim ContentJson As JObject = Nothing
|
||||
If Content.StartsWith("{""") AndAlso Content.EndsWith("}") Then
|
||||
ContentJson = GetJson(Content)
|
||||
ContentTest = If(ContentJson("error"), ContentJson("msg")).ToString.ToLower
|
||||
ErrorMessage = ContentJson("error")
|
||||
End If
|
||||
If ContentTest.Contains("hiper certificate for this host is expired") Then
|
||||
PossibleFailReason = "$你的索引码已过期,请更换新的索引码!"
|
||||
ElseIf ContentTest.Contains("error creating interface: access is denied") Then
|
||||
PossibleFailReason = "$没有获得管理员权限,无法创建网络通道!"
|
||||
ElseIf ContentTest.Contains("cannot create a file when that file already exists") Then
|
||||
PossibleFailReason = "$请不要重复开启多个联机模块!"
|
||||
ElseIf Content.Contains("failed to load config") Then
|
||||
PossibleFailReason = "$索引码文件内容存在错误!"
|
||||
ElseIf Content.Contains("system cannot find the file specified") Then
|
||||
PossibleFailReason = "$创建网络通道失败!" & vbCrLf & "如果你曾启动过 VPN 软件,请先打开那个软件,然后关掉它,最后再重试。虽然不知道为啥,但这样大概管用……"
|
||||
End If
|
||||
If PossibleFailReason Is Nothing AndAlso ErrorMessage IsNot Nothing Then PossibleFailReason = ErrorMessage
|
||||
|
||||
'检查结束
|
||||
If ContentJson IsNot Nothing Then
|
||||
Dim Message As String = ContentJson("msg")
|
||||
If Message = "HiPer interface is active" Then
|
||||
HiperIp = ContentJson("network").ToString.Split("/").First
|
||||
If IsServerSide Then HostIp = HiperIp
|
||||
Log("[Hiper] Hiper 启动完成,IP:" & HiperIp)
|
||||
HiperState = LoadState.Finished
|
||||
ElseIf Message = "Validity of client certificate" Then
|
||||
Dim VaildTime As String = ContentJson("valid")
|
||||
Date.TryParseExact(VaildTime, "yyyy-MM-dd HH:mm:ss", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, HiperCertTime)
|
||||
Log("[Hiper] 索引码到期时间:" & HiperCertTime.ToString)
|
||||
Setup.Set("LinkHiperCertTime", HiperCertTime.ToString)
|
||||
End If
|
||||
End If
|
||||
|
||||
'写入日志
|
||||
If ModeDebug OrElse Content.Contains("""error""") Then Log("[Hiper] " & Content)
|
||||
|
||||
End Sub
|
||||
Private Shared PossibleFailReason As String = Nothing
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "监视线程"
|
||||
|
||||
'主 Timer 线程
|
||||
Private IsWatcherStarted As Boolean = False
|
||||
Private Sub WatcherThread()
|
||||
Dim Sec15 As Integer = 0
|
||||
Do While True
|
||||
Try
|
||||
For i = 1 To 5
|
||||
Thread.Sleep(200)
|
||||
If InitLoader.State = LoadState.Loading Then
|
||||
RunInUi(AddressOf UpdateProgress)
|
||||
End If
|
||||
Next
|
||||
Thread.Sleep(1000)
|
||||
Sec15 += 1
|
||||
WatcherTimer1()
|
||||
If Sec15 = 15 Then
|
||||
Sec15 = 0
|
||||
WatcherTimer15()
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log(ex, "联机模块主时钟出错", LogLevel.Feedback)
|
||||
Thread.Sleep(20000)
|
||||
End Try
|
||||
Loop
|
||||
End Sub
|
||||
|
||||
'每 1 秒执行的 Timer
|
||||
Private Sub WatcherTimer1()
|
||||
If HiperState <> LoadState.Finished Then Exit Sub
|
||||
RunInUi(Sub()
|
||||
'索引码剩余时间
|
||||
Dim Span As TimeSpan = HiperCertTime - Date.Now
|
||||
If Span.TotalDays >= 30 Then
|
||||
LabFinishTime.Text = "> 30 天"
|
||||
ElseIf Span.TotalDays >= 4 Then
|
||||
LabFinishTime.Text = Span.Days & " 天"
|
||||
ElseIf Span.TotalDays >= 1 Then
|
||||
LabFinishTime.Text = Span.Days & " 天" & If(Span.Hours > 0, " " & Span.Hours & " 小时", "")
|
||||
ElseIf Span.TotalMinutes >= 10 Then
|
||||
LabFinishTime.Text = Span.Hours & ":" & Span.Minutes.ToString.PadLeft(2, "0") & "'"
|
||||
Else
|
||||
LabFinishTime.Text = Span.Minutes & "'" & Span.Seconds.ToString.PadLeft(2, "0") & """"
|
||||
End If
|
||||
'提示索引码即将到期
|
||||
If Span.TotalSeconds <= 5 * 60 AndAlso Span.TotalSeconds > 5 * 60 - 1 AndAlso Setup.Get("LinkHiperCertWarn") Then
|
||||
MyMsgBox("你的索引码还有不到 5 分钟就要过期了!" & vbCrLf & "你可以在设置中关闭这个提示……", "索引码即将过期", "我知道了……")
|
||||
ShowWindowToTop(Handle)
|
||||
Beep()
|
||||
End If
|
||||
'检查索引码到期
|
||||
If Span.TotalSeconds < 2 Then
|
||||
LabCertTitle.Text = "索引码已过期"
|
||||
LabCertDesc.Text = "你的 HiPer 索引码已经过期,请输入新的索引码。" & vbCrLf & "如果实在没有索引码,可以在左侧选择 IOI 方式联机。"
|
||||
TextCert.Text = ""
|
||||
HiperExit(True)
|
||||
ShowWindowToTop(Handle)
|
||||
Beep()
|
||||
Exit Sub
|
||||
End If
|
||||
'网络质量
|
||||
Dim QualityScore As Integer = If(IpIsInChina, 0, -2)
|
||||
QualityScore -= Math.Ceiling((Math.Min(PingTime, 600) + Math.Min(PingNodes, 600)) / 80)
|
||||
Select Case QualityScore
|
||||
Case Is >= -1
|
||||
LabFinishQuality.Text = "优秀"
|
||||
Case Is >= -2
|
||||
LabFinishQuality.Text = "优良"
|
||||
Case Is >= -3
|
||||
LabFinishQuality.Text = "良好"
|
||||
Case Is >= -5
|
||||
LabFinishQuality.Text = "一般"
|
||||
Case Is >= -7
|
||||
LabFinishQuality.Text = "较差"
|
||||
Case Else
|
||||
LabFinishQuality.Text = "很差"
|
||||
End Select
|
||||
'Ping
|
||||
If HostPing <> -1 Then
|
||||
If FrmLinkHiper IsNot Nothing AndAlso FrmLinkHiper.LabFinishPing.IsLoaded Then
|
||||
FrmLinkHiper.LabFinishPing.Text = HostPing & "ms"
|
||||
End If
|
||||
End If
|
||||
End Sub)
|
||||
End Sub
|
||||
'每 15 秒执行的 Timer
|
||||
Private Shared HostPing As Integer = -1
|
||||
Private Sub WatcherTimer15()
|
||||
If Not (HiperState = LoadState.Finished OrElse HiperState = LoadState.Loading) Then Exit Sub
|
||||
'检查 HiPer 崩溃
|
||||
Try
|
||||
Process.GetProcessById(HiperProcessId)
|
||||
Catch
|
||||
Dim LogLines = ReadFile(PathHiper & "logs\hiper.log").TrimEnd(vbLf).Split(vbLf)
|
||||
HiperExit(False)
|
||||
MyMsgBox("由于联机模块异常退出,已退出联机房间。" & vbCrLf & vbCrLf &
|
||||
"联机模块最后的日志:" & vbCrLf & Join(LogLines.Skip(LogLines.Count - 3).ToList, vbCrLf), "联机断开")
|
||||
End Try
|
||||
'下面的部分需要完全完成加载
|
||||
If HiperState <> LoadState.Finished Then Exit Sub
|
||||
'检查 MCB 崩溃
|
||||
Try
|
||||
If Not IsServerSide Then Process.GetProcessById(McbProcessId)
|
||||
Catch
|
||||
HiperExit(False)
|
||||
MyMsgBox("由于 MCB 联机模块异常退出,已退出联机房间。", "联机断开")
|
||||
End Try
|
||||
'重新检查 Ping
|
||||
If Not IsServerSide Then
|
||||
Dim PingHostFailedCount As Integer = 0
|
||||
Do
|
||||
TaskPingHost.WaitForExit(True, IsForceRestart:=True)
|
||||
If TaskPingHost.Output = -1 Then
|
||||
PingHostFailedCount += 1
|
||||
Log("[HiPer] Ping 房主失败(第 " & PingHostFailedCount & " 次)")
|
||||
If PingHostFailedCount >= 3 Then
|
||||
HiperExit(False) : MyMsgBox("与房主断开连接,已退出联机房间。", "联机断开") : Exit Sub
|
||||
End If
|
||||
Else
|
||||
If PingHostFailedCount > 0 Then Log("[HiPer] Ping 房主已恢复成功(" & HostPing & "ms)")
|
||||
Exit Do
|
||||
End If
|
||||
Loop While True
|
||||
End If
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "PanCert | 索引码输入页面"
|
||||
|
||||
'检测输入
|
||||
Private Sub TextCert_ValidateChanged(sender As Object, e As EventArgs) Handles TextCert.ValidateChanged
|
||||
BtnCertDone.IsEnabled = TextCert.ValidateResult = ""
|
||||
End Sub
|
||||
Private Sub TextCert_KeyUp(sender As Object, e As KeyEventArgs) Handles TextCert.KeyUp
|
||||
If e.Key = Key.Enter AndAlso BtnCertDone.IsEnabled Then BtnCertDone_Click() '允许回车确认
|
||||
End Sub
|
||||
|
||||
'确认
|
||||
Private Sub BtnCertDone_Click() Handles BtnCertDone.Click
|
||||
CurrentSubpage = Subpages.PanSelect
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "PanSelect | 种类选择页面"
|
||||
|
||||
'返回
|
||||
Private Sub BtnSelectReturn_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnSelectReturn.MouseLeftButtonUp
|
||||
LabCertTitle.Text = "输入索引码"
|
||||
LabCertDesc.Text = "你需要获取索引码才能使用 HiPer。" & vbCrLf & "如果实在没有索引码,可以在左侧选择 IOI 方式联机。"
|
||||
CurrentSubpage = Subpages.PanCert
|
||||
End Sub
|
||||
|
||||
'创建房间
|
||||
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))
|
||||
End Sub
|
||||
Private Sub RoomCreate(Port As Integer)
|
||||
'记录信息
|
||||
HostIp = Nothing : HostPort = Port
|
||||
IsServerSide = True
|
||||
'启动
|
||||
InitLoader.Start(IsForceRestart:=True)
|
||||
End Sub
|
||||
|
||||
'加入房间
|
||||
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)
|
||||
End Sub
|
||||
Private Sub RoomJoin(Ip As String, Port As Integer)
|
||||
'记录信息
|
||||
HostIp = Ip : HostPort = Port
|
||||
IsServerSide = False
|
||||
'启动
|
||||
InitLoader.Start(IsForceRestart:=True)
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "PanLoad | 加载中页面"
|
||||
|
||||
'承接状态切换的 UI 改变
|
||||
Private Sub OnLoadStateChanged(Loader As LoaderBase, NewState As LoadState, OldState As LoadState)
|
||||
Select Case NewState
|
||||
Case LoadState.Loading
|
||||
UpdateProgress(0)
|
||||
If IsServerSide Then
|
||||
LabLoadTitle.Text = "正在创建联机房间"
|
||||
Log("[Hiper] 正在创建联机房间,端口 " & HostPort)
|
||||
Else
|
||||
LabLoadTitle.Text = "正在加入联机房间"
|
||||
Log("[Hiper] 正在加入联机房间,目标 IP " & HostIp & ":" & HostPort)
|
||||
End If
|
||||
LabLoadDesc.Text = "正在初始化……"
|
||||
LoadStep = "准备初始化"
|
||||
Case LoadState.Failed
|
||||
UpdateProgress(1)
|
||||
If IsServerSide Then
|
||||
LabLoadTitle.Text = "创建联机房间失败"
|
||||
Else
|
||||
LabLoadTitle.Text = "加入联机房间失败"
|
||||
End If
|
||||
Dim RealException As Exception = If(Loader.Error.InnerException, Loader.Error)
|
||||
If TypeOf RealException Is CertOutdatedException Then
|
||||
LabCertTitle.Text = "索引码无效"
|
||||
LabCertDesc.Text = "你的 HiPer 索引码无效或者已经过期!" & vbCrLf & "请重新输入索引码。"
|
||||
HiperExit(True)
|
||||
ElseIf RealException.Message.StartsWith("$") Then
|
||||
LabLoadDesc.Text = RealException.Message.TrimStart("$") & vbCrLf &
|
||||
"点击镐子重试,或者点击灰色的 × 取消。"
|
||||
Else
|
||||
LabLoadDesc.Text = LoadStep & "失败:" & GetExceptionSummary(RealException) & vbCrLf &
|
||||
"点击镐子重试,或者点击灰色的 × 取消。"
|
||||
End If
|
||||
Log(Loader.Error, "HiPer 联机尝试失败")
|
||||
Case LoadState.Finished
|
||||
UpdateProgress(1)
|
||||
CurrentSubpage = Subpages.PanFinish
|
||||
BtnFinishPing.Visibility = If(IsServerSide, Visibility.Collapsed, Visibility.Visible)
|
||||
LineFinishPing.Visibility = If(IsServerSide, Visibility.Collapsed, Visibility.Visible)
|
||||
BtnFinishCopy.Visibility = If(IsServerSide, Visibility.Visible, Visibility.Collapsed)
|
||||
If IsServerSide Then
|
||||
LabFinishTitle.Text = "已创建联机房间"
|
||||
LabFinishDesc.Text = "已在端口 " & HostPort & " 创建了联机房间。" & vbCrLf & "点击下方的复制联机码按钮,然后把联机码发给朋友吧!"
|
||||
Else
|
||||
LabFinishTitle.Text = "已加入联机房间"
|
||||
LabFinishDesc.Text = "启动游戏,进入多人游戏页面后稍等片刻,房间就会出现在服务器列表的最下方。" & vbCrLf & "如果提示无效会话,不要退出联机房间,重新启动游戏即可!"
|
||||
End If
|
||||
LabFinishIp.Text = HostIp & ":" & HostPort
|
||||
Log("[Hiper] 已完成连接")
|
||||
End Select
|
||||
End Sub
|
||||
Private Shared LoadStep As String = "准备初始化"
|
||||
Private Shared Sub SetLoadDesc(Intro As String, [Step] As String)
|
||||
Log("[Hiper] 连接步骤:" & Intro)
|
||||
LoadStep = [Step]
|
||||
RunInUiWait(Sub()
|
||||
If FrmLinkHiper Is Nothing OrElse Not FrmLinkHiper.LabLoadDesc.IsLoaded Then Exit Sub
|
||||
FrmLinkHiper.LabLoadDesc.Text = Intro
|
||||
FrmLinkHiper.UpdateProgress()
|
||||
End Sub)
|
||||
End Sub
|
||||
|
||||
'承接重试
|
||||
Private Sub CardLoad_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles CardLoad.MouseLeftButtonUp
|
||||
If Not InitLoader.State = LoadState.Failed Then Exit Sub
|
||||
InitLoader.Start(IsForceRestart:=True)
|
||||
End Sub
|
||||
|
||||
'取消加载
|
||||
Private Sub CancelLoad() Handles BtnLoadCancel.Click
|
||||
If InitLoader.State = LoadState.Loading Then
|
||||
CurrentSubpage = Subpages.PanSelect
|
||||
InitLoader.Abort()
|
||||
Else
|
||||
InitLoader.State = LoadState.Waiting
|
||||
End If
|
||||
HiperStop(False)
|
||||
End Sub
|
||||
|
||||
'进度改变
|
||||
Private Sub UpdateProgress(Optional Value As Double = -1)
|
||||
If Value = -1 Then Value = InitLoader.Progress
|
||||
Dim DisplayingProgress As Double = ColumnProgressA.Width.Value
|
||||
If Math.Round(Value - DisplayingProgress, 3) = 0 Then Exit Sub
|
||||
If DisplayingProgress > Value Then
|
||||
ColumnProgressA.Width = New GridLength(Value, GridUnitType.Star)
|
||||
ColumnProgressB.Width = New GridLength(1 - Value, GridUnitType.Star)
|
||||
AniStop("Hiper Progress")
|
||||
Else
|
||||
Dim NewProgress As Double = If(Value = 1, 1, (Value - DisplayingProgress) * 0.2 + DisplayingProgress)
|
||||
AniStart({
|
||||
AaGridLengthWidth(ColumnProgressA, NewProgress - ColumnProgressA.Width.Value, 300, Ease:=New AniEaseOutFluent),
|
||||
AaGridLengthWidth(ColumnProgressB, (1 - NewProgress) - ColumnProgressB.Width.Value, 300, Ease:=New AniEaseOutFluent)
|
||||
}, "Hiper Progress")
|
||||
End If
|
||||
End Sub
|
||||
Private Sub CardResized() Handles CardLoad.SizeChanged
|
||||
RectProgressClip.Rect = New Rect(0, 0, CardLoad.ActualWidth, 12)
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "PanFinish | 加载完成页面"
|
||||
|
||||
'复制 IP
|
||||
Private Sub BtnFinishIp_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnFinishIp.MouseLeftButtonUp
|
||||
ClipboardSet(LabFinishIp.Text)
|
||||
End Sub
|
||||
|
||||
'退出
|
||||
Private Sub BtnFinishExit_Click(sender As Object, e As EventArgs) Handles BtnFinishExit.Click
|
||||
If IsServerSide AndAlso MyMsgBox("你确定要关闭联机房间吗?", "确认退出", "确定", "取消", IsWarn:=True) = 2 Then Exit Sub
|
||||
HiperExit(False)
|
||||
End Sub
|
||||
|
||||
'复制联机码
|
||||
Private Sub BtnFinishCopy_Click(sender As Object, e As EventArgs) Handles BtnFinishCopy.Click
|
||||
Dim IpParts = HostIp.Split(".").Select(Function(l) Val(l)).ToList
|
||||
Dim IpAndPort As Long = HostPort + IpParts(0) * 65536 + IpParts(1) * 65536 * 256 + IpParts(2) * 65536 * 256 * 256 + IpParts(3) * 65536 * 256 * 256 * 256
|
||||
ClipboardSet("P" & RadixConvert(IpAndPort, 10, 36) & RequestVersion, False)
|
||||
Hint("已复制联机码!", HintType.Finish)
|
||||
End Sub
|
||||
|
||||
'Ping 房主
|
||||
Private Sub BtnFinishPing_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnFinishPing.MouseLeftButtonUp
|
||||
LabFinishPing.Text = "检测中"
|
||||
If TaskPingHost.State = LoadState.Loading Then Exit Sub
|
||||
TaskPingHost.Start(True, IsForceRestart:=True)
|
||||
End Sub
|
||||
Private Shared TaskPingHost As New LoaderTask(Of Boolean, Integer)("HiPer Ping Host",
|
||||
Sub(Task As LoaderTask(Of Boolean, Integer))
|
||||
HostPing = -1
|
||||
HostPing = Ping(HostIp, 5000, Task.Input)
|
||||
End Sub)
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "子页面管理"
|
||||
|
||||
Public Enum Subpages
|
||||
PanCert
|
||||
PanSelect
|
||||
PanFinish
|
||||
End Enum
|
||||
Private _CurrentSubpage As Subpages = Subpages.PanCert
|
||||
Public Property CurrentSubpage As Subpages
|
||||
Get
|
||||
Return _CurrentSubpage
|
||||
End Get
|
||||
Set(value As Subpages)
|
||||
If _CurrentSubpage = value Then Exit Property
|
||||
_CurrentSubpage = value
|
||||
Log("[Hiper] 子页面更改为 " & GetStringFromEnum(value))
|
||||
PageOnContentExit()
|
||||
If value = Subpages.PanSelect Then
|
||||
LabSelectCode.Text = "(" & TextCert.Text.Substring(0, Math.Min(TextCert.Text.Length, 3)) & "…)"
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private Sub PageLinkHiper_OnPageEnter() Handles Me.PageEnter
|
||||
FrmLinkHiper.PanCert.Visibility = If(CurrentSubpage = Subpages.PanCert, Visibility.Visible, Visibility.Collapsed)
|
||||
FrmLinkHiper.PanSelect.Visibility = If(CurrentSubpage = Subpages.PanSelect, Visibility.Visible, Visibility.Collapsed)
|
||||
FrmLinkHiper.PanFinish.Visibility = If(CurrentSubpage = Subpages.PanFinish, Visibility.Visible, Visibility.Collapsed)
|
||||
End Sub
|
||||
|
||||
Private Shared Sub HiperExit(ExitToCertPage As Boolean)
|
||||
Log("[Hiper] 要求退出 Hiper(当前加载器状态为 " & GetStringFromEnum(InitLoader.State) & ")")
|
||||
HiperStop(False)
|
||||
If InitLoader.State = LoadState.Loading Then InitLoader.Abort()
|
||||
If InitLoader.State = LoadState.Failed Then InitLoader.State = LoadState.Waiting
|
||||
RunInUi(Sub()
|
||||
If FrmLinkHiper Is Nothing OrElse Not FrmLinkHiper.IsLoaded Then Exit Sub
|
||||
FrmLinkHiper.CurrentSubpage = If(ExitToCertPage, Subpages.PanCert, Subpages.PanSelect)
|
||||
FrmLinkHiper.PageOnContentExit()
|
||||
End Sub)
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
@@ -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>-->
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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>
|
||||
@@ -18,7 +18,6 @@
|
||||
<local:MyListItem x:Name="ItemFeedback" IsScaleAnimationEnabled="False" Type="Clickable" Tag="3" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="反馈"
|
||||
LogoScale="0.9" Logo="M613.717333 64.426667l3.413334 3.242666 331.861333 331.861334a85.333333 85.333333 0 0 1 3.2 117.269333l-3.2 3.413333L573.162667 896H960a21.333333 21.333333 0 0 1 21.333333 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333333 21.333333H64a21.333333 21.333333 0 0 1-21.333333-21.333333v-42.666667a21.333333 21.333333 0 0 1 21.333333-21.333333h295.338667L74.069333 610.709333a85.333333 85.333333 0 0 1-3.221333-117.269333l3.2-3.413333 422.4-422.357334a85.333333 85.333333 0 0 1 117.269333-3.221333z m-20.629333 99.882666l-21.418667 321.493334a85.333333 85.333333 0 0 1-74.944 79.04l-4.522666 0.426666-321.493334 21.44 295.552 295.530667 422.4-422.378667L593.066667 164.309333z m-86.442667 13.824L184.533333 500.266667l301.994667-20.117334 20.117333-301.994666z" />
|
||||
<local:MyListItem x:Name="ItemVote" IsScaleAnimationEnabled="False" Type="Clickable" Tag="4" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="新功能投票"
|
||||
EventType="打开网页" EventData="https://github.com/Hex-Dragon/PCL2/discussions/categories/%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8"
|
||||
LogoScale="0.92" Logo="M979 1024H45c-24.9 0-45-20.1-45-45s20.1-45 45-45h934c24.9 0 45 20.1 45 45s-20.1 45-45 45zM135 887C60.6 887 0 826.4 0 752V334c0-74.4 60.6-135 135-135s135 60.6 135 135v418c0 74.4-60.6 135-135 135z m0-598c-24.8 0-45 20.2-45 45v418c0 24.8 20.2 45 45 45s45-20.2 45-45V334c0-24.8-20.2-45-45-45zM512 887c-74.4 0-135-60.6-135-135V532c0-74.4 60.6-135 135-135s135 60.6 135 135v220c0 74.4-60.6 135-135 135z m0-400c-24.8 0-45 20.2-45 45v220c0 24.8 20.2 45 45 45s45-20.2 45-45V532c0-24.8-20.2-45-45-45zM889 887c-74.4 0-135-60.6-135-135V135C754 60.6 814.6 0 889 0s135 60.6 135 135v617c0 74.4-60.6 135-135 135z m0-797c-24.8 0-45 20.2-45 45v617c0 24.8 20.2 45 45 45s45-20.2 45-45V135c0-24.8-20.2-45-45-45z" />
|
||||
</StackPanel>
|
||||
</local:MyPageLeft>
|
||||
@@ -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) '强制重新解压文件
|
||||
@@ -122,9 +124,21 @@
|
||||
FrmOtherHelp.SearchBox.Text = ""
|
||||
End Sub
|
||||
|
||||
'打开反馈
|
||||
'打开网页
|
||||
Public Shared Sub TryFeedback() Handles ItemFeedback.Click
|
||||
If CanFeedback(True) Then Feedback(True, False)
|
||||
If Not CanFeedback(True) Then Exit Sub
|
||||
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。",
|
||||
"提醒", "打开", "取消") = 2 Then Exit Sub
|
||||
OpenWebsite("https://github.com/Hex-Dragon/PCL2/discussions/categories/%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8?discussions_q=category%3A%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8+sort%3Adate_created")
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
@@ -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="未找到任何版本的游戏,请先下载任意版本的游戏。
若有已存在的游戏,请在左边的列表中选择“添加文件夹”,选择 .minecraft 文件夹将其导入。" TextWrapping="Wrap" />
|
||||
<TextBlock Name="LabEmptyContent" Margin="10,15,10,5" Text="未找到任何版本的游戏,请先下载任意版本的游戏。
若有已存在的游戏,请在左边的列表中选择“添加文件夹”,选择 .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="以资源包的形式加载自定义皮肤。
使用此方式更换的皮肤在多人游戏中仅自己可见,且会替换游戏中所有的角色。" />
|
||||
<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="以资源包的形式加载自定义皮肤。
使用此方式更换的皮肤在多人游戏中仅自己可见,且会替换游戏中所有的角色。" />
|
||||
</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="自定义游戏窗口的标题,若留空则不进行更改。
支持以下替换标记:
 - {user}:玩家名字
 - {login}:玩家的登录方式
 - {name}:游戏版本名
 - {time}:当前的系统时间
 - {version}:游戏对应的原版版本号
 - {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="自定义游戏窗口的标题,若留空则不进行更改。
支持以下替换标记:
 · {user}:玩家名字
 · {login}:玩家的登录方式
 · {name}:游戏版本名
 · {time}:当前的系统时间
 · {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、资源包等均为公用。
若存在不同版本的 Forge,可能会由于 Mod 与版本冲突导致未知问题。" />
|
||||
<local:MyComboBoxItem Content="关闭" ToolTip="所有版本均使用同一档案,存档、Mod、资源包等均为公用。
若存在不同版本的 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 参数,在没有确定把握的情况下请不要尝试修改。
你可以通过点击左侧选项卡的初始化按钮来恢复到默认设置。" 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 参数,在没有确定把握的情况下请不要尝试修改。
你可以通过点击左侧选项卡的初始化按钮来恢复到默认设置。" 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="文本框中的内容将会被直接拼合在启动参数的末尾。
例如输入 --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="文本框中的内容将会被直接拼合在启动参数的末尾。
例如输入 --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 文件夹。
如果你没有修改相关文件,请勿勾选此项。
更推荐在版本设置中关闭特定版本的校验,而不是在这里关闭所有版本的校验。" ToolTipService.ShowDuration="2333333" />
|
||||
ToolTip="在启动时不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。
如果你没有修改相关文件,请勿勾选此项。
更推荐在版本设置中关闭特定版本的校验,而不是在这里关闭所有版本的校验。" />
|
||||
</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="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。
一般而言,64 线程已可以保证足够的下载速度。" />
|
||||
ToolTip="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。
一般而言,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="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。
在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" />
|
||||
<TextBlock Margin="0,5" HorizontalAlignment="Left" Text="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。
在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" 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 的下载、皮肤等缓存文件的存储位置。
不推荐路径中带有空格。
留空即为默认值,重启 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="在下载时不直接复制已经存在的文件,而是重新下载每个文件。
只建议在测试下载速度时开启。" />
|
||||
<local:MyCheckBox Grid.Column="1" Text="调试模式" Height="22" x:Name="CheckDebugMode" Tag="SystemDebugMode" ToolTip="显示调试信息与更多错误信息。
这会导致启动器性能略有下降,若无特殊需要不建议开启。" />
|
||||
<local:MyCheckBox Grid.Column="2" Text="添加延迟" Height="22" x:Name="CheckDebugDelay" Tag="SystemDebugDelay" ToolTip="在各个环节添加随机的延迟,拖慢加载速度,以测试部分功能是否正常运行。
这会严重影响启动器运行,若无特殊需要不建议开启。" />
|
||||
<local:MyCheckBox Grid.Column="0" Text="禁止在下载时复制已存在的文件" Height="22" x:Name="CheckDebugSkipCopy" Tag="SystemDebugSkipCopy" ToolTip="在下载时不直接复制已经存在的文件,而是重新下载每个文件。
只建议在测试下载速度时开启。" />
|
||||
<local:MyCheckBox Grid.Column="1" Text="调试模式" Height="22" x:Name="CheckDebugMode" Tag="SystemDebugMode" ToolTip="显示调试信息与更多错误信息。
这会导致启动器性能略有下降,若无特殊需要不建议开启。" />
|
||||
<local:MyCheckBox Grid.Column="2" Text="添加延迟" Height="22" x:Name="CheckDebugDelay" Tag="SystemDebugDelay" ToolTip="在各个环节添加随机的延迟,拖慢加载速度,以测试部分功能是否正常运行。
这会严重影响启动器运行,若无特殊需要不建议开启。" />
|
||||
</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 的版本要求、重复、前置缺失等问题。
结果仅供参考,由于部分 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 的版本要求、重复、前置缺失等问题。
结果仅供参考,由于部分 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 窗口。
如果你确定你已经安装了 Mod,但仍然看到了这条提示,那么你的版本隔离设置可能有误。请尝试在启动设置中调整版本隔离选项。" TextWrapping="Wrap" />
|
||||
<TextBlock Margin="10,15,10,0" Text="要安装 Mod,请直接将 Mod 文件拖入 PCL2 窗口。
如果你确定你已经安装了 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,请在下载页面重新安装这些版本。
如果你已经安装过了 Forge 或 Fabric,那么你很可能选择了错误的版本,请点击版本选择按钮切换版本,并注意 Forge 在版本选择列表中的图标为铁砧,Fabric 的图标为丝绸。" TextWrapping="Wrap" />
|
||||
<TextBlock Grid.Row="2" Grid.ColumnSpan="4" Margin="10,15,10,5" Text="你需要先安装 Forge 或 Fabric 等 Mod 加载器才能使用 Mod,请在下载页面重新安装这些版本。
如果你已经安装过了 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="该版本默认将不会在版本列表中显示。
在版本列表页面按下 F11,即可查看所有隐藏的版本。" ToolTipService.ShowDuration="2333333" />
|
||||
<local:MyComboBoxItem Content="从版本列表中隐藏" ToolTip="该版本默认将不会在版本列表中显示。
在版本列表页面按下 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 索引与缺失、校验失败的文件。
若游戏缺失音效,请尝试此项。" 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 索引与缺失、校验失败的文件。
若游戏缺失音效,请尝试此项。" />
|
||||
<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="自定义游戏窗口的标题,若留空则使用全局设置的值。
支持以下替换标记:
 - {user}:玩家名字
 - {login}:玩家的登录方式
 - {name}:游戏版本名
 - {time}:当前的系统时间
 - {version}:游戏对应的原版版本号
 - {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="自定义游戏窗口的标题,若留空则使用全局设置的值。
支持以下替换标记:
 · {user}:玩家名字
 · {login}:玩家的登录方式
 · {name}:游戏版本名
 · {time}:当前的系统时间
 · {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 调试页面的左上角。
若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333">
|
||||
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="VersionArgumentInfo" Grid.Column="1" HintText="使用全局设置" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角。
若留空,则使用全局设置的值。">
|
||||
<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 参数,在没有确定把握的情况下请不要尝试修改。
若留空,则使用全局设置的值。" 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="文本框中的内容将会被直接拼合在启动参数的末尾。
例如输入 --demo 则会以试玩模式启动游戏。
若留空,则使用全局设置的值。" 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 等均为公用。
若存在不同版本的 Forge 或 Fabric,可能会由于 Mod 与版本冲突导致未知问题。" />
|
||||
<local:MyComboBoxItem Content="关闭" ToolTip="与其余未开启隔离的版本均使用同一档案,存档、Mod 等均为公用。
若存在不同版本的 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 文件夹。
如果你没有修改相关文件,请勿选择此项。" />
|
||||
</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 后自动进入某服务器。
用英文冒号间隔 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 后自动进入某服务器。
用英文冒号间隔 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 参数,在没有确定把握的情况下请不要尝试修改。
若留空,则使用全局设置的值。" 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="文本框中的内容将会被直接拼合在启动参数的末尾。
例如输入 --demo 则会以试玩模式启动游戏。
若留空,则使用全局设置的值。" 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 文件夹。
如果你没有修改相关文件,请勿选择此项。" />
|
||||
</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 的运行窗口一致。

可以使用以下替换标记实现相对路径(路径均以 \ 结尾):
 · {path}:PCL 的 exe 文件所在的文件夹
 · {minecraft}:.minecraft 文件夹
 · {verpath}:版本文件夹(.minecraft\versions\版本名\)
 · {verindie}:开启版本隔离时等同版本文件夹,未开启时等同 .minecraft 文件夹
 · {java}:游戏运行时的 Java 文件夹

除此之外,也支持以下替换标记:
 · {user}:玩家名字
 · {login}:玩家的登录方式
 · {uuid}:玩家的 UUID
 · {name}:游戏版本名
 · {time}:当前的系统时间
 · {version}:游戏对应的原版版本号

例如:
 · "{verpath}test.exe" :运行版本文件夹下的 test.exe 程序
 · "{java}java.exe" -jar "{verpath}test.jar" :用 Java 运行版本文件夹下的 test.jar
 · notepad "{verindie}option.txt" :使用记事本打开该版本的设置文件

涉及路径的操作最好都打上双引号,以避免路径中的空格导致运行失败。" />
|
||||
<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>
|
||||
@@ -899,5 +900,14 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\ModData.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\Skins\Ari.png" />
|
||||
<Resource Include="Images\Skins\Efe.png" />
|
||||
<Resource Include="Images\Skins\Kai.png" />
|
||||
<Resource Include="Images\Skins\Makena.png" />
|
||||
<Resource Include="Images\Skins\Noor.png" />
|
||||
<Resource Include="Images\Skins\Sunny.png" />
|
||||
<Resource Include="Images\Skins\Zuri.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -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 即可改为提示样式。
使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
|
||||
Text="将提示条的 IsWarn 属性改为 False 即可改为提示样式。
使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
|
||||
<TextBlock Margin="0,6,0,0"
|
||||
Text="卡片(local:MyCard)的 Title 属性决定了它的标题。
为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
|
||||
Text="卡片(local:MyCard)的 Title 属性决定了它的标题。
为卡片添加 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。
点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
|
||||
Text="定位游戏启动脚本" EventType="打开文件" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL2 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。
点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
|
||||
</StackPanel>
|
||||
</local:MyCard>
|
||||
|
||||
@@ -216,7 +216,7 @@ Image(图片):
|
||||
- Source:要显示的图片的网址
|
||||
|
||||
local:MyHint(提示条):
|
||||
- Text:设置显示的文本(
 代表换行)
|
||||
- Text:设置显示的文本(
 代表换行)
|
||||
- IsWarn:设置为 True 代表警告样式,False 代表提示样式
|
||||
|
||||
local:MyButton(按钮):
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Reference in new issue
Block a user