2.8.9
This commit is contained in:
@@ -102,7 +102,7 @@ Public Class Application
|
|||||||
Log($"[Start] 程序版本:{VersionDisplayName} ({VersionCode}{If(CommitHash = "", "", $",#{CommitHash}")})")
|
Log($"[Start] 程序版本:{VersionDisplayName} ({VersionCode}{If(CommitHash = "", "", $",#{CommitHash}")})")
|
||||||
Log($"[Start] 识别码:{UniqueAddress}{If(ThemeCheckOne(9), ",已解锁反馈主题", "")}")
|
Log($"[Start] 识别码:{UniqueAddress}{If(ThemeCheckOne(9), ",已解锁反馈主题", "")}")
|
||||||
Log($"[Start] 程序路径:{PathWithName}")
|
Log($"[Start] 程序路径:{PathWithName}")
|
||||||
Log($"[Start] 系统编码:{Encoding.Default} ({Encoding.Default.CodePage}, GBK={IsGBKEncoding})")
|
Log($"[Start] 系统编码:{Encoding.Default.HeaderName} ({Encoding.Default.CodePage}, GBK={IsGBKEncoding})")
|
||||||
Log($"[Start] 管理员权限:{IsAdmin()}")
|
Log($"[Start] 管理员权限:{IsAdmin()}")
|
||||||
'检测异常环境
|
'检测异常环境
|
||||||
If Path.Contains(IO.Path.GetTempPath()) OrElse Path.Contains("AppData\Local\Temp\") Then
|
If Path.Contains(IO.Path.GetTempPath()) OrElse Path.Contains("AppData\Local\Temp\") Then
|
||||||
@@ -210,8 +210,8 @@ Public Class Application
|
|||||||
If AssemblyImazenWebp Is Nothing Then
|
If AssemblyImazenWebp Is Nothing Then
|
||||||
Log("[Start] 加载 DLL:Imazen.WebP")
|
Log("[Start] 加载 DLL:Imazen.WebP")
|
||||||
AssemblyImazenWebp = Assembly.Load(GetResources("Imazen_WebP"))
|
AssemblyImazenWebp = Assembly.Load(GetResources("Imazen_WebP"))
|
||||||
SetDllDirectory(GetPureAsciiDir())
|
SetDllDirectory(PathPure.TrimEnd("\"))
|
||||||
File.WriteAllBytes(GetPureAsciiDir() & "\libwebp.dll", GetResources("libwebp64"))
|
WriteFile(PathPure & "libwebp.dll", GetResources("libwebp64"))
|
||||||
End If
|
End If
|
||||||
Return AssemblyImazenWebp
|
Return AssemblyImazenWebp
|
||||||
End SyncLock
|
End SyncLock
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Public Class MyImage
|
Public Class MyImage
|
||||||
Inherits Image
|
Inherits Image
|
||||||
|
|
||||||
#Region "辅助属性注册"
|
#Region "公开属性"
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 网络图片的缓存有效期。
|
''' 网络图片的缓存有效期。
|
||||||
@@ -22,14 +22,6 @@ Public Class MyImage
|
|||||||
End Property
|
End Property
|
||||||
Private _EnableCache As Boolean = True
|
Private _EnableCache As Boolean = True
|
||||||
|
|
||||||
'将 Source 属性映射到 XAML
|
|
||||||
Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register(
|
|
||||||
"Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback(
|
|
||||||
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString())))
|
|
||||||
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
Private _Source As String = ""
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 与 Image 的 Source 类似。
|
''' 与 Image 的 Source 类似。
|
||||||
''' 若输入以 http 开头的字符串,则会尝试下载图片然后显示,图片会保存为本地缓存。
|
''' 若输入以 http 开头的字符串,则会尝试下载图片然后显示,图片会保存为本地缓存。
|
||||||
@@ -43,74 +35,150 @@ Public Class MyImage
|
|||||||
If value = "" Then value = Nothing
|
If value = "" Then value = Nothing
|
||||||
If _Source = value Then Exit Property
|
If _Source = value Then Exit Property
|
||||||
_Source = value
|
_Source = value
|
||||||
Dim TempPath As String = $"{PathTemp}MyImage\{GetHash(value)}.png"
|
If Not IsInitialized Then Exit Property '属性读取顺序修正:在完成 XAML 属性读取后再触发图片加载(#4868)
|
||||||
|
Load()
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private _Source As String = ""
|
||||||
|
Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register(
|
||||||
|
"Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback(
|
||||||
|
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString())))
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 当 Source 首次下载失败时,会从该备用地址加载图片。
|
||||||
|
''' </summary>
|
||||||
|
Public Property FallbackSource As String
|
||||||
|
Get
|
||||||
|
Return _FallbackSource
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
_FallbackSource = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private _FallbackSource As String = Nothing
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 正在下载网络图片时显示的本地图片。
|
||||||
|
''' </summary>
|
||||||
|
Public Property LoadingSource As String
|
||||||
|
Get
|
||||||
|
Return _LoadingSource
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
_LoadingSource = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private _LoadingSource As String = "pack://application:,,,/images/Icons/NoIcon.png"
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 实际被呈现的图片地址。
|
||||||
|
''' </summary>
|
||||||
|
Public Property ActualSource As String
|
||||||
|
Get
|
||||||
|
Return _ActualSource
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
If value = "" Then value = Nothing
|
||||||
|
If _ActualSource = value Then Exit Property
|
||||||
|
_ActualSource = value
|
||||||
Try
|
Try
|
||||||
'空
|
Dim Bitmap As MyBitmap = If(value Is Nothing, Nothing, New MyBitmap(value)) '在这里先触发可能的文件读取,尽量避免在 UI 线程中读取文件
|
||||||
If value Is Nothing Then
|
RunInUiWait(Sub() MyBase.Source = Bitmap)
|
||||||
MyBase.Source = Nothing
|
|
||||||
Exit Property
|
|
||||||
End If
|
|
||||||
'本地图片
|
|
||||||
If Not value.StartsWithF("http") Then
|
|
||||||
MyBase.Source = New MyBitmap(value)
|
|
||||||
Exit Property
|
|
||||||
End If
|
|
||||||
'从缓存加载网络图片
|
|
||||||
If EnableCache AndAlso File.Exists(TempPath) Then
|
|
||||||
MyBase.Source = New MyBitmap(TempPath)
|
|
||||||
If (Date.Now - File.GetCreationTime(TempPath)) < FileCacheExpiredTime Then
|
|
||||||
Exit Property '无需刷新缓存
|
|
||||||
Else
|
|
||||||
File.Delete(TempPath) '需要刷新缓存
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
MyBase.Source = Nothing '清空显示
|
|
||||||
End If
|
|
||||||
'下载网络图片
|
|
||||||
RunInNewThread(
|
|
||||||
Sub()
|
|
||||||
Dim Url As String = value '重新捕获变量,以检测在下载过程中 Source 被修改的情况
|
|
||||||
Dim Retried As Boolean = False
|
|
||||||
RetryStart:
|
|
||||||
Dim TempDownloadingPath As String = TempPath & RandomInteger(0, 10000000)
|
|
||||||
Try
|
|
||||||
Log("[MyImage] 正在下载图片:" & Url)
|
|
||||||
NetDownload(Url, TempDownloadingPath, True)
|
|
||||||
If Url <> Source Then
|
|
||||||
'若 Source 在下载时被修改,则不显示
|
|
||||||
File.Delete(TempDownloadingPath)
|
|
||||||
ElseIf EnableCache Then
|
|
||||||
'保存缓存并显示
|
|
||||||
Rename(TempDownloadingPath, TempPath)
|
|
||||||
RunInUi(Sub() MyBase.Source = New MyBitmap(TempPath))
|
|
||||||
Else
|
|
||||||
'直接显示
|
|
||||||
RunInUiWait(Sub() MyBase.Source = New MyBitmap(TempDownloadingPath))
|
|
||||||
File.Delete(TempDownloadingPath)
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
|
||||||
Try
|
|
||||||
File.Delete(TempDownloadingPath)
|
|
||||||
Catch
|
|
||||||
End Try
|
|
||||||
If Not Retried Then
|
|
||||||
Log(ex, $"下载图片可重试地失败({Url})", LogLevel.Developer)
|
|
||||||
Retried = True
|
|
||||||
Thread.Sleep(1000)
|
|
||||||
GoTo RetryStart
|
|
||||||
Else
|
|
||||||
Log(ex, $"下载图片失败({Url})", LogLevel.Hint)
|
|
||||||
End If
|
|
||||||
End Try
|
|
||||||
End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal)
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, $"加载图片失败({value})", LogLevel.Hint)
|
Log(ex, $"加载图片失败({value})")
|
||||||
Try
|
Try
|
||||||
File.Delete(TempPath) '删除缓存,以免缓存出现问题导致一直加载失败
|
If value.StartsWithF(PathTemp) AndAlso File.Exists(value) Then File.Delete(value)
|
||||||
Catch
|
Catch
|
||||||
End Try
|
End Try
|
||||||
End Try
|
End Try
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Private _ActualSource As String = Nothing
|
||||||
|
|
||||||
End Class
|
Private Sub Load() _
|
||||||
|
Handles Me.Initialized '属性读取顺序修正:在完成 XAML 属性读取后再触发图片加载(#4868)
|
||||||
|
'空
|
||||||
|
If Source Is Nothing Then
|
||||||
|
ActualSource = Nothing
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
'本地图片
|
||||||
|
If Not Source.StartsWithF("http") Then
|
||||||
|
ActualSource = Source
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
'从缓存加载网络图片
|
||||||
|
Dim Url As String = Source
|
||||||
|
Dim Retried As Boolean = False
|
||||||
|
Dim TempPath As String = GetTempPath(Url)
|
||||||
|
Dim TempFile As New FileInfo(TempPath)
|
||||||
|
If EnableCache AndAlso TempFile.Exists Then
|
||||||
|
ActualSource = TempPath
|
||||||
|
If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Exit Sub '无需刷新缓存
|
||||||
|
End If
|
||||||
|
RunInNewThread(
|
||||||
|
Sub()
|
||||||
|
Dim TempDownloadingPath As String = Nothing
|
||||||
|
Try
|
||||||
|
RetryStart:
|
||||||
|
'下载
|
||||||
|
ActualSource = LoadingSource '显示加载中图片
|
||||||
|
TempDownloadingPath = TempPath & RandomInteger(0, 10000000)
|
||||||
|
NetDownload(Url, TempDownloadingPath, True)
|
||||||
|
If Url <> Source AndAlso Url <> FallbackSource Then
|
||||||
|
'已经更换了地址
|
||||||
|
File.Delete(TempDownloadingPath)
|
||||||
|
ElseIf EnableCache Then
|
||||||
|
'保存缓存并显示
|
||||||
|
If File.Exists(TempPath) Then File.Delete(TempPath)
|
||||||
|
Rename(TempDownloadingPath, TempPath)
|
||||||
|
RunInUi(Sub() ActualSource = TempPath)
|
||||||
|
Else
|
||||||
|
'直接显示
|
||||||
|
RunInUiWait(Sub() ActualSource = TempDownloadingPath)
|
||||||
|
File.Delete(TempDownloadingPath)
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
Try
|
||||||
|
If TempPath IsNot Nothing Then File.Delete(TempPath)
|
||||||
|
If TempDownloadingPath IsNot Nothing Then File.Delete(TempDownloadingPath)
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
If Not Retried Then
|
||||||
|
'更换备用地址
|
||||||
|
Log(ex, $"下载图片可重试地失败({Url})", LogLevel.Developer)
|
||||||
|
Retried = True
|
||||||
|
Url = If(FallbackSource, Source)
|
||||||
|
'空
|
||||||
|
If Url Is Nothing Then
|
||||||
|
ActualSource = Nothing
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
'本地图片
|
||||||
|
If Not Url.StartsWithF("http") Then
|
||||||
|
ActualSource = Url
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
'从缓存加载网络图片
|
||||||
|
TempPath = GetTempPath(Url)
|
||||||
|
TempFile = New FileInfo(TempPath)
|
||||||
|
If EnableCache AndAlso TempFile.Exists() Then
|
||||||
|
ActualSource = TempPath
|
||||||
|
If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Exit Sub '无需刷新缓存
|
||||||
|
End If
|
||||||
|
'下载
|
||||||
|
If Source = Url Then Thread.Sleep(1000) '延迟 1s 重试
|
||||||
|
GoTo RetryStart
|
||||||
|
Else
|
||||||
|
Log(ex, $"下载图片失败({Url})", LogLevel.Hint)
|
||||||
|
End If
|
||||||
|
End Try
|
||||||
|
End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal)
|
||||||
|
End Sub
|
||||||
|
Public Shared Function GetTempPath(Url As String) As String
|
||||||
|
Return $"{PathTemp}MyImage\{GetHash(Url)}.png"
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
@@ -212,33 +212,26 @@
|
|||||||
If Not _Logo = "" Then
|
If Not _Logo = "" Then
|
||||||
If _Logo.StartsWithF("http", True) Then
|
If _Logo.StartsWithF("http", True) Then
|
||||||
'网络图片
|
'网络图片
|
||||||
PathLogo = New Image With {
|
PathLogo = New MyImage With {
|
||||||
.Tag = Me,
|
.Tag = Me,
|
||||||
.IsHitTestVisible = LogoClickable,
|
.IsHitTestVisible = LogoClickable,
|
||||||
.Source = New ImageSourceConverter().ConvertFromString(_Logo),
|
.Source = _Logo,
|
||||||
.RenderTransformOrigin = New Point(0.5, 0.5),
|
.RenderTransformOrigin = New Point(0.5, 0.5),
|
||||||
.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale},
|
.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale},
|
||||||
.SnapsToDevicePixels = True, .UseLayoutRounding = False}
|
.SnapsToDevicePixels = True, .UseLayoutRounding = False}
|
||||||
RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.Linear)
|
RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.Linear)
|
||||||
ElseIf _Logo.EndsWithF(".png", True) OrElse _Logo.EndsWithF(".jpg", True) Then
|
ElseIf _Logo.EndsWithF(".png", True) OrElse _Logo.EndsWithF(".jpg", True) OrElse _Logo.EndsWithF(".webp", True) Then
|
||||||
'位图
|
'位图
|
||||||
Dim Bitmap = New MyBitmap(_Logo)
|
|
||||||
PathLogo = New Canvas With {
|
PathLogo = New Canvas With {
|
||||||
.Tag = Me,
|
.Tag = Me,
|
||||||
.IsHitTestVisible = LogoClickable,
|
.IsHitTestVisible = LogoClickable,
|
||||||
.Background = Bitmap,
|
.Background = New MyBitmap(_Logo),
|
||||||
.RenderTransformOrigin = New Point(0.5, 0.5),
|
.RenderTransformOrigin = New Point(0.5, 0.5),
|
||||||
.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale},
|
.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale},
|
||||||
.SnapsToDevicePixels = True, .UseLayoutRounding = False}
|
.SnapsToDevicePixels = True, .UseLayoutRounding = False,
|
||||||
'If Bitmap.Pic.Width = 16 AndAlso Bitmap.Pic.Height = 16 Then
|
.HorizontalAlignment = HorizontalAlignment.Stretch, .VerticalAlignment = VerticalAlignment.Stretch
|
||||||
' '使用最适合 16x16 物品图片显示的大小
|
}
|
||||||
' RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.NearestNeighbor)
|
RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.Linear)
|
||||||
' PathLogo.HorizontalAlignment = HorizontalAlignment.Center : PathLogo.VerticalAlignment = VerticalAlignment.Center
|
|
||||||
' PathLogo.Width = GetWPFSize(Math.Floor(GetPixelSize(32) / 16) * 16) : PathLogo.Height = PathLogo.Width
|
|
||||||
'Else
|
|
||||||
PathLogo.HorizontalAlignment = HorizontalAlignment.Stretch : PathLogo.VerticalAlignment = VerticalAlignment.Stretch
|
|
||||||
RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.HighQuality)
|
|
||||||
'End If
|
|
||||||
Else
|
Else
|
||||||
'矢量图
|
'矢量图
|
||||||
PathLogo = New Shapes.Path With {
|
PathLogo = New Shapes.Path With {
|
||||||
@@ -327,8 +320,8 @@
|
|||||||
Private Sub OnSizeChanged() Handles Me.SizeChanged
|
Private Sub OnSizeChanged() Handles Me.SizeChanged
|
||||||
ColumnCheck.Width = New GridLength(If(_Type = CheckType.None OrElse _Type = CheckType.Clickable, If(Height < 40, 4, 2), 6))
|
ColumnCheck.Width = New GridLength(If(_Type = CheckType.None OrElse _Type = CheckType.Clickable, If(Height < 40, 4, 2), 6))
|
||||||
ColumnLogo.Width = New GridLength(If(_Logo = "", 0, 34) + If(Height < 40, 0, 4))
|
ColumnLogo.Width = New GridLength(If(_Logo = "", 0, 34) + If(Height < 40, 0, 4))
|
||||||
If Not IsNothing(PathLogo) Then
|
If PathLogo IsNot Nothing Then
|
||||||
If _Logo.EndsWithF(".png", True) Then
|
If _Logo.EndsWithF(".png", True) OrElse _Logo.EndsWithF(".jpg", True) OrElse _Logo.EndsWithF(".webp", True) Then
|
||||||
PathLogo.Margin = New Thickness(4, 5, 3, 5)
|
PathLogo.Margin = New Thickness(4, 5, 3, 5)
|
||||||
Else
|
Else
|
||||||
PathLogo.Margin = New Thickness(If(Height < 40, 6, 8), 8, If(Height < 40, 4, 6), 8)
|
PathLogo.Margin = New Thickness(If(Height < 40, 6, 8), 8, If(Height < 40, 4, 6), 8)
|
||||||
|
|||||||
@@ -157,9 +157,7 @@
|
|||||||
End Set
|
End Set
|
||||||
End Property '内容
|
End Property '内容
|
||||||
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioBox), New PropertyMetadata(New PropertyChangedCallback(
|
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioBox), New PropertyMetadata(New PropertyChangedCallback(
|
||||||
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyRadioBox).LabText.Text = e.NewValue)))
|
||||||
If Not IsNothing(sender) Then CType(sender, MyRadioBox).LabText.Text = e.NewValue
|
|
||||||
End Sub)))
|
|
||||||
|
|
||||||
'点击事件
|
'点击事件
|
||||||
|
|
||||||
|
|||||||
@@ -117,9 +117,7 @@
|
|||||||
End Set
|
End Set
|
||||||
End Property '内容
|
End Property '内容
|
||||||
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioButton), New PropertyMetadata(New PropertyChangedCallback(
|
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioButton), New PropertyMetadata(New PropertyChangedCallback(
|
||||||
Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyRadioButton).LabText.Text = e.NewValue)))
|
||||||
If Not IsNothing(sender) Then CType(sender, MyRadioButton).LabText.Text = e.NewValue
|
|
||||||
End Sub)))
|
|
||||||
Public Enum ColorState
|
Public Enum ColorState
|
||||||
White
|
White
|
||||||
Highlight
|
Highlight
|
||||||
|
|||||||
@@ -90,21 +90,21 @@
|
|||||||
Get
|
Get
|
||||||
Return GetValue(EventTypeProperty)
|
Return GetValue(EventTypeProperty)
|
||||||
End Get
|
End Get
|
||||||
|
|
||||||
Set(value As String)
|
Set(value As String)
|
||||||
SetValue(EventTypeProperty, value)
|
SetValue(EventTypeProperty, value)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing))
|
Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register(
|
||||||
|
"EventType", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing))
|
||||||
Public Property EventData As String
|
Public Property EventData As String
|
||||||
Get
|
Get
|
||||||
Return GetValue(EventDataProperty)
|
Return GetValue(EventDataProperty)
|
||||||
End Get
|
End Get
|
||||||
|
|
||||||
Set(value As String)
|
Set(value As String)
|
||||||
SetValue(EventDataProperty, value)
|
SetValue(EventDataProperty, value)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing))
|
Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register(
|
||||||
|
"EventData", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing))
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
<GradientStop Color="{StaticResource ColorObject3}" Offset="1"/>
|
<GradientStop Color="{StaticResource ColorObject3}" Offset="1"/>
|
||||||
</LinearGradientBrush>
|
</LinearGradientBrush>
|
||||||
</Grid.Background>
|
</Grid.Background>
|
||||||
<Image x:Name="ImgTitle" IsHitTestVisible="False" Stretch="UniformToFill" IsEnabled="False" RenderOptions.BitmapScalingMode="LowQuality" />
|
<local:MyImage x:Name="ImgTitle" IsHitTestVisible="False" Stretch="UniformToFill" IsEnabled="False" RenderOptions.BitmapScalingMode="LowQuality" />
|
||||||
<local:MyIconButton x:Name="BtnTitleClose" HorizontalAlignment="Right" Height="28" VerticalAlignment="Center" Width="28" Margin="0,0,12,0" Theme="White"
|
<local:MyIconButton x:Name="BtnTitleClose" HorizontalAlignment="Right" Height="28" VerticalAlignment="Center" Width="28" Margin="0,0,12,0" Theme="White"
|
||||||
LogoScale="0.72" 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" />
|
LogoScale="0.72" 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" />
|
||||||
<local:MyIconButton x:Name="BtnTitleMin" HorizontalAlignment="Right" Height="28" VerticalAlignment="Center" Width="28" Margin="0,0,44,0" Theme="White"
|
<local:MyIconButton x:Name="BtnTitleMin" HorizontalAlignment="Right" Height="28" VerticalAlignment="Center" Width="28" Margin="0,0,44,0" Theme="White"
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Path x:Name="ShapeTitleLogo" Data="M26,29 v-25 h5 a7,7 180 0 1 0,14 h-5 M61,6.5 a10,11.5 180 1 0 0,18 M68,2.5 v24.5 h12 M98,2 v27 M107,2 v27" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="19,15.5,0,15.5" Stretch="fill" Stroke="White" StrokeThickness="1.9" Width="53" />
|
<Path x:Name="ShapeTitleLogo" Data="M26,29 v-25 h5 a7,7 180 0 1 0,14 h-5 M61,6.5 a10,11.5 180 1 0 0,18 M68,2.5 v24.5 h12 M98,2 v27 M107,2 v27" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="19,15.5,0,15.5" Stretch="fill" Stroke="White" StrokeThickness="1.9" Width="53" />
|
||||||
<TextBlock x:Name="LabTitleLogo" Visibility="Collapsed" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="18,0,0,0" Foreground="White" FontSize="17" VerticalAlignment="Center" />
|
<TextBlock x:Name="LabTitleLogo" Visibility="Collapsed" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="18,0,0,0" Foreground="White" FontSize="17" VerticalAlignment="Center" />
|
||||||
<Image x:Name="ImageTitleLogo" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="7" VerticalAlignment="Center" Visibility="Collapsed" />
|
<local:MyImage x:Name="ImageTitleLogo" SnapsToDevicePixels="False" UseLayoutRounding="False" IsHitTestVisible="False" HorizontalAlignment="Left" Margin="7" VerticalAlignment="Center" Visibility="Collapsed" />
|
||||||
<StackPanel Grid.Column="1" x:Name="PanTitleSelect" HorizontalAlignment="Left" Height="27" VerticalAlignment="Center" Orientation="Horizontal" Margin="13,0">
|
<StackPanel Grid.Column="1" x:Name="PanTitleSelect" HorizontalAlignment="Left" Height="27" VerticalAlignment="Center" Orientation="Horizontal" Margin="13,0">
|
||||||
<local:MyRadioButton x:Name="BtnTitleSelect0" Text="{DynamicResource LangTitleHome}" Tag="0" Margin="5,0" Checked="True" Padding="2,0"
|
<local:MyRadioButton x:Name="BtnTitleSelect0" Text="{DynamicResource LangTitleHome}" Tag="0" Margin="5,0" Checked="True" Padding="2,0"
|
||||||
LogoScale="0.95" Logo="M985.403 552.96C985.403 812.702 773.041 1024 512 1024S38.597 812.702 38.597 552.96c0-158.208 79.163-304.955 211.771-392.625 31.074-20.52 72.94-11.973 93.46 19.101s12.012 72.94-19.062 93.46c-94.681 62.622-151.237 167.306-151.237 280.064 0 185.344 151.788 336.108 338.471 336.108S850.471 738.304 850.471 552.96c0-114.649-57.974-220.278-155.096-282.585-31.35-20.125-40.448-61.833-20.362-93.184s61.794-40.448 93.184-20.4c135.995 87.236 217.206 235.362 217.206 396.169zM512 560.128c37.258 0 67.466-30.208 67.466-67.466V67.466C579.466 30.208 549.258 0 512 0s-67.466 30.208-67.466 67.466v425.196c0 37.258 30.208 67.466 67.466 67.466z" />
|
LogoScale="0.95" Logo="M985.403 552.96C985.403 812.702 773.041 1024 512 1024S38.597 812.702 38.597 552.96c0-158.208 79.163-304.955 211.771-392.625 31.074-20.52 72.94-11.973 93.46 19.101s12.012 72.94-19.062 93.46c-94.681 62.622-151.237 167.306-151.237 280.064 0 185.344 151.788 336.108 338.471 336.108S850.471 738.304 850.471 552.96c0-114.649-57.974-220.278-155.096-282.585-31.35-20.125-40.448-61.833-20.362-93.184s61.794-40.448 93.184-20.4c135.995 87.236 217.206 235.362 217.206 396.169zM512 560.128c37.258 0 67.466-30.208 67.466-67.466V67.466C579.466 30.208 549.258 0 512 0s-67.466 30.208-67.466 67.466v425.196c0 37.258 30.208 67.466 67.466 67.466z" />
|
||||||
|
|||||||
@@ -69,84 +69,19 @@ Public Class FormMain
|
|||||||
FeatureCount += 10
|
FeatureCount += 10
|
||||||
BugCount += 10
|
BugCount += 10
|
||||||
End If
|
End If
|
||||||
If LastVersion < 317 Then 'Release 2.6.15
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法安装 Forge 的 Bug"))
|
|
||||||
FeatureCount += 2
|
|
||||||
BugCount += 2
|
|
||||||
End If
|
|
||||||
If LastVersion < 315 Then 'Release 2.6.14
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 MC 下载,尝试解决各种导致 MC 下载失败的问题"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "由于 MCBBS 关站,移除其相关内容"))
|
|
||||||
FeatureCount += 17
|
|
||||||
BugCount += 16
|
|
||||||
End If
|
|
||||||
If LastVersion < 313 Then 'Release 2.6.13
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动 Forge 1.18.3+ 的 Bug"))
|
|
||||||
FeatureCount += 6
|
|
||||||
BugCount += 10
|
|
||||||
End If
|
|
||||||
If LastVersion < 311 Then 'Release 2.6.12
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面将显示 Mod 的中文名、图标、标签等信息"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "从 Mod 管理页面查看 Mod 信息时会跳转到其下载详情页面"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新设计 Mod 管理页面的交互与样式"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.18.3+ 的 Bug"))
|
|
||||||
FeatureCount += 27
|
|
||||||
BugCount += 25
|
|
||||||
End If
|
|
||||||
If LastVersion < 308 Then 'Release 2.6.10
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为版本独立设置添加忽略 Java 兼容性警告选项"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复开始或结束游戏时可能报错的 Bug"))
|
|
||||||
FeatureCount += 31
|
|
||||||
BugCount += 37
|
|
||||||
End If
|
|
||||||
If LastVersion < 302 Then 'Release 2.6.7
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "再次修复网络条件差时可能无法下载 MC 的 Bug"))
|
|
||||||
BugCount += 1
|
|
||||||
End If
|
|
||||||
If LastVersion < 300 Then 'Release 2.6.6
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持选择多种预设的主页"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理中允许多选 Mod 进行批量操作"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化崩溃分析,添加多种崩溃情况的判断"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化联网获取的主页的加载与缓存"))
|
|
||||||
FeatureCount += 40
|
|
||||||
BugCount += 34
|
|
||||||
End If
|
|
||||||
If LastVersion < 296 Then 'Release 2.6.3
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增内存优化功能,可以将所有程序的物理内存占用降低约 1/3"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择 OptiFine 与 Fabric 后会自动选择 OptiFabric"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化崩溃分析,添加多种崩溃情况的判断"))
|
|
||||||
FeatureCount += 21
|
|
||||||
BugCount += 30
|
|
||||||
End If
|
|
||||||
If LastVersion < 293 Then 'Release 2.6.1
|
|
||||||
BugCount += 1
|
|
||||||
End If
|
|
||||||
If LastVersion < 292 Then 'Release 2.6.0
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在多个正版账号间切换"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "在缺少 Java 时会自动下载所需的 Java"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新制作正版登录页面"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "彻底移除 Mojang 登录"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod / 整合包下载会单独列出筛选的版本"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条"))
|
|
||||||
FeatureCount += 24
|
|
||||||
BugCount += 24
|
|
||||||
End If
|
|
||||||
If LastVersion < 286 Then 'Release 2.5.2
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持搜索、安装 Modrinth 的 Mod 与整合包"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "资源搜索页面支持翻页"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在全局启动设置中添加了 启动前执行命令 选项"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "重做资源下载的资源项界面"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择下载 Fabric 时会自动选择 Fabric API"))
|
|
||||||
FeatureCount += 35
|
|
||||||
BugCount += 36
|
|
||||||
End If
|
|
||||||
#Else
|
#Else
|
||||||
'5: FEAT+
|
'5: FEAT+
|
||||||
'4: IMP+ FEAT*
|
'4: IMP+ FEAT*
|
||||||
'3:BUG+ IMP* FEAT-
|
'3:BUG+ IMP* FEAT-
|
||||||
'2:BUG* IMP-
|
'2:BUG* IMP-
|
||||||
'1:BUG-
|
'1:BUG-
|
||||||
|
If LastVersion < 341 Then 'Snapshot 2.8.9
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持下载原版服务端"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "本地 Mod 的标题支持选择显示 Mod 原始文件名"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复搜索后启用/禁用 Mod 时出错的 Bug"))
|
||||||
|
FeatureCount += 17
|
||||||
|
BugCount += 13
|
||||||
|
End If
|
||||||
If LastVersion < 339 Then 'Snapshot 2.8.8
|
If LastVersion < 339 Then 'Snapshot 2.8.8
|
||||||
If LastVersion = 337 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复数个与新正版登录相关的严重 Bug"))
|
If LastVersion = 337 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复数个与新正版登录相关的严重 Bug"))
|
||||||
FeatureCount += 3
|
FeatureCount += 3
|
||||||
@@ -233,117 +168,6 @@ Public Class FormMain
|
|||||||
FeatureCount += 10
|
FeatureCount += 10
|
||||||
BugCount += 10
|
BugCount += 10
|
||||||
End If
|
End If
|
||||||
If LastVersion < 316 Then 'Snapshot 2.6.15
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法安装 Forge 的 Bug"))
|
|
||||||
FeatureCount += 2
|
|
||||||
BugCount += 2
|
|
||||||
End If
|
|
||||||
If LastVersion < 314 Then 'Snapshot 2.6.14
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 MC 下载,尝试解决各种导致 MC 下载失败的问题"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "由于 MCBBS 关站,移除其相关内容"))
|
|
||||||
FeatureCount += 17
|
|
||||||
BugCount += 16
|
|
||||||
End If
|
|
||||||
If LastVersion < 312 Then 'Snapshot 2.6.13
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动 Forge 1.18.3+ 的 Bug"))
|
|
||||||
FeatureCount += 6
|
|
||||||
BugCount += 10
|
|
||||||
End If
|
|
||||||
If LastVersion < 310 Then 'Snapshot 2.6.12
|
|
||||||
If LastVersion = 309 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理页面添加启用、禁用单个 Mod 的快捷按钮"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.18.3+ 的 Bug"))
|
|
||||||
FeatureCount += 13
|
|
||||||
BugCount += 12
|
|
||||||
End If
|
|
||||||
If LastVersion < 309 Then 'Snapshot 2.6.11
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面将显示 Mod 的中文名、图标、标签等信息"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "从 Mod 管理页面查看 Mod 信息时会跳转到其下载详情页面"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新设计 Mod 管理页面的交互与样式"))
|
|
||||||
FeatureCount += 15
|
|
||||||
BugCount += 13
|
|
||||||
End If
|
|
||||||
If LastVersion < 307 Then 'Snapshot 2.6.10
|
|
||||||
FeatureCount += 2
|
|
||||||
BugCount += 3
|
|
||||||
End If
|
|
||||||
If LastVersion < 306 Then 'Snapshot 2.6.9
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为版本独立设置添加忽略 Java 兼容性警告选项"))
|
|
||||||
FeatureCount += 9
|
|
||||||
BugCount += 11
|
|
||||||
End If
|
|
||||||
If LastVersion < 305 Then 'Snapshot 2.6.8
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复开始或结束游戏时可能报错的 Bug"))
|
|
||||||
FeatureCount += 20
|
|
||||||
BugCount += 25
|
|
||||||
End If
|
|
||||||
If LastVersion < 303 Then 'Snapshot 2.6.7
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "再次修复网络条件差时可能无法下载 MC 的 Bug"))
|
|
||||||
BugCount += 1
|
|
||||||
End If
|
|
||||||
If LastVersion < 301 Then 'Snapshot 2.6.6
|
|
||||||
FeatureCount += 4
|
|
||||||
BugCount += 2
|
|
||||||
End If
|
|
||||||
If LastVersion < 299 Then 'Snapshot 2.6.5
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持选择多种预设的主页"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化联网获取的主页的加载与缓存"))
|
|
||||||
FeatureCount += 18
|
|
||||||
BugCount += 13
|
|
||||||
End If
|
|
||||||
If LastVersion < 298 Then 'Snapshot 2.6.4
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理中允许多选 Mod 进行批量操作"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化崩溃分析,添加多种崩溃情况的判断"))
|
|
||||||
FeatureCount += 18
|
|
||||||
BugCount += 19
|
|
||||||
End If
|
|
||||||
If LastVersion < 297 Then 'Snapshot 2.6.3
|
|
||||||
FeatureCount += 12
|
|
||||||
BugCount += 14
|
|
||||||
End If
|
|
||||||
If LastVersion < 294 Then 'Snapshot 2.6.2
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增内存优化功能,可以将所有程序的物理内存占用降低约 1/3"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择 OptiFine 与 Fabric 后会自动选择 OptiFabric"))
|
|
||||||
FeatureCount += 9
|
|
||||||
BugCount += 16
|
|
||||||
End If
|
|
||||||
If LastVersion < 291 Then 'Snapshot 2.6.0
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在多个正版账号间切换"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod / 整合包下载会单独列出筛选的版本"))
|
|
||||||
FeatureCount += 10
|
|
||||||
BugCount += 2
|
|
||||||
End If
|
|
||||||
If LastVersion < 289 Then 'Snapshot 2.5.4
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新制作正版登录页面"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "彻底移除 Mojang 登录"))
|
|
||||||
FeatureCount += 6
|
|
||||||
BugCount += 14
|
|
||||||
End If
|
|
||||||
If LastVersion < 288 Then 'Snapshot 2.5.3
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "在缺少 Java 时会自动下载所需的 Java"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条"))
|
|
||||||
FeatureCount += 8
|
|
||||||
BugCount += 8
|
|
||||||
End If
|
|
||||||
If LastVersion < 285 Then 'Snapshot 2.5.2
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "重做资源下载的资源项界面"))
|
|
||||||
If LastVersion = 284 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复打开部分帮助报错的 Bug"))
|
|
||||||
FeatureCount += 8
|
|
||||||
BugCount += 8
|
|
||||||
End If
|
|
||||||
If LastVersion < 284 Then 'Snapshot 2.5.1
|
|
||||||
If LastVersion >= 275 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在全局启动设置中添加了 启动前执行命令 选项"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择下载 Fabric 时会自动选择 Fabric API"))
|
|
||||||
FeatureCount += 22
|
|
||||||
BugCount += 21
|
|
||||||
End If
|
|
||||||
If LastVersion < 283 Then 'Snapshot 2.5.0
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持搜索、下载 Modrinth 中的 Mod 与整合包"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "资源搜索页面支持翻页"))
|
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持安装 Modrinth 整合包"))
|
|
||||||
FeatureCount += 5
|
|
||||||
BugCount += 5
|
|
||||||
End If
|
|
||||||
#End If
|
#End If
|
||||||
'整理更新日志文本
|
'整理更新日志文本
|
||||||
Dim ContentList As New List(Of String)
|
Dim ContentList As New List(Of String)
|
||||||
@@ -386,9 +210,6 @@ Public Class FormMain
|
|||||||
'触发降级
|
'触发降级
|
||||||
DowngradeSub(LastVersion)
|
DowngradeSub(LastVersion)
|
||||||
End If
|
End If
|
||||||
''刷新语言
|
|
||||||
'Lang = ReadReg("Lang", "zh_CN")
|
|
||||||
'Application.Current.Resources.MergedDictionaries(1) = New ResourceDictionary With {.Source = New Uri("Resources\Language\" & Lang & ".xaml", UriKind.Relative)}
|
|
||||||
'刷新主题
|
'刷新主题
|
||||||
ThemeCheckAll(False)
|
ThemeCheckAll(False)
|
||||||
Setup.Load("UiLauncherTheme")
|
Setup.Load("UiLauncherTheme")
|
||||||
@@ -451,12 +272,12 @@ Public Class FormMain
|
|||||||
'加载窗口
|
'加载窗口
|
||||||
ThemeRefreshMain()
|
ThemeRefreshMain()
|
||||||
Try
|
Try
|
||||||
Height = ReadReg("WindowHeight", MinHeight + 50)
|
Height = Setup.Get("WindowHeight")
|
||||||
Width = ReadReg("WindowWidth", MinWidth + 50)
|
Width = Setup.Get("WindowWidth")
|
||||||
Catch ex As Exception '修复 #2019
|
Catch ex As Exception '修复 #2019
|
||||||
Log(ex, "读取窗口默认大小失败", LogLevel.Hint)
|
Log(ex, "读取窗口默认大小失败", LogLevel.Hint)
|
||||||
Height = MinHeight + 50
|
Height = MinHeight + 100
|
||||||
Width = MinWidth + 50
|
Width = MinWidth + 100
|
||||||
End Try
|
End Try
|
||||||
#If DEBUG Then
|
#If DEBUG Then
|
||||||
MinHeight = 50
|
MinHeight = 50
|
||||||
@@ -595,6 +416,16 @@ Public Class FormMain
|
|||||||
Setup.Set("UiHiddenOtherHelp", False)
|
Setup.Set("UiHiddenOtherHelp", False)
|
||||||
Log("[Start] 已解除帮助页面的隐藏")
|
Log("[Start] 已解除帮助页面的隐藏")
|
||||||
End If
|
End If
|
||||||
|
'单向迁移微软登录结果(#4836)
|
||||||
|
If Not Setup.Get("CacheMsV2Migrated") Then
|
||||||
|
Setup.Set("CacheMsV2Migrated", True)
|
||||||
|
Setup.Set("CacheMsV2OAuthRefresh", Setup.Get("CacheMsOAuthRefresh"))
|
||||||
|
Setup.Set("CacheMsV2Access", Setup.Get("CacheMsAccess"))
|
||||||
|
Setup.Set("CacheMsV2ProfileJson", Setup.Get("CacheMsProfileJson"))
|
||||||
|
Setup.Set("CacheMsV2Uuid", Setup.Get("CacheMsUuid"))
|
||||||
|
Setup.Set("CacheMsV2Name", Setup.Get("CacheMsName"))
|
||||||
|
Log("[Start] 已从老版本迁移微软登录结果")
|
||||||
|
End If
|
||||||
'输出更新日志
|
'输出更新日志
|
||||||
If LastVersionCode = 0 Then Exit Sub
|
If LastVersionCode = 0 Then Exit Sub
|
||||||
If LowerVersionCode >= VersionCode Then Exit Sub
|
If LowerVersionCode >= VersionCode Then Exit Sub
|
||||||
@@ -636,35 +467,35 @@ Public Class FormMain
|
|||||||
End If
|
End If
|
||||||
'关闭
|
'关闭
|
||||||
RunInUiWait(
|
RunInUiWait(
|
||||||
Sub()
|
Sub()
|
||||||
IsHitTestVisible = False
|
IsHitTestVisible = False
|
||||||
If PanBack.RenderTransform Is Nothing Then
|
If PanBack.RenderTransform Is Nothing Then
|
||||||
Dim TransformPos As New TranslateTransform(0, 0)
|
Dim TransformPos As New TranslateTransform(0, 0)
|
||||||
Dim TransformRotate As New RotateTransform(0)
|
Dim TransformRotate As New RotateTransform(0)
|
||||||
Dim TransformScale As New ScaleTransform(1, 1)
|
Dim TransformScale As New ScaleTransform(1, 1)
|
||||||
PanBack.RenderTransform = New TransformGroup() With {.Children = New TransformCollection({TransformRotate, TransformPos, TransformScale})}
|
PanBack.RenderTransform = New TransformGroup() With {.Children = New TransformCollection({TransformRotate, TransformPos, TransformScale})}
|
||||||
AniStart({
|
AniStart({
|
||||||
AaOpacity(Me, -Opacity, 140, 40, New AniEaseOutFluent(AniEasePower.Weak)),
|
AaOpacity(Me, -Opacity, 140, 40, New AniEaseOutFluent(AniEasePower.Weak)),
|
||||||
AaDouble(
|
AaDouble(
|
||||||
Sub(i)
|
Sub(i)
|
||||||
TransformScale.ScaleX += i
|
TransformScale.ScaleX += i
|
||||||
TransformScale.ScaleY += i
|
TransformScale.ScaleY += i
|
||||||
End Sub, 0.88 - TransformScale.ScaleX, 180),
|
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) 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)),
|
AaDouble(Sub(i) TransformRotate.Angle += i, 0.6 - TransformRotate.Angle, 180, 0, New AniEaseInoutFluent(AniEasePower.Weak)),
|
||||||
AaCode(
|
AaCode(
|
||||||
Sub()
|
Sub()
|
||||||
IsHitTestVisible = False
|
IsHitTestVisible = False
|
||||||
Top = -10000
|
Top = -10000
|
||||||
ShowInTaskbar = False
|
ShowInTaskbar = False
|
||||||
End Sub, 210),
|
End Sub, 210),
|
||||||
AaCode(AddressOf EndProgramForce, 230)
|
AaCode(AddressOf EndProgramForce, 230)
|
||||||
}, "Form Close")
|
}, "Form Close")
|
||||||
Else
|
Else
|
||||||
EndProgramForce()
|
EndProgramForce()
|
||||||
End If
|
End If
|
||||||
Log("[System] 收到关闭指令")
|
Log("[System] 收到关闭指令")
|
||||||
End Sub)
|
End Sub)
|
||||||
End Sub
|
End Sub
|
||||||
Private Shared IsLogShown As Boolean = False
|
Private Shared IsLogShown As Boolean = False
|
||||||
Public Shared Sub EndProgramForce(Optional ReturnCode As Result = Result.Success)
|
Public Shared Sub EndProgramForce(Optional ReturnCode As Result = Result.Success)
|
||||||
@@ -709,8 +540,8 @@ Public Class FormMain
|
|||||||
Public IsSizeSaveable As Boolean = False
|
Public IsSizeSaveable As Boolean = False
|
||||||
Private Sub FormMain_SizeChanged() Handles Me.SizeChanged, Me.Loaded
|
Private Sub FormMain_SizeChanged() Handles Me.SizeChanged, Me.Loaded
|
||||||
If IsSizeSaveable Then
|
If IsSizeSaveable Then
|
||||||
WriteReg("WindowHeight", Height)
|
Setup.Set("WindowHeight", Height)
|
||||||
WriteReg("WindowWidth", Width)
|
Setup.Set("WindowWidth", Width)
|
||||||
End If
|
End If
|
||||||
RectForm.Rect = New Rect(0, 0, BorderForm.ActualWidth, BorderForm.ActualHeight)
|
RectForm.Rect = New Rect(0, 0, BorderForm.ActualWidth, BorderForm.ActualHeight)
|
||||||
PanForm.Width = BorderForm.ActualWidth + 0.001
|
PanForm.Width = BorderForm.ActualWidth + 0.001
|
||||||
@@ -921,11 +752,12 @@ Public Class FormMain
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
CopyFile(FilePath, Path & "PCL\Custom.xaml")
|
CopyFile(FilePath, Path & "PCL\Custom.xaml")
|
||||||
RunInUi(Sub()
|
RunInUi(
|
||||||
Setup.Set("UiCustomType", 1)
|
Sub()
|
||||||
FrmLaunchRight.ForceRefresh()
|
Setup.Set("UiCustomType", 1)
|
||||||
Hint("已加载主页自定义文件!", HintType.Finish)
|
FrmLaunchRight.ForceRefresh()
|
||||||
End Sub)
|
Hint("已加载主页自定义文件!", HintType.Finish)
|
||||||
|
End Sub)
|
||||||
Exit Sub
|
Exit Sub
|
||||||
End If
|
End If
|
||||||
'Mod 安装
|
'Mod 安装
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ Public Module ModBase
|
|||||||
#Region "声明"
|
#Region "声明"
|
||||||
|
|
||||||
'下列版本信息由更新器自动修改
|
'下列版本信息由更新器自动修改
|
||||||
Public Const VersionBaseName As String = "2.8.8" '不含分支前缀的显示用版本名
|
Public Const VersionBaseName As String = "2.8.9" '不含分支前缀的显示用版本名
|
||||||
Public Const VersionStandardCode As String = "2.8.8." & VersionBranchCode '标准格式的四段式版本号
|
Public Const VersionStandardCode As String = "2.8.9." & VersionBranchCode '标准格式的四段式版本号
|
||||||
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
|
||||||
#If BETA Then
|
#If BETA Then
|
||||||
Public Const VersionCode As Integer = 340 'Release
|
Public Const VersionCode As Integer = 340 'Release
|
||||||
#Else
|
#Else
|
||||||
Public Const VersionCode As Integer = 339 'Snapshot
|
Public Const VersionCode As Integer = 341 'Snapshot
|
||||||
#End If
|
#End If
|
||||||
'自动生成的版本信息
|
'自动生成的版本信息
|
||||||
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
||||||
@@ -176,9 +176,9 @@ Public Module ModBase
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Const IconButtonOffline As String = "M533.293176 788.841412a60.235294 60.235294 0 1 1 85.202824 85.202823l-42.616471 42.586353c-129.355294 129.385412-339.124706 129.385412-468.510117 0-129.385412-129.385412-129.385412-339.124706 0-468.510117l42.586353-42.616471a60.235294 60.235294 0 1 1 85.202823 85.202824l-42.61647 42.586352a210.823529 210.823529 0 1 0 298.164706 298.164706l42.586352-42.61647z m255.548236-255.548236l42.61647-42.586352a210.823529 210.823529 0 1 0-298.164706-298.164706l-42.586352 42.61647a60.235294 60.235294 0 1 1-85.202824-85.202823l42.616471-42.586353c129.355294-129.385412 339.124706-129.385412 468.510117 0 129.385412 129.385412 129.385412 339.124706 0 468.510117l-42.586353 42.616471a60.235294 60.235294 0 1 1-85.202823-85.202824zM192.542118 192.542118a60.235294 60.235294 0 0 1 85.202823 0l553.712941 553.712941a60.235294 60.235294 0 0 1-85.202823 85.202823L192.542118 277.744941a60.235294 60.235294 0 0 1 0-85.202823z"
|
Public Const IconButtonOffline As String = "M533.293176 788.841412a60.235294 60.235294 0 1 1 85.202824 85.202823l-42.616471 42.586353c-129.355294 129.385412-339.124706 129.385412-468.510117 0-129.385412-129.385412-129.385412-339.124706 0-468.510117l42.586353-42.616471a60.235294 60.235294 0 1 1 85.202823 85.202824l-42.61647 42.586352a210.823529 210.823529 0 1 0 298.164706 298.164706l42.586352-42.61647z m255.548236-255.548236l42.61647-42.586352a210.823529 210.823529 0 1 0-298.164706-298.164706l-42.586352 42.61647a60.235294 60.235294 0 1 1-85.202824-85.202823l42.616471-42.586353c129.355294-129.385412 339.124706-129.385412 468.510117 0 129.385412 129.385412 129.385412 339.124706 0 468.510117l-42.586353 42.616471a60.235294 60.235294 0 1 1-85.202823-85.202824zM192.542118 192.542118a60.235294 60.235294 0 0 1 85.202823 0l553.712941 553.712941a60.235294 60.235294 0 0 1-85.202823 85.202823L192.542118 277.744941a60.235294 60.235294 0 0 1 0-85.202823z"
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 图标,音符,1x
|
''' 图标,服务端,1x
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Const IconButtonServer As String = "M640 725.333333a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m-256 0H256a42.666667 42.666667 0 0 0 0 85.333334h128a42.666667 42.666667 0 1 0 0-85.333334z m384 0a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m-128-256a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m-256 0H256a42.666667 42.666667 0 1 0 0 85.333334h128a42.666667 42.666667 0 1 0 0-85.333334z m384-256a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m0 256a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m170.666667-256a128 128 0 0 0-128-128H213.333333a128 128 0 0 0-128 128v85.333334a128 128 0 0 0 33.28 85.333333A128 128 0 0 0 85.333333 469.333333v85.333334a128 128 0 0 0 33.28 85.333333A128 128 0 0 0 85.333333 725.333333v85.333334a128 128 0 0 0 128 128h597.333334a128 128 0 0 0 128-128v-85.333334a128 128 0 0 0-33.28-85.333333 128 128 0 0 0 33.28-85.333333v-85.333334a128 128 0 0 0-33.28-85.333333A128 128 0 0 0 938.666667 298.666667V213.333333z m-85.333334 597.333334a42.666667 42.666667 0 0 1-42.666666 42.666666H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666666v-85.333334a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334a42.666667 42.666667 0 0 1 42.666666 42.666666v85.333334z m0-256a42.666667 42.666667 0 0 1-42.666666 42.666666H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666666v-85.333334a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334a42.666667 42.666667 0 0 1 42.666666 42.666666v85.333334z m0-256a42.666667 42.666667 0 0 1-42.666666 42.666666H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666666V213.333333a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334a42.666667 42.666667 0 0 1 42.666666 42.666666v85.333334z m-213.333333-85.333334a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334zM384 213.333333H256a42.666667 42.666667 0 1 0 0 85.333334h128a42.666667 42.666667 0 1 0 0-85.333334z"
|
Public Const IconButtonServer As String = "M224 160a64 64 0 0 0-64 64v576a64 64 0 0 0 64 64h576a64 64 0 0 0 64-64V224a64 64 0 0 0-64-64H224z m0 384h576v256H224v-256z m192 96v64h320v-64H416z m-128 0v64h64v-64H288zM224 224h576v256H224V224z m192 96v64h320v-64H416z m-128 0v64h64v-64H288z"
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 图标,音符,1x
|
''' 图标,音符,1x
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@@ -1348,8 +1348,8 @@ RetryDir:
|
|||||||
|
|
||||||
'常见错误(记得同时修改下面的)
|
'常见错误(记得同时修改下面的)
|
||||||
Dim CommonReason As String = Nothing
|
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
|
If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is BadImageFormatException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then
|
||||||
CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。"
|
CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。"
|
||||||
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
|
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
|
||||||
CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
||||||
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
||||||
@@ -1368,7 +1368,7 @@ RetryDir:
|
|||||||
If CommonReason Is Nothing Then
|
If CommonReason Is Nothing Then
|
||||||
Return Desc & Stack & TypeDesc
|
Return Desc & Stack & TypeDesc
|
||||||
Else
|
Else
|
||||||
Dim Result As String = DescList.First & vbCrLf & CommonReason & vbCrLf & "————————————" & vbCrLf
|
Dim Result As String = CommonReason & vbCrLf & DescList.First & vbCrLf & "————————————" & vbCrLf
|
||||||
DescList(0) = "详细错误信息:"
|
DescList(0) = "详细错误信息:"
|
||||||
Return Result & Join(DescList, vbCrLf & "→ ") & Stack & TypeDesc
|
Return Result & Join(DescList, vbCrLf & "→ ") & Stack & TypeDesc
|
||||||
End If
|
End If
|
||||||
@@ -1396,8 +1396,8 @@ RetryDir:
|
|||||||
|
|
||||||
'常见错误(记得同时修改上面的)
|
'常见错误(记得同时修改上面的)
|
||||||
Dim CommonReason As String = Nothing
|
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
|
If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is BadImageFormatException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then
|
||||||
CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。"
|
CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。"
|
||||||
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
|
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
|
||||||
CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
||||||
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
||||||
@@ -1411,7 +1411,7 @@ RetryDir:
|
|||||||
|
|
||||||
'构造输出信息
|
'构造输出信息
|
||||||
If CommonReason IsNot Nothing Then
|
If CommonReason IsNot Nothing Then
|
||||||
Return DescList.First & ":" & CommonReason
|
Return CommonReason & "详细错误:" & DescList.First
|
||||||
Else
|
Else
|
||||||
DescList.Reverse() '让最深层错误在最左边
|
DescList.Reverse() '让最深层错误在最左边
|
||||||
Return Join(DescList, " → ")
|
Return Join(DescList, " → ")
|
||||||
@@ -1721,16 +1721,6 @@ RetryDir:
|
|||||||
Public Function RegexReplaceEach(Input As String, Replacement As MatchEvaluator, Regex As String, Optional options As RegexOptions = RegularExpressions.RegexOptions.None) As String
|
Public Function RegexReplaceEach(Input As String, Replacement As MatchEvaluator, Regex As String, Optional options As RegexOptions = RegularExpressions.RegexOptions.None) As String
|
||||||
Return RegularExpressions.Regex.Replace(Input, Regex, Replacement, options)
|
Return RegularExpressions.Regex.Replace(Input, Regex, Replacement, options)
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
|
||||||
''' 检查传入字符串会不会引发 Issue #4505
|
|
||||||
''' </summary>
|
|
||||||
Public Function Ntfs83NameCheck(name As String) As Boolean
|
|
||||||
Dim regex As New Regex("(.*)~(\d*)")
|
|
||||||
Dim namePart As Byte() = Encoding.UTF8.GetBytes(regex.Match(name).Groups(1).Value)
|
|
||||||
Dim numPart As Integer = regex.Match(name).Groups(2).Value.Length
|
|
||||||
|
|
||||||
Return namePart.Length >= 6 AndAlso numPart = 1
|
|
||||||
End Function
|
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
@@ -1822,10 +1812,10 @@ RetryDir:
|
|||||||
'进行搜索,获取相似信息
|
'进行搜索,获取相似信息
|
||||||
For Each Entry In Entries
|
For Each Entry In Entries
|
||||||
Entry.Similarity = SearchSimilarityWeighted(Entry.SearchSource, Query)
|
Entry.Similarity = SearchSimilarityWeighted(Entry.SearchSource, Query)
|
||||||
Entry.AbsoluteRight = False
|
Entry.AbsoluteRight =
|
||||||
For Each Pair In Entry.SearchSource
|
Query.Split(" ").All( '对于按空格分割的每一段
|
||||||
If Pair.Key.Replace(" ", "").ContainsF(Query.Replace(" ", ""), True) Then Entry.AbsoluteRight = True
|
Function(QueryPart) Entry.SearchSource.Any( '若与任意一个搜索源完全匹配,则标记为完全匹配项
|
||||||
Next
|
Function(Source) Source.Key.Replace(" ", "").ContainsF(QueryPart, True)))
|
||||||
Next
|
Next
|
||||||
'按照相似度进行排序
|
'按照相似度进行排序
|
||||||
Entries = Sort(Entries,
|
Entries = Sort(Entries,
|
||||||
@@ -1854,10 +1844,26 @@ RetryDir:
|
|||||||
|
|
||||||
#Region "系统"
|
#Region "系统"
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 可用于临时存放文件的,不含任何特殊字符的文件夹路径,以“\”结尾。
|
||||||
|
''' </summary>
|
||||||
|
Public PathPure As String = GetPureASCIIDir()
|
||||||
|
Private Function GetPureASCIIDir() As String
|
||||||
|
If (Path & "PCL").IsASCII() Then
|
||||||
|
Return Path & "PCL\"
|
||||||
|
ElseIf PathAppdata.IsASCII() Then
|
||||||
|
Return PathAppdata
|
||||||
|
ElseIf PathTemp.IsASCII() Then
|
||||||
|
Return PathTemp
|
||||||
|
Else
|
||||||
|
Return OsDrive & "ProgramData\PCL\"
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 指示接取到这个异常的函数进行重试。
|
''' 指示接取到这个异常的函数进行重试。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Class RetryException
|
Public Class RestartException
|
||||||
Inherits Exception
|
Inherits Exception
|
||||||
End Class
|
End Class
|
||||||
|
|
||||||
|
|||||||
@@ -939,7 +939,6 @@ RequestFinished:
|
|||||||
Dim StartPosition As Long, StartSource As NetSource = Nothing
|
Dim StartPosition As Long, StartSource As NetSource = Nothing
|
||||||
Dim Th As Thread, ThreadInfo As NetThread
|
Dim Th As Thread, ThreadInfo As NetThread
|
||||||
SyncLock LockChain
|
SyncLock LockChain
|
||||||
|
|
||||||
'获取线程起点与下载源
|
'获取线程起点与下载源
|
||||||
'不分割
|
'不分割
|
||||||
If IsNoSplit Then GoTo Capture
|
If IsNoSplit Then GoTo Capture
|
||||||
@@ -1049,6 +1048,15 @@ StartThread:
|
|||||||
If ModeDebug AndAlso HttpResponse.ResponseUri.OriginalString <> Info.Source.Url Then
|
If ModeDebug AndAlso HttpResponse.ResponseUri.OriginalString <> Info.Source.Url Then
|
||||||
Log($"[Download] {LocalName} {Info.Uuid}#:重定向至 {HttpResponse.ResponseUri.OriginalString}")
|
Log($"[Download] {LocalName} {Info.Uuid}#:重定向至 {HttpResponse.ResponseUri.OriginalString}")
|
||||||
End If
|
End If
|
||||||
|
''从响应头获取文件名
|
||||||
|
'If Info.IsFirstThread Then
|
||||||
|
' Dim FileName As String = GetFileNameFromResponse(HttpResponse)
|
||||||
|
' If ModeDebug Then Log($"[Download] {LocalName} {Info.Uuid}#:远程文件名:{If(FileName, "未提供")}")
|
||||||
|
' If FileName IsNot Nothing AndAlso LocalName = "待定" Then
|
||||||
|
' LocalName = FileName
|
||||||
|
' Log($"[Download] {LocalName} {Info.Uuid}#:从响应头获取到文件名")
|
||||||
|
' End If
|
||||||
|
'End If
|
||||||
'文件大小校验
|
'文件大小校验
|
||||||
ContentLength = HttpResponse.ContentLength
|
ContentLength = HttpResponse.ContentLength
|
||||||
If ContentLength = -1 Then
|
If ContentLength = -1 Then
|
||||||
@@ -1133,7 +1141,7 @@ NotSupportRange:
|
|||||||
If NetTaskSpeedLimitHigh > 0 Then NetTaskSpeedLimitLeft -= RealDataCount
|
If NetTaskSpeedLimitHigh > 0 Then NetTaskSpeedLimitLeft -= RealDataCount
|
||||||
End SyncLock
|
End SyncLock
|
||||||
Dim DeltaTime = GetTimeTick() - Info.LastReceiveTime
|
Dim DeltaTime = GetTimeTick() - Info.LastReceiveTime
|
||||||
If DeltaTime > 1000000 Then DeltaTime = 0 '时间刻反转导致出现极大值
|
If DeltaTime > 1000000 Then DeltaTime = 1 '时间刻反转导致出现极大值
|
||||||
If RealDataCount > 0 Then
|
If RealDataCount > 0 Then
|
||||||
'有数据
|
'有数据
|
||||||
If Info.DownloadDone = 0 Then
|
If Info.DownloadDone = 0 Then
|
||||||
@@ -1174,7 +1182,7 @@ NotSupportRange:
|
|||||||
ResultStream.Write(HttpData, 0, RealDataCount)
|
ResultStream.Write(HttpData, 0, RealDataCount)
|
||||||
End If
|
End If
|
||||||
'检查速度是否过慢
|
'检查速度是否过慢
|
||||||
If DeltaTime > 1000 AndAlso DeltaTime > RealDataCount Then '数据包间隔大于 1s,且速度小于 1K/s
|
If DeltaTime > 1500 AndAlso DeltaTime > RealDataCount Then '数据包间隔大于 1.5s,且速度小于 1.5K/s
|
||||||
Throw New TimeoutException("由于速度过慢断开链接,下载 " & RealDataCount & " B,消耗 " & DeltaTime & " ms。")
|
Throw New TimeoutException("由于速度过慢断开链接,下载 " & RealDataCount & " B,消耗 " & DeltaTime & " ms。")
|
||||||
End If
|
End If
|
||||||
Info.LastReceiveTime = GetTimeTick()
|
Info.LastReceiveTime = GetTimeTick()
|
||||||
@@ -1286,6 +1294,17 @@ Wrong:
|
|||||||
If ((FileSize >= 0 AndAlso DownloadDone >= FileSize) OrElse (FileSize = -1 AndAlso DownloadDone > 0)) AndAlso State < NetState.Merge Then Merge()
|
If ((FileSize >= 0 AndAlso DownloadDone >= FileSize) OrElse (FileSize = -1 AndAlso DownloadDone > 0)) AndAlso State < NetState.Merge Then Merge()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
''' <summary>
|
||||||
|
''' 从 HTTP 响应头中获取文件名。
|
||||||
|
''' 如果没有,返回 Nothing。
|
||||||
|
''' </summary>
|
||||||
|
Private Function GetFileNameFromResponse(response As HttpWebResponse) As String
|
||||||
|
Dim header As String = response.Headers("Content-Disposition")
|
||||||
|
If String.IsNullOrEmpty(header) Then Return Nothing
|
||||||
|
'attachment; filename="filename.ext"
|
||||||
|
If Not header.Contains("filename=") Then Return Nothing
|
||||||
|
Return header.After("filename=").Trim(""""c, " "c).Before(";")
|
||||||
|
End Function
|
||||||
|
|
||||||
'下载文件的最终收束事件
|
'下载文件的最终收束事件
|
||||||
''' <summary>
|
''' <summary>
|
||||||
|
|||||||
@@ -233,8 +233,8 @@ Public Class ValidateFolderName
|
|||||||
'检查特殊字符串
|
'检查特殊字符串
|
||||||
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)
|
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 Not InvalidStrCheck = "" Then Return InvalidStrCheck
|
||||||
'检查 NTFS 8.3 (issue #4505)
|
'检查 NTFS 8.3 文件名(#4505)
|
||||||
If Ntfs83NameCheck(Str) Then Return "文件夹名不能是一个有效的 NTFS 8.3 文件名!"
|
If RegexCheck(Str, ".{2,}~\d") Then Return "文件夹名不能包含这一特殊格式!"
|
||||||
'检查文件夹重名
|
'检查文件夹重名
|
||||||
Dim Arr As New List(Of String)
|
Dim Arr As New List(Of String)
|
||||||
If PathIgnore IsNot Nothing Then
|
If PathIgnore IsNot Nothing Then
|
||||||
@@ -288,8 +288,8 @@ Public Class ValidateFileName
|
|||||||
'检查特殊字符串
|
'检查特殊字符串
|
||||||
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)
|
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 Not InvalidStrCheck = "" Then Return InvalidStrCheck
|
||||||
'检查 NTFS 8.3 (issue #4505)
|
'检查 NTFS 8.3 文件名(#4505)
|
||||||
If Ntfs83NameCheck(Str) Then Return "文件名不能是一个有效的 NTFS 8.3 文件名!"
|
If RegexCheck(Str, ".{2,}~\d") Then Return "文件名不能包含这一特殊格式!"
|
||||||
'检查文件重名
|
'检查文件重名
|
||||||
If ParentFolder IsNot Nothing Then
|
If ParentFolder IsNot Nothing Then
|
||||||
Dim DirInfo As New DirectoryInfo(ParentFolder)
|
Dim DirInfo As New DirectoryInfo(ParentFolder)
|
||||||
@@ -355,9 +355,9 @@ Fin:
|
|||||||
'检查特殊字符串
|
'检查特殊字符串
|
||||||
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(SubStr)
|
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(SubStr)
|
||||||
If Not InvalidStrCheck = "" Then Return InvalidStrCheck
|
If Not InvalidStrCheck = "" Then Return InvalidStrCheck
|
||||||
'检查 NTFS 8.3 (issue #4505)
|
'检查 NTFS 8.3 文件名(#4505)
|
||||||
If Ntfs83NameCheck(Str) Then Return "文件夹名不能是一个有效的 NTFS 8.3 文件名!"
|
If RegexCheck(Str, ".{2,}~\d") Then Return "文件夹名不能包含这一特殊格式!"
|
||||||
Next
|
Next
|
||||||
Return ""
|
Return ""
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Public Class MyBitmap
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 位图缓存。
|
''' 位图缓存。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Shared BitmapCache As New Dictionary(Of String, MyBitmap)
|
Public Shared BitmapCache As New Concurrent.ConcurrentDictionary(Of String, MyBitmap)
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 存储的图片
|
''' 存储的图片
|
||||||
@@ -61,7 +61,7 @@ Public Class MyBitmap
|
|||||||
Pic = BitmapCache(FilePathOrResourceName).Pic
|
Pic = BitmapCache(FilePathOrResourceName).Pic
|
||||||
Else
|
Else
|
||||||
Pic = New MyBitmap(CType((New ImageSourceConverter).ConvertFromString(FilePathOrResourceName), ImageSource))
|
Pic = New MyBitmap(CType((New ImageSourceConverter).ConvertFromString(FilePathOrResourceName), ImageSource))
|
||||||
BitmapCache.Add(FilePathOrResourceName, Pic)
|
BitmapCache.TryAdd(FilePathOrResourceName, Pic)
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
'使用这种自己接管 FileStream 的方法加载才能解除文件占用
|
'使用这种自己接管 FileStream 的方法加载才能解除文件占用
|
||||||
@@ -72,11 +72,9 @@ Public Class MyBitmap
|
|||||||
InputStream.Seek(0, SeekOrigin.Begin)
|
InputStream.Seek(0, SeekOrigin.Begin)
|
||||||
If Header(0) = 82 AndAlso Header(1) = 73 Then
|
If Header(0) = 82 AndAlso Header(1) = 73 Then
|
||||||
'读取 WebP
|
'读取 WebP
|
||||||
If Is32BitSystem Then Throw New Exception("不支持在 32 位系统下加载 WebP 图片。")
|
|
||||||
Dim FileBytes(InputStream.Length - 1) As Byte
|
Dim FileBytes(InputStream.Length - 1) As Byte
|
||||||
InputStream.Read(FileBytes, 0, FileBytes.Length)
|
InputStream.Read(FileBytes, 0, FileBytes.Length)
|
||||||
Dim Decoder As New Imazen.WebP.SimpleDecoder()
|
Pic = WebPDecoder.DecodeFromBytes(FileBytes) '将代码隔离在另外一个类中,这样只要不走进这个分支就不会加载 Imazen.WebP.dll
|
||||||
Pic = Decoder.DecodeFromBytes(FileBytes, FileBytes.Length)
|
|
||||||
Else
|
Else
|
||||||
Pic = New System.Drawing.Bitmap(InputStream)
|
Pic = New System.Drawing.Bitmap(InputStream)
|
||||||
End If
|
End If
|
||||||
@@ -86,10 +84,9 @@ Public Class MyBitmap
|
|||||||
Pic = My.Application.TryFindResource(FilePathOrResourceName)
|
Pic = My.Application.TryFindResource(FilePathOrResourceName)
|
||||||
If Pic Is Nothing Then
|
If Pic Is Nothing Then
|
||||||
Pic = New System.Drawing.Bitmap(1, 1)
|
Pic = New System.Drawing.Bitmap(1, 1)
|
||||||
Log(ex, $"加载位图失败({FilePathOrResourceName})")
|
Throw New Exception($"加载 MyBitmap 失败({FilePathOrResourceName})", ex)
|
||||||
Throw
|
|
||||||
Else
|
Else
|
||||||
Log(ex, $"指定类型有误的位图加载({FilePathOrResourceName})", LogLevel.Developer)
|
Log(ex, $"指定类型有误的 MyBitmap 加载({FilePathOrResourceName})", LogLevel.Developer)
|
||||||
Exit Try
|
Exit Try
|
||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
@@ -116,6 +113,13 @@ Public Class MyBitmap
|
|||||||
Pic = New System.Drawing.Bitmap(MS)
|
Pic = New System.Drawing.Bitmap(MS)
|
||||||
End Using
|
End Using
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Class WebPDecoder '将代码隔离在另外一个类中,这样只要不调用这个方法就不会加载 Imazen.WebP.dll
|
||||||
|
Public Shared Function DecodeFromBytes(Bytes As Byte()) As System.Drawing.Bitmap
|
||||||
|
If Is32BitSystem Then Throw New Exception("不支持在 32 位系统下加载 WebP 图片。")
|
||||||
|
Dim Decoder As New Imazen.WebP.SimpleDecoder()
|
||||||
|
Return Decoder.DecodeFromBytes(Bytes, Bytes.Length)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 获取裁切的图片,这个方法不会导致原对象改变且会返回一个新的对象。
|
''' 获取裁切的图片,这个方法不会导致原对象改变且会返回一个新的对象。
|
||||||
@@ -152,4 +156,4 @@ Public Class MyBitmap
|
|||||||
End Using
|
End Using
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ Extracted:
|
|||||||
版本Json中存在多个Forge
|
版本Json中存在多个Forge
|
||||||
Mod过多导致超出ID限制
|
Mod过多导致超出ID限制
|
||||||
NightConfig的Bug
|
NightConfig的Bug
|
||||||
ShadersMod与Optifine同时安装
|
ShadersMod与OptiFine同时安装
|
||||||
Forge安装不完整
|
Forge安装不完整
|
||||||
Mod需要Java11
|
Mod需要Java11
|
||||||
Mod缺少前置或MC版本错误
|
Mod缺少前置或MC版本错误
|
||||||
@@ -516,7 +516,7 @@ Done:
|
|||||||
If LogMc.Contains("java.lang.ClassNotFoundException: org.spongepowered.asm.launch.MixinTweaker") Then AppendReason(CrashReason.MixinBootstrap缺失)
|
If LogMc.Contains("java.lang.ClassNotFoundException: org.spongepowered.asm.launch.MixinTweaker") Then AppendReason(CrashReason.MixinBootstrap缺失)
|
||||||
If LogMc.Contains("Couldn't set pixel format") Then AppendReason(CrashReason.显卡驱动不支持导致无法设置像素格式)
|
If LogMc.Contains("Couldn't set pixel format") Then AppendReason(CrashReason.显卡驱动不支持导致无法设置像素格式)
|
||||||
If LogMc.Contains("java.lang.OutOfMemoryError") OrElse LogMc.Contains("an out of memory error") Then AppendReason(CrashReason.内存不足)
|
If LogMc.Contains("java.lang.OutOfMemoryError") OrElse LogMc.Contains("an out of memory error") Then AppendReason(CrashReason.内存不足)
|
||||||
If LogMc.Contains("java.lang.RuntimeException: Shaders Mod detected. Please remove it, OptiFine has built-in support for shaders.") Then AppendReason(CrashReason.ShadersMod与Optifine同时安装)
|
If LogMc.Contains("java.lang.RuntimeException: Shaders Mod detected. Please remove it, OptiFine has built-in support for shaders.") Then AppendReason(CrashReason.ShadersMod与OptiFine同时安装)
|
||||||
If LogMc.Contains("java.lang.NoSuchMethodError: sun.security.util.ManifestEntryVerifier") Then AppendReason(CrashReason.低版本Forge与高版本Java不兼容)
|
If LogMc.Contains("java.lang.NoSuchMethodError: sun.security.util.ManifestEntryVerifier") Then AppendReason(CrashReason.低版本Forge与高版本Java不兼容)
|
||||||
If LogMc.Contains("1282: Invalid operation") Then AppendReason(CrashReason.光影或资源包导致OpenGL1282错误)
|
If LogMc.Contains("1282: Invalid operation") Then AppendReason(CrashReason.光影或资源包导致OpenGL1282错误)
|
||||||
If LogMc.Contains("signer information does not match signer information of other classes in the same package") Then AppendReason(CrashReason.文件或内容校验失败, If(RegexSeek(LogMc, "(?<=class "")[^']+(?=""'s signer information)"), "").TrimEnd(vbCrLf))
|
If LogMc.Contains("signer information does not match signer information of other classes in the same package") Then AppendReason(CrashReason.文件或内容校验失败, If(RegexSeek(LogMc, "(?<=class "")[^']+(?=""'s signer information)"), "").TrimEnd(vbCrLf))
|
||||||
@@ -525,6 +525,7 @@ Done:
|
|||||||
If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本不兼容)
|
If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本不兼容)
|
||||||
If LogMc.Contains("com.electronwill.nightconfig.core.io.ParsingException: Not enough data available") Then AppendReason(CrashReason.NightConfig的Bug)
|
If LogMc.Contains("com.electronwill.nightconfig.core.io.ParsingException: Not enough data available") Then AppendReason(CrashReason.NightConfig的Bug)
|
||||||
If LogMc.Contains("Cannot find launch target fmlclient, unable to launch") Then AppendReason(CrashReason.Forge安装不完整)
|
If LogMc.Contains("Cannot find launch target fmlclient, unable to launch") Then AppendReason(CrashReason.Forge安装不完整)
|
||||||
|
If LogMc.Contains("Invalid paths argument, contained no existing paths") AndAlso LogMc.Contains("libraries\net\minecraftforge\fmlcore") Then AppendReason(CrashReason.Forge安装不完整)
|
||||||
If LogMc.Contains("Invalid module name: '' is not a Java identifier") Then AppendReason(CrashReason.Mod名称包含特殊字符)
|
If LogMc.Contains("Invalid module name: '' is not a Java identifier") Then AppendReason(CrashReason.Mod名称包含特殊字符)
|
||||||
If LogMc.Contains("has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to") Then AppendReason(CrashReason.Mod需要Java11)
|
If LogMc.Contains("has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to") Then AppendReason(CrashReason.Mod需要Java11)
|
||||||
If LogMc.Contains("java.lang.RuntimeException: java.lang.NoSuchMethodException: no such method: sun.misc.Unsafe.defineAnonymousClass(Class,byte[],Object[])Class/invokeVirtual") Then AppendReason(CrashReason.Mod需要Java11)
|
If LogMc.Contains("java.lang.RuntimeException: java.lang.NoSuchMethodException: no such method: sun.misc.Unsafe.defineAnonymousClass(Class,byte[],Object[])Class/invokeVirtual") Then AppendReason(CrashReason.Mod需要Java11)
|
||||||
@@ -623,8 +624,11 @@ Done:
|
|||||||
'崩溃报告分析
|
'崩溃报告分析
|
||||||
If LogCrash IsNot Nothing Then
|
If LogCrash IsNot Nothing Then
|
||||||
If LogCrash.Contains("Suspected Mod") Then
|
If LogCrash.Contains("Suspected Mod") Then
|
||||||
Dim Suspects = RegexSearch(LogCrash.Between("Suspected Mod", "Stacktrace"), "(?<=\n\t[^(\t]+\()[^)\n]+")
|
Dim SuspectsRaw As String = LogCrash.Between("Suspected Mod", "Stacktrace")
|
||||||
If Suspects.Any Then AppendReason(CrashReason.怀疑Mod导致游戏崩溃, TryAnalyzeModName(Suspects))
|
If Not SuspectsRaw.StartsWithF("s: None") Then 'Suspected Mods: None
|
||||||
|
Dim Suspects = RegexSearch(SuspectsRaw, "(?<=\n\t[^(\t]+\()[^)\n]+")
|
||||||
|
If Suspects.Any Then AppendReason(CrashReason.怀疑Mod导致游戏崩溃, TryAnalyzeModName(Suspects))
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
@@ -744,7 +748,7 @@ NextStack:
|
|||||||
'[Fabric] 获取所有包含 Mod 信息的行
|
'[Fabric] 获取所有包含 Mod 信息的行
|
||||||
Dim ModNameLines As New List(Of String)
|
Dim ModNameLines As New List(Of String)
|
||||||
For Each Line In Details.Split(vbLf)
|
For Each Line In Details.Split(vbLf)
|
||||||
If Line.ContainsF(".jar", True) OrElse
|
If (Line.ContainsF(".jar", True) AndAlso Line.Length - Line.Replace(".jar", "").Length = 4) OrElse '只有一个 .jar
|
||||||
(IsFabricDetail AndAlso Line.StartsWithF(vbTab & vbTab) AndAlso Not RegexCheck(Line, "\t\tfabric[\w-]*: Fabric")) Then ModNameLines.Add(Line)
|
(IsFabricDetail AndAlso Line.StartsWithF(vbTab & vbTab) AndAlso Not RegexCheck(Line, "\t\tfabric[\w-]*: Fabric")) Then ModNameLines.Add(Line)
|
||||||
Next
|
Next
|
||||||
Log("[Crash] 崩溃报告中找到 " & ModNameLines.Count & " 个可能的 Mod 项目行")
|
Log("[Crash] 崩溃报告中找到 " & ModNameLines.Count & " 个可能的 Mod 项目行")
|
||||||
@@ -886,6 +890,7 @@ NextStack:
|
|||||||
WriteFile(TempFolder & "Report\" & FileName,
|
WriteFile(TempFolder & "Report\" & FileName,
|
||||||
SecretFilter(ReadFile(OutputFile, FileEncoding), If(FileName = "启动脚本.bat", "F", "*")),
|
SecretFilter(ReadFile(OutputFile, FileEncoding), If(FileName = "启动脚本.bat", "F", "*")),
|
||||||
Encoding:=FileEncoding)
|
Encoding:=FileEncoding)
|
||||||
|
Log($"[Crash] 导出文件:{FileName},编码:{FileEncoding.HeaderName}")
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
'导出报告
|
'导出报告
|
||||||
@@ -942,9 +947,9 @@ NextStack:
|
|||||||
End If
|
End If
|
||||||
Case CrashReason.Mod缺少前置或MC版本错误
|
Case CrashReason.Mod缺少前置或MC版本错误
|
||||||
If Additional.Any Then
|
If Additional.Any Then
|
||||||
Results.Add("由于未满足 Mod 的依赖项,导致游戏退出。\n未满足的依赖项:\n - " & Join(Additional, "\n - ") & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。")
|
Results.Add("由于未安装正确的前置 Mod,导致游戏退出。\n缺失的依赖项:\n - " & Join(Additional, "\n - ") & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。")
|
||||||
Else
|
Else
|
||||||
Results.Add("由于未满足 Mod 的依赖项,导致游戏退出。\n请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。\h")
|
Results.Add("由于未安装正确的前置 Mod,导致游戏退出。\n请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。\h")
|
||||||
End If
|
End If
|
||||||
Case CrashReason.堆栈分析发现关键字
|
Case CrashReason.堆栈分析发现关键字
|
||||||
If Additional.Count = 1 Then
|
If Additional.Count = 1 Then
|
||||||
@@ -980,7 +985,7 @@ NextStack:
|
|||||||
If Additional.Count = 1 Then
|
If Additional.Count = 1 Then
|
||||||
Results.Add("名为 " & Additional.First & " 的 Mod 初始化失败,导致游戏无法继续加载。\n你可以尝试禁用此 Mod,然后观察游戏是否还会崩溃。\n\e\h")
|
Results.Add("名为 " & Additional.First & " 的 Mod 初始化失败,导致游戏无法继续加载。\n你可以尝试禁用此 Mod,然后观察游戏是否还会崩溃。\n\e\h")
|
||||||
Else
|
Else
|
||||||
Results.Add("以下 Mod 初始化失败,导致游戏无法继续加载:\n - " & Join(Additional, "\n - ") & "\n\n你可以尝试依次禁用上述 Mod,然后观察游戏是否还会崩溃。\n\e\h")
|
Results.Add("以下 Mod 初始化失败,导致游戏出错:\n - " & Join(Additional, "\n - ") & "\n\n你可以尝试依次禁用上述 Mod,然后观察游戏是否还会崩溃。\n\e\h")
|
||||||
End If
|
End If
|
||||||
Case CrashReason.特定方块导致崩溃
|
Case CrashReason.特定方块导致崩溃
|
||||||
If Additional.Count = 1 Then
|
If Additional.Count = 1 Then
|
||||||
@@ -992,7 +997,7 @@ NextStack:
|
|||||||
If Additional.Count >= 2 Then
|
If Additional.Count >= 2 Then
|
||||||
Results.Add("你重复安装了多个相同的 Mod:\n - " & Join(Additional, "\n - ") & "\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。")
|
Results.Add("你重复安装了多个相同的 Mod:\n - " & Join(Additional, "\n - ") & "\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。")
|
||||||
Else
|
Else
|
||||||
Results.Add("你可能重复安装了多个相同的 Mod,导致游戏无法继续加载。\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。\e\h")
|
Results.Add("你可能重复安装了多个相同的 Mod,导致游戏出错。\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。\e\h")
|
||||||
End If
|
End If
|
||||||
Case CrashReason.特定实体导致崩溃
|
Case CrashReason.特定实体导致崩溃
|
||||||
If Additional.Count = 1 Then
|
If Additional.Count = 1 Then
|
||||||
@@ -1002,12 +1007,12 @@ NextStack:
|
|||||||
End If
|
End If
|
||||||
Case CrashReason.OptiFine与Forge不兼容
|
Case CrashReason.OptiFine与Forge不兼容
|
||||||
Results.Add("由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。\n\n请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。")
|
Results.Add("由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。\n\n请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。")
|
||||||
Case CrashReason.ShadersMod与Optifine同时安装
|
Case CrashReason.ShadersMod与OptiFine同时安装
|
||||||
Results.Add("无需同时安装 Optifine 和 Shaders Mod,Optifine 已经集成了 Shaders Mod 的功能。\n在删除 Shaders Mod 后,游戏即可正常运行。")
|
Results.Add("无需同时安装 Optifine 和 Shaders Mod,OptiFine 已经集成了 Shaders Mod 的功能。\n在删除 Shaders Mod 后,游戏即可正常运行。")
|
||||||
Case CrashReason.低版本Forge与高版本Java不兼容
|
Case CrashReason.低版本Forge与高版本Java不兼容
|
||||||
Results.Add("由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。\n\n请尝试以下解决方案:\n - 更新 Forge 到 36.2.26 或更高版本\n - 换用版本低于 1.8.0.320 的 Java")
|
Results.Add("由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。\n\n请尝试以下解决方案:\n - 更新 Forge 到 36.2.26 或更高版本\n - 换用版本低于 1.8.0.320 的 Java")
|
||||||
Case CrashReason.版本Json中存在多个Forge
|
Case CrashReason.版本Json中存在多个Forge
|
||||||
Results.Add("可能由于使用其他启动器修改了 Forge 版本,当前版本的文件存在异常,导致了游戏崩溃。\n请尝试重新全新安装 Forge,而非使用其他启动器修改 Forge 版本。")
|
Results.Add("可能由于其他启动器修改了 Forge 版本,当前版本的文件存在异常,导致了游戏崩溃。\n请尝试重新全新安装 Forge,而非使用其他启动器修改 Forge 版本。")
|
||||||
Case CrashReason.玩家手动触发调试崩溃
|
Case CrashReason.玩家手动触发调试崩溃
|
||||||
Results.Add("* 事实上,你的游戏没有任何问题,这是你自己触发的崩溃。\n* 你难道没有更重要的事要做吗?")
|
Results.Add("* 事实上,你的游戏没有任何问题,这是你自己触发的崩溃。\n* 你难道没有更重要的事要做吗?")
|
||||||
Case CrashReason.Mod需要Java11
|
Case CrashReason.Mod需要Java11
|
||||||
@@ -1033,7 +1038,7 @@ NextStack:
|
|||||||
Case CrashReason.文件或内容校验失败
|
Case CrashReason.文件或内容校验失败
|
||||||
Results.Add("部分文件或内容校验失败,导致游戏出现了问题。\n\n请尝试删除游戏(包括 Mod)并重新下载,或尝试在重新下载时使用 VPN。\h")
|
Results.Add("部分文件或内容校验失败,导致游戏出现了问题。\n\n请尝试删除游戏(包括 Mod)并重新下载,或尝试在重新下载时使用 VPN。\h")
|
||||||
Case CrashReason.Forge安装不完整
|
Case CrashReason.Forge安装不完整
|
||||||
Results.Add("由于 Forge 安装不完整,导致游戏无法正常运行。\n请尝试重新安装 Forge。\h")
|
Results.Add("由于安装的 Forge 文件丢失,导致游戏无法正常运行。\n请重新安装一次相同版本的 Forge,然后再启动游戏。\n在打包游戏时删除 libraries 文件夹可能导致此错误。\h")
|
||||||
Case CrashReason.Fabric报错
|
Case CrashReason.Fabric报错
|
||||||
If Additional.Count = 1 Then
|
If Additional.Count = 1 Then
|
||||||
Results.Add("Fabric 提供了以下错误信息:\n" & Additional.First & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。")
|
Results.Add("Fabric 提供了以下错误信息:\n" & Additional.First & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。")
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ NextInner:
|
|||||||
'根据当前登录方式优先返回
|
'根据当前登录方式优先返回
|
||||||
Select Case Setup.Get("LoginType")
|
Select Case Setup.Get("LoginType")
|
||||||
Case McLoginType.Ms
|
Case McLoginType.Ms
|
||||||
If Setup.Get("CacheMsName") <> "" Then Return Setup.Get("CacheMsName")
|
If Setup.Get("CacheMsV2Name") <> "" Then Return Setup.Get("CacheMsV2Name")
|
||||||
Case McLoginType.Legacy
|
Case McLoginType.Legacy
|
||||||
If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Before("¨")
|
If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Before("¨")
|
||||||
Case McLoginType.Nide
|
Case McLoginType.Nide
|
||||||
@@ -387,7 +387,7 @@ NextInner:
|
|||||||
If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName")
|
If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName")
|
||||||
End Select
|
End Select
|
||||||
'查找所有可能的项
|
'查找所有可能的项
|
||||||
If Setup.Get("CacheMsName") <> "" Then Return Setup.Get("CacheMsName")
|
If Setup.Get("CacheMsV2Name") <> "" Then Return Setup.Get("CacheMsV2Name")
|
||||||
If Setup.Get("CacheNideName") <> "" Then Return Setup.Get("CacheNideName")
|
If Setup.Get("CacheNideName") <> "" Then Return Setup.Get("CacheNideName")
|
||||||
If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName")
|
If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName")
|
||||||
If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Before("¨")
|
If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Before("¨")
|
||||||
@@ -399,7 +399,7 @@ NextInner:
|
|||||||
Public Function McLoginAble() As String
|
Public Function McLoginAble() As String
|
||||||
Select Case Setup.Get("LoginType")
|
Select Case Setup.Get("LoginType")
|
||||||
Case McLoginType.Ms
|
Case McLoginType.Ms
|
||||||
If Setup.Get("CacheMsOAuthRefresh") = "" Then
|
If Setup.Get("CacheMsV2OAuthRefresh") = "" Then
|
||||||
Return FrmLoginMs.IsVaild()
|
Return FrmLoginMs.IsVaild()
|
||||||
Else
|
Else
|
||||||
Return ""
|
Return ""
|
||||||
@@ -450,7 +450,7 @@ NextInner:
|
|||||||
Case McLoginType.Legacy
|
Case McLoginType.Legacy
|
||||||
LoginData = PageLoginLegacy.GetLoginData()
|
LoginData = PageLoginLegacy.GetLoginData()
|
||||||
Case McLoginType.Ms
|
Case McLoginType.Ms
|
||||||
If Setup.Get("CacheMsOAuthRefresh") = "" Then
|
If Setup.Get("CacheMsV2OAuthRefresh") = "" Then
|
||||||
LoginData = PageLoginMs.GetLoginData()
|
LoginData = PageLoginMs.GetLoginData()
|
||||||
Else
|
Else
|
||||||
LoginData = PageLoginMsSkin.GetLoginData()
|
LoginData = PageLoginMsSkin.GetLoginData()
|
||||||
@@ -552,11 +552,11 @@ Relogin:
|
|||||||
Dim Result = MsLoginStep6(AccessToken)
|
Dim Result = MsLoginStep6(AccessToken)
|
||||||
Data.Progress = 0.98
|
Data.Progress = 0.98
|
||||||
'输出登录结果
|
'输出登录结果
|
||||||
Setup.Set("CacheMsOAuthRefresh", OAuthRefreshToken)
|
Setup.Set("CacheMsV2OAuthRefresh", OAuthRefreshToken)
|
||||||
Setup.Set("CacheMsAccess", AccessToken)
|
Setup.Set("CacheMsV2Access", AccessToken)
|
||||||
Setup.Set("CacheMsUuid", Result(0))
|
Setup.Set("CacheMsV2Uuid", Result(0))
|
||||||
Setup.Set("CacheMsName", Result(1))
|
Setup.Set("CacheMsV2Name", Result(1))
|
||||||
Setup.Set("CacheMsProfileJson", Result(2))
|
Setup.Set("CacheMsV2ProfileJson", Result(2))
|
||||||
Dim MsJson As JObject = GetJson(Setup.Get("LoginMsJson"))
|
Dim MsJson As JObject = GetJson(Setup.Get("LoginMsJson"))
|
||||||
MsJson.Remove(Input.UserName) '如果更改了玩家名……
|
MsJson.Remove(Input.UserName) '如果更改了玩家名……
|
||||||
MsJson(Result(1)) = OAuthRefreshToken
|
MsJson(Result(1)) = OAuthRefreshToken
|
||||||
@@ -850,7 +850,7 @@ Retry:
|
|||||||
While Converter.Result Is Nothing
|
While Converter.Result Is Nothing
|
||||||
Thread.Sleep(100)
|
Thread.Sleep(100)
|
||||||
End While
|
End While
|
||||||
If TypeOf Converter.Result Is RetryException Then
|
If TypeOf Converter.Result Is RestartException Then
|
||||||
If MyMsgBox($"请在登录时选择 {vbLQ}其他登录方法{vbRQ},然后选择 {vbLQ}使用我的密码{vbRQ}。{vbCrLf}如果没有该选项,请选择 {vbLQ}设置密码{vbRQ},设置完毕后再登录。",
|
If MyMsgBox($"请在登录时选择 {vbLQ}其他登录方法{vbRQ},然后选择 {vbLQ}使用我的密码{vbRQ}。{vbCrLf}如果没有该选项,请选择 {vbLQ}设置密码{vbRQ},设置完毕后再登录。",
|
||||||
"需要使用密码登录", "重新登录", "设置密码", "取消",
|
"需要使用密码登录", "重新登录", "设置密码", "取消",
|
||||||
Button2Action:=Sub() OpenWebsite("https://account.live.com/password/Change")) = 1 Then
|
Button2Action:=Sub() OpenWebsite("https://account.live.com/password/Change")) = 1 Then
|
||||||
@@ -1262,8 +1262,7 @@ Retry:
|
|||||||
''' 释放 Java Wrapper 并返回完整文件路径。
|
''' 释放 Java Wrapper 并返回完整文件路径。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function ExtractJavaWrapper() As String
|
Public Function ExtractJavaWrapper() As String
|
||||||
Dim BaseDir As String = GetPureASCIIDir()
|
Dim WrapperPath As String = PathPure & "JavaWrapper.jar"
|
||||||
Dim WrapperPath As String = BaseDir & "\JavaWrapper.jar"
|
|
||||||
Log("[Java] 选定的 Java Wrapper 路径:" & WrapperPath)
|
Log("[Java] 选定的 Java Wrapper 路径:" & WrapperPath)
|
||||||
SyncLock ExtractJavaWrapperLock '避免 OptiFine 和 Forge 安装时同时释放 Java Wrapper 导致冲突
|
SyncLock ExtractJavaWrapperLock '避免 OptiFine 和 Forge 安装时同时释放 Java Wrapper 导致冲突
|
||||||
Try
|
Try
|
||||||
@@ -1277,7 +1276,7 @@ Retry:
|
|||||||
WriteFile(WrapperPath, GetResources("JavaWrapper"))
|
WriteFile(WrapperPath, GetResources("JavaWrapper"))
|
||||||
Catch ex2 As Exception
|
Catch ex2 As Exception
|
||||||
Log(ex2, "Java Wrapper 文件重新释放失败,将尝试更换文件名重新生成", LogLevel.Developer)
|
Log(ex2, "Java Wrapper 文件重新释放失败,将尝试更换文件名重新生成", LogLevel.Developer)
|
||||||
WrapperPath = BaseDir & "\JavaWrapper2.jar"
|
WrapperPath = PathPure & "JavaWrapper2.jar"
|
||||||
Try
|
Try
|
||||||
WriteFile(WrapperPath, GetResources("JavaWrapper"))
|
WriteFile(WrapperPath, GetResources("JavaWrapper"))
|
||||||
Catch ex3 As Exception
|
Catch ex3 As Exception
|
||||||
@@ -1293,22 +1292,6 @@ Retry:
|
|||||||
End Function
|
End Function
|
||||||
Private ExtractJavaWrapperLock As New Object
|
Private ExtractJavaWrapperLock As New Object
|
||||||
|
|
||||||
''' <summary>
|
|
||||||
''' 获取一个可用于临时存放文件的,不含任何特殊字符的文件夹路径。
|
|
||||||
''' 返回值不以 \ 结尾。
|
|
||||||
''' </summary>
|
|
||||||
Public Function GetPureASCIIDir() As String
|
|
||||||
If (Path & "PCL").IsASCII() Then
|
|
||||||
Return Path & "PCL"
|
|
||||||
ElseIf PathAppdata.IsASCII() Then
|
|
||||||
Return PathAppdata.TrimEnd("\")
|
|
||||||
ElseIf PathTemp.IsASCII() Then
|
|
||||||
Return PathTemp.TrimEnd("\")
|
|
||||||
Else
|
|
||||||
Return OsDrive & "ProgramData\PCL"
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
|
|
||||||
'主方法,合并 Jvm、Game、Replace 三部分的参数数据
|
'主方法,合并 Jvm、Game、Replace 三部分的参数数据
|
||||||
Private Sub McLaunchArgumentMain(Loader As LoaderTask(Of String, List(Of McLibToken)))
|
Private Sub McLaunchArgumentMain(Loader As LoaderTask(Of String, List(Of McLibToken)))
|
||||||
McLaunchLog("开始获取 Minecraft 启动参数")
|
McLaunchLog("开始获取 Minecraft 启动参数")
|
||||||
@@ -1408,7 +1391,7 @@ Retry:
|
|||||||
Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent))
|
Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent))
|
||||||
Try
|
Try
|
||||||
Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8)
|
Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8)
|
||||||
DataList.Insert(0, "-javaagent:""" & PathAppdata & "authlib-injector.jar""=" & Server &
|
DataList.Insert(0, "-javaagent:""" & PathPure & "authlib-injector.jar""=" & Server &
|
||||||
" -Dauthlibinjector.side=client" &
|
" -Dauthlibinjector.side=client" &
|
||||||
" -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response)))
|
" -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response)))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -1418,7 +1401,7 @@ Retry:
|
|||||||
|
|
||||||
'添加 Java Wrapper 作为主 Jar
|
'添加 Java Wrapper 作为主 Jar
|
||||||
If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED")
|
If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED")
|
||||||
DataList.Add("-Doolloo.jlw.tmpdir=""" & GetPureASCIIDir() & """")
|
DataList.Add("-Doolloo.jlw.tmpdir=""" & PathPure.TrimEnd("\") & """")
|
||||||
DataList.Add("-jar """ & ExtractJavaWrapper() & """")
|
DataList.Add("-jar """ & ExtractJavaWrapper() & """")
|
||||||
|
|
||||||
'添加 MainClass
|
'添加 MainClass
|
||||||
@@ -1475,7 +1458,7 @@ NextVersion:
|
|||||||
Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent))
|
Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent))
|
||||||
Try
|
Try
|
||||||
Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8)
|
Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8)
|
||||||
DataList.Insert(0, "-javaagent:""" & PathAppdata & "authlib-injector.jar""=" & Server &
|
DataList.Insert(0, "-javaagent:""" & PathPure & "authlib-injector.jar""=" & Server &
|
||||||
" -Dauthlibinjector.side=client" &
|
" -Dauthlibinjector.side=client" &
|
||||||
" -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response)))
|
" -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response)))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -1485,7 +1468,7 @@ NextVersion:
|
|||||||
|
|
||||||
'添加 Java Wrapper 作为主 Jar
|
'添加 Java Wrapper 作为主 Jar
|
||||||
If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED")
|
If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED")
|
||||||
DataList.Add("-Doolloo.jlw.tmpdir=""" & GetPureASCIIDir() & """")
|
DataList.Add("-Doolloo.jlw.tmpdir=""" & PathPure.TrimEnd("\") & """")
|
||||||
DataList.Add("-jar """ & ExtractJavaWrapper() & """")
|
DataList.Add("-jar """ & ExtractJavaWrapper() & """")
|
||||||
|
|
||||||
'将 "-XXX" 与后面 "XXX" 合并到一起
|
'将 "-XXX" 与后面 "XXX" 合并到一起
|
||||||
|
|||||||
@@ -1256,9 +1256,8 @@ OnLoaded:
|
|||||||
Dim VersionList As New List(Of McVersion)
|
Dim VersionList As New List(Of McVersion)
|
||||||
|
|
||||||
#Region "循环加载每个版本的信息"
|
#Region "循环加载每个版本的信息"
|
||||||
Dim Dirs As DirectoryInfo() = New DirectoryInfo(Path & "versions").GetDirectories
|
For Each Folder As DirectoryInfo In New DirectoryInfo(Path & "versions").GetDirectories
|
||||||
For Each Folder As DirectoryInfo In Dirs
|
If Not Folder.Exists OrElse Not Folder.EnumerateFiles.Any Then
|
||||||
If Not Folder.EnumerateFiles.Any Then
|
|
||||||
Log("[Minecraft] 跳过空文件夹:" & Folder.FullName)
|
Log("[Minecraft] 跳过空文件夹:" & Folder.FullName)
|
||||||
Continue For
|
Continue For
|
||||||
End If
|
End If
|
||||||
@@ -1528,7 +1527,7 @@ OnLoaded:
|
|||||||
''' 要求玩家选择一个皮肤文件,并进行相关校验。
|
''' 要求玩家选择一个皮肤文件,并进行相关校验。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function McSkinSelect() As McSkinInfo
|
Public Function McSkinSelect() As McSkinInfo
|
||||||
Dim FileName As String = SelectFile("皮肤文件(*.png)|*.png", "选择皮肤文件")
|
Dim FileName As String = SelectFile("皮肤文件(*.png;*.jpg;*.webp)|*.png;*.jpg;*.webp", "选择皮肤文件")
|
||||||
|
|
||||||
'验证有效性
|
'验证有效性
|
||||||
If FileName = "" Then Return New McSkinInfo With {.IsVaild = False}
|
If FileName = "" Then Return New McSkinInfo With {.IsVaild = False}
|
||||||
@@ -1935,7 +1934,7 @@ OnLoaded:
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 获取版本缺失的支持库文件所对应的 NetTaskFile。
|
''' 获取版本缺失的支持库文件所对应的 NetTaskFile。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function McLibFix(Version As McVersion, Optional CoreJarOnly As Boolean = False) As List(Of NetFile)
|
Public Function McLibFix(Version As McVersion) As List(Of NetFile)
|
||||||
If Not Version.IsLoaded Then Version.Load() '确保例如 JumpLoader 等项被合并入 Json
|
If Not Version.IsLoaded Then Version.Load() '确保例如 JumpLoader 等项被合并入 Json
|
||||||
Dim Result As New List(Of NetFile)
|
Dim Result As New List(Of NetFile)
|
||||||
|
|
||||||
@@ -1948,7 +1947,6 @@ OnLoaded:
|
|||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "版本缺失主 jar 文件所必须的信息", LogLevel.Developer)
|
Log(ex, "版本缺失主 jar 文件所必须的信息", LogLevel.Developer)
|
||||||
End Try
|
End Try
|
||||||
If CoreJarOnly Then Return Result
|
|
||||||
|
|
||||||
'Library 文件
|
'Library 文件
|
||||||
Result.AddRange(McLibFixFromLibToken(McLibListGet(Version, False), JumpLoaderFolder:=Version.PathIndie & ".jumploader\"))
|
Result.AddRange(McLibFixFromLibToken(McLibListGet(Version, False), JumpLoaderFolder:=Version.PathIndie & ".jumploader\"))
|
||||||
@@ -1957,15 +1955,15 @@ OnLoaded:
|
|||||||
If Setup.Get("VersionServerLogin", Version:=Version) = 3 Then
|
If Setup.Get("VersionServerLogin", Version:=Version) = 3 Then
|
||||||
Dim TargetFile = PathAppdata & "nide8auth.jar"
|
Dim TargetFile = PathAppdata & "nide8auth.jar"
|
||||||
Dim DownloadInfo As JObject = Nothing
|
Dim DownloadInfo As JObject = Nothing
|
||||||
'获取下载信息
|
'获取下载信息
|
||||||
Try
|
Try
|
||||||
Log("[Minecraft] 开始获取统一通行证下载信息")
|
Log("[Minecraft] 开始获取统一通行证下载信息")
|
||||||
'测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/
|
'测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/
|
||||||
DownloadInfo = GetJson(NetGetCodeByDownload({
|
DownloadInfo = GetJson(NetGetCodeByDownload({
|
||||||
"https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version)}, IsJson:=True))
|
"https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version)}, IsJson:=True))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "获取统一通行证下载信息失败")
|
Log(ex, "获取统一通行证下载信息失败")
|
||||||
End Try
|
End Try
|
||||||
'校验文件
|
'校验文件
|
||||||
If DownloadInfo IsNot Nothing Then
|
If DownloadInfo IsNot Nothing Then
|
||||||
Dim Checker As New FileChecker(Hash:=DownloadInfo("jarHash").ToString)
|
Dim Checker As New FileChecker(Hash:=DownloadInfo("jarHash").ToString)
|
||||||
@@ -1978,9 +1976,8 @@ OnLoaded:
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
'Authlib-Injector 文件
|
'Authlib-Injector 文件
|
||||||
If Setup.Get("VersionServerLogin", Version:=Version) = 4 OrElse
|
If Setup.Get("VersionServerLogin", Version:=Version) = 4 Then
|
||||||
(PageLinkHiper.HiperState = LoadState.Finished AndAlso Setup.Get("LoginType") = McLoginType.Legacy) Then 'HiPer 登录转接
|
Dim TargetFile = PathPure & "\authlib-injector.jar"
|
||||||
Dim TargetFile = PathAppdata & "authlib-injector.jar"
|
|
||||||
Dim DownloadInfo As JObject = Nothing
|
Dim DownloadInfo As JObject = Nothing
|
||||||
'获取下载信息
|
'获取下载信息
|
||||||
Try
|
Try
|
||||||
@@ -2001,9 +1998,9 @@ OnLoaded:
|
|||||||
Replace("bmclapi2.bangbang93.com/mirrors/authlib-injector", "authlib-injector.yushi.moe")
|
Replace("bmclapi2.bangbang93.com/mirrors/authlib-injector", "authlib-injector.yushi.moe")
|
||||||
Log("[Minecraft] Authlib-Injector 需要更新:" & DownloadAddress, LogLevel.Developer)
|
Log("[Minecraft] Authlib-Injector 需要更新:" & DownloadAddress, LogLevel.Developer)
|
||||||
Result.Add(New NetFile({
|
Result.Add(New NetFile({
|
||||||
DownloadAddress,
|
DownloadAddress,
|
||||||
DownloadAddress.Replace("authlib-injector.yushi.moe", "bmclapi2.bangbang93.com/mirrors/authlib-injector")
|
DownloadAddress.Replace("authlib-injector.yushi.moe", "bmclapi2.bangbang93.com/mirrors/authlib-injector")
|
||||||
}, TargetFile, New FileChecker(Hash:=DownloadInfo("checksums")("sha256").ToString)))
|
}, TargetFile, New FileChecker(Hash:=DownloadInfo("checksums")("sha256").ToString)))
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -825,6 +825,7 @@ Finished:
|
|||||||
Finally
|
Finally
|
||||||
RunInUiWait(Sub() If FrmVersionMod IsNot Nothing Then FrmVersionMod.Load.Text = "正在加载 Mod 列表")
|
RunInUiWait(Sub() If FrmVersionMod IsNot Nothing Then FrmVersionMod.Load.Text = "正在加载 Mod 列表")
|
||||||
End Try
|
End Try
|
||||||
|
FrmVersionMod.LoaderRun(LoaderFolderRunType.UpdateOnly)
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'获取 Mod 文件夹下的可用文件列表
|
'获取 Mod 文件夹下的可用文件列表
|
||||||
|
|||||||
@@ -342,8 +342,8 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
'删除原始整合包文件
|
'删除原始整合包文件
|
||||||
For Each Target As String In {VersionFolder & "原始整合包.zip", VersionFolder & "原始整合包.mrpack"}
|
For Each Target As String In {VersionFolder & "原始整合包.zip", VersionFolder & "原始整合包.mrpack"}
|
||||||
If Not Setup.Get("ToolDownloadKeepModpack") AndAlso File.Exists(Target) Then
|
If File.Exists(Target) Then
|
||||||
Log("[ModPack] 根据设置要求删除原始整合包文件:" & Target)
|
Log("[ModPack] 删除原始整合包文件:" & Target)
|
||||||
File.Delete(Target)
|
File.Delete(Target)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
@@ -491,8 +491,8 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
'删除原始整合包文件
|
'删除原始整合包文件
|
||||||
For Each Target As String In {VersionFolder & "原始整合包.zip", VersionFolder & "原始整合包.mrpack"}
|
For Each Target As String In {VersionFolder & "原始整合包.zip", VersionFolder & "原始整合包.mrpack"}
|
||||||
If Not Setup.Get("ToolDownloadKeepModpack") AndAlso File.Exists(Target) Then
|
If File.Exists(Target) Then
|
||||||
Log("[ModPack] 根据设置要求删除原始整合包文件:" & Target)
|
Log("[ModPack] 删除原始整合包文件:" & Target)
|
||||||
File.Delete(Target)
|
File.Delete(Target)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<Grid x:Class="MyCompItem"
|
<Grid x:Class="MyCompItem"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:PCL"
|
||||||
x:Name="PanBack" Height="64"
|
x:Name="PanBack" Height="64"
|
||||||
RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" SnapsToDevicePixels="True">
|
RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" SnapsToDevicePixels="True">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
<Border.Clip>
|
<Border.Clip>
|
||||||
<RectangleGeometry Rect="0,0,50,50" RadiusX="6" RadiusY="6" />
|
<RectangleGeometry Rect="0,0,50,50" RadiusX="6" RadiusY="6" />
|
||||||
</Border.Clip>
|
</Border.Clip>
|
||||||
<Image x:Name="PathLogo" RenderOptions.BitmapScalingMode="HighQuality" />
|
<local:MyImage x:Name="PathLogo" RenderOptions.BitmapScalingMode="HighQuality" FallbackSource="pack://application:,,,/images/Icons/NoIcon.png" />
|
||||||
</Border>
|
</Border>
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<StackPanel Grid.Column="3" Grid.ColumnSpan="2" Grid.Row="1" VerticalAlignment="Bottom" Margin="0,1,0,0" Orientation="Horizontal"
|
<StackPanel Grid.Column="3" Grid.ColumnSpan="2" Grid.Row="1" VerticalAlignment="Bottom" Margin="0,1,0,0" Orientation="Horizontal"
|
||||||
|
|||||||
@@ -4,87 +4,14 @@
|
|||||||
Public Uuid As Integer = GetUuid()
|
Public Uuid As Integer = GetUuid()
|
||||||
|
|
||||||
'Logo
|
'Logo
|
||||||
Private _Logo As String = ""
|
|
||||||
Public Property Logo As String
|
Public Property Logo As String
|
||||||
Get
|
Get
|
||||||
Return _Logo
|
Return PathLogo.Source
|
||||||
End Get
|
End Get
|
||||||
Set(value As String)
|
Set(value As String)
|
||||||
If _Logo = value OrElse value Is Nothing Then Exit Property
|
PathLogo.Source = value
|
||||||
_Logo = value
|
|
||||||
Dim FileAddress = PathTemp & "CompLogo\" & GetHash(_Logo) & ".png"
|
|
||||||
Try
|
|
||||||
If _Logo.StartsWithF("http", True) Then
|
|
||||||
'网络图片
|
|
||||||
If File.Exists(FileAddress) Then
|
|
||||||
PathLogo.Source = New MyBitmap(FileAddress)
|
|
||||||
Else
|
|
||||||
PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png")
|
|
||||||
RunInNewThread(Sub() LogoLoader(FileAddress), "Comp Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal)
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
'位图
|
|
||||||
PathLogo.Source = New MyBitmap(_Logo)
|
|
||||||
End If
|
|
||||||
Catch ex As IOException
|
|
||||||
Log(ex, "加载资源工程图标时读取失败(" & FileAddress & ")")
|
|
||||||
Catch ex As ArgumentException
|
|
||||||
'考虑缓存的图片本身可能有误
|
|
||||||
Log(ex, "可视化资源工程图标失败(" & FileAddress & ")")
|
|
||||||
Try
|
|
||||||
File.Delete(FileAddress)
|
|
||||||
Log("[Comp] 已清理损坏的资源工程图标:" & FileAddress)
|
|
||||||
Catch exx As Exception
|
|
||||||
Log(exx, "清理损坏的资源工程图标缓存失败(" & FileAddress & ")", LogLevel.Hint)
|
|
||||||
End Try
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "加载资源工程图标失败(" & value & ")")
|
|
||||||
End Try
|
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
'后台加载 Logo
|
|
||||||
Private Sub LogoLoader(LocalFileAddress As String)
|
|
||||||
Dim Retried As Boolean = False
|
|
||||||
Dim DownloadEnd As String = GetUuid()
|
|
||||||
RetryStart:
|
|
||||||
Try
|
|
||||||
'CurseForge 图片使用缩略图
|
|
||||||
Dim Url As String = _Logo
|
|
||||||
If Url.Contains("/256/256/") AndAlso GetPixelSize(1) <= 1.25 AndAlso Not Retried Then
|
|
||||||
Url = Url.Replace("/256/256/", "/64/64/") '#3075:部分 Mod 不存在 64x64 图标,所以重试时不再缩小
|
|
||||||
End If
|
|
||||||
'下载图片
|
|
||||||
NetDownload(Url, LocalFileAddress & DownloadEnd, True)
|
|
||||||
Dim LoadError As Exception = Nothing
|
|
||||||
RunInUiWait(
|
|
||||||
Sub()
|
|
||||||
Try
|
|
||||||
'在地址更换时取消加载
|
|
||||||
If LocalFileAddress <> $"{PathTemp}CompLogo\{GetHash(_Logo)}.png" Then Exit Sub
|
|
||||||
'在完成正常加载后才保存缓存图片
|
|
||||||
PathLogo.Source = New MyBitmap(LocalFileAddress & DownloadEnd)
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, $"读取资源工程图标失败({LocalFileAddress})")
|
|
||||||
File.Delete(LocalFileAddress & DownloadEnd)
|
|
||||||
LoadError = ex
|
|
||||||
End Try
|
|
||||||
End Sub)
|
|
||||||
If LoadError IsNot Nothing Then Throw LoadError
|
|
||||||
If File.Exists(LocalFileAddress) Then
|
|
||||||
File.Delete(LocalFileAddress & DownloadEnd)
|
|
||||||
Else
|
|
||||||
FileIO.FileSystem.MoveFile(LocalFileAddress & DownloadEnd, LocalFileAddress)
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
|
||||||
If Not Retried Then
|
|
||||||
Retried = True
|
|
||||||
GoTo RetryStart
|
|
||||||
Else
|
|
||||||
Log(ex, $"下载资源工程图标失败({_Logo})")
|
|
||||||
RunInUi(Sub() PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png"))
|
|
||||||
End If
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
'标题
|
'标题
|
||||||
Public Property Title As String
|
Public Property Title As String
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<Border.Clip>
|
<Border.Clip>
|
||||||
<RectangleGeometry Rect="0,0,34,34" RadiusX="6" RadiusY="6" />
|
<RectangleGeometry Rect="0,0,34,34" RadiusX="6" RadiusY="6" />
|
||||||
</Border.Clip>
|
</Border.Clip>
|
||||||
<Image x:Name="PathLogo" RenderOptions.BitmapScalingMode="HighQuality" />
|
<local:MyImage x:Name="PathLogo" RenderOptions.BitmapScalingMode="HighQuality" FallbackSource="pack://application:,,,/images/Icons/NoIcon.png" />
|
||||||
</Border>
|
</Border>
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<Grid Grid.Column="3" Grid.ColumnSpan="2" Grid.Row="1" VerticalAlignment="Bottom" Margin="0,1,0,0"
|
<Grid Grid.Column="3" Grid.ColumnSpan="2" Grid.Row="1" VerticalAlignment="Bottom" Margin="0,1,0,0"
|
||||||
@@ -52,6 +52,6 @@
|
|||||||
</Border>-->
|
</Border>-->
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock x:Name="LabInfo" Grid.Row="2" Grid.Column="4" VerticalAlignment="Bottom" Margin="0,0,3,1"
|
<TextBlock x:Name="LabInfo" Grid.Row="2" Grid.Column="4" VerticalAlignment="Bottom" Margin="0,0,3,1"
|
||||||
TextTrimming="CharacterEllipsis" FontSize="12" Foreground="{StaticResource ColorBrushGray3}"
|
TextTrimming="CharacterEllipsis" FontSize="12" Foreground="{StaticResource ColorBrushGray4}"
|
||||||
IsHitTestVisible="False" SnapsToDevicePixels="False" UseLayoutRounding="False" />
|
IsHitTestVisible="False" SnapsToDevicePixels="False" UseLayoutRounding="False" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -6,88 +6,14 @@ Public Class MyLocalModItem
|
|||||||
Public Uuid As Integer = GetUuid()
|
Public Uuid As Integer = GetUuid()
|
||||||
|
|
||||||
'Logo
|
'Logo
|
||||||
Private _Logo As String = ""
|
|
||||||
Public Property Logo As String
|
Public Property Logo As String
|
||||||
Get
|
Get
|
||||||
Return _Logo
|
Return PathLogo.Source
|
||||||
End Get
|
End Get
|
||||||
Set(value As String)
|
Set(value As String)
|
||||||
If _Logo = value OrElse value Is Nothing Then Exit Property
|
PathLogo.Source = value
|
||||||
_Logo = value
|
|
||||||
If ModeDebug AndAlso Not _Logo = PathImage & "Icons/NoIcon.png" Then Log($"[LocalModItem] Mod {Title} 的图标:{value}")
|
|
||||||
Dim FileAddress = PathTemp & "CompLogo\" & GetHash(_Logo) & ".png"
|
|
||||||
Try
|
|
||||||
If _Logo.StartsWithF("http", True) Then
|
|
||||||
'网络图片
|
|
||||||
If File.Exists(FileAddress) Then
|
|
||||||
PathLogo.Source = New MyBitmap(FileAddress)
|
|
||||||
Else
|
|
||||||
PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png")
|
|
||||||
RunInNewThread(Sub() LogoLoader(FileAddress), "Comp Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal)
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
'位图
|
|
||||||
PathLogo.Source = New MyBitmap(_Logo)
|
|
||||||
End If
|
|
||||||
Catch ex As IOException
|
|
||||||
Log(ex, "加载本地 Mod 图标时读取失败(" & FileAddress & ")")
|
|
||||||
Catch ex As ArgumentException
|
|
||||||
'考虑缓存的图片本身可能有误
|
|
||||||
Log(ex, "可视化本地 Mod 图标失败(" & FileAddress & ")")
|
|
||||||
Try
|
|
||||||
File.Delete(FileAddress)
|
|
||||||
Log("[LocalModItem] 已清理损坏的本地 Mod 图标:" & FileAddress)
|
|
||||||
Catch exx As Exception
|
|
||||||
Log(exx, "清理损坏的本地 Mod 图标缓存失败(" & FileAddress & ")", LogLevel.Hint)
|
|
||||||
End Try
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "加载本地 Mod 图标失败(" & value & ")")
|
|
||||||
End Try
|
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
'后台加载 Logo
|
|
||||||
Private Sub LogoLoader(LocalFileAddress As String)
|
|
||||||
Dim Retried As Boolean = False
|
|
||||||
Dim DownloadEnd As String = GetUuid()
|
|
||||||
RetryStart:
|
|
||||||
Try
|
|
||||||
'CurseForge 图片使用缩略图
|
|
||||||
Dim Url As String = _Logo
|
|
||||||
If Url.Contains("/256/256/") AndAlso GetPixelSize(1) <= 1.25 AndAlso Not Retried Then '#3075:部分 Mod 不存在 64x64 图标,所以重试时不再缩小
|
|
||||||
Url = Url.Replace("/256/256/", "/64/64/")
|
|
||||||
End If
|
|
||||||
'下载图片
|
|
||||||
NetDownload(Url, LocalFileAddress & DownloadEnd, True)
|
|
||||||
Dim LoadError As Exception = Nothing
|
|
||||||
RunInUiWait(
|
|
||||||
Sub()
|
|
||||||
Try
|
|
||||||
'在地址更换时取消加载
|
|
||||||
If LocalFileAddress <> $"{PathTemp}CompLogo\{GetHash(_Logo)}.png" Then Exit Sub
|
|
||||||
'在完成正常加载后才保存缓存图片
|
|
||||||
PathLogo.Source = New MyBitmap(LocalFileAddress & DownloadEnd)
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "读取本地 Mod 图标失败(" & LocalFileAddress & ")")
|
|
||||||
File.Delete(LocalFileAddress & DownloadEnd)
|
|
||||||
LoadError = ex
|
|
||||||
End Try
|
|
||||||
End Sub)
|
|
||||||
If LoadError IsNot Nothing Then Throw LoadError
|
|
||||||
If File.Exists(LocalFileAddress) Then
|
|
||||||
File.Delete(LocalFileAddress & DownloadEnd)
|
|
||||||
Else
|
|
||||||
FileIO.FileSystem.MoveFile(LocalFileAddress & DownloadEnd, LocalFileAddress)
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
|
||||||
If Not Retried Then
|
|
||||||
Retried = True
|
|
||||||
GoTo RetryStart
|
|
||||||
Else
|
|
||||||
Log(ex, $"下载本地 Mod 图标失败({_Logo})")
|
|
||||||
RunInUi(Sub() PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png"))
|
|
||||||
End If
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
'标题
|
'标题
|
||||||
Private _Title As String
|
Private _Title As String
|
||||||
@@ -143,9 +69,9 @@ RetryStart:
|
|||||||
For Each TagText In value
|
For Each TagText In value
|
||||||
Dim NewTag = GetObjectFromXML(
|
Dim NewTag = GetObjectFromXML(
|
||||||
"<Border xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
|
"<Border xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
|
||||||
Background=""#11000000"" Padding=""3,1"" CornerRadius=""3"" Margin=""0,0,3,0""
|
Background=""#0C000000"" Padding=""3,1"" CornerRadius=""3"" Margin=""0,0,3,0""
|
||||||
SnapsToDevicePixels=""True"" UseLayoutRounding=""False"">
|
SnapsToDevicePixels=""True"" UseLayoutRounding=""False"">
|
||||||
<TextBlock Text=""" & TagText & """ Foreground=""#868686"" FontSize=""11"" />
|
<TextBlock Text=""" & TagText & """ Foreground=""#88000000"" FontSize=""11"" />
|
||||||
</Border>")
|
</Border>")
|
||||||
PanTags.Children.Add(NewTag)
|
PanTags.Children.Add(NewTag)
|
||||||
Next
|
Next
|
||||||
@@ -377,7 +303,7 @@ RetryStart:
|
|||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
Public Sub Refresh()
|
Public Sub Refresh() Handles Me.Loaded
|
||||||
RunInUi(
|
RunInUi(
|
||||||
Sub()
|
Sub()
|
||||||
'更新
|
'更新
|
||||||
@@ -404,30 +330,45 @@ RetryStart:
|
|||||||
Else
|
Else
|
||||||
BtnUpdate.Visibility = Visibility.Collapsed
|
BtnUpdate.Visibility = Visibility.Collapsed
|
||||||
End If
|
End If
|
||||||
'标题
|
'标题与描述
|
||||||
If Entry.Comp Is Nothing Then
|
Dim DescFileName As String
|
||||||
Title = Entry.Name
|
|
||||||
SubTitle = If(Entry.Version Is Nothing, "", " | " & Entry.Version)
|
|
||||||
Else
|
|
||||||
Dim Titles = Entry.Comp.GetControlTitle(False)
|
|
||||||
Title = Titles.Key
|
|
||||||
SubTitle = Titles.Value & If(Entry.Version Is Nothing, "", " | " & Entry.Version)
|
|
||||||
End If
|
|
||||||
If Checked Then
|
|
||||||
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5"))
|
|
||||||
Else
|
|
||||||
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4"))
|
|
||||||
End If
|
|
||||||
'描述
|
|
||||||
Dim NewDescription As String
|
|
||||||
Select Case Entry.State
|
Select Case Entry.State
|
||||||
Case McMod.McModState.Fine
|
Case McMod.McModState.Fine
|
||||||
NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path)
|
DescFileName = GetFileNameWithoutExtentionFromPath(Entry.Path)
|
||||||
Case McMod.McModState.Disabled
|
Case McMod.McModState.Disabled
|
||||||
NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path.Replace(".disabled", "").Replace(".old", ""))
|
DescFileName = GetFileNameWithoutExtentionFromPath(Entry.Path.Replace(".disabled", "").Replace(".old", ""))
|
||||||
Case Else 'McMod.McModState.Unavailable
|
Case Else 'McMod.McModState.Unavailable
|
||||||
NewDescription = GetFileNameFromPath(Entry.Path)
|
DescFileName = GetFileNameFromPath(Entry.Path)
|
||||||
End Select
|
End Select
|
||||||
|
Dim NewDescription As String
|
||||||
|
If Setup.Get("ToolModLocalNameStyle") = 1 Then
|
||||||
|
'标题显示文件名,详情显示译名
|
||||||
|
'标题
|
||||||
|
Title = DescFileName
|
||||||
|
SubTitle = ""
|
||||||
|
'描述
|
||||||
|
If Entry.Comp Is Nothing Then
|
||||||
|
NewDescription = Entry.Name
|
||||||
|
Else
|
||||||
|
Dim Titles = Entry.Comp.GetControlTitle(False)
|
||||||
|
NewDescription = Titles.Key & Titles.Value
|
||||||
|
End If
|
||||||
|
NewDescription = NewDescription.Replace(" | ", " / ")
|
||||||
|
If Entry.Version IsNot Nothing Then NewDescription &= $" ({Entry.Version})"
|
||||||
|
Else
|
||||||
|
'标题显示译名,详情显示文件名
|
||||||
|
'标题
|
||||||
|
If Entry.Comp Is Nothing Then
|
||||||
|
Title = Entry.Name
|
||||||
|
SubTitle = If(Entry.Version Is Nothing, "", " | " & Entry.Version)
|
||||||
|
Else
|
||||||
|
Dim Titles = Entry.Comp.GetControlTitle(False)
|
||||||
|
Title = Titles.Key
|
||||||
|
SubTitle = Titles.Value & If(Entry.Version Is Nothing, "", " | " & Entry.Version)
|
||||||
|
End If
|
||||||
|
'描述
|
||||||
|
NewDescription = DescFileName
|
||||||
|
End If
|
||||||
If Entry.Comp IsNot Nothing Then
|
If Entry.Comp IsNot Nothing Then
|
||||||
NewDescription += ": " & Entry.Comp.Description.Replace(vbCr, "").Replace(vbLf, "")
|
NewDescription += ": " & Entry.Comp.Description.Replace(vbCr, "").Replace(vbLf, "")
|
||||||
ElseIf Entry.Description IsNot Nothing Then
|
ElseIf Entry.Description IsNot Nothing Then
|
||||||
@@ -436,6 +377,11 @@ RetryStart:
|
|||||||
NewDescription += ": " & "存在错误,无法获取信息"
|
NewDescription += ": " & "存在错误,无法获取信息"
|
||||||
End If
|
End If
|
||||||
Description = NewDescription
|
Description = NewDescription
|
||||||
|
If Checked Then
|
||||||
|
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5"))
|
||||||
|
Else
|
||||||
|
LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4"))
|
||||||
|
End If
|
||||||
'主 Logo
|
'主 Logo
|
||||||
Logo = If(Entry.Comp Is Nothing, PathImage & "Icons/NoIcon.png", Entry.Comp.GetControlLogo())
|
Logo = If(Entry.Comp Is Nothing, PathImage & "Icons/NoIcon.png", Entry.Comp.GetControlLogo())
|
||||||
'图标右下角的 Logo
|
'图标右下角的 Logo
|
||||||
|
|||||||
@@ -92,7 +92,18 @@
|
|||||||
MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败")
|
MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败")
|
||||||
Exit Sub
|
Exit Sub
|
||||||
End If
|
End If
|
||||||
PageOtherTest.StartCustomDownload(Data(0), GetFileNameFromPath(Data(0)))
|
Try
|
||||||
|
Select Case Data.Length
|
||||||
|
Case 1
|
||||||
|
PageOtherTest.StartCustomDownload(Data(0), GetFileNameFromPath(Data(0)))
|
||||||
|
Case 2
|
||||||
|
PageOtherTest.StartCustomDownload(Data(0), Data(1))
|
||||||
|
Case Else
|
||||||
|
PageOtherTest.StartCustomDownload(Data(0), Data(1), Data(2))
|
||||||
|
End Select
|
||||||
|
Catch
|
||||||
|
PageOtherTest.StartCustomDownload(Data(0), "未知")
|
||||||
|
End Try
|
||||||
|
|
||||||
Case Else
|
Case Else
|
||||||
MyMsgBox("未知的事件类型:" & Type & vbCrLf & "请检查事件类型填写是否正确,或者 PCL 是否为最新版本。", "事件执行失败")
|
MyMsgBox("未知的事件类型:" & Type & vbCrLf & "请检查事件类型填写是否正确,或者 PCL 是否为最新版本。", "事件执行失败")
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ Friend Module ModSecret
|
|||||||
''' 设置 Headers 的 UA、Referer。
|
''' 设置 Headers 的 UA、Referer。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Friend Sub SecretHeadersSign(Url As String, ByRef Client As WebClient, Optional UseBrowserUserAgent As Boolean = False)
|
Friend Sub SecretHeadersSign(Url As String, ByRef Client As WebClient, Optional UseBrowserUserAgent As Boolean = False)
|
||||||
If Url.Contains("modrinth.com") Then '根据 #4334,不添加 PCL 的 UA 反而能正常访问
|
If Url.Contains("baidupcs.com") OrElse Url.Contains("baidu.com") Then
|
||||||
Client.Headers("User-Agent") = "Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36"
|
Client.Headers("User-Agent") = "LogStatistic" '#4951
|
||||||
ElseIf UseBrowserUserAgent Then
|
ElseIf UseBrowserUserAgent Then
|
||||||
Client.Headers("User-Agent") = "PCL2/" & VersionStandardCode & " Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36"
|
Client.Headers("User-Agent") = "PCL2/" & VersionStandardCode & " Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36"
|
||||||
Else
|
Else
|
||||||
@@ -115,8 +115,8 @@ Friend Module ModSecret
|
|||||||
''' 设置 Headers 的 UA、Referer。
|
''' 设置 Headers 的 UA、Referer。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Friend Sub SecretHeadersSign(Url As String, ByRef Request As HttpWebRequest, Optional UseBrowserUserAgent As Boolean = False)
|
Friend Sub SecretHeadersSign(Url As String, ByRef Request As HttpWebRequest, Optional UseBrowserUserAgent As Boolean = False)
|
||||||
If Url.Contains("modrinth.com") Then '根据 #4334,不添加 PCL 的 UA 反而能正常访问
|
If Url.Contains("baidupcs.com") OrElse Url.Contains("baidu.com") Then
|
||||||
Request.UserAgent = "Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36"
|
Client.Headers("User-Agent") = "LogStatistic" '#4951
|
||||||
ElseIf UseBrowserUserAgent Then
|
ElseIf UseBrowserUserAgent Then
|
||||||
Request.UserAgent = "PCL2/" & VersionStandardCode & " Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36"
|
Request.UserAgent = "PCL2/" & VersionStandardCode & " Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36"
|
||||||
Else
|
Else
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||||
' 方法是按如下所示使用“*”
|
' 方法是按如下所示使用“*”
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2.8.8.0")>
|
<Assembly: AssemblyVersion("2.8.9.0")>
|
||||||
<Assembly: AssemblyFileVersion("2.8.8.0")>
|
<Assembly: AssemblyFileVersion("2.8.9.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("")>
|
<Assembly: NeutralResourcesLanguage("")>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
Imports System.IO.Compression
|
Imports System.IO.Compression
|
||||||
|
Imports System.Net.Http
|
||||||
|
|
||||||
Public Module ModDownloadLib
|
Public Module ModDownloadLib
|
||||||
|
|
||||||
@@ -59,47 +60,6 @@ Public Module ModDownloadLib
|
|||||||
Return Nothing
|
Return Nothing
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
|
||||||
''' 保存某个 Minecraft 版本的核心文件(仅 Json 与核心 Jar)。
|
|
||||||
''' </summary>
|
|
||||||
''' <param name="Id">所下载的 Minecraft 的版本名。</param>
|
|
||||||
''' <param name="JsonUrl">Json 文件的 Mojang 官方地址。</param>
|
|
||||||
Public Sub McDownloadClientCore(Id As String, JsonUrl As String, Behaviour As NetPreDownloadBehaviour)
|
|
||||||
Try
|
|
||||||
Dim VersionFolder As String = SelectFolder()
|
|
||||||
If Not VersionFolder.Contains("\") Then Exit Sub
|
|
||||||
VersionFolder = VersionFolder & Id & "\"
|
|
||||||
|
|
||||||
'重复任务检查
|
|
||||||
For Each OngoingLoader In LoaderTaskbar.ToList()
|
|
||||||
If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For
|
|
||||||
If Behaviour = NetPreDownloadBehaviour.ExitWhileExistsOrDownloading Then Exit Sub
|
|
||||||
Hint("该版本正在下载中!", HintType.Critical)
|
|
||||||
Exit Sub
|
|
||||||
Next
|
|
||||||
|
|
||||||
Dim Loaders As New List(Of LoaderBase)
|
|
||||||
'下载版本 Json 文件
|
|
||||||
Loaders.Add(New LoaderDownload("下载版本 json 文件", New List(Of NetFile) From {
|
|
||||||
New NetFile(DlSourceLauncherOrMetaGet(JsonUrl), VersionFolder & Id & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True))
|
|
||||||
}) With {.ProgressWeight = 2})
|
|
||||||
'获取支持库文件地址
|
|
||||||
Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析核心 jar 文件下载地址",
|
|
||||||
Sub(Task As LoaderTask(Of String, List(Of NetFile))) Task.Output = McLibFix(New McVersion(VersionFolder), True)) With {.ProgressWeight = 0.5, .Show = False})
|
|
||||||
'下载支持库文件
|
|
||||||
Loaders.Add(New LoaderDownload("下载核心 jar 文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
|
||||||
|
|
||||||
'启动
|
|
||||||
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
|
||||||
Loader.Start(Id)
|
|
||||||
LoaderTaskbarAdd(Loader)
|
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
|
||||||
FrmMain.BtnExtraDownload.Ribble()
|
|
||||||
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "开始 Minecraft 下载失败", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 获取下载某个 Minecraft 版本的加载器列表。
|
''' 获取下载某个 Minecraft 版本的加载器列表。
|
||||||
@@ -207,19 +167,14 @@ Public Module ModDownloadLib
|
|||||||
ToolTipService.SetVerticalOffset(BtnInfo, 30)
|
ToolTipService.SetVerticalOffset(BtnInfo, 30)
|
||||||
ToolTipService.SetHorizontalOffset(BtnInfo, 2)
|
ToolTipService.SetHorizontalOffset(BtnInfo, 2)
|
||||||
AddHandler BtnInfo.Click, AddressOf McDownloadMenuLog
|
AddHandler BtnInfo.Click, AddressOf McDownloadMenuLog
|
||||||
Dim BtnServer As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"}
|
Dim BtnServer As New MyIconButton With {.LogoScale = 1, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"}
|
||||||
ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center)
|
ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center)
|
||||||
ToolTipService.SetVerticalOffset(BtnServer, 30)
|
ToolTipService.SetVerticalOffset(BtnServer, 30)
|
||||||
ToolTipService.SetHorizontalOffset(BtnServer, 2)
|
ToolTipService.SetHorizontalOffset(BtnServer, 2)
|
||||||
AddHandler BtnServer.Click, AddressOf McDownloadMenuServer
|
AddHandler BtnServer.Click, AddressOf McDownloadMenuSaveServer
|
||||||
sender.Buttons = {BtnServer, BtnInfo}
|
sender.Buttons = {BtnServer, BtnInfo}
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub McDownloadMenuBuild(sender As Object, e As EventArgs)
|
Private Sub McDownloadMenuBuild(sender As Object, e As EventArgs)
|
||||||
Dim BtnServer As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"}
|
|
||||||
ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center)
|
|
||||||
ToolTipService.SetVerticalOffset(BtnServer, 30)
|
|
||||||
ToolTipService.SetHorizontalOffset(BtnServer, 2)
|
|
||||||
AddHandler BtnServer.Click, AddressOf McDownloadMenuServer
|
|
||||||
Dim BtnSave As New MyIconButton With {.Logo = Logo.IconButtonSave, .ToolTip = "另存为"}
|
Dim BtnSave As New MyIconButton With {.Logo = Logo.IconButtonSave, .ToolTip = "另存为"}
|
||||||
ToolTipService.SetPlacement(BtnSave, Primitives.PlacementMode.Center)
|
ToolTipService.SetPlacement(BtnSave, Primitives.PlacementMode.Center)
|
||||||
ToolTipService.SetVerticalOffset(BtnSave, 30)
|
ToolTipService.SetVerticalOffset(BtnSave, 30)
|
||||||
@@ -230,7 +185,12 @@ Public Module ModDownloadLib
|
|||||||
ToolTipService.SetVerticalOffset(BtnInfo, 30)
|
ToolTipService.SetVerticalOffset(BtnInfo, 30)
|
||||||
ToolTipService.SetHorizontalOffset(BtnInfo, 2)
|
ToolTipService.SetHorizontalOffset(BtnInfo, 2)
|
||||||
AddHandler BtnInfo.Click, AddressOf McDownloadMenuLog
|
AddHandler BtnInfo.Click, AddressOf McDownloadMenuLog
|
||||||
sender.Buttons = {BtnServer, BtnSave, BtnInfo}
|
Dim BtnServer As New MyIconButton With {.LogoScale = 1, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"}
|
||||||
|
ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center)
|
||||||
|
ToolTipService.SetVerticalOffset(BtnServer, 30)
|
||||||
|
ToolTipService.SetHorizontalOffset(BtnServer, 2)
|
||||||
|
AddHandler BtnServer.Click, AddressOf McDownloadMenuSaveServer
|
||||||
|
sender.Buttons = {BtnSave, BtnInfo, BtnServer}
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub McDownloadMenuLog(sender As Object, e As RoutedEventArgs)
|
Private Sub McDownloadMenuLog(sender As Object, e As RoutedEventArgs)
|
||||||
Dim Version As JToken
|
Dim Version As JToken
|
||||||
@@ -243,60 +203,74 @@ Public Module ModDownloadLib
|
|||||||
End If
|
End If
|
||||||
McUpdateLogShow(Version)
|
McUpdateLogShow(Version)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub McDownloadMenuServer(sender As Object, e As RoutedEventArgs)
|
Private Sub McDownloadMenuSaveServer(sender As Object, e As RoutedEventArgs)
|
||||||
Dim Version As JToken
|
Dim Version As MyListItem
|
||||||
If sender.Tag IsNot Nothing Then
|
If TypeOf sender Is MyListItem Then
|
||||||
Version = sender.Tag
|
Version = sender
|
||||||
ElseIf sender.Parent.Tag IsNot Nothing Then
|
ElseIf TypeOf sender.Parent Is MyListItem Then
|
||||||
Version = sender.Parent.Tag
|
Version = sender.Parent
|
||||||
Else
|
Else
|
||||||
Version = sender.Parent.Parent.Tag
|
Version = sender.Parent.Parent
|
||||||
End If
|
End If
|
||||||
RunInThread(Sub()
|
Try
|
||||||
Dim Json As JObject
|
Dim Id = Version.Title
|
||||||
Try
|
Dim JsonUrl = Version.Tag("url").ToString
|
||||||
Json = NetGetCodeByRequestRetry(Version("url"), IsJson:=True)
|
Dim VersionFolder As String = SelectFolder()
|
||||||
Catch ex As Exception
|
If Not VersionFolder.Contains("\") Then Exit Sub
|
||||||
Log(ex, "未找能获取到服务端文件,文件可能不存在")
|
VersionFolder = VersionFolder & Id & "\"
|
||||||
End Try
|
|
||||||
If Json?("downloads")?("server") Is Nothing Then
|
|
||||||
Hint("此版本暂未有服务端文件提供下载")
|
|
||||||
Else
|
|
||||||
RunInUi(Sub()
|
|
||||||
Try
|
|
||||||
Dim Url As String = Json("downloads")("server")("url").ToString()
|
|
||||||
Dim FileName As String = Version("id").ToString() & "-server.jar"
|
|
||||||
Dim VersionID As String = Version("id").ToString()
|
|
||||||
Dim Target As String = SelectAs("选择保存位置", FileName, "原版服务端 (*.jar)|*.jar")
|
|
||||||
If Not Target.Contains("\") Then Exit Sub
|
|
||||||
|
|
||||||
'重复任务检查
|
'重复任务检查
|
||||||
For Each OngoingLoader In LoaderTaskbar
|
For Each OngoingLoader In LoaderTaskbar.ToList()
|
||||||
If OngoingLoader.Name <> $"{VersionID} 服务端下载" Then Continue For
|
If OngoingLoader.Name <> $"Minecraft {Id} 服务端下载" Then Continue For
|
||||||
Hint("该服务端文件正在下载中!", HintType.Critical)
|
Hint("该服务端正在下载中!", HintType.Critical)
|
||||||
Exit Sub
|
Exit Sub
|
||||||
Next
|
Next
|
||||||
|
|
||||||
'构造步骤加载器
|
Dim Loaders As New List(Of LoaderBase)
|
||||||
Dim Loaders As New List(Of LoaderBase)
|
'下载版本 JSON 文件
|
||||||
'下载
|
Loaders.Add(New LoaderDownload("下载版本 JSON 文件", New List(Of NetFile) From {
|
||||||
Dim Address As New List(Of String)
|
New NetFile(DlSourceLauncherOrMetaGet(JsonUrl), VersionFolder & Id & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True))
|
||||||
Address.Add(Url)
|
}) With {.ProgressWeight = 2})
|
||||||
Loaders.Add(New LoaderDownload("下载服务端文件", New List(Of NetFile) From {New NetFile(Address.ToArray, Target, New FileChecker(MinSize:=1024 * 64))}) With {.ProgressWeight = 15})
|
'构建服务端
|
||||||
'启动
|
Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("构建服务端",
|
||||||
Dim Loader As New LoaderCombo(Of JObject)($"{VersionID} 服务端下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
Sub(Task As LoaderTask(Of String, List(Of NetFile)))
|
||||||
Loader.Start(Json("downloads")("server"))
|
'分析服务端 JAR 文件下载地址
|
||||||
LoaderTaskbarAdd(Loader)
|
Dim McVersion As New McVersion(VersionFolder)
|
||||||
FrmMain.BtnExtraDownload.ShowRefresh()
|
If McVersion.JsonObject("downloads") Is Nothing OrElse McVersion.JsonObject("downloads")("server") Is Nothing OrElse McVersion.JsonObject("downloads")("server")("url") Is Nothing Then Throw New Exception($"{Id} 版本没有提供服务端文件")
|
||||||
FrmMain.BtnExtraDownload.Ribble()
|
Dim JarUrl As String = McVersion.JsonObject("downloads")("server")("url")
|
||||||
|
Dim Checker As New FileChecker(MinSize:=1024, ActualSize:=If(McVersion.JsonObject("downloads")("server")("size"), -1), Hash:=McVersion.JsonObject("downloads")("server")("sha1"))
|
||||||
|
Task.Output = New List(Of NetFile) From {New NetFile(DlSourceLauncherOrMetaGet(JarUrl), VersionFolder & Id & "-server.jar", Checker)}
|
||||||
|
'添加启动脚本
|
||||||
|
Dim Bat As String =
|
||||||
|
$"@echo off
|
||||||
|
title {Id} 原版服务端
|
||||||
|
echo 如果服务端立即停止,请右键编辑该脚本,将下一行开头的 java 替换为适合该 Minecraft 版本的完整 java.exe 的路径。
|
||||||
|
echo 你可以在 PCL 的 [设置 → 启动选项] 中查看已安装的 java,所需的 java.exe 一般在其中的 bin 文件夹下。
|
||||||
|
echo ------------------------------
|
||||||
|
echo 如果提示 ""You need to agree to the EULA in order to run the server"",请打开 eula.txt,按说明阅读并同意 Minecraft EULA 后,将该文件最后一行中的 eula=false 改为 eula=true。
|
||||||
|
echo ------------------------------
|
||||||
|
""java"" -server -XX:+UseG1GC -Xmx4096M -Xms1024M -XX:+UseCompressedOops -jar {Id}-server.jar nogui
|
||||||
|
echo ----------------------
|
||||||
|
echo 服务端已停止。
|
||||||
|
pause"
|
||||||
|
WriteFile(VersionFolder & "Launch Server.bat", Bat,
|
||||||
|
Encoding:=If(Encoding.Default.Equals(Encoding.UTF8), Encoding.UTF8, Encoding.GetEncoding("GB18030")))
|
||||||
|
'删除版本 JSON
|
||||||
|
File.Delete(VersionFolder & Id & ".json")
|
||||||
|
End Sub
|
||||||
|
) With {.ProgressWeight = 0.5, .Show = False})
|
||||||
|
'下载服务端文件
|
||||||
|
Loaders.Add(New LoaderDownload("下载服务端文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
||||||
|
|
||||||
Catch ex As Exception
|
'启动
|
||||||
Log(ex, "开始服务端文件下载失败", LogLevel.Feedback)
|
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 服务端下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
||||||
End Try
|
Loader.Start(Id)
|
||||||
End Sub)
|
LoaderTaskbarAdd(Loader)
|
||||||
End If
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
End Sub
|
FrmMain.BtnExtraDownload.Ribble()
|
||||||
)
|
Catch ex As Exception
|
||||||
|
Log(ex, "开始 Minecraft 服务端下载失败", LogLevel.Feedback)
|
||||||
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub McDownloadMenuSave(sender As Object, e As RoutedEventArgs)
|
Public Sub McDownloadMenuSave(sender As Object, e As RoutedEventArgs)
|
||||||
Dim Version As MyListItem
|
Dim Version As MyListItem
|
||||||
@@ -307,7 +281,41 @@ Public Module ModDownloadLib
|
|||||||
Else
|
Else
|
||||||
Version = sender.Parent.Parent
|
Version = sender.Parent.Parent
|
||||||
End If
|
End If
|
||||||
McDownloadClientCore(Version.Title, Version.Tag("url").ToString, NetPreDownloadBehaviour.HintWhileExists)
|
Try
|
||||||
|
Dim Id = Version.Title
|
||||||
|
Dim JsonUrl = Version.Tag("url").ToString
|
||||||
|
Dim VersionFolder As String = SelectFolder()
|
||||||
|
If Not VersionFolder.Contains("\") Then Exit Sub
|
||||||
|
VersionFolder = VersionFolder & Id & "\"
|
||||||
|
|
||||||
|
'重复任务检查
|
||||||
|
For Each OngoingLoader In LoaderTaskbar.ToList()
|
||||||
|
If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For
|
||||||
|
Hint("该版本正在下载中!", HintType.Critical)
|
||||||
|
Exit Sub
|
||||||
|
Next
|
||||||
|
|
||||||
|
Dim Loaders As New List(Of LoaderBase)
|
||||||
|
'下载版本 JSON 文件
|
||||||
|
Loaders.Add(New LoaderDownload("下载版本 JSON 文件", New List(Of NetFile) From {
|
||||||
|
New NetFile(DlSourceLauncherOrMetaGet(JsonUrl), VersionFolder & Id & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True))
|
||||||
|
}) With {.ProgressWeight = 2})
|
||||||
|
'获取支持库文件地址
|
||||||
|
Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析核心 JAR 文件下载地址",
|
||||||
|
Sub(Task) Task.Output = New List(Of NetFile) From {DlClientJarGet(New McVersion(VersionFolder), False)}
|
||||||
|
) With {.ProgressWeight = 0.5, .Show = False})
|
||||||
|
'下载支持库文件
|
||||||
|
Loaders.Add(New LoaderDownload("下载核心 JAR 文件", New List(Of NetFile)) With {.ProgressWeight = 5})
|
||||||
|
|
||||||
|
'启动
|
||||||
|
Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
|
||||||
|
Loader.Start(Id)
|
||||||
|
LoaderTaskbarAdd(Loader)
|
||||||
|
FrmMain.BtnExtraDownload.ShowRefresh()
|
||||||
|
FrmMain.BtnExtraDownload.Ribble()
|
||||||
|
Catch ex As Exception
|
||||||
|
Log(ex, "开始 Minecraft 下载失败", LogLevel.Feedback)
|
||||||
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 显示某 Minecraft 版本的更新日志。
|
''' 显示某 Minecraft 版本的更新日志。
|
||||||
@@ -424,7 +432,7 @@ Public Module ModDownloadLib
|
|||||||
'添加 Java Wrapper 作为主 Jar
|
'添加 Java Wrapper 作为主 Jar
|
||||||
Dim Arguments As String
|
Dim Arguments As String
|
||||||
If UseJavaWrapper Then
|
If UseJavaWrapper Then
|
||||||
Arguments = $"-Doolloo.jlw.tmpdir=""{GetPureASCIIDir()}"" -Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" -jar ""{ExtractJavaWrapper()}"" optifine.Installer"
|
Arguments = $"-Doolloo.jlw.tmpdir=""{PathPure.TrimEnd("\")}"" -Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" -jar ""{ExtractJavaWrapper()}"" optifine.Installer"
|
||||||
Else
|
Else
|
||||||
Arguments = $"-Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" optifine.Installer"
|
Arguments = $"-Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" optifine.Installer"
|
||||||
End If
|
End If
|
||||||
@@ -1091,7 +1099,7 @@ Retry:
|
|||||||
'添加 Java Wrapper 作为主 Jar
|
'添加 Java Wrapper 作为主 Jar
|
||||||
Dim Arguments As String
|
Dim Arguments As String
|
||||||
If UseJavaWrapper Then
|
If UseJavaWrapper Then
|
||||||
Arguments = $"-Doolloo.jlw.tmpdir=""{GetPureASCIIDir()}"" -cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" -jar ""{ExtractJavaWrapper()}"" com.bangbang93.ForgeInstaller ""{McFolder}"
|
Arguments = $"-Doolloo.jlw.tmpdir=""{PathPure.TrimEnd("\")}"" -cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" -jar ""{ExtractJavaWrapper()}"" com.bangbang93.ForgeInstaller ""{McFolder}"
|
||||||
Else
|
Else
|
||||||
Arguments = $"-cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" com.bangbang93.ForgeInstaller ""{McFolder}"
|
Arguments = $"-cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" com.bangbang93.ForgeInstaller ""{McFolder}"
|
||||||
End If
|
End If
|
||||||
@@ -1446,8 +1454,6 @@ Retry:
|
|||||||
'没有新增文件夹
|
'没有新增文件夹
|
||||||
Log("[Download] 未找到新增的版本文件夹")
|
Log("[Download] 未找到新增的版本文件夹")
|
||||||
End If
|
End If
|
||||||
'新建 mods 文件夹
|
|
||||||
Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\")
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Throw New Exception($"安装新 {LoaderName} 版本失败", ex)
|
Throw New Exception($"安装新 {LoaderName} 版本失败", ex)
|
||||||
Finally
|
Finally
|
||||||
@@ -1463,57 +1469,55 @@ Retry:
|
|||||||
Else
|
Else
|
||||||
Log("[Download] 检测为非新版 Forge:" & LoaderVersion)
|
Log("[Download] 检测为非新版 Forge:" & LoaderVersion)
|
||||||
Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)($"安装 {LoaderName}(方式 B)",
|
Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)($"安装 {LoaderName}(方式 B)",
|
||||||
Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
||||||
Dim Installer As ZipArchive = Nothing
|
Dim Installer As ZipArchive = Nothing
|
||||||
Try
|
Try
|
||||||
'解压并获取信息
|
'解压并获取信息
|
||||||
Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open))
|
Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open))
|
||||||
Task.Progress = 0.2
|
Task.Progress = 0.2
|
||||||
Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open))
|
Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open))
|
||||||
Task.Progress = 0.4
|
Task.Progress = 0.4
|
||||||
'新建版本文件夹
|
'新建版本文件夹
|
||||||
Directory.CreateDirectory(VersionFolder)
|
Directory.CreateDirectory(VersionFolder)
|
||||||
Task.Progress = 0.5
|
Task.Progress = 0.5
|
||||||
If Json("install") Is Nothing Then
|
If Json("install") Is Nothing Then
|
||||||
'中版:Legacy 方式 1
|
'中版:Legacy 方式 1
|
||||||
Log("[Download] 开始进行 Forge 安装,Legacy 方式 1:" & InstallerAddress)
|
Log("[Download] 开始进行 Forge 安装,Legacy 方式 1:" & InstallerAddress)
|
||||||
'建立 Json 文件
|
'建立 Json 文件
|
||||||
Dim JsonVersion As JObject = GetJson(ReadFile(Installer.GetEntry(Json("json").ToString.TrimStart("/")).Open))
|
Dim JsonVersion As JObject = GetJson(ReadFile(Installer.GetEntry(Json("json").ToString.TrimStart("/")).Open))
|
||||||
JsonVersion("id") = TargetVersion
|
JsonVersion("id") = TargetVersion
|
||||||
WriteFile(VersionFolder & TargetVersion & ".json", JsonVersion.ToString)
|
WriteFile(VersionFolder & TargetVersion & ".json", JsonVersion.ToString)
|
||||||
Task.Progress = 0.6
|
Task.Progress = 0.6
|
||||||
'解压支持库文件
|
'解压支持库文件
|
||||||
Installer.Dispose()
|
Installer.Dispose()
|
||||||
ExtractFile(InstallerAddress, InstallerAddress & "_unrar\")
|
ExtractFile(InstallerAddress, InstallerAddress & "_unrar\")
|
||||||
CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\")
|
CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\")
|
||||||
DeleteDirectory(InstallerAddress & "_unrar\")
|
DeleteDirectory(InstallerAddress & "_unrar\")
|
||||||
Else
|
Else
|
||||||
'旧版:Legacy 方式 2
|
'旧版:Legacy 方式 2
|
||||||
Log("[Download] 开始进行 Forge 安装,Legacy 方式 2:" & InstallerAddress)
|
Log("[Download] 开始进行 Forge 安装,Legacy 方式 2:" & InstallerAddress)
|
||||||
'解压 Jar 文件
|
'解压 Jar 文件
|
||||||
Dim JarAddress As String = McLibGet(Json("install")("path"), CustomMcFolder:=McFolder)
|
Dim JarAddress As String = McLibGet(Json("install")("path"), CustomMcFolder:=McFolder)
|
||||||
If File.Exists(JarAddress) Then File.Delete(JarAddress)
|
If File.Exists(JarAddress) Then File.Delete(JarAddress)
|
||||||
WriteFile(JarAddress, Installer.GetEntry(Json("install")("filePath")).Open)
|
WriteFile(JarAddress, Installer.GetEntry(Json("install")("filePath")).Open)
|
||||||
Task.Progress = 0.9
|
Task.Progress = 0.9
|
||||||
'建立 Json 文件
|
'建立 Json 文件
|
||||||
Json("versionInfo")("id") = TargetVersion
|
Json("versionInfo")("id") = TargetVersion
|
||||||
If Json("versionInfo")("inheritsFrom") Is Nothing Then CType(Json("versionInfo"), JObject).Add("inheritsFrom", Inherit)
|
If Json("versionInfo")("inheritsFrom") Is Nothing Then CType(Json("versionInfo"), JObject).Add("inheritsFrom", Inherit)
|
||||||
WriteFile(VersionFolder & TargetVersion & ".json", Json("versionInfo").ToString)
|
WriteFile(VersionFolder & TargetVersion & ".json", Json("versionInfo").ToString)
|
||||||
End If
|
End If
|
||||||
'新建 mods 文件夹
|
Catch ex As Exception
|
||||||
Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\")
|
Throw New Exception("非新版方式安装 Forge 失败", ex)
|
||||||
Catch ex As Exception
|
Finally
|
||||||
Throw New Exception("非新版方式安装 Forge 失败", ex)
|
Try
|
||||||
Finally
|
'清理文件
|
||||||
Try
|
If Installer IsNot Nothing Then Installer.Dispose()
|
||||||
'清理文件
|
If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress)
|
||||||
If Installer IsNot Nothing Then Installer.Dispose()
|
If Directory.Exists(InstallerAddress & "_unrar\") Then DeleteDirectory(InstallerAddress & "_unrar\")
|
||||||
If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress)
|
Catch ex As Exception
|
||||||
If Directory.Exists(InstallerAddress & "_unrar\") Then DeleteDirectory(InstallerAddress & "_unrar\")
|
Log(ex, "非新版方式安装 Forge 清理文件时出错")
|
||||||
Catch ex As Exception
|
End Try
|
||||||
Log(ex, "非新版方式安装 Forge 清理文件时出错")
|
End Try
|
||||||
End Try
|
|
||||||
End Try
|
|
||||||
End Sub) With {.ProgressWeight = 1})
|
End Sub) With {.ProgressWeight = 1})
|
||||||
End If
|
End If
|
||||||
|
|
||||||
@@ -1830,8 +1834,6 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
|||||||
"https://bmclapi2.bangbang93.com/fabric-meta/v2/versions/loader/" & MinecraftName & "/" & FabricVersion & "/profile/json",
|
"https://bmclapi2.bangbang93.com/fabric-meta/v2/versions/loader/" & MinecraftName & "/" & FabricVersion & "/profile/json",
|
||||||
"https://meta.fabricmc.net/v2/versions/loader/" & MinecraftName & "/" & FabricVersion & "/profile/json"
|
"https://meta.fabricmc.net/v2/versions/loader/" & MinecraftName & "/" & FabricVersion & "/profile/json"
|
||||||
}, VersionFolder & Id & ".json", New FileChecker(IsJson:=True))}
|
}, VersionFolder & Id & ".json", New FileChecker(IsJson:=True))}
|
||||||
'新建 mods 文件夹
|
|
||||||
Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\")
|
|
||||||
End Sub) With {.ProgressWeight = 0.5})
|
End Sub) With {.ProgressWeight = 0.5})
|
||||||
Loaders.Add(New LoaderDownload("下载 Fabric 主文件", New List(Of NetFile)) With {.ProgressWeight = 2.5})
|
Loaders.Add(New LoaderDownload("下载 Fabric 主文件", New List(Of NetFile)) With {.ProgressWeight = 2.5})
|
||||||
|
|
||||||
@@ -2090,9 +2092,11 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
|||||||
Dim OptiFineAsMod As Boolean = Request.OptiFineEntry IsNot Nothing AndAlso '1. 选择了 OptiFine
|
Dim OptiFineAsMod As Boolean = Request.OptiFineEntry IsNot Nothing AndAlso '1. 选择了 OptiFine
|
||||||
(Request.FabricVersion IsNot Nothing OrElse '2. 选择了 Fabric...
|
(Request.FabricVersion IsNot Nothing OrElse '2. 选择了 Fabric...
|
||||||
(Request.ForgeEntry IsNot Nothing AndAlso MinecraftCode >= 14 AndAlso MinecraftCode <= 15)) '...或者 Forge 1.14~15(#4134)
|
(Request.ForgeEntry IsNot Nothing AndAlso MinecraftCode >= 14 AndAlso MinecraftCode <= 15)) '...或者 Forge 1.14~15(#4134)
|
||||||
|
Dim ModsFolder As String = New McVersion(OutputFolder).GetPathIndie(True) & "mods\"
|
||||||
|
|
||||||
If OptiFineAsMod Then
|
If OptiFineAsMod Then
|
||||||
Log("[Download] OptiFine 将作为 Mod 进行下载")
|
Log("[Download] OptiFine 将作为 Mod 进行下载")
|
||||||
OptiFineFolder = New McVersion(OutputFolder).GetPathIndie(True) & "mods\"
|
OptiFineFolder = ModsFolder
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'记录日志
|
'记录日志
|
||||||
@@ -2114,11 +2118,11 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
|||||||
LoaderList.Add(New LoaderTask(Of Integer, Integer)("添加忽略标识", Sub() WriteFile(OutputFolder & ".pclignore", "用于临时地在 PCL 的版本列表中屏蔽此版本。")) With {.Show = False, .Block = False})
|
LoaderList.Add(New LoaderTask(Of Integer, Integer)("添加忽略标识", Sub() WriteFile(OutputFolder & ".pclignore", "用于临时地在 PCL 的版本列表中屏蔽此版本。")) With {.Show = False, .Block = False})
|
||||||
'Fabric API
|
'Fabric API
|
||||||
If Request.FabricApi IsNot Nothing Then
|
If Request.FabricApi IsNot Nothing Then
|
||||||
LoaderList.Add(New LoaderDownload("下载 Fabric API", New List(Of NetFile) From {Request.FabricApi.ToNetFile(New McVersion(OutputFolder).GetPathIndie(True) & "mods\")}) With {.ProgressWeight = 3, .Block = False})
|
LoaderList.Add(New LoaderDownload("下载 Fabric API", New List(Of NetFile) From {Request.FabricApi.ToNetFile(ModsFolder)}) With {.ProgressWeight = 3, .Block = False})
|
||||||
End If
|
End If
|
||||||
'OptiFabric
|
'OptiFabric
|
||||||
If Request.OptiFabric IsNot Nothing Then
|
If Request.OptiFabric IsNot Nothing Then
|
||||||
LoaderList.Add(New LoaderDownload("下载 OptiFabric", New List(Of NetFile) From {Request.OptiFabric.ToNetFile(New McVersion(OutputFolder).GetPathIndie(True) & "mods\")}) With {.ProgressWeight = 3, .Block = False})
|
LoaderList.Add(New LoaderDownload("下载 OptiFabric", New List(Of NetFile) From {Request.OptiFabric.ToNetFile(ModsFolder)}) With {.ProgressWeight = 3, .Block = False})
|
||||||
End If
|
End If
|
||||||
'原版
|
'原版
|
||||||
Dim ClientLoader = New LoaderCombo(Of String)("下载原版 " & Request.MinecraftName, McDownloadClientLoader(Request.MinecraftName, Request.MinecraftJson, Request.TargetVersionName)) With {.Show = False, .ProgressWeight = 39, .Block = Request.ForgeVersion Is Nothing AndAlso Request.OptiFineEntry Is Nothing AndAlso Request.FabricVersion Is Nothing AndAlso Request.LiteLoaderEntry Is Nothing}
|
Dim ClientLoader = New LoaderCombo(Of String)("下载原版 " & Request.MinecraftName, McDownloadClientLoader(Request.MinecraftName, Request.MinecraftJson, Request.TargetVersionName)) With {.Show = False, .ProgressWeight = 39, .Block = Request.ForgeVersion Is Nothing AndAlso Request.OptiFineEntry Is Nothing AndAlso Request.FabricVersion Is Nothing AndAlso Request.LiteLoaderEntry Is Nothing}
|
||||||
@@ -2153,7 +2157,12 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
|
|||||||
InstallMerge(OutputFolder, OutputFolder, OptiFineFolder, OptiFineAsMod, ForgeFolder, Request.ForgeVersion, NeoForgeFolder, Request.NeoForgeVersion, FabricFolder, LiteLoaderFolder)
|
InstallMerge(OutputFolder, OutputFolder, OptiFineFolder, OptiFineAsMod, ForgeFolder, Request.ForgeVersion, NeoForgeFolder, Request.NeoForgeVersion, FabricFolder, LiteLoaderFolder)
|
||||||
Task.Progress = 0.3
|
Task.Progress = 0.3
|
||||||
If Directory.Exists(TempMcFolder & "libraries") Then CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries")
|
If Directory.Exists(TempMcFolder & "libraries") Then CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries")
|
||||||
If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", PathMcFolder & "mods")
|
If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", ModsFolder)
|
||||||
|
'新建 mods 文件夹
|
||||||
|
If Request.ForgeVersion IsNot Nothing OrElse Request.FabricVersion IsNot Nothing OrElse Request.NeoForgeEntry IsNot Nothing OrElse Request.LiteLoaderEntry IsNot Nothing Then
|
||||||
|
Directory.CreateDirectory(ModsFolder)
|
||||||
|
Log("[Download] 自动创建 mods 文件夹:" & ModsFolder)
|
||||||
|
End If
|
||||||
End Sub) With {.ProgressWeight = 2, .Block = True})
|
End Sub) With {.ProgressWeight = 2, .Block = True})
|
||||||
'补全文件
|
'补全文件
|
||||||
If Not DontFixLibraries AndAlso
|
If Not DontFixLibraries AndAlso
|
||||||
|
|||||||
@@ -167,7 +167,7 @@
|
|||||||
'构造步骤加载器
|
'构造步骤加载器
|
||||||
Dim Loaders As New List(Of LoaderBase)
|
Dim Loaders As New List(Of LoaderBase)
|
||||||
Dim Target As String = $"{PathMcFolder}versions\{VersionName}\原始整合包.{If(Project.FromCurseForge, "zip", "mrpack")}"
|
Dim Target As String = $"{PathMcFolder}versions\{VersionName}\原始整合包.{If(Project.FromCurseForge, "zip", "mrpack")}"
|
||||||
Dim LogoFileAddress As String = PathTemp & "CompLogo\" & GetHash(CompItem.Logo) & ".png"
|
Dim LogoFileAddress As String = MyImage.GetTempPath(CompItem.Logo)
|
||||||
Loaders.Add(New LoaderDownload("下载整合包文件", New List(Of NetFile) From {File.ToNetFile(Target)}) With {.ProgressWeight = 10, .Block = True})
|
Loaders.Add(New LoaderDownload("下载整合包文件", New List(Of NetFile) From {File.ToNetFile(Target)}) With {.ProgressWeight = 10, .Block = True})
|
||||||
Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包",
|
Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包",
|
||||||
Sub()
|
Sub()
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
PageChangeRun(PageGet(ID))
|
PageChangeRun(PageGet(ID))
|
||||||
PageID = ID
|
PageID = ID
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
||||||
Finally
|
Finally
|
||||||
AniControlEnabled -= 1
|
AniControlEnabled -= 1
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -13,12 +13,18 @@
|
|||||||
Private Shared Function LoaderInput() As CompProjectRequest
|
Private Shared Function LoaderInput() As CompProjectRequest
|
||||||
Dim Request As New CompProjectRequest(CompType.Mod, Storage, (Page + 1) * PageSize)
|
Dim Request As New CompProjectRequest(CompType.Mod, Storage, (Page + 1) * PageSize)
|
||||||
If FrmDownloadMod IsNot Nothing Then
|
If FrmDownloadMod IsNot Nothing Then
|
||||||
|
Dim ModLoader As CompModLoaderType = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag)
|
||||||
|
Dim GameVersion As String = If(FrmDownloadMod.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
|
||||||
|
If(FrmDownloadMod.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadMod.TextSearchVersion.Text.Contains("w"), FrmDownloadMod.TextSearchVersion.Text, Nothing))
|
||||||
|
If GameVersion IsNot Nothing AndAlso GameVersion.Contains(".") AndAlso Val(GameVersion.Split(".")(1)) < 14 AndAlso '1.14-
|
||||||
|
ModLoader = CompModLoaderType.Forge Then '选择了 Forge
|
||||||
|
ModLoader = CompModLoaderType.Any '此时,视作没有筛选 Mod Loader(因为部分老 Mod 没有设置自己支持的加载器)
|
||||||
|
End If
|
||||||
With Request
|
With Request
|
||||||
.SearchText = FrmDownloadMod.TextSearchName.Text
|
.SearchText = FrmDownloadMod.TextSearchName.Text
|
||||||
.GameVersion = If(FrmDownloadMod.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
|
.GameVersion = GameVersion
|
||||||
If(FrmDownloadMod.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadMod.TextSearchVersion.Text.Contains("w"), FrmDownloadMod.TextSearchVersion.Text, Nothing))
|
|
||||||
.Tag = FrmDownloadMod.ComboSearchTag.SelectedItem.Tag
|
.Tag = FrmDownloadMod.ComboSearchTag.SelectedItem.Tag
|
||||||
.ModLoader = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag)
|
.ModLoader = ModLoader
|
||||||
.Source = CType(Val(FrmDownloadMod.ComboSearchSource.SelectedItem.Tag), CompSourceType)
|
.Source = CType(Val(FrmDownloadMod.ComboSearchSource.SelectedItem.Tag), CompSourceType)
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -126,7 +126,7 @@
|
|||||||
Finished(New Exception("$登录用时太长啦,重新试试吧!"))
|
Finished(New Exception("$登录用时太长啦,重新试试吧!"))
|
||||||
Return
|
Return
|
||||||
ElseIf ex.Message.Contains("AADSTS70000") Then '可能不能判 “invalid_grant”,见 #269
|
ElseIf ex.Message.Contains("AADSTS70000") Then '可能不能判 “invalid_grant”,见 #269
|
||||||
Finished(New RetryException)
|
Finished(New RestartException)
|
||||||
Return
|
Return
|
||||||
ElseIf ex.Message.Contains("authorization_pending") Then
|
ElseIf ex.Message.Contains("authorization_pending") Then
|
||||||
Thread.Sleep(2000)
|
Thread.Sleep(2000)
|
||||||
|
|||||||
@@ -177,8 +177,8 @@
|
|||||||
Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
'更新缓存
|
'更新缓存
|
||||||
WriteIni(PathTemp & "Cache\Skin\IndexMs.ini", Setup.Get("CacheMsUuid"), SkinAddress)
|
WriteIni(PathTemp & "Cache\Skin\IndexMs.ini", Setup.Get("CacheMsV2Uuid"), SkinAddress)
|
||||||
Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("CacheMsUuid"), SkinAddress))
|
Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("CacheMsV2Uuid"), SkinAddress))
|
||||||
'刷新控件
|
'刷新控件
|
||||||
For Each SkinLoader In {PageLaunchLeft.SkinMs, PageLaunchLeft.SkinLegacy}
|
For Each SkinLoader In {PageLaunchLeft.SkinMs, PageLaunchLeft.SkinLegacy}
|
||||||
SkinLoader.WaitForExit(IsForceRestart:=True)
|
SkinLoader.WaitForExit(IsForceRestart:=True)
|
||||||
|
|||||||
@@ -296,7 +296,7 @@
|
|||||||
Case 0 '正版或离线
|
Case 0 '正版或离线
|
||||||
UnknownType:
|
UnknownType:
|
||||||
If RadioLoginType5.Checked Then
|
If RadioLoginType5.Checked Then
|
||||||
If Setup.Get("CacheMsAccess") = "" Then
|
If Setup.Get("CacheMsV2Access") = "" Then
|
||||||
Type = PageType.Ms
|
Type = PageType.Ms
|
||||||
Else
|
Else
|
||||||
Type = PageType.MsSkin
|
Type = PageType.MsSkin
|
||||||
@@ -311,7 +311,7 @@ UnknownType:
|
|||||||
RadioLoginType5.Visibility = Visibility.Visible
|
RadioLoginType5.Visibility = Visibility.Visible
|
||||||
RadioLoginType0.Visibility = Visibility.Visible
|
RadioLoginType0.Visibility = Visibility.Visible
|
||||||
Case 1 '仅正版
|
Case 1 '仅正版
|
||||||
If Setup.Get("CacheMsAccess") = "" Then
|
If Setup.Get("CacheMsV2Access") = "" Then
|
||||||
Type = PageType.Ms
|
Type = PageType.Ms
|
||||||
Else
|
Else
|
||||||
Type = PageType.MsSkin
|
Type = PageType.MsSkin
|
||||||
@@ -375,7 +375,7 @@ UnknownType:
|
|||||||
Public Shared SkinMs As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Ms", AddressOf SkinMsLoad, AddressOf SkinMsInput, ThreadPriority.AboveNormal)
|
Public Shared SkinMs As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Ms", AddressOf SkinMsLoad, AddressOf SkinMsInput, ThreadPriority.AboveNormal)
|
||||||
Private Shared Function SkinMsInput() As EqualableList(Of String)
|
Private Shared Function SkinMsInput() As EqualableList(Of String)
|
||||||
'获取名称
|
'获取名称
|
||||||
Return New EqualableList(Of String) From {Setup.Get("CacheMsName"), Setup.Get("CacheMsUuid")}
|
Return New EqualableList(Of String) From {Setup.Get("CacheMsV2Name"), Setup.Get("CacheMsV2Uuid")}
|
||||||
End Function
|
End Function
|
||||||
Private Shared Sub SkinMsLoad(Data As LoaderTask(Of EqualableList(Of String), String))
|
Private Shared Sub SkinMsLoad(Data As LoaderTask(Of EqualableList(Of String), String))
|
||||||
'清空已有皮肤
|
'清空已有皮肤
|
||||||
|
|||||||
@@ -114,6 +114,14 @@ Download:
|
|||||||
Log("[Page] 主页预设:更新日志")
|
Log("[Page] 主页预设:更新日志")
|
||||||
Url = "https://updatehomepage.pages.dev/UpdateHomepage.xaml"
|
Url = "https://updatehomepage.pages.dev/UpdateHomepage.xaml"
|
||||||
GoTo Download
|
GoTo Download
|
||||||
|
Case 9
|
||||||
|
Log("[Page] 主页预设:PCL 新功能说明书")
|
||||||
|
Url = "https://gitee.com/wforstbreeze/whats-new-pcl/raw/main/Custom.xaml"
|
||||||
|
GoTo Download
|
||||||
|
Case 10
|
||||||
|
Log("[Page] 主页预设:OpenMCIM Dashboard")
|
||||||
|
Url = "https://files.mcimirror.top/PCL"
|
||||||
|
GoTo Download
|
||||||
End Select
|
End Select
|
||||||
End Select
|
End Select
|
||||||
RunInUi(Sub() LoadContent(Content))
|
RunInUi(Sub() LoadContent(Content))
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
''' 获取当前页面的登录信息。
|
''' 获取当前页面的登录信息。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Shared Function GetLoginData() As McLoginMs
|
Public Shared Function GetLoginData() As McLoginMs
|
||||||
If FrmLoginMs Is Nothing Then Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")}
|
If FrmLoginMs Is Nothing Then Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsV2OAuthRefresh"), .UserName = Setup.Get("CacheMsV2Name")}
|
||||||
Dim Result As McLoginMs = Nothing
|
Dim Result As McLoginMs = Nothing
|
||||||
RunInUiWait(
|
RunInUiWait(
|
||||||
Sub()
|
Sub()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
''' 刷新页面显示的所有信息。
|
''' 刷新页面显示的所有信息。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Sub Reload(KeepInput As Boolean)
|
Public Sub Reload(KeepInput As Boolean)
|
||||||
TextName.Text = Setup.Get("CacheMsName")
|
TextName.Text = Setup.Get("CacheMsV2Name")
|
||||||
'皮肤在 Loaded 加载
|
'皮肤在 Loaded 加载
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -20,9 +20,9 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Shared Function GetLoginData() As McLoginMs
|
Public Shared Function GetLoginData() As McLoginMs
|
||||||
If McLoginMsLoader.State = LoadState.Finished Then
|
If McLoginMsLoader.State = LoadState.Finished Then
|
||||||
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName"), .AccessToken = Setup.Get("CacheMsAccess"), .Uuid = Setup.Get("CacheMsUuid"), .ProfileJson = Setup.Get("CacheMsProfileJson")}
|
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsV2OAuthRefresh"), .UserName = Setup.Get("CacheMsV2Name"), .AccessToken = Setup.Get("CacheMsV2Access"), .Uuid = Setup.Get("CacheMsV2Uuid"), .ProfileJson = Setup.Get("CacheMsV2ProfileJson")}
|
||||||
Else
|
Else
|
||||||
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")}
|
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsV2OAuthRefresh"), .UserName = Setup.Get("CacheMsV2Name")}
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
@@ -50,11 +50,11 @@
|
|||||||
|
|
||||||
'退出登录
|
'退出登录
|
||||||
Private Sub BtnExit_Click() Handles BtnExit.Click
|
Private Sub BtnExit_Click() Handles BtnExit.Click
|
||||||
Setup.Set("CacheMsOAuthRefresh", "")
|
Setup.Set("CacheMsV2OAuthRefresh", "")
|
||||||
Setup.Set("CacheMsAccess", "")
|
Setup.Set("CacheMsV2Access", "")
|
||||||
Setup.Set("CacheMsProfileJson", "")
|
Setup.Set("CacheMsV2ProfileJson", "")
|
||||||
Setup.Set("CacheMsUuid", "")
|
Setup.Set("CacheMsV2Uuid", "")
|
||||||
Setup.Set("CacheMsName", "")
|
Setup.Set("CacheMsV2Name", "")
|
||||||
McLoginMsLoader.Abort()
|
McLoginMsLoader.Abort()
|
||||||
FrmLaunchLeft.RefreshPage(False, True)
|
FrmLaunchLeft.RefreshPage(False, True)
|
||||||
End Sub
|
End Sub
|
||||||
@@ -90,8 +90,8 @@
|
|||||||
Try
|
Try
|
||||||
Retry:
|
Retry:
|
||||||
If McLoginMsLoader.State = LoadState.Loading Then McLoginMsLoader.WaitForExit() '等待登录结束
|
If McLoginMsLoader.State = LoadState.Loading Then McLoginMsLoader.WaitForExit() '等待登录结束
|
||||||
Dim AccessToken As String = Setup.Get("CacheMsAccess")
|
Dim AccessToken As String = Setup.Get("CacheMsV2Access")
|
||||||
Dim Uuid As String = Setup.Get("CacheMsUuid")
|
Dim Uuid As String = Setup.Get("CacheMsV2Uuid")
|
||||||
|
|
||||||
Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 30)}
|
Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 30)}
|
||||||
Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken)
|
Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken)
|
||||||
|
|||||||
@@ -419,75 +419,6 @@ Public Class PageLinkIoi
|
|||||||
|
|
||||||
'获取数据包
|
'获取数据包
|
||||||
Public Shared Sub ReceiveJson(JsonData As JObject, Optional NewSocket As Socket = Nothing)
|
Public Shared Sub ReceiveJson(JsonData As JObject, Optional NewSocket As Socket = Nothing)
|
||||||
'获取数据
|
|
||||||
Dim Id As String = JsonData("id"), Type As String = JsonData("type")
|
|
||||||
Select Case Type
|
|
||||||
Case "connect"
|
|
||||||
Dim DisplayName As String = JsonData("name")
|
|
||||||
Dim User As New LinkUserIoi(Id, DisplayName, NewSocket)
|
|
||||||
'如果发生了双向连接
|
|
||||||
If UserList.ContainsKey(Id) Then
|
|
||||||
If Id > IoiId Then
|
|
||||||
Log("[IOI] 双向连接,应当抛弃当前用户(" & DisplayName & ")")
|
|
||||||
For Each Pair In UserList(User.Id).Ports.ToList
|
|
||||||
User.Ports(Pair.Key) = Pair.Value
|
|
||||||
Next
|
|
||||||
UserList(Id).Dispose()
|
|
||||||
Else
|
|
||||||
'应当保留当前用户
|
|
||||||
Log("[IOI] 双向连接,应当保留当前用户(" & DisplayName & ")")
|
|
||||||
NewSocket.Dispose()
|
|
||||||
Exit Sub
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
'加入列表
|
|
||||||
UserList.Add(Id, User)
|
|
||||||
'返回请求
|
|
||||||
User.RelativeThread = RunInNewThread(Sub()
|
|
||||||
SendPortsubBack(User, JsonData("version").ToObject(Of Integer))
|
|
||||||
End Sub, "Link Connect " & DisplayName)
|
|
||||||
'更新时间
|
|
||||||
User.LastReceive = Date.Now
|
|
||||||
Case "update"
|
|
||||||
If Not UserList.ContainsKey(Id) Then Throw New Exception("未在列表中的用户发送了更新请求:" & Id)
|
|
||||||
Dim User = UserList(Id)
|
|
||||||
'拉满进度(该请求也作为反向连接回应出现,用于向正向连接方传达连接已完成信号)
|
|
||||||
User.Progress = 1
|
|
||||||
'更新名称
|
|
||||||
Dim DisplayName As String = JsonData("name")
|
|
||||||
User.DisplayName = DisplayName
|
|
||||||
'更新房间列表
|
|
||||||
If JsonData("rooms") IsNot Nothing Then
|
|
||||||
User.Rooms = New List(Of RoomEntry)
|
|
||||||
For Each RoomObject In JsonData("rooms")
|
|
||||||
User.Rooms.Add(New RoomEntry(RoomObject("port"), RoomObject("name"), User))
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
'更新 Ping
|
|
||||||
Dim Stage As Integer = JsonData("stage"), Unique As Long = JsonData("unique")
|
|
||||||
If Stage > 1 Then
|
|
||||||
User.PingRecord.Enqueue((Date.Now - User.PingPending(Unique)).TotalMilliseconds / 2)
|
|
||||||
If User.PingRecord.Count > 5 Then User.PingRecord.Dequeue()
|
|
||||||
User.PingPending.Remove(Unique)
|
|
||||||
End If
|
|
||||||
'返回请求
|
|
||||||
If Stage > 0 AndAlso Stage < 3 Then RunInNewThread(Sub()
|
|
||||||
Try
|
|
||||||
SendUpdateRequest(User, Stage + 1, Unique)
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "发送回程请求失败")
|
|
||||||
End Try
|
|
||||||
End Sub, "Link Update " & DisplayName)
|
|
||||||
'更新时间
|
|
||||||
User.LastReceive = Date.Now
|
|
||||||
Case "disconnect"
|
|
||||||
'断开连接
|
|
||||||
If Not UserList.ContainsKey(Id) Then Exit Sub
|
|
||||||
UserRemove(UserList(Id), ShowLeaveMessage:=JsonData("message") Is Nothing)
|
|
||||||
If JsonData("message") IsNot Nothing Then Hint(JsonData("message").ToString, If(JsonData("isError").ToObject(Of Boolean), HintType.Critical, HintType.Info))
|
|
||||||
Case Else
|
|
||||||
Throw New Exception("未知的操作种类:" & Type)
|
|
||||||
End Select
|
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 从用户列表中移除一位用户。提示信息视作该用户主动离开。
|
''' 从用户列表中移除一位用户。提示信息视作该用户主动离开。
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
PageChangeRun(PageGet(ID))
|
PageChangeRun(PageGet(ID))
|
||||||
PageID = ID
|
PageID = ID
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
||||||
Finally
|
Finally
|
||||||
AniControlEnabled -= 1
|
AniControlEnabled -= 1
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
PageChangeRun(PageGet(ID))
|
PageChangeRun(PageGet(ID))
|
||||||
PageID = ID
|
PageID = ID
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
||||||
Finally
|
Finally
|
||||||
AniControlEnabled -= 1
|
AniControlEnabled -= 1
|
||||||
End Try
|
End Try
|
||||||
@@ -127,8 +127,8 @@
|
|||||||
'打开网页
|
'打开网页
|
||||||
Public Shared Sub TryFeedback() Handles ItemFeedback.Click
|
Public Shared Sub TryFeedback() Handles ItemFeedback.Click
|
||||||
If Not CanFeedback(True) Then Exit Sub
|
If Not CanFeedback(True) Then Exit Sub
|
||||||
Select Case MyMsgBox("是否要打开反馈列表网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
|
Select Case MyMsgBox("在提交新反馈前,建议先搜索反馈列表,以避免重复提交。" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
|
||||||
"反馈提示", "提交新反馈", "查看反馈列表", "取消")
|
"反馈", "提交新反馈", "查看反馈列表", "取消")
|
||||||
Case 1
|
Case 1
|
||||||
Feedback(True, False)
|
Feedback(True, False)
|
||||||
Case 2
|
Case 2
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
End Sub
|
End Sub
|
||||||
Public Shared Sub TryVote() Handles ItemVote.Click
|
Public Shared Sub TryVote() Handles ItemVote.Click
|
||||||
If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
|
If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。",
|
||||||
"提醒", "打开", "取消") = 2 Then Exit Sub
|
"新功能投票", "打开", "取消") = 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")
|
OpenWebsite("https://github.com/Hex-Dragon/PCL2/discussions/categories/%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8?discussions_q=category%3A%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8+sort%3Adate_created")
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Private ReadOnly SetupDict As New Dictionary(Of String, SetupEntry) From {
|
Private ReadOnly SetupDict As New Dictionary(Of String, SetupEntry) From {
|
||||||
{"Identify", New SetupEntry("", Source:=SetupSource.Registry)},
|
{"Identify", New SetupEntry("", Source:=SetupSource.Registry)},
|
||||||
|
{"WindowHeight", New SetupEntry(550)},
|
||||||
|
{"WindowWidth", New SetupEntry(900)},
|
||||||
{"HintDownloadThread", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"HintDownloadThread", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
{"HintNotice", New SetupEntry(0, Source:=SetupSource.Registry)},
|
{"HintNotice", New SetupEntry(0, Source:=SetupSource.Registry)},
|
||||||
{"HintDownload", New SetupEntry(0, Source:=SetupSource.Registry)},
|
{"HintDownload", New SetupEntry(0, Source:=SetupSource.Registry)},
|
||||||
@@ -42,6 +44,12 @@
|
|||||||
{"CacheMsProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheMsProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"CacheMsUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheMsUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"CacheMsName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheMsName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
{"CacheMsV2Migrated", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
|
{"CacheMsV2OAuthRefresh", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
{"CacheMsV2Access", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
{"CacheMsV2ProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
{"CacheMsV2Uuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
|
{"CacheMsV2Name", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"CacheNideAccess", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheNideAccess", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"CacheNideClient", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheNideClient", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"CacheNideUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
{"CacheNideUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
@@ -105,10 +113,10 @@
|
|||||||
{"ToolDownloadSpeed", New SetupEntry(42, Source:=SetupSource.Registry)},
|
{"ToolDownloadSpeed", New SetupEntry(42, Source:=SetupSource.Registry)},
|
||||||
{"ToolDownloadVersion", New SetupEntry(0, Source:=SetupSource.Registry)},
|
{"ToolDownloadVersion", New SetupEntry(0, Source:=SetupSource.Registry)},
|
||||||
{"ToolDownloadTranslate", New SetupEntry(0, Source:=SetupSource.Registry)},
|
{"ToolDownloadTranslate", New SetupEntry(0, Source:=SetupSource.Registry)},
|
||||||
{"ToolDownloadKeepModpack", New SetupEntry(False, Source:=SetupSource.Registry)},
|
|
||||||
{"ToolDownloadIgnoreQuilt", New SetupEntry(True, Source:=SetupSource.Registry)},
|
{"ToolDownloadIgnoreQuilt", New SetupEntry(True, Source:=SetupSource.Registry)},
|
||||||
{"ToolDownloadCert", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"ToolDownloadCert", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
{"ToolDownloadMod", New SetupEntry(1, Source:=SetupSource.Registry)},
|
{"ToolDownloadMod", New SetupEntry(1, Source:=SetupSource.Registry)},
|
||||||
|
{"ToolModLocalNameStyle", New SetupEntry(0, Source:=SetupSource.Registry)},
|
||||||
{"ToolUpdateAlpha", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
{"ToolUpdateAlpha", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
|
||||||
{"ToolUpdateRelease", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"ToolUpdateRelease", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
{"ToolUpdateSnapshot", New SetupEntry(False, Source:=SetupSource.Registry)},
|
{"ToolUpdateSnapshot", New SetupEntry(False, Source:=SetupSource.Registry)},
|
||||||
@@ -592,7 +600,7 @@
|
|||||||
FrmSetupUI.PanLogoChange.Visibility = Visibility.Visible
|
FrmSetupUI.PanLogoChange.Visibility = Visibility.Visible
|
||||||
End If
|
End If
|
||||||
Try
|
Try
|
||||||
FrmMain.ImageTitleLogo.Source = New MyBitmap(Path & "PCL\Logo.png")
|
FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
FrmMain.ImageTitleLogo.Source = Nothing
|
FrmMain.ImageTitleLogo.Source = Nothing
|
||||||
Log(ex, "显示标题栏图片失败", LogLevel.Msgbox)
|
Log(ex, "显示标题栏图片失败", LogLevel.Msgbox)
|
||||||
|
|||||||
@@ -115,7 +115,7 @@
|
|||||||
|
|
||||||
PageID = ID
|
PageID = ID
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
||||||
Finally
|
Finally
|
||||||
AniControlEnabled -= 1
|
AniControlEnabled -= 1
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -7,9 +7,43 @@
|
|||||||
PanScroll="{Binding ElementName=PanBack}">
|
PanScroll="{Binding ElementName=PanBack}">
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
||||||
<StackPanel x:Name="PanMain" Margin="25,10">
|
<StackPanel x:Name="PanMain" Margin="25,10">
|
||||||
|
|
||||||
<local:MyCard Margin="0,15" Title="下载">
|
<local:MyCard Margin="0,15" Title="下载">
|
||||||
<StackPanel Margin="25,37,25,12">
|
<StackPanel Margin="25,37,25,15">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="28" />
|
||||||
|
<RowDefinition Height="7" />
|
||||||
|
<RowDefinition Height="27" />
|
||||||
|
<RowDefinition Height="27" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本列表源" Margin="0,0,25,0" />
|
||||||
|
<local:MyComboBox x:Name="ComboDownloadVersion" Grid.ColumnSpan="2" Tag="ToolDownloadVersion" Grid.Column="1">
|
||||||
|
<local:MyComboBoxItem Content="尽量使用镜像源(加载快,但版本可能不是最新的)" IsSelected="True" />
|
||||||
|
<local:MyComboBoxItem Content="仅在官方源加载缓慢时改用镜像源" />
|
||||||
|
<local:MyComboBoxItem Content="尽量使用官方源(保证版本最新,但加载缓慢)" />
|
||||||
|
</local:MyComboBox>
|
||||||
|
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="最大线程数" Margin="0,0,25,0" />
|
||||||
|
<local:MySlider x:Name="SliderDownloadThread" Grid.Row="2" Tag="ToolDownloadThread" MaxValue="255" Value="63" Grid.Column="1"
|
||||||
|
ToolTip="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。
一般而言,64 线程已可以保证足够的下载速度。" />
|
||||||
|
<TextBlock VerticalAlignment="Center" Grid.Row="3" HorizontalAlignment="Left" Text="速度限制" Margin="0,0,25,0" />
|
||||||
|
<local:MySlider x:Name="SliderDownloadSpeed" Grid.Row="3" Tag="ToolDownloadSpeed" MaxValue="42" Value="42" Grid.Column="1"
|
||||||
|
ToolTip="设置下载的速度上限,以避免在下载时导致其他需要联网的程序卡死" />
|
||||||
|
<TextBlock VerticalAlignment="Top" Grid.Row="4" HorizontalAlignment="Left" Text="目标文件夹" Margin="0,5,25,5" />
|
||||||
|
<TextBlock Margin="0,5" HorizontalAlignment="Left" Text="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。
在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" Grid.Row="4" Grid.Column="1" VerticalAlignment="Center" Opacity="0.5" />
|
||||||
|
<local:MyCheckBox Margin="0,2,0,4" Text="验证 SSL 证书" Grid.Row="5" Height="22" Grid.ColumnSpan="2"
|
||||||
|
x:Name="CheckDownloadCert" Tag="ToolDownloadCert"
|
||||||
|
ToolTip="开启验证会提高安全性、降低盗号风险(见 #2767),但也可能导致正版登录失败(见 #3018)。" />
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</local:MyCard>
|
||||||
|
<local:MyCard Margin="0,0,0,15" Title="Mod 与整合包">
|
||||||
|
<StackPanel Margin="25,37,25,15">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
|
||||||
@@ -22,51 +56,31 @@
|
|||||||
<RowDefinition Height="7" />
|
<RowDefinition Height="7" />
|
||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
<RowDefinition Height="7" />
|
<RowDefinition Height="7" />
|
||||||
<RowDefinition Height="27" />
|
|
||||||
<RowDefinition Height="27" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本列表获取" Margin="0,0,25,0" />
|
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="下载源" Margin="0,0,25,0" />
|
||||||
<local:MyComboBox x:Name="ComboDownloadVersion" Grid.ColumnSpan="2" Tag="ToolDownloadVersion" Grid.Column="1">
|
<local:MyComboBox x:Name="ComboDownloadMod" Grid.Row="0" Grid.ColumnSpan="2" Tag="ToolDownloadMod" Grid.Column="1">
|
||||||
<local:MyComboBoxItem Content="尽量使用镜像源(加载快,但版本可能不是最新的)" IsSelected="True" />
|
<local:MyComboBoxItem Content="尽量使用镜像源(暂时无效)" />
|
||||||
<local:MyComboBoxItem Content="仅在官方源加载缓慢时改用镜像源" />
|
|
||||||
<local:MyComboBoxItem Content="尽量使用官方源(保证版本最新,但加载缓慢)" />
|
|
||||||
</local:MyComboBox>
|
|
||||||
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Mod 信息获取" Margin="0,0,25,0" />
|
|
||||||
<local:MyComboBox x:Name="ComboDownloadMod" Grid.Row="2" Grid.ColumnSpan="2" Tag="ToolDownloadMod" Grid.Column="1">
|
|
||||||
<local:MyComboBoxItem Content="尽量使用镜像源" />
|
|
||||||
<local:MyComboBoxItem Content="仅在官方源加载缓慢时改用镜像源" />
|
<local:MyComboBoxItem Content="仅在官方源加载缓慢时改用镜像源" />
|
||||||
<local:MyComboBoxItem Content="尽量使用官方源" IsSelected="True" />
|
<local:MyComboBoxItem Content="尽量使用官方源" IsSelected="True" />
|
||||||
</local:MyComboBox>
|
</local:MyComboBox>
|
||||||
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Mod 命名风格" Margin="0,0,25,0" />
|
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="下载文件名" Margin="0,0,25,0" />
|
||||||
<local:MyComboBox Grid.Row="4" x:Name="ComboDownloadTranslate" Grid.ColumnSpan="2" Tag="ToolDownloadTranslate" Grid.Column="1"
|
<local:MyComboBox Grid.Row="2" x:Name="ComboDownloadTranslate" Grid.ColumnSpan="2" Tag="ToolDownloadTranslate" Grid.Column="1"
|
||||||
ToolTip="决定下载的 Mod 的默认文件名中,中文译名应该放在哪个位置">
|
ToolTip="下载 Mod 时,Mod 的默认文件名中,中文译名应该放在哪个位置">
|
||||||
<local:MyComboBoxItem Content="译名位于文件名开头:[遗物] relics-0.1.14" IsSelected="True" />
|
<local:MyComboBoxItem Content="译名位于文件名开头:[遗物] relics-0.1.14" IsSelected="True" />
|
||||||
<local:MyComboBoxItem Content="译名位于文件名开头:遗物-relics-0.1.14" />
|
<local:MyComboBoxItem Content="译名位于文件名开头:遗物-relics-0.1.14" />
|
||||||
<local:MyComboBoxItem Content="译名位于文件名末尾:relics-0.1.14-遗物" />
|
<local:MyComboBoxItem Content="译名位于文件名末尾:relics-0.1.14-遗物" />
|
||||||
<local:MyComboBoxItem Content="不添加中文译名:relics-0.1.14" />
|
<local:MyComboBoxItem Content="不添加中文译名:relics-0.1.14" />
|
||||||
</local:MyComboBox>
|
</local:MyComboBox>
|
||||||
<TextBlock Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Text="最大线程数" Margin="0,0,25,0" />
|
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Mod 管理样式" Margin="0,0,25,0" />
|
||||||
<local:MySlider x:Name="SliderDownloadThread" Grid.Row="6" Tag="ToolDownloadThread" MaxValue="255" Value="63" Grid.Column="1"
|
<local:MyComboBox Grid.Row="4" x:Name="ComboModLocalNameStyle" Grid.ColumnSpan="2" Tag="ToolModLocalNameStyle" Grid.Column="1"
|
||||||
ToolTip="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。
一般而言,64 线程已可以保证足够的下载速度。" />
|
ToolTip="在 Mod 管理页面中,Mod 项的显示方式">
|
||||||
<TextBlock VerticalAlignment="Center" Grid.Row="7" HorizontalAlignment="Left" Text="速度限制" Margin="0,0,25,0" />
|
<local:MyComboBoxItem Content="标题显示译名,详情显示文件名" IsSelected="True" />
|
||||||
<local:MySlider x:Name="SliderDownloadSpeed" Grid.Row="7" Tag="ToolDownloadSpeed" MaxValue="42" Value="42" Grid.Column="1"
|
<local:MyComboBoxItem Content="标题显示文件名,详情显示译名" />
|
||||||
ToolTip="设置下载的速度上限,以避免在下载时导致其他需要联网的程序卡死" />
|
</local:MyComboBox>
|
||||||
<TextBlock VerticalAlignment="Top" Grid.Row="9" HorizontalAlignment="Left" Text="目标文件夹" Margin="0,5,25,5" />
|
<local:MyCheckBox Margin="0,2,0,4" Text="简化 Mod 加载器显示" Grid.Row="6" Height="22" Grid.ColumnSpan="2"
|
||||||
<TextBlock Margin="0,5" HorizontalAlignment="Left" Text="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。
在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" Grid.Row="9" Grid.Column="1" VerticalAlignment="Center" Opacity="0.5" />
|
|
||||||
<local:MyCheckBox Margin="0,5,0,4" Text="安装整合包时保留原始压缩包" Grid.Row="10" Height="22" Grid.ColumnSpan="2"
|
|
||||||
x:Name="CheckDownloadKeepModpack" Tag="ToolDownloadKeepModpack"
|
|
||||||
ToolTip="安装整合包时,在版本文件夹下保留用于安装的原始整合包压缩包文件" />
|
|
||||||
<local:MyCheckBox Margin="0,2,0,4" Text="简化 Mod 加载器显示" Grid.Row="11" Height="22" Grid.ColumnSpan="2"
|
|
||||||
x:Name="CheckDownloadIgnoreQuilt" Tag="ToolDownloadIgnoreQuilt"
|
x:Name="CheckDownloadIgnoreQuilt" Tag="ToolDownloadIgnoreQuilt"
|
||||||
ToolTip="下载 Mod 时,若该 Mod 支持 Forge 和 Fabric,则显示为支持任意 Mod 加载器。
例如,开启时 JEI 显示支持全版本,关闭后 JEI 就会显示仅支持 Forge / Fabric 全版本。" />
|
ToolTip="下载 Mod 时,若该 Mod 支持 Forge 和 Fabric,则显示为支持任意 Mod 加载器。
例如,开启时 JEI 显示支持全版本,关闭后 JEI 就会显示仅支持 Forge / Fabric 全版本。" />
|
||||||
<local:MyCheckBox Margin="0,2,0,4" Text="验证 SSL 证书" Grid.Row="12" Height="22" Grid.ColumnSpan="2"
|
|
||||||
x:Name="CheckDownloadCert" Tag="ToolDownloadCert"
|
|
||||||
ToolTip="开启验证会提高安全性、降低盗号风险(见 #2767),但也可能导致正版登录失败(见 #3018)。" />
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|||||||
@@ -1,33 +1,5 @@
|
|||||||
Class PageSetupSystem
|
Class PageSetupSystem
|
||||||
|
|
||||||
#Region "语言"
|
|
||||||
'Private Sub PageSetupUI_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
|
|
||||||
' AniControlEnabled -= 1
|
|
||||||
|
|
||||||
' '读取设置
|
|
||||||
' Select Case Lang
|
|
||||||
' Case "zh_CN"
|
|
||||||
' ComboLang.SelectedIndex = 0
|
|
||||||
' Case "zh_HK"
|
|
||||||
' ComboLang.SelectedIndex = 1
|
|
||||||
' Case "en_US"
|
|
||||||
' ComboLang.SelectedIndex = 2
|
|
||||||
' End Select
|
|
||||||
' CheckDebug.Checked = ReadReg("SystemDebugMode", "False")
|
|
||||||
|
|
||||||
' AniControlEnabled += 1
|
|
||||||
'End Sub
|
|
||||||
|
|
||||||
'Private Sub RefreshLang() Handles ComboLang.SelectionChanged
|
|
||||||
' If IsLoaded Then
|
|
||||||
' If Not ComboLang.IsLoaded Then Exit Sub
|
|
||||||
' Lang = CType(ComboLang.SelectedItem, MyComboBoxItem).Tag
|
|
||||||
' Application.Current.Resources.MergedDictionaries(1) = New ResourceDictionary With {.Source = New Url("Languages\" & Lang & ".xaml", UrlKind.Relative)}
|
|
||||||
' WriteReg("Lang", Lang)
|
|
||||||
' End If
|
|
||||||
'End Sub
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
Private Shadows IsLoaded As Boolean = False
|
Private Shadows IsLoaded As Boolean = False
|
||||||
|
|
||||||
Private Sub PageSetupSystem_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
|
Private Sub PageSetupSystem_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
|
||||||
@@ -58,11 +30,13 @@
|
|||||||
SliderDownloadThread.Value = Setup.Get("ToolDownloadThread")
|
SliderDownloadThread.Value = Setup.Get("ToolDownloadThread")
|
||||||
SliderDownloadSpeed.Value = Setup.Get("ToolDownloadSpeed")
|
SliderDownloadSpeed.Value = Setup.Get("ToolDownloadSpeed")
|
||||||
ComboDownloadVersion.SelectedIndex = Setup.Get("ToolDownloadVersion")
|
ComboDownloadVersion.SelectedIndex = Setup.Get("ToolDownloadVersion")
|
||||||
|
CheckDownloadCert.Checked = Setup.Get("ToolDownloadCert")
|
||||||
|
|
||||||
|
'Mod 与整合包
|
||||||
ComboDownloadTranslate.SelectedIndex = Setup.Get("ToolDownloadTranslate")
|
ComboDownloadTranslate.SelectedIndex = Setup.Get("ToolDownloadTranslate")
|
||||||
ComboDownloadMod.SelectedIndex = Setup.Get("ToolDownloadMod")
|
ComboDownloadMod.SelectedIndex = Setup.Get("ToolDownloadMod")
|
||||||
CheckDownloadKeepModpack.Checked = Setup.Get("ToolDownloadKeepModpack")
|
ComboModLocalNameStyle.SelectedIndex = Setup.Get("ToolModLocalNameStyle")
|
||||||
CheckDownloadIgnoreQuilt.Checked = Setup.Get("ToolDownloadIgnoreQuilt")
|
CheckDownloadIgnoreQuilt.Checked = Setup.Get("ToolDownloadIgnoreQuilt")
|
||||||
CheckDownloadCert.Checked = Setup.Get("ToolDownloadCert")
|
|
||||||
|
|
||||||
'Minecraft 更新提示
|
'Minecraft 更新提示
|
||||||
CheckUpdateRelease.Checked = Setup.Get("ToolUpdateRelease")
|
CheckUpdateRelease.Checked = Setup.Get("ToolUpdateRelease")
|
||||||
@@ -91,10 +65,10 @@
|
|||||||
Setup.Reset("ToolDownloadSpeed")
|
Setup.Reset("ToolDownloadSpeed")
|
||||||
Setup.Reset("ToolDownloadVersion")
|
Setup.Reset("ToolDownloadVersion")
|
||||||
Setup.Reset("ToolDownloadTranslate")
|
Setup.Reset("ToolDownloadTranslate")
|
||||||
Setup.Reset("ToolDownloadKeepModpack")
|
|
||||||
Setup.Reset("ToolDownloadIgnoreQuilt")
|
Setup.Reset("ToolDownloadIgnoreQuilt")
|
||||||
Setup.Reset("ToolDownloadCert")
|
Setup.Reset("ToolDownloadCert")
|
||||||
Setup.Reset("ToolDownloadMod")
|
Setup.Reset("ToolDownloadMod")
|
||||||
|
Setup.Reset("ToolModLocalNameStyle")
|
||||||
Setup.Reset("ToolUpdateRelease")
|
Setup.Reset("ToolUpdateRelease")
|
||||||
Setup.Reset("ToolUpdateSnapshot")
|
Setup.Reset("ToolUpdateSnapshot")
|
||||||
Setup.Reset("ToolHelpChinese")
|
Setup.Reset("ToolHelpChinese")
|
||||||
@@ -116,13 +90,13 @@
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'将控件改变路由到设置改变
|
'将控件改变路由到设置改变
|
||||||
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change, CheckDownloadKeepModpack.Change, CheckDownloadIgnoreQuilt.Change, CheckDownloadCert.Change
|
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change, CheckDownloadIgnoreQuilt.Change, CheckDownloadCert.Change
|
||||||
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
|
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
|
||||||
End Sub
|
End Sub
|
||||||
Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderDebugAnim.Change, SliderDownloadThread.Change, SliderDownloadSpeed.Change
|
Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderDebugAnim.Change, SliderDownloadThread.Change, SliderDownloadSpeed.Change
|
||||||
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value)
|
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value)
|
||||||
End Sub
|
End Sub
|
||||||
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboDownloadVersion.SelectionChanged, ComboDownloadTranslate.SelectionChanged, ComboSystemUpdate.SelectionChanged, ComboSystemActivity.SelectionChanged, ComboDownloadMod.SelectionChanged
|
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboDownloadVersion.SelectionChanged, ComboModLocalNameStyle.SelectionChanged, ComboDownloadTranslate.SelectionChanged, ComboSystemUpdate.SelectionChanged, ComboSystemActivity.SelectionChanged, ComboDownloadMod.SelectionChanged
|
||||||
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex)
|
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex)
|
||||||
End Sub
|
End Sub
|
||||||
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextSystemCache.ValidatedTextChanged
|
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextSystemCache.ValidatedTextChanged
|
||||||
|
|||||||
@@ -245,6 +245,8 @@
|
|||||||
<local:MyComboBoxItem Content="OpenBMCLAPI 仪表盘 Lite(作者:Silverteal、Mxmilu666)" />
|
<local:MyComboBoxItem Content="OpenBMCLAPI 仪表盘 Lite(作者:Silverteal、Mxmilu666)" />
|
||||||
<local:MyComboBoxItem Content="PCL 主页市场(作者:凌云)" />
|
<local:MyComboBoxItem Content="PCL 主页市场(作者:凌云)" />
|
||||||
<local:MyComboBoxItem Content="PCL 更新日志(作者:Joker2184)" />
|
<local:MyComboBoxItem Content="PCL 更新日志(作者:Joker2184)" />
|
||||||
|
<local:MyComboBoxItem Content="PCL 新功能说明书(作者:WForst-Breeze)" />
|
||||||
|
<local:MyComboBoxItem Content="OpenMCIM 仪表盘(作者:SALTWOOD)" />
|
||||||
</local:MyComboBox>
|
</local:MyComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -25,14 +25,15 @@
|
|||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
AniControlEnabled += 1
|
||||||
|
Reload() '#4826,在每次进入页面时都刷新一下
|
||||||
|
AniControlEnabled -= 1
|
||||||
|
|
||||||
'非重复加载部分
|
'非重复加载部分
|
||||||
If IsLoaded Then Exit Sub
|
If IsLoaded Then Exit Sub
|
||||||
IsLoaded = True
|
IsLoaded = True
|
||||||
|
|
||||||
AniControlEnabled += 1
|
|
||||||
SliderLoad()
|
SliderLoad()
|
||||||
Reload()
|
|
||||||
AniControlEnabled -= 1
|
|
||||||
|
|
||||||
#If BETA Then
|
#If BETA Then
|
||||||
PanLauncherHide.Visibility = Visibility.Visible
|
PanLauncherHide.Visibility = Visibility.Visible
|
||||||
@@ -269,17 +270,16 @@
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
|
||||||
'顶部栏
|
'顶部栏
|
||||||
Private Sub BtnLogoChange_Click(sender As Object, e As EventArgs) Handles BtnLogoChange.Click
|
Private Sub BtnLogoChange_Click(sender As Object, e As EventArgs) Handles BtnLogoChange.Click
|
||||||
Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
|
Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片")
|
||||||
If FileName = "" Then Exit Sub
|
If FileName = "" Then Exit Sub
|
||||||
Try
|
Try
|
||||||
'拷贝文件
|
'拷贝文件
|
||||||
File.Delete(Path & "PCL\Logo.png")
|
File.Delete(Path & "PCL\Logo.png")
|
||||||
CopyFile(FileName, Path & "PCL\Logo.png")
|
CopyFile(FileName, Path & "PCL\Logo.png")
|
||||||
'设置当前显示
|
'设置当前显示
|
||||||
FrmMain.ImageTitleLogo.Source = New MyBitmap(Path & "PCL\Logo.png")
|
FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If ex.Message.Contains("参数无效") Then
|
If ex.Message.Contains("参数无效") Then
|
||||||
Log("改变标题栏图片失败,该图片文件可能并非标准格式。" & vbCrLf &
|
Log("改变标题栏图片失败,该图片文件可能并非标准格式。" & vbCrLf &
|
||||||
@@ -296,7 +296,7 @@ Refresh:
|
|||||||
'已有图片则不再选择
|
'已有图片则不再选择
|
||||||
If File.Exists(Path & "PCL\Logo.png") Then
|
If File.Exists(Path & "PCL\Logo.png") Then
|
||||||
Try
|
Try
|
||||||
FrmMain.ImageTitleLogo.Source = New MyBitmap(Path & "PCL\Logo.png")
|
FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If ex.Message.Contains("参数无效") Then
|
If ex.Message.Contains("参数无效") Then
|
||||||
Log("调整标题栏图片失败,该图片文件可能并非标准格式。" & vbCrLf &
|
Log("调整标题栏图片失败,该图片文件可能并非标准格式。" & vbCrLf &
|
||||||
@@ -315,7 +315,7 @@ Refresh:
|
|||||||
Exit Sub
|
Exit Sub
|
||||||
End If
|
End If
|
||||||
'没有图片则要求选择
|
'没有图片则要求选择
|
||||||
Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
|
Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片")
|
||||||
If FileName = "" Then
|
If FileName = "" Then
|
||||||
FrmMain.ImageTitleLogo.Source = Nothing
|
FrmMain.ImageTitleLogo.Source = Nothing
|
||||||
e.Handled = True
|
e.Handled = True
|
||||||
@@ -428,8 +428,8 @@ Refresh:
|
|||||||
RadioLauncherTheme5Gray.Opacity -= 0.23
|
RadioLauncherTheme5Gray.Opacity -= 0.23
|
||||||
RadioLauncherTheme5.Opacity += 0.23
|
RadioLauncherTheme5.Opacity += 0.23
|
||||||
AniStart({
|
AniStart({
|
||||||
AaOpacity(RadioLauncherTheme5Gray, 1, 1000),
|
AaOpacity(RadioLauncherTheme5Gray, 1, 1000 * AniSpeed),
|
||||||
AaOpacity(RadioLauncherTheme5, -1, 1000)
|
AaOpacity(RadioLauncherTheme5, -1, 1000 * AniSpeed)
|
||||||
}, "ThemeUnlock")
|
}, "ThemeUnlock")
|
||||||
If RadioLauncherTheme5Gray.Opacity < 0.08 Then
|
If RadioLauncherTheme5Gray.Opacity < 0.08 Then
|
||||||
ThemeUnlock(5, UnlockHint:="隐藏主题 玄素黑 已解锁!")
|
ThemeUnlock(5, UnlockHint:="隐藏主题 玄素黑 已解锁!")
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
PageChangeRun(PageGet(ID))
|
PageChangeRun(PageGet(ID))
|
||||||
PageID = ID
|
PageID = ID
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback)
|
||||||
Finally
|
Finally
|
||||||
AniControlEnabled -= 1
|
AniControlEnabled -= 1
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
''' 刷新 Mod 列表。
|
''' 刷新 Mod 列表。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Sub ReloadModList(Optional ForceReload As Boolean = False)
|
Public Sub ReloadModList(Optional ForceReload As Boolean = False)
|
||||||
If LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then
|
If LoaderRun(If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then
|
||||||
Log("[System] 已刷新 Mod 列表")
|
Log("[System] 已刷新 Mod 列表")
|
||||||
Filter = FilterType.All
|
Filter = FilterType.All
|
||||||
PanBack.ScrollToHome()
|
PanBack.ScrollToHome()
|
||||||
@@ -43,9 +43,12 @@
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click
|
Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click
|
||||||
If McModLoader.State = LoadState.Failed Then
|
If McModLoader.State = LoadState.Failed Then
|
||||||
LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.ForceRun)
|
LoaderRun(LoaderFolderRunType.ForceRun)
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
Public Function LoaderRun(Type As LoaderFolderRunType) As Boolean
|
||||||
|
Return LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", Type)
|
||||||
|
End Function
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
@@ -329,7 +332,7 @@
|
|||||||
Private Sub ChangeAllSelected(Value As Boolean)
|
Private Sub ChangeAllSelected(Value As Boolean)
|
||||||
AniControlEnabled += 1
|
AniControlEnabled += 1
|
||||||
SelectedMods.Clear()
|
SelectedMods.Clear()
|
||||||
For Each Item As MyLocalModItem In GetShowingMods(True).Select(Function(m) ModItems(m.RawFileName))
|
For Each Item As MyLocalModItem In GetShowingMods(True).Where(Function(m) ModItems.ContainsKey(m.RawFileName)).Select(Function(m) ModItems(m.RawFileName))
|
||||||
Item.Checked = Value
|
Item.Checked = Value
|
||||||
If Value Then SelectedMods.Add(Item.Entry.RawFileName)
|
If Value Then SelectedMods.Add(Item.Entry.RawFileName)
|
||||||
Next
|
Next
|
||||||
@@ -467,10 +470,12 @@
|
|||||||
'更改 Loader 中的列表
|
'更改 Loader 中的列表
|
||||||
Dim NewModEntity As New McMod(NewPath)
|
Dim NewModEntity As New McMod(NewPath)
|
||||||
NewModEntity.FromJson(ModEntity.ToJson)
|
NewModEntity.FromJson(ModEntity.ToJson)
|
||||||
Dim IndexOfLoader As Integer = McModLoader.Output.IndexOf(ModEntity)
|
If McModLoader.Output.Contains(ModEntity) Then
|
||||||
McModLoader.Output.RemoveAt(IndexOfLoader)
|
Dim IndexOfLoader As Integer = McModLoader.Output.IndexOf(ModEntity)
|
||||||
McModLoader.Output.Insert(IndexOfLoader, NewModEntity)
|
McModLoader.Output.RemoveAt(IndexOfLoader)
|
||||||
If SearchResult IsNot Nothing Then
|
McModLoader.Output.Insert(IndexOfLoader, NewModEntity)
|
||||||
|
End If
|
||||||
|
If SearchResult IsNot Nothing AndAlso SearchResult.Contains(ModEntity) Then '#4862
|
||||||
Dim IndexOfResult As Integer = SearchResult.IndexOf(ModEntity)
|
Dim IndexOfResult As Integer = SearchResult.IndexOf(ModEntity)
|
||||||
SearchResult.Remove(ModEntity)
|
SearchResult.Remove(ModEntity)
|
||||||
SearchResult.Insert(IndexOfResult, NewModEntity)
|
SearchResult.Insert(IndexOfResult, NewModEntity)
|
||||||
@@ -489,6 +494,7 @@
|
|||||||
Hint("由于文件被占用,Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
|
Hint("由于文件被占用,Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
|
||||||
ReloadModList(True)
|
ReloadModList(True)
|
||||||
End If
|
End If
|
||||||
|
LoaderRun(LoaderFolderRunType.UpdateOnly)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'更新
|
'更新
|
||||||
@@ -696,6 +702,7 @@
|
|||||||
Log(ex, "删除 Mod 出现未知错误", LogLevel.Feedback)
|
Log(ex, "删除 Mod 出现未知错误", LogLevel.Feedback)
|
||||||
ReloadModList(True)
|
ReloadModList(True)
|
||||||
End Try
|
End Try
|
||||||
|
LoaderRun(LoaderFolderRunType.UpdateOnly)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'取消选择
|
'取消选择
|
||||||
|
|||||||
@@ -186,12 +186,15 @@
|
|||||||
<Compile Include="Controls\MyComboBox.vb" />
|
<Compile Include="Controls\MyComboBox.vb" />
|
||||||
<Compile Include="Controls\MyComboBoxItem.vb" />
|
<Compile Include="Controls\MyComboBoxItem.vb" />
|
||||||
<Compile Include="Controls\MyCard.vb" />
|
<Compile Include="Controls\MyCard.vb" />
|
||||||
|
<Compile Include="Controls\MyImage.vb" />
|
||||||
<Compile Include="Controls\MyPageRight.vb" />
|
<Compile Include="Controls\MyPageRight.vb" />
|
||||||
<Compile Include="Controls\MyPageLeft.vb" />
|
<Compile Include="Controls\MyPageLeft.vb" />
|
||||||
<Compile Include="Controls\MyIconTextButton.xaml.vb">
|
<Compile Include="Controls\MyIconTextButton.xaml.vb">
|
||||||
<DependentUpon>MyIconTextButton.xaml</DependentUpon>
|
<DependentUpon>MyIconTextButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\MyImage.vb" />
|
|
||||||
|
|
||||||
|
|
||||||
<Compile Include="Modules\Minecraft\ModComp.vb" />
|
<Compile Include="Modules\Minecraft\ModComp.vb" />
|
||||||
<Compile Include="Modules\Minecraft\ModJava.vb" />
|
<Compile Include="Modules\Minecraft\ModJava.vb" />
|
||||||
<Compile Include="Modules\Minecraft\ModMod.vb" />
|
<Compile Include="Modules\Minecraft\ModMod.vb" />
|
||||||
@@ -476,6 +479,7 @@
|
|||||||
<DependentUpon>FormMain.xaml</DependentUpon>
|
<DependentUpon>FormMain.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
||||||
<Page Include="Modules\Minecraft\MyLocalModItem.xaml">
|
<Page Include="Modules\Minecraft\MyLocalModItem.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -910,6 +914,7 @@
|
|||||||
<Resource Include="Images\Heads\MCBBS.png" />
|
<Resource Include="Images\Heads\MCBBS.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Images\Blocks\NeoForge.png" />
|
<Resource Include="Images\Blocks\NeoForge.png" />
|
||||||
|
|||||||
@@ -4,311 +4,309 @@
|
|||||||
你也可以使用 Ctrl + F 快速查找。例如,若需要改变文本颜色,则搜索 “颜色” 即可。 -->
|
你也可以使用 Ctrl + F 快速查找。例如,若需要改变文本颜色,则搜索 “颜色” 即可。 -->
|
||||||
|
|
||||||
<local:MyCard Title="纯文本" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="纯文本" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="每个 local:MyCard 代表一张卡片,你可以添加、删除格式类似的 MyCard 来添加多个卡片。每个 TextBlock 代表一段文本,你可以在 Text 属性中书写任何你想写的内容,也可以自行添加更多的 TextBlock。" />
|
Text="每个 local:MyCard 代表一张卡片,你可以添加、删除格式类似的 MyCard 来添加多个卡片。每个 TextBlock 代表一段文本,你可以在 Text 属性中书写任何你想写的内容,也可以自行添加更多的 TextBlock。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" FontSize="11"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" FontSize="11"
|
||||||
Text="你可以通过添加、删除属性修改样式,例如上一行的 FontSize 就会将字号改为 11 号。" />
|
Text="你可以通过添加、删除属性修改样式,例如上一行的 FontSize 就会将字号改为 11 号。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="20,5,20,0" Foreground="#8C7721"
|
<TextBlock TextWrapping="Wrap" Margin="20,5,20,0" Foreground="#8C7721"
|
||||||
Text="它还有许多可以调整的属性:上一行的 Margin 调整了边距,Foreground 则会让文字变色。" />
|
Text="它还有许多可以调整的属性:上一行的 Margin 调整了边距,Foreground 则会让文字变色。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="卡片、提示条" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="卡片、提示条" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<local:MyHint Text="local:MyHint 代表提示条,它默认是警告样式。" />
|
<local:MyHint Text="local:MyHint 代表提示条,它默认是警告样式。" />
|
||||||
<local:MyHint Margin="0,8,0,2" IsWarn="False"
|
<local:MyHint Margin="0,8,0,2" IsWarn="False"
|
||||||
Text="将提示条的 IsWarn 属性改为 False 即可改为提示样式。
使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
|
Text="将提示条的 IsWarn 属性改为 False 即可改为提示样式。
使用左边的那堆字符可以在任意地方手动换行,如果需要使用等号、引号等特殊字符,可以自行百度 XAML 转义字符。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,6,0,0"
|
<TextBlock TextWrapping="Wrap" Margin="0,6,0,0"
|
||||||
Text="卡片(local:MyCard)的 Title 属性决定了它的标题。
为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
|
Text="卡片(local:MyCard)的 Title 属性决定了它的标题。
为卡片添加 CanSwap 属性让它可以被折叠,True 代表是,False 代表否。在此基础上,再使用 IsSwaped 属性调整它是否默认被折叠。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="长宽属性、图片" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="长宽属性、图片" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" Width="320" HorizontalAlignment="Right"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" Width="320" HorizontalAlignment="Right"
|
||||||
Text="任意项目都可以添加 Width 与 Height 属性来控制宽高。HorizontalAlignment 属性可以控制对齐:Center 代表居中,Right 代表居右,例如这段文本就被居右了。" />
|
Text="任意项目都可以添加 Width 与 Height 属性来控制宽高。HorizontalAlignment 属性可以控制对齐:Center 代表居中,Right 代表居右,例如这段文本就被居右了。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,6"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,6"
|
||||||
Text="Image 代表图片,你需要在它的 Source 属性中填写一个网址或文件路径,它会从该处获取图片并显示。通常需要使用 Height 限制它的高度。" />
|
Text="local:MyImage 代表图片,你需要在它的 Source 属性中填写一个网址或文件路径,它会从该处获取图片并显示。通常需要使用 Height 限制它的高度。" />
|
||||||
<Image Height="50" HorizontalAlignment="Center" Source="https://zh.minecraft.wiki/images/Grass_Block_JE7_BE6.png?bf67e" />
|
<local:MyImage Height="50" HorizontalAlignment="Center" Source="https://www.baidu.com/img/flexible/logo/pc/result.png" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="按钮" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="按钮" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="添加 local:MyButton 即可新建一个按钮。你需要限定它的尺寸与位置,并通过 Padding 属性进一步控制它的内边距。" />
|
Text="添加 local:MyButton 即可新建一个按钮。你需要限定它的尺寸与位置,并通过 Padding 属性进一步控制它的内边距。" />
|
||||||
<local:MyButton Margin="0,4,0,10" Height="35" HorizontalAlignment="Left" Padding="25,0,25,0"
|
<local:MyButton Margin="0,4,0,10" Height="35" HorizontalAlignment="Left" Padding="25,0,25,0"
|
||||||
Text="这是一个按钮!一个按钮!" />
|
Text="这是一个按钮!一个按钮!" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="你可以修改 ColorType 属性来调整按钮配色:Highlight 代表当前主题色,Red 代表红色。ToolTip 属性还可以让你在鼠标悬浮在上面的时候显示提示文本。" />
|
Text="你可以修改 ColorType 属性来调整按钮配色:Highlight 代表当前主题色,Red 代表红色。ToolTip 属性还可以让你在鼠标悬浮在上面的时候显示提示文本。" />
|
||||||
<local:MyButton Margin="0,4,0,10" Width="250" Height="35" ColorType="Highlight"
|
<local:MyButton Margin="0,4,0,10" Width="250" Height="35" ColorType="Highlight"
|
||||||
Text="把鼠标停在这里别动……" ToolTip="……就能看到这句话!" />
|
Text="把鼠标停在这里别动……" ToolTip="……就能看到这句话!" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="local:MyTextButton 是没有边框的 “纯文本按钮”,其作用与 local:MyButton 一致。" />
|
Text="local:MyTextButton 是没有边框的 “纯文本按钮”,其作用与 local:MyButton 一致。" />
|
||||||
<local:MyTextButton Margin="0,8,0,10" HorizontalAlignment="Center"
|
<local:MyTextButton Margin="0,8,0,10" HorizontalAlignment="Center"
|
||||||
Text="一个精简版的文本按钮" />
|
Text="一个精简版的文本按钮" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="按钮可以做到很多事,具体将在 “事件” 部分介绍。" />
|
Text="按钮可以做到很多事,具体将在 “事件” 部分介绍。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="事件 1:打开网页、弹出窗口" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="事件 1:打开网页、弹出窗口" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
||||||
Text="将按钮的 EventType 属性设为 打开网页,然后在 EventData 属性中写入网址,即可通过点击按钮打开网页。" />
|
Text="将按钮的 EventType 属性设为 打开网页,然后在 EventData 属性中写入网址,即可通过点击按钮打开网页。" />
|
||||||
<local:MyButton Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
<local:MyButton Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
||||||
Text="打开 Minecraft Wiki" EventType="打开网页" EventData="https://zh.minecraft.wiki/" />
|
Text="打开 Minecraft Wiki" EventType="打开网页" EventData="https://zh.minecraft.wiki/" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,10,0,10"
|
<TextBlock TextWrapping="Wrap" Margin="0,10,0,10"
|
||||||
Text="或者将 EventType 属性改为 弹出窗口,然后在 EventData 属性中写入弹窗的标题与内容……" />
|
Text="或者将 EventType 属性改为 弹出窗口,然后在 EventData 属性中写入弹窗的标题与内容……" />
|
||||||
<local:MyButton Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
<local:MyButton Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
||||||
Text="显示一个弹窗" EventType="弹出窗口" EventData="这是标题|标题与内容以竖线间隔。\n你也可以直接在其中换行。" />
|
Text="显示一个弹窗" EventType="弹出窗口" EventData="这是标题|标题与内容以竖线间隔。\n你也可以直接在其中换行。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,10,0,0"
|
<TextBlock TextWrapping="Wrap" Margin="0,10,0,0"
|
||||||
Text="local:MyTextButton 同样可以设置 EventType 与 EventData 让它具有特定功能。" />
|
Text="local:MyTextButton 同样可以设置 EventType 与 EventData 让它具有特定功能。" />
|
||||||
<local:MyTextButton Margin="0,8,0,0" HorizontalAlignment="Center"
|
<local:MyTextButton Margin="0,8,0,0" HorizontalAlignment="Center"
|
||||||
Text="点击打开知乎" EventType="打开网页" EventData="https://www.zhihu.com/" />
|
Text="点击打开知乎" EventType="打开网页" EventData="https://www.zhihu.com/" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="事件 2:启动游戏" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="事件 2:启动游戏" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="将 EventType 设置为 启动游戏,EventData 设置为具体的游戏版本,即可通过点击按钮启动游戏。如果当前游戏文件夹没有该版本,则无法启动。" />
|
Text="将 EventType 设置为 启动游戏,EventData 设置为具体的游戏版本,即可通过点击按钮启动游戏。如果当前游戏文件夹没有该版本,则无法启动。" />
|
||||||
<local:MyButton Margin="0,4,0,10" Width="250" Height="35"
|
<local:MyButton Margin="0,4,0,10" Width="250" Height="35"
|
||||||
Text="启动 Minecraft 1.12.2" EventType="启动游戏" EventData="1.12.2" />
|
Text="启动 Minecraft 1.12.2" EventType="启动游戏" EventData="1.12.2" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="在 EventData 后面添加一条竖线(|),竖线后填写服务器 IP,即可在启动该版本的同时自动进入服务器。" />
|
Text="在 EventData 后面添加一条竖线(|),竖线后填写服务器 IP,即可在启动该版本的同时自动进入服务器。" />
|
||||||
<local:MyButton Margin="0,4,0,0" Width="250" Height="35"
|
<local:MyButton Margin="0,4,0,0" Width="250" Height="35"
|
||||||
Text="启动 1.20.1 并进入 Hypixel" EventType="启动游戏" EventData="1.20.1|mc.hypixel.net" ToolTip="服务器 IP:mc.hypixel.net" />
|
Text="启动 1.20.1 并进入 Hypixel" EventType="启动游戏" EventData="1.20.1|mc.hypixel.net" ToolTip="服务器 IP:mc.hypixel.net" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="在 EventData 中填写 \current,表示启动当前被选中的游戏版本,同样可以在后面填写服务器 IP。" />
|
Text="在 EventData 中填写 \current,表示启动当前被选中的游戏版本,同样可以在后面填写服务器 IP。" />
|
||||||
<local:MyButton Margin="0,4,0,10" Width="250" Height="35"
|
<local:MyButton Margin="0,4,0,10" Width="250" Height="35"
|
||||||
Text="启动当前选中版本并进入 Hypixel" EventType="启动游戏" EventData="\current|mc.hypixel.net" ToolTip="启动当前版本" />
|
Text="启动当前选中版本并进入 Hypixel" EventType="启动游戏" EventData="\current|mc.hypixel.net" ToolTip="启动当前版本" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="事件 3:打开文件" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="事件 3:打开文件" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="将 EventType 设置为 打开文件,EventData 设置为文件路径,即可点击打开特定文件或启动程序。" />
|
Text="将 EventType 设置为 打开文件,EventData 设置为文件路径,即可点击打开特定文件或启动程序。" />
|
||||||
<local:MyButton Margin="0,4,0,8" Width="200" Height="35"
|
<local:MyButton Margin="0,4,0,8" Width="200" Height="35"
|
||||||
Text="打开记事本" EventType="打开文件" EventData="notepad.exe" />
|
Text="打开记事本" EventType="打开文件" EventData="notepad.exe" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,4,0,0"
|
<TextBlock TextWrapping="Wrap" Margin="0,4,0,0"
|
||||||
Text="如果能在 PCL 文件夹中找到该文件,则会优先打开 PCL 文件夹中的文件。当然,你可以使用例如 C:\ 开头的绝对路径。" />
|
Text="如果能在 PCL 文件夹中找到该文件,则会优先打开 PCL 文件夹中的文件。当然,你可以使用例如 C:\ 开头的绝对路径。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="此外,PCL 会将文件中的 “花括号 path” 替换为 PCL 可执行文件所在文件夹({path}),可以用于执行特定程序或加载图片。" />
|
Text="此外,PCL 会将文件中的 “花括号 path” 替换为 PCL 可执行文件所在文件夹({path}),可以用于执行特定程序或加载图片。" />
|
||||||
<local:MyButton Margin="0,4,0,10" Width="200" Height="35"
|
<local:MyButton Margin="0,4,0,10" Width="200" Height="35"
|
||||||
Text="打开 PCL 日志" EventType="打开文件" EventData="Log1.txt" ToolTip="PCL 的日志文件就在 PCL 文件夹内,且名为 Log1.txt" />
|
Text="打开 PCL 日志" EventType="打开文件" EventData="Log1.txt" ToolTip="PCL 的日志文件就在 PCL 文件夹内,且名为 Log1.txt" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="就像为游戏指定服务器 IP 一样,你也可以在 EventData 的竖线后为程序添加启动参数。" />
|
Text="就像为游戏指定服务器 IP 一样,你也可以在 EventData 的竖线后为程序添加启动参数。" />
|
||||||
<local:MyButton Margin="0,4,0,0" Width="200" Height="35"
|
<local:MyButton Margin="0,4,0,0" Width="200" Height="35"
|
||||||
Text="定位游戏启动脚本" EventType="打开文件" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。
点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
|
Text="定位游戏启动脚本" EventType="打开文件" EventData="explorer.exe|/select,LatestLaunch.bat" ToolTip="PCL 会将上一次启动 MC 的脚本保存在 PCL 文件夹内,且名为 LatestLaunch.bat。
点击按钮会打开文件管理器,并且借助参数要求它选中这个文件。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="事件 4:其他事件类型" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="事件 4:其他事件类型" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock Margin="0,4,0,6" FontWeight="Bold"
|
<TextBlock Margin="0,4,0,6" FontWeight="Bold"
|
||||||
Text="EventType 共有以下种类:" />
|
Text="EventType 共有以下种类:" />
|
||||||
<TextBlock Margin="0,0,0,4"
|
<TextBlock Margin="0,0,0,4"
|
||||||
Text="· 打开网页、启动游戏、打开文件:已在上方的卡片中介绍" />
|
Text="· 打开网页、启动游戏、打开文件:已在上方的卡片中介绍" />
|
||||||
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
||||||
Text="查看 PCL 源代码" EventType="打开网页" EventData="https://github.com/Hex-Dragon/PCL2/blob/main/Plain%20Craft%20Launcher%202/FormMain.xaml.vb"/>
|
Text="查看 PCL 源代码" EventType="打开网页" EventData="https://github.com/Hex-Dragon/PCL2/blob/main/Plain%20Craft%20Launcher%202/FormMain.xaml.vb"/>
|
||||||
<TextBlock Margin="0,0,0,4"
|
<TextBlock Margin="0,0,0,4"
|
||||||
Text="· 今日人品、清理垃圾、内存优化、安装整合包:触发对应功能" />
|
Text="· 今日人品、清理垃圾、内存优化、安装整合包:触发对应功能" />
|
||||||
<TextBlock Margin="0,0,0,4"
|
<TextBlock Margin="0,0,0,4"
|
||||||
Text="· 复制文本:将 EventData 中的内容复制到剪贴板" />
|
Text="· 复制文本:将 EventData 中的内容复制到剪贴板" />
|
||||||
<TextBlock Margin="0,0,0,4"
|
<TextBlock Margin="0,0,0,4"
|
||||||
Text="· 刷新主页:点击重新加载主页。如果主页文件为联网更新,这会重新下载主页内容" />
|
Text="· 刷新主页:点击重新加载主页。如果主页文件为联网更新,这会重新下载主页内容" />
|
||||||
<TextBlock Margin="0,0,0,4"
|
<TextBlock Margin="0,0,0,4"
|
||||||
Text="· 下载文件:在点击时要求选择文件保存位置,并且下载 EventData 的链接中的文件" />
|
Text="· 下载文件:在点击时要求选择文件保存位置,并且下载 EventData 的链接中的文件
 EventData 中也能可选地指定文件名或目标文件夹,格式为:链接|文件名|文件夹" />
|
||||||
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
||||||
Text="下载百度的 Logo" EventType="下载文件" EventData="https://www.baidu.com/img/flexible/logo/pc/result.png" />
|
Text="下载百度的 Logo" EventType="下载文件" EventData="https://www.baidu.com/img/flexible/logo/pc/result.png" />
|
||||||
<TextBlock Margin="0,4,0,4"
|
<TextBlock Margin="0,4,0,4"
|
||||||
Text="· 打开帮助:跳转到 EventData 对应的帮助文件(输入相对 Help 文件夹的路径)"/>
|
Text="· 打开帮助:跳转到 EventData 对应的帮助文件(输入相对 Help 文件夹的路径)"/>
|
||||||
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
||||||
Text="打开自定义帮助页面" EventType="打开帮助" EventData="帮助/自定义帮助.json"/>
|
Text="打开自定义帮助页面" EventType="打开帮助" EventData="帮助/自定义帮助.json"/>
|
||||||
<TextBlock Margin="0,4,0,4"
|
<TextBlock Margin="0,4,0,4"
|
||||||
Text="· 切换页面:强制切换到 PCL 的某一页面(尝试切换到不太对头的页面会出现不可预知的 Bug,使用时请谨慎)
 EventData 为 页面种类|次要页面种类(PageType|PageSubType,例如 1|1)
 点击上方的 查看 PCL 源代码 按钮,在 1000 行左右的位置即可查找到对应数值"/>
|
Text="· 切换页面:强制切换到 PCL 的某一页面(尝试切换到不太对头的页面会出现不可预知的 Bug)
 EventData 为 页面种类|次要页面种类(PageType|PageSubType,例如 1|1)
 点击上方的 查看 PCL 源代码 按钮,在 1000 行左右的位置即可查找到对应数值"/>
|
||||||
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
||||||
Text="切换到下载页面" EventType="切换页面" EventData="1|1"/>
|
Text="切换到下载页面" EventType="切换页面" EventData="1|1"/>
|
||||||
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
<local:MyButton Margin="0,5,0,6" Width="250" Height="35"
|
||||||
Text="切换到启动器设置" EventType="切换页面" EventData="3|2"/>
|
Text="切换到启动器设置" EventType="切换页面" EventData="3|2"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="StackPanel 横向布局" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="StackPanel 横向布局" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
||||||
Text="你需要使用 StackPanel 在一行里塞下多个按钮。你可以仅在这个教学卡片的基础上稍作调整,来实现自己的按钮布局。" />
|
Text="你需要使用 StackPanel 在一行里塞下多个按钮。你可以仅在这个教学卡片的基础上稍作调整,来实现自己的按钮布局。" />
|
||||||
<!-- 这是第一行 -->
|
<!-- 这是第一行 -->
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0" ColorType="Highlight"
|
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0" ColorType="Highlight"
|
||||||
Text="打开 B 站" EventType="打开网页" EventData="https://www.bilibili.com/" />
|
Text="打开 B 站" EventType="打开网页" EventData="https://www.bilibili.com/" />
|
||||||
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
||||||
Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" />
|
Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" />
|
||||||
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
||||||
Text="打开记事本" EventType="打开文件" EventData="notepad" />
|
Text="打开记事本" EventType="打开文件" EventData="notepad" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<!-- 这是第二行 -->
|
<!-- 这是第二行 -->
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
|
||||||
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0" ColorType="Red"
|
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0" ColorType="Red"
|
||||||
Text="复制召唤命令" EventType="复制文本" EventData="/execute as @a at @s run summon Creeper ~ ~2 ~" ToolTip="这条 Minecraft 命令会在每个玩家头顶召唤一只苦力怕!" />
|
Text="复制召唤命令" EventType="复制文本" EventData="/execute as @a at @s run summon Creeper ~ ~2 ~" ToolTip="这条 Minecraft 命令会在每个玩家头顶召唤一只苦力怕!" />
|
||||||
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
||||||
Text="内存优化" EventType="内存优化" />
|
Text="内存优化" EventType="内存优化" />
|
||||||
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
|
||||||
Text="下载百度的 Logo" EventType="下载文件" EventData="https://www.baidu.com/img/flexible/logo/pc/result.png" />
|
Text="下载百度的 Logo" EventType="下载文件" EventData="https://www.baidu.com/img/flexible/logo/pc/result.png" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="列表项 1:基础" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="列表项 1:基础" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="你也可以使用列表项 “local:MyListItem” 来替代按钮,其使用方式与按钮类似。" />
|
Text="你也可以使用列表项 “local:MyListItem” 来替代按钮,其使用方式与按钮类似。" />
|
||||||
<local:MyListItem Margin="-5,2,-5,8"
|
<local:MyListItem Margin="-5,2,-5,8"
|
||||||
Logo="https://www.baidu.com/favicon.ico" Title="百度" Info="百度一下,你就知道!"
|
Logo="https://www.baidu.com/favicon.ico" Title="百度" Info="百度一下,你就知道!"
|
||||||
EventType="打开网页" EventData="https://www.baidu.com/" Type="Clickable" />
|
EventType="打开网页" EventData="https://www.baidu.com/" Type="Clickable" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="Logo 属性为列表项的图标,指定的可以是链接也可以是文件路径;Title 是大标题,Info 是可选的小标题(详细信息);Type 如果省略,该列表项则单纯只展示信息,仅当 Type 为 Clickable 才能触发点击效果。"/>
|
Text="Logo 属性为列表项的图标,指定的可以是链接也可以是文件路径;Title 是大标题,Info 是可选的小标题(详细信息);Type 如果省略,该列表项则单纯只展示信息,仅当 Type 为 Clickable 才能触发点击效果。"/>
|
||||||
<local:MyListItem Margin="-5,2,-5,8"
|
<local:MyListItem Margin="-5,2,-5,8"
|
||||||
Logo="pack://application:,,,/images/Blocks/Grass.png"
|
Logo="pack://application:,,,/images/Blocks/Grass.png"
|
||||||
EventType="打开帮助" EventData="帮助/自定义帮助.json" Type="Clickable" />
|
EventType="打开帮助" EventData="帮助/自定义帮助.json" Type="Clickable" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="EventType、EventData 与按钮几乎一致,唯一不同的是,列表项不支持联网加载帮助文件。" />
|
Text="EventType、EventData 与按钮几乎一致,唯一不同的是,列表项不支持联网加载帮助文件。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="列表项 2:内置图片" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="列表项 2:内置图片" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="PCL 内置了一些 Minecraft 方块与物品图片,可以直接使用。"/>
|
Text="PCL 内置了一些 Minecraft 方块与物品图片,可以直接使用。"/>
|
||||||
<StackPanel Orientation="Horizontal" Margin="10,8,0,15" Height="30">
|
<StackPanel Orientation="Horizontal" Margin="10,8,0,15" Height="30">
|
||||||
<!-- 命令方块 -->
|
<!-- 命令方块 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/CommandBlock.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/CommandBlock.png"/>
|
||||||
<!-- 圆石 -->
|
<!-- 圆石 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Cobblestone.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Cobblestone.png"/>
|
||||||
<!-- 金块 -->
|
<!-- 金块 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GoldBlock.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GoldBlock.png"/>
|
||||||
<!-- 草方块 -->
|
<!-- 草方块 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Grass.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Grass.png"/>
|
||||||
<!-- 草径 -->
|
<!-- 草径 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GrassPath.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GrassPath.png"/>
|
||||||
<!-- 铁砧 -->
|
<!-- 铁砧 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Anvil.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Anvil.png"/>
|
||||||
<!-- 红石块 -->
|
<!-- 红石块 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneBlock.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneBlock.png"/>
|
||||||
<!-- 红石灯(亮) -->
|
<!-- 红石灯(亮) -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOn.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOn.png"/>
|
||||||
<!-- 红石灯(灭) -->
|
<!-- 红石灯(灭) -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOff.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOff.png"/>
|
||||||
<!-- 鸡蛋 -->
|
<!-- 鸡蛋 -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Egg.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Egg.png"/>
|
||||||
<!-- 布料(Fabric 图标) -->
|
<!-- 布料(Fabric 图标) -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Fabric.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Fabric.png"/>
|
||||||
<!-- 狐狸(NeoForge 图标) -->
|
<!-- 狐狸(NeoForge 图标) -->
|
||||||
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/NeoForge.png"/>
|
<local:MyImage Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/NeoForge.png"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="使用时,将上方对应行的 Source 复制到 MyListItem 的 Logo 属性处即可。"/>
|
Text="使用时,将上方对应行的 Source 复制到 MyListItem 的 Logo 属性处即可。"/>
|
||||||
<local:MyListItem Margin="-5,0,-5,8"
|
<local:MyListItem Margin="-5,0,-5,8"
|
||||||
Logo="pack://application:,,,/images/Blocks/CommandBlock.png"
|
Logo="pack://application:,,,/images/Blocks/CommandBlock.png"
|
||||||
Title="清理垃圾" Info="使用内置的命令方块图片作为 Logo" EventType="清理垃圾" Type="Clickable" />
|
Title="清理垃圾" Info="使用内置的命令方块图片作为 Logo" EventType="清理垃圾" Type="Clickable" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="主题色" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="主题色" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,15"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,15"
|
||||||
Text="你可以用类似 {DynamicResource ColorBrush5} 的格式使用 PCL 当前的主题颜色,修改末尾的数字编号以改变颜色浓度。" />
|
Text="你可以用类似 {DynamicResource ColorBrush5} 的格式使用 PCL 当前的主题颜色,修改末尾的数字编号以改变颜色浓度。" />
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="8,4">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="8,4">
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 1 " Margin="5,0" Background="{DynamicResource ColorBrush1}" Foreground="#FFFFFF" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 1 " Margin="5,0" Background="{DynamicResource ColorBrush1}" Foreground="#FFFFFF" />
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 2 " Margin="5,0" Background="{DynamicResource ColorBrush2}" Foreground="#FFFFFF" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 2 " Margin="5,0" Background="{DynamicResource ColorBrush2}" Foreground="#FFFFFF" />
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 3 " Margin="5,0" Background="{DynamicResource ColorBrush3}" Foreground="#FFFFFF" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 3 " Margin="5,0" Background="{DynamicResource ColorBrush3}" Foreground="#FFFFFF" />
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 4 " Margin="5,0" Background="{DynamicResource ColorBrush4}" Foreground="#FFFFFF" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 4 " Margin="5,0" Background="{DynamicResource ColorBrush4}" Foreground="#FFFFFF" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="8,4">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="8,4">
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 5 " Margin="5,0" Background="{DynamicResource ColorBrush5}" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 5 " Margin="5,0" Background="{DynamicResource ColorBrush5}" />
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 6 " Margin="5,0" Background="{DynamicResource ColorBrush6}" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 6 " Margin="5,0" Background="{DynamicResource ColorBrush6}" />
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 7 " Margin="5,0" Background="{DynamicResource ColorBrush7}" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 7 " Margin="5,0" Background="{DynamicResource ColorBrush7}" />
|
||||||
<TextBlock TextWrapping="Wrap" Text=" 浓度 8 " Margin="5,0" Background="{DynamicResource ColorBrush8}" />
|
<TextBlock TextWrapping="Wrap" Text=" 浓度 8 " Margin="5,0" Background="{DynamicResource ColorBrush8}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,15,0,8" Foreground="{DynamicResource ColorBrush2}" Background="{DynamicResource ColorBrush6}"
|
<TextBlock TextWrapping="Wrap" Margin="0,15,0,8" Foreground="{DynamicResource ColorBrush2}" Background="{DynamicResource ColorBrush6}"
|
||||||
Text="除了字体颜色,你也可以将主题色用于背景色、边框颜色等颜色参数。例如这行字的颜色为浓度 2,背景为浓度 6。" />
|
Text="除了字体颜色,你也可以将主题色用于背景色、边框颜色等颜色参数。例如这行字的颜色为浓度 2,背景为浓度 6。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="替换标记" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="替换标记" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="在花括号 {} 中写入特定内容,PCL 会在加载时对其进行替换。
例如,path 会被替换为 PCL 可执行文件所在文件夹({path}),用于在 EventData 中指定特定文件,或是加载图片。" />
|
Text="在花括号 {} 中写入特定内容,PCL 会在加载时对其进行替换。
例如,path 会被替换为 PCL 可执行文件所在文件夹({path}),用于在 EventData 中指定特定文件,或是加载图片。" />
|
||||||
<local:MyHint Margin="0,6,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
|
<local:MyHint Margin="0,6,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="你也可以使用替换标记来获取随机内容:cave 会被替换为一条随机的回声洞内容,hint 则是 “你知道吗” 的内容。" />
|
Text="你也可以使用替换标记来获取随机内容:cave 会被替换为一条随机的回声洞内容,hint 则是 “你知道吗” 的内容。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="10,6,0,5" Foreground="{DynamicResource ColorBrush3}"
|
<TextBlock TextWrapping="Wrap" Margin="10,6,0,5" Foreground="{DynamicResource ColorBrush3}"
|
||||||
Text="你知道吗:{hint}" />
|
Text="你知道吗:{hint}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="进阶:Grid 布局" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="进阶:Grid 布局" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="如果要实现更复杂的布局,则必须使用 Grid。Grid 可以让按钮们自动适应窗口宽度:随意拉伸 PCL 窗口,按钮大小会自动改变。" />
|
Text="如果要实现更复杂的布局,则必须使用 Grid。Grid 可以让按钮们自动适应窗口宽度:随意拉伸 PCL 窗口,按钮大小会自动改变。" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
||||||
Text="你可以上网查找 “WPF Grid” 的相关教程,这里仅给出一个例子,不作详细介绍。你可以仅在这个教学卡片的基础上稍作调整,来实现自己的按钮布局。" />
|
Text="你可以上网查找 “WPF Grid” 的相关教程,这里仅给出一个例子,不作详细介绍。你可以仅在这个教学卡片的基础上稍作调整,来实现自己的按钮布局。" />
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="1*" />
|
<ColumnDefinition Width="1*" />
|
||||||
<ColumnDefinition Width="1.6*" MinWidth="200" />
|
<ColumnDefinition Width="1.6*" MinWidth="200" /> <!-- 第二个按钮的宽度是第一个按钮的 1.6 倍,且至少为 200 -->
|
||||||
<!-- 第二个按钮的宽度是第一个按钮的 1.6 倍,且至少为 200 -->
|
<ColumnDefinition Width="150" /> <!-- 如果不打 *,则会占用固定的宽度,也可以写 Auto 来自适应 -->
|
||||||
<ColumnDefinition Width="150" />
|
</Grid.ColumnDefinitions>
|
||||||
<!-- 如果不打 *,则会占用固定的宽度,也可以写 Auto 来自适应 -->
|
<!-- 为按钮添加 Grid.Column 属性指定它所在的列,不要添加 Width 与 HorizontalAlignment 属性 -->
|
||||||
</Grid.ColumnDefinitions>
|
<local:MyButton Grid.Column="0" Margin="0,0,10,0" Height="35" ColorType="Highlight"
|
||||||
<!-- 为按钮添加 Grid.Column 属性指定它所在的列,不要添加 Width 与 HorizontalAlignment 属性 -->
|
|
||||||
<local:MyButton Grid.Column="0" Margin="0,0,10,0" Height="35" ColorType="Highlight"
|
|
||||||
Text="打开 B 站" EventType="打开网页" EventData="https://www.bilibili.com/" />
|
Text="打开 B 站" EventType="打开网页" EventData="https://www.bilibili.com/" />
|
||||||
<local:MyButton Grid.Column="1" Margin="0,0,10,0" Height="35"
|
<local:MyButton Grid.Column="1" Margin="0,0,10,0" Height="35"
|
||||||
Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" />
|
Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" />
|
||||||
<local:MyButton Grid.Column="2" Margin="0,0,10,0" Height="35"
|
<local:MyButton Grid.Column="2" Margin="0,0,10,0" Height="35"
|
||||||
Text="打开记事本" EventType="打开文件" EventData="notepad" />
|
Text="打开记事本" EventType="打开文件" EventData="notepad" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="进阶:图标按钮" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="进阶:图标按钮" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<local:MyHint Margin="0,0,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
|
<local:MyHint Margin="0,0,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="MyIconTextButton 是一种带有自定义矢量图标的按钮变体,它同样支持 EventType 与 EventData 属性。
通过设置 Logo 属性来控制它的图标,设置 LogoScale 属性还可以调整图标的缩放比例。" />
|
Text="MyIconTextButton 是一种带有自定义矢量图标的按钮变体,它同样支持 EventType 与 EventData 属性。
通过设置 Logo 属性来控制它的图标,设置 LogoScale 属性还可以调整图标的缩放比例。" />
|
||||||
<local:MyIconTextButton Margin="0,4,0,8" Height="35" HorizontalAlignment="Center"
|
<local:MyIconTextButton Margin="0,4,0,8" Height="35" HorizontalAlignment="Center"
|
||||||
Text="查看 SVG Path 简介" EventType="打开网页" EventData="https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Paths"
|
Text="查看 SVG Path 简介" EventType="打开网页" EventData="https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Paths"
|
||||||
LogoScale="1.02" Logo="M1091 0H78C35 0 0 35 0 78v863c0 43 35 78 78 78H1091c43 0 78-35 78-78V78C1170 35 1134 0 1091 0z m-8 87v78H87v-78h994zM87 933V254h994v679H87v0zM724 340l-206 547a43 43 0 0 1-82-31l206-547a43 43 0 0 1 82 30zM369 545l-85 85 85 85a43 43 0 0 1-62 62l-116-116a43 43 0 0 1 0-62l116-116a43 43 0 0 1 62 61z m610-37a43 43 0 0 1 0 62l-116 116a43 43 0 0 1-62 0 43 43 0 0 1 0-62l85-85-85-85a43 43 0 0 1 62-62l116 116z" />
|
LogoScale="1.02" Logo="M1091 0H78C35 0 0 35 0 78v863c0 43 35 78 78 78H1091c43 0 78-35 78-78V78C1170 35 1134 0 1091 0z m-8 87v78H87v-78h994zM87 933V254h994v679H87v0zM724 340l-206 547a43 43 0 0 1-82-31l206-547a43 43 0 0 1 82 30zM369 545l-85 85 85 85a43 43 0 0 1-62 62l-116-116a43 43 0 0 1 0-62l116-116a43 43 0 0 1 62 61z m610-37a43 43 0 0 1 0 62l-116 116a43 43 0 0 1-62 0 43 43 0 0 1 0-62l85-85-85-85a43 43 0 0 1 62-62l116 116z" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="Logo 属性的内容是 SVG Path 的值,你需要使用 SVG 编辑器或者从图标资源网站(如 IconFont)查找它。不要自己写,写不懂的。
此外,它还有两种 ColorType:Black(默认)和 Highlight。" />
|
Text="Logo 属性的内容是 SVG Path 的值,你需要使用 SVG 编辑器或者从图标资源网站(如 IconFont)查找它。不要自己写,写不懂的。
此外,它还有两种 ColorType:Black(默认)和 Highlight。" />
|
||||||
<local:MyIconTextButton Margin="0,4,0,8" Height="35" HorizontalAlignment="Center"
|
<local:MyIconTextButton Margin="0,4,0,8" Height="35" HorizontalAlignment="Center"
|
||||||
ColorType="Highlight" Text="打开 IconFont" EventType="打开网页" EventData="https://www.iconfont.cn/"
|
ColorType="Highlight" Text="打开 IconFont" EventType="打开网页" EventData="https://www.iconfont.cn/"
|
||||||
LogoScale="1" Logo="M510 959c-51-31-40-86-74-120-61-63-168-66-231-138C-5 457 196 3 593 70c231 39 407 363 250 592-67 98-198 106-277 213-23 23-11 81-55 83zM176 432c-9 176 240 167 240 9 0-80-72-145-166-111-66 23-71 49-74 101z m509 129c212 59 217-307 0-231-102 36-90 206 0 231z m-213 111c33 7 44-91 9-92-19 19-64 79-9 92z m83 0H575c23-37-8-87-46-92 3 37-11 92 27 92z" />
|
LogoScale="1" Logo="M510 959c-51-31-40-86-74-120-61-63-168-66-231-138C-5 457 196 3 593 70c231 39 407 363 250 592-67 98-198 106-277 213-23 23-11 81-55 83zM176 432c-9 176 240 167 240 9 0-80-72-145-166-111-66 23-71 49-74 101z m509 129c212 59 217-307 0-231-102 36-90 206 0 231z m-213 111c33 7 44-91 9-92-19 19-64 79-9 92z m83 0H575c23-37-8-87-46-92 3 37-11 92 27 92z" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="如果只想要图标,不要文字,还可以使用 MyIconButton。它不能设置 Text 属性,只有一个图标可以按。
它的 Theme 属性可以设置为 Color(默认)、White、Black、Red。" />
|
Text="如果只想要图标,不要文字,还可以使用 MyIconButton。它不能设置 Text 属性,只有一个图标可以按。
它的 Theme 属性可以设置为 Color(默认)、White、Black、Red。" />
|
||||||
<local:MyIconButton Margin="0,4,0,0" Width="25" Height="25" HorizontalAlignment="Center"
|
<local:MyIconButton Margin="0,4,0,0" Width="25" Height="25" HorizontalAlignment="Center"
|
||||||
Theme="Black" EventType="弹出窗口" EventData="事件|MyIconButton 当然也支持 EventType 和 EventData——要不然介绍它干啥?"
|
Theme="Black" EventType="弹出窗口" EventData="事件|MyIconButton 当然也支持 EventType 和 EventData——要不然介绍它干啥?"
|
||||||
LogoScale="1" Logo="M149 873c47 47 101 83 162 109 63 26 130 40 199 40 69 0 136-13 199-40 61-25 115-62 162-109s83-101 109-162c26-63 40-130 40-199 0-69-13-136-40-199-25-61-62-115-109-162-46-46-101-83-162-109C648 13 580 0 511 0s-136 13-199 40c-61 25-115 62-162 109s-83 101-109 162C13 375 0 442 0 511s13 136 40 199c25 61 62 115 109 162zM97 511c0-228 185-414 414-414 228 0 414 185 414 414S740 926 511 926c-228 0-414-185-414-414z M539 244c-8-4-17-7-27-7-9 0-19 2-27 7-16 9-27 27-27 47 0 30 24 54 54 54 30 0 54-24 54-54 0-19-10-37-27-47zM566 732v-284c0-30-24-54-54-54-30 0-54 24-54 54v284c0 30 24 54 54 54 30 0 54-24 54-54z" />
|
LogoScale="1" Logo="M149 873c47 47 101 83 162 109 63 26 130 40 199 40 69 0 136-13 199-40 61-25 115-62 162-109s83-101 109-162c26-63 40-130 40-199 0-69-13-136-40-199-25-61-62-115-109-162-46-46-101-83-162-109C648 13 580 0 511 0s-136 13-199 40c-61 25-115 62-162 109s-83 101-109 162C13 375 0 442 0 511s13 136 40 199c25 61 62 115 109 162zM97 511c0-228 185-414 414-414 228 0 414 185 414 414S740 926 511 926c-228 0-414-185-414-414z M539 244c-8-4-17-7-27-7-9 0-19 2-27 7-16 9-27 27-27 47 0 30 24 54 54 54 30 0 54-24 54-54 0-19-10-37-27-47zM566 732v-284c0-30-24-54-54-54-30 0-54 24-54 54v284c0 30 24 54 54 54 30 0 54-24 54-54z" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
|
||||||
Text="如果只想显示一个图标,不想让它是能按的按钮,可以使用 WPF 自带的 Path 等绘图控件,感兴趣的话可以自行搜索。想偷懒也可以把 MyIconButton 的 IsHitTestVisible 属性改为 False……" />
|
Text="如果只想显示一个图标,不想让它是能按的按钮,可以使用 WPF 自带的 Path 等绘图控件,感兴趣的话可以自行搜索。想偷懒也可以把 MyIconButton 的 IsHitTestVisible 属性改为 False……" />
|
||||||
<Path Margin="0,4,0,0" Width="20" Height="20" HorizontalAlignment="Center"
|
<Path Margin="0,4,0,0" Width="20" Height="20" HorizontalAlignment="Center"
|
||||||
Stretch="Uniform" Fill="{DynamicResource ColorBrush1}"
|
Stretch="Uniform" Fill="{DynamicResource ColorBrush1}"
|
||||||
Data="M149 873c47 47 101 83 162 109 63 26 130 40 199 40 69 0 136-13 199-40 61-25 115-62 162-109s83-101 109-162c26-63 40-130 40-199 0-69-13-136-40-199-25-61-62-115-109-162-46-46-101-83-162-109C648 13 580 0 511 0s-136 13-199 40c-61 25-115 62-162 109s-83 101-109 162C13 375 0 442 0 511s13 136 40 199c25 61 62 115 109 162zM97 511c0-228 185-414 414-414 228 0 414 185 414 414S740 926 511 926c-228 0-414-185-414-414z M539 244c-8-4-17-7-27-7-9 0-19 2-27 7-16 9-27 27-27 47 0 30 24 54 54 54 30 0 54-24 54-54 0-19-10-37-27-47zM566 732v-284c0-30-24-54-54-54-30 0-54 24-54 54v284c0 30 24 54 54 54 30 0 54-24 54-54z" />
|
Data="M149 873c47 47 101 83 162 109 63 26 130 40 199 40 69 0 136-13 199-40 61-25 115-62 162-109s83-101 109-162c26-63 40-130 40-199 0-69-13-136-40-199-25-61-62-115-109-162-46-46-101-83-162-109C648 13 580 0 511 0s-136 13-199 40c-61 25-115 62-162 109s-83 101-109 162C13 375 0 442 0 511s13 136 40 199c25 61 62 115 109 162zM97 511c0-228 185-414 414-414 228 0 414 185 414 414S740 926 511 926c-228 0-414-185-414-414z M539 244c-8-4-17-7-27-7-9 0-19 2-27 7-16 9-27 27-27 47 0 30 24 54 54 54 30 0 54-24 54-54 0-19-10-37-27-47zM566 732v-284c0-30-24-54-54-54-30 0-54 24-54 54v284c0 30 24 54 54 54 30 0 54-24 54-54z" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<local:MyCard Title="进阶:联网自定义主页" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
<local:MyCard Title="进阶:联网自定义主页" Margin="0,0,0,15" CanSwap="True" IsSwaped="True">
|
||||||
<StackPanel Margin="25,40,23,15">
|
<StackPanel Margin="25,40,23,15">
|
||||||
<local:MyHint Margin="0,0,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
|
<local:MyHint Margin="0,0,0,10" Text="以下特性于 PCL 2.6.5 (299) 加入,不适用于更早版本的 PCL。" IsWarn="False" />
|
||||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10"
|
||||||
Text="如果你在尝试制作联网更新的自定义主页,可以查看下方的 GitHub 讨论页。
你可以根据其中的介绍为主页添加版本号检查以节省流量,也可以通过检查 Referer 和 User Agent 来确定对方的 PCL 版本。" />
|
Text="如果你在尝试制作联网更新的自定义主页,可以查看下方的 GitHub 讨论页。
你可以根据其中的介绍为主页添加版本号检查以节省流量,也可以通过检查 Referer 和 User Agent 来确定对方的 PCL 版本。" />
|
||||||
<local:MyButton Margin="0,0,0,8" Height="35" HorizontalAlignment="Center" Padding="20,0,20,0"
|
<local:MyButton Margin="0,0,0,8" Height="35" HorizontalAlignment="Center" Padding="20,0,20,0"
|
||||||
Text="打开 GitHub 讨论页" EventType="打开网页" EventData="https://github.com/Hex-Dragon/PCL2/discussions/2528" />
|
Text="打开 GitHub 讨论页" EventType="打开网页" EventData="https://github.com/Hex-Dragon/PCL2/discussions/2528" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -317,9 +315,9 @@
|
|||||||
- Width、Height:设置宽度与高度
|
- Width、Height:设置宽度与高度
|
||||||
- ToolTip:设置鼠标指向时的提示文本
|
- ToolTip:设置鼠标指向时的提示文本
|
||||||
- Margin:调整外边距(格式为 左,上,右,下。例如 Margin="0,0,0,2" 即为 2 单位的下边距)
|
- Margin:调整外边距(格式为 左,上,右,下。例如 Margin="0,0,0,2" 即为 2 单位的下边距)
|
||||||
- HorizontalAlignment:设置横向对齐方式,居左:Left、居中:Center、居右:Right、拉伸(默认):Stretch
|
- HorizontalAlignment:设置横向对齐方式;居左:Left、居中:Center、居右:Right、拉伸(默认):Stretch
|
||||||
- VerticalAlignment:设置纵向对齐方式,居上:Top、居中:Center、居下:Bottom、拉伸(默认):Stretch
|
- VerticalAlignment:设置纵向对齐方式;居上:Top、居中:Center、居下:Bottom、拉伸(默认):Stretch
|
||||||
- IsHitTestVisible:该控件是否响应交互(点击、指向动画等),True 为是(默认),False 为否
|
- IsHitTestVisible:该控件是否响应交互(点击、指向动画等);True 为是(默认),False 为否
|
||||||
|
|
||||||
TextBlock(纯文本):
|
TextBlock(纯文本):
|
||||||
- Text:设置显示的文本(如果要使用引号等特殊字符,自行百度 XAML 转义)
|
- Text:设置显示的文本(如果要使用引号等特殊字符,自行百度 XAML 转义)
|
||||||
@@ -328,17 +326,20 @@ TextBlock(纯文本):
|
|||||||
- FontWeight:设置为 Bold 时,文字加粗
|
- FontWeight:设置为 Bold 时,文字加粗
|
||||||
- Foreground:调整前景颜色(十六进制字符串,例如 #FF010203 代表 ARGB 中的 255,1,2,3。前两位代表不透明度,FF 为全不透明,00 为全透明)
|
- Foreground:调整前景颜色(十六进制字符串,例如 #FF010203 代表 ARGB 中的 255,1,2,3。前两位代表不透明度,FF 为全不透明,00 为全透明)
|
||||||
|
|
||||||
Image(图片):
|
local:MyImage(图片):
|
||||||
- Source:要显示的图片的网址,或 PCL 内置图片位置
|
- Source:要显示的图片的网址,或 PCL 内置图片位置
|
||||||
|
- FallbackSource:当 Source 首次下载失败时,会从该备用地址加载图片
|
||||||
|
- LoadingSource:正在下载网络图片时显示的本地图片(不支持联网下载);默认为 pack://application:,,,/images/Icons/NoIcon.png
|
||||||
|
- EnableCache:若图片是联网获取的,是否将图片保存到本地缓存,在 7 天内不再重新下载;True 为是(默认),False 为否
|
||||||
|
|
||||||
local:MyCard(卡片):
|
local:MyCard(卡片):
|
||||||
- Title:设置显示的标题文本
|
- Title:设置显示的标题文本
|
||||||
- CanSwap:卡片是否可以折叠,True 为是,False 为否
|
- CanSwap:卡片是否可以折叠,True 为是,False 为否
|
||||||
- IsSwaped:卡片是否默认折叠,要求 CanSwap 必须为 True
|
- IsSwaped:卡片是否默认折叠,要求 CanSwap 必须为 True
|
||||||
- HorizontalAlignment:若使用,要求 CanSwap 必须为 False
|
- HorizontalAlignment:若使用,要求 CanSwap 必须为 False
|
||||||
- UseAnimation:是否在展开等高度改变时触发动画,True 为是(默认),False 为否
|
- UseAnimation:是否在展开等高度改变时触发动画;True 为是(默认),False 为否
|
||||||
- SwapLogoRight:卡片折叠时的箭头是朝下还是朝右,True 为朝右,False 为朝下(默认)
|
- SwapLogoRight:卡片折叠时的箭头是朝下还是朝右;True 为朝右,False 为朝下(默认)
|
||||||
- HasMouseAnimation:是否在鼠标指向时改变卡片颜色,True 为是(默认),False 为否
|
- HasMouseAnimation:是否在鼠标指向时改变卡片颜色;True 为是(默认),False 为否
|
||||||
|
|
||||||
local:MyHint(提示条):
|
local:MyHint(提示条):
|
||||||
- Text:设置显示的文本(
 代表换行)
|
- Text:设置显示的文本(
 代表换行)
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user