2.10.7
This commit is contained in:
@@ -67,9 +67,9 @@ Public Class Application
|
|||||||
If Not CheckPermission(PathTemp) Then Throw New Exception("PCL 没有对 " & PathTemp & " 的访问权限")
|
If Not CheckPermission(PathTemp) Then Throw New Exception("PCL 没有对 " & PathTemp & " 的访问权限")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If PathTemp = IO.Path.GetTempPath() & "PCL\" Then
|
If PathTemp = IO.Path.GetTempPath() & "PCL\" Then
|
||||||
MyMsgBox("PCL 无法访问缓存文件夹,可能导致程序出错或无法正常使用!" & vbCrLf & "错误原因:" & GetExceptionDetail(ex), "缓存文件夹不可用")
|
MyMsgBox("PCL 无法访问缓存文件夹,可能导致程序出错或无法正常使用!" & vbCrLf & vbCrLf & "错误原因:" & ex.GetDetail(), "缓存文件夹不可用")
|
||||||
Else
|
Else
|
||||||
MyMsgBox("手动设置的缓存文件夹不可用,PCL 将使用默认缓存文件夹。" & vbCrLf & "错误原因:" & GetExceptionDetail(ex), "缓存文件夹不可用")
|
MyMsgBox("手动设置的缓存文件夹不可用,PCL 将使用默认缓存文件夹。" & vbCrLf & vbCrLf & "错误原因:" & ex.GetDetail(), "缓存文件夹不可用")
|
||||||
Setup.Set("SystemSystemCache", "")
|
Setup.Set("SystemSystemCache", "")
|
||||||
PathTemp = IO.Path.GetTempPath() & "PCL\"
|
PathTemp = IO.Path.GetTempPath() & "PCL\"
|
||||||
End If
|
End If
|
||||||
@@ -104,6 +104,13 @@ WaitRetry:
|
|||||||
ToolTipService.PlacementProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(Primitives.PlacementMode.Bottom))
|
ToolTipService.PlacementProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(Primitives.PlacementMode.Bottom))
|
||||||
ToolTipService.HorizontalOffsetProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(8.0))
|
ToolTipService.HorizontalOffsetProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(8.0))
|
||||||
ToolTipService.VerticalOffsetProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(4.0))
|
ToolTipService.VerticalOffsetProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(4.0))
|
||||||
|
'设置网络配置默认值
|
||||||
|
ServicePointManager.Expect100Continue = False
|
||||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12
|
||||||
|
ServicePointManager.DefaultConnectionLimit = 10000
|
||||||
|
ServicePointManager.UseNagleAlgorithm = False
|
||||||
|
ServicePointManager.EnableDnsRoundRobin = True
|
||||||
|
ServicePointManager.ReusePort = True
|
||||||
'设置初始窗口
|
'设置初始窗口
|
||||||
If Setup.Get("UiLauncherLogo") Then
|
If Setup.Get("UiLauncherLogo") Then
|
||||||
FrmStart = New SplashScreen("Images\icon.ico")
|
FrmStart = New SplashScreen("Images\icon.ico")
|
||||||
@@ -136,11 +143,6 @@ WaitRetry:
|
|||||||
Setup.Load("ToolDownloadThread")
|
Setup.Load("ToolDownloadThread")
|
||||||
Setup.Load("ToolDownloadCert")
|
Setup.Load("ToolDownloadCert")
|
||||||
Setup.Load("ToolDownloadSpeed")
|
Setup.Load("ToolDownloadSpeed")
|
||||||
'网络配置初始化
|
|
||||||
ServicePointManager.Expect100Continue = True
|
|
||||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12
|
|
||||||
ServicePointManager.DefaultConnectionLimit = 1024
|
|
||||||
ServicePointManager.UseNagleAlgorithm = False
|
|
||||||
'计时
|
'计时
|
||||||
Log("[Start] 第一阶段加载用时:" & GetTimeTick() - ApplicationStartTick & " ms")
|
Log("[Start] 第一阶段加载用时:" & GetTimeTick() - ApplicationStartTick & " ms")
|
||||||
ApplicationStartTick = GetTimeTick()
|
ApplicationStartTick = GetTimeTick()
|
||||||
@@ -155,7 +157,7 @@ WaitRetry:
|
|||||||
FilePath = PathWithName
|
FilePath = PathWithName
|
||||||
Catch
|
Catch
|
||||||
End Try
|
End Try
|
||||||
MsgBox(GetExceptionDetail(ex, True) & vbCrLf & "PCL 所在路径:" & If(String.IsNullOrEmpty(FilePath), "获取失败", FilePath), MsgBoxStyle.Critical, "PCL 初始化错误")
|
MsgBox(ex.GetDetail(True) & vbCrLf & "PCL 所在路径:" & If(String.IsNullOrEmpty(FilePath), "获取失败", FilePath), MsgBoxStyle.Critical, "PCL 初始化错误")
|
||||||
FormMain.EndProgramForce(ProcessReturnValues.Exception)
|
FormMain.EndProgramForce(ProcessReturnValues.Exception)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
@@ -168,10 +170,20 @@ WaitRetry:
|
|||||||
'异常
|
'异常
|
||||||
Private Sub Application_DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
|
Private Sub Application_DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
|
||||||
On Error Resume Next
|
On Error Resume Next
|
||||||
|
'触发页面的 Dispatcher
|
||||||
|
If FrmMain?.PageLeft IsNot Nothing AndAlso TypeOf FrmMain.PageLeft Is IDispatcherUnhandledException Then
|
||||||
|
CType(FrmMain.PageLeft, IDispatcherUnhandledException).DispatcherUnhandledException(sender, e)
|
||||||
|
If e.Handled Then Return
|
||||||
|
End If
|
||||||
|
If FrmMain?.PageRight IsNot Nothing AndAlso TypeOf FrmMain.PageRight Is IDispatcherUnhandledException Then
|
||||||
|
CType(FrmMain.PageRight, IDispatcherUnhandledException).DispatcherUnhandledException(sender, e)
|
||||||
|
If e.Handled Then Return
|
||||||
|
End If
|
||||||
|
'正常处理
|
||||||
e.Handled = True
|
e.Handled = True
|
||||||
If IsProgramEnded Then Return
|
If IsProgramEnded Then Return
|
||||||
FeedbackInfo()
|
FeedbackInfo()
|
||||||
Dim Detail As String = GetExceptionDetail(e.Exception, True)
|
Dim Detail As String = e.Exception.GetDetail(True)
|
||||||
If Detail.Contains("System.Windows.Threading.Dispatcher.Invoke") OrElse Detail.Contains("MS.Internal.AppModel.ITaskbarList.HrInit") OrElse Detail.Contains("未能加载文件或程序集") OrElse
|
If Detail.Contains("System.Windows.Threading.Dispatcher.Invoke") OrElse Detail.Contains("MS.Internal.AppModel.ITaskbarList.HrInit") OrElse Detail.Contains("未能加载文件或程序集") OrElse
|
||||||
Detail.Contains(".NET Framework") Then ' “自动错误判断” 的结果分析
|
Detail.Contains(".NET Framework") Then ' “自动错误判断” 的结果分析
|
||||||
OpenWebsite("https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-offline-installer")
|
OpenWebsite("https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-offline-installer")
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
Imports System.Windows.Threading
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 指示页面可以通过按下 F5 或以其他方式刷新。
|
||||||
|
''' </summary>
|
||||||
|
Public Interface IRefreshable
|
||||||
|
Sub Refresh()
|
||||||
|
End Interface
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 指示页面可以处理未捕获的异常。
|
||||||
|
''' </summary>
|
||||||
|
Public Interface IDispatcherUnhandledException
|
||||||
|
Sub DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs)
|
||||||
|
End Interface
|
||||||
@@ -123,14 +123,6 @@
|
|||||||
End Select
|
End Select
|
||||||
'控件转换
|
'控件转换
|
||||||
Select Case Type
|
Select Case Type
|
||||||
Case 5
|
|
||||||
Dim LoadingPickaxe As New MyLoading With {.Text = "正在获取版本列表", .Margin = New Thickness(5)}
|
|
||||||
Dim Loader = New LoaderTask(Of String, List(Of DlForgeVersionEntry))("DlForgeVersion Main", AddressOf DlForgeVersionMain)
|
|
||||||
LoadingPickaxe.State = Loader
|
|
||||||
Loader.Start(Stack.Tag)
|
|
||||||
AddHandler LoadingPickaxe.StateChanged, AddressOf FrmDownloadForge.Forge_StateChanged
|
|
||||||
AddHandler LoadingPickaxe.Click, AddressOf FrmDownloadForge.Forge_Click
|
|
||||||
Stack.Children.Add(LoadingPickaxe)
|
|
||||||
Case 6
|
Case 6
|
||||||
ForgeDownloadListItemPreload(Stack, Stack.Tag, AddressOf ForgeSave_Click, True)
|
ForgeDownloadListItemPreload(Stack, Stack.Tag, AddressOf ForgeSave_Click, True)
|
||||||
Case 8
|
Case 8
|
||||||
@@ -145,9 +137,6 @@
|
|||||||
Stack.Children.Add(McDownloadListItem(Data, AddressOf McDownloadMenuSave, True))
|
Stack.Children.Add(McDownloadListItem(Data, AddressOf McDownloadMenuSave, True))
|
||||||
Case 3
|
Case 3
|
||||||
Stack.Children.Add(OptiFineDownloadListItem(Data, AddressOf OptiFineSave_Click, True))
|
Stack.Children.Add(OptiFineDownloadListItem(Data, AddressOf OptiFineSave_Click, True))
|
||||||
Case 4
|
|
||||||
Stack.Children.Add(LiteLoaderDownloadListItem(Data, AddressOf FrmDownloadLiteLoader.DownloadStart, False))
|
|
||||||
Case 5
|
|
||||||
Case 6
|
Case 6
|
||||||
Stack.Children.Add(ForgeDownloadListItem(Data, AddressOf ForgeSave_Click, True))
|
Stack.Children.Add(ForgeDownloadListItem(Data, AddressOf ForgeSave_Click, True))
|
||||||
Case 7
|
Case 7
|
||||||
@@ -332,13 +321,8 @@
|
|||||||
SetValue(IsSwapedProperty, value)
|
SetValue(IsSwapedProperty, value)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Public Shared ReadOnly IsSwapedProperty As DependencyProperty = DependencyProperty.Register("IsSwaped", GetType(Boolean), GetType(MyCard), New PropertyMetadata(False, AddressOf OnIsSwapedPropertyChanged))
|
Public Shared ReadOnly IsSwapedProperty As DependencyProperty = DependencyProperty.Register("IsSwaped", GetType(Boolean), GetType(MyCard), New PropertyMetadata(False,
|
||||||
Private Shared Sub OnIsSwapedPropertyChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
Sub(sender, e) If sender IsNot Nothing AndAlso TypeOf sender Is MyCard Then CType(sender, MyCard).IsSwapped = CType(e.NewValue, Boolean)))
|
||||||
Dim self = TryCast(d, MyCard)
|
|
||||||
If self IsNot Nothing Then
|
|
||||||
self.IsSwapped = CType(e.NewValue, Boolean)
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Public Property SwapLogoRight As Boolean = False
|
Public Property SwapLogoRight As Boolean = False
|
||||||
Private IsMouseDown As Boolean = False
|
Private IsMouseDown As Boolean = False
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 与 Image 的 Source 类似。
|
''' 与 Image 的 Source 类似。
|
||||||
''' 若输入以 http 开头的字符串,则会尝试下载图片然后显示,图片会保存为本地缓存。
|
''' 若输入以 http 开头的字符串,则会尝试下载图片然后显示;若 EnableCache 设为 True,图片还会保存为本地缓存。
|
||||||
''' 支持 WebP 格式的图片。
|
''' 支持 WebP 格式的图片。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Shadows Property Source As String '覆写 Image 的 Source 属性
|
Public Shadows Property Source As String '覆写 Image 的 Source 属性
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString())))
|
Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString())))
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 当 Source 首次下载失败时,会从该备用地址加载图片。
|
''' 若 Source 是一个网络图片,该地址将作为第二下载源。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Property FallbackSource As String
|
Public Property FallbackSource As String
|
||||||
Get
|
Get
|
||||||
@@ -111,74 +111,36 @@
|
|||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
'从缓存加载网络图片
|
'从缓存加载网络图片
|
||||||
Dim Url As String = Source
|
|
||||||
Dim Retried As Boolean = False
|
|
||||||
Dim TempPath As String = GetTempPath(Url)
|
|
||||||
Dim TempFile As New FileInfo(TempPath)
|
|
||||||
Dim EnableCache As Boolean = Me.EnableCache
|
Dim EnableCache As Boolean = Me.EnableCache
|
||||||
|
Dim TempPath As String = GetTempPath(Source) & If(EnableCache, "", GetUuid()) '不启用缓存时加上随机字符串,避免冲突
|
||||||
|
Dim TempFile As New FileInfo(TempPath)
|
||||||
If EnableCache AndAlso TempFile.Exists Then
|
If EnableCache AndAlso TempFile.Exists Then
|
||||||
ActualSource = TempPath
|
ActualSource = TempPath
|
||||||
If (Date.Now - TempFile.LastWriteTime) < FileCacheExpiredTime Then Return '无需刷新缓存
|
If (Date.Now - TempFile.LastWriteTime) < FileCacheExpiredTime Then Return '无需刷新缓存
|
||||||
End If
|
End If
|
||||||
RunInNewThread(
|
RunInNewThread(
|
||||||
Sub()
|
Sub()
|
||||||
Dim TempDownloadingPath As String = Nothing
|
|
||||||
Try
|
Try
|
||||||
RetryStart:
|
RetryStart:
|
||||||
'下载
|
'下载
|
||||||
ActualSource = LoadingSource '显示加载中图片
|
ActualSource = LoadingSource '显示加载中的占位图片
|
||||||
TempDownloadingPath = TempPath & RandomInteger(0, 10000000)
|
NetDownloadByLoader(
|
||||||
Directory.CreateDirectory(GetPathFromFullPath(TempPath)) '重新实现下载,以避免携带 Header(#5072)
|
If(String.IsNullOrEmpty(FallbackSource), {Source}, {Source, FallbackSource}),
|
||||||
Using Client As New Net.WebClient
|
TempPath, SimulateBrowserHeaders:=True)
|
||||||
Client.DownloadFile(Url, TempDownloadingPath)
|
If EnableCache Then
|
||||||
End Using
|
|
||||||
If Url <> Source AndAlso Url <> FallbackSource Then
|
|
||||||
'已经更换了地址
|
|
||||||
File.Delete(TempDownloadingPath)
|
|
||||||
ElseIf EnableCache Then
|
|
||||||
'保存缓存并显示
|
'保存缓存并显示
|
||||||
If File.Exists(TempPath) Then File.Delete(TempPath)
|
|
||||||
FileSystem.Rename(TempDownloadingPath, TempPath)
|
|
||||||
RunInUi(Sub() ActualSource = TempPath)
|
RunInUi(Sub() ActualSource = TempPath)
|
||||||
Else
|
Else
|
||||||
'直接显示
|
'直接显示
|
||||||
RunInUiWait(Sub() ActualSource = TempDownloadingPath)
|
RunInUiWait(Sub() ActualSource = TempPath)
|
||||||
File.Delete(TempDownloadingPath)
|
File.Delete(TempPath)
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Try
|
Try
|
||||||
If TempPath IsNot Nothing Then File.Delete(TempPath)
|
If TempPath IsNot Nothing Then File.Delete(TempPath)
|
||||||
If TempDownloadingPath IsNot Nothing Then File.Delete(TempDownloadingPath)
|
|
||||||
Catch
|
Catch
|
||||||
End Try
|
End Try
|
||||||
If Not Retried Then
|
Log(ex, $"下载图片失败", LogLevel.Hint)
|
||||||
'更换备用地址
|
|
||||||
Log(ex, $"下载图片可重试地失败({Url})", LogLevel.Developer)
|
|
||||||
Retried = True
|
|
||||||
Url = If(FallbackSource, Source)
|
|
||||||
'空
|
|
||||||
If Url Is Nothing Then
|
|
||||||
ActualSource = Nothing
|
|
||||||
Return
|
|
||||||
End If
|
|
||||||
'本地图片
|
|
||||||
If Not Url.StartsWithF("http") Then
|
|
||||||
ActualSource = Url
|
|
||||||
Return
|
|
||||||
End If
|
|
||||||
'从缓存加载网络图片
|
|
||||||
TempPath = GetTempPath(Url)
|
|
||||||
TempFile = New FileInfo(TempPath)
|
|
||||||
If EnableCache AndAlso TempFile.Exists() Then
|
|
||||||
ActualSource = TempPath
|
|
||||||
If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Return '无需刷新缓存
|
|
||||||
End If
|
|
||||||
'下载
|
|
||||||
If Source = Url Then Thread.Sleep(1000) '延迟 1s 重试
|
|
||||||
GoTo RetryStart
|
|
||||||
Else
|
|
||||||
Log(ex, $"下载图片失败({Url})", LogLevel.Hint)
|
|
||||||
End If
|
|
||||||
End Try
|
End Try
|
||||||
End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal)
|
End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal)
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -79,11 +79,7 @@ Public Class MyLoading
|
|||||||
Do While Ex.InnerException IsNot Nothing
|
Do While Ex.InnerException IsNot Nothing
|
||||||
Ex = Ex.InnerException
|
Ex = Ex.InnerException
|
||||||
Loop
|
Loop
|
||||||
LabText.Text = StrTrim(Ex.Message)
|
LabText.Text = If(Ex.IsNetworkRelated(), "网络环境不佳,请稍后再试,或使用 VPN 改善网络环境", StrTrim(Ex.Message))
|
||||||
If {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
|
|
||||||
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) LabText.Text.Contains(s)) Then
|
|
||||||
LabText.Text = "网络环境不佳,请稍后重试,或使用 VPN 以改善网络环境"
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
LabText.Text = TextError
|
LabText.Text = TextError
|
||||||
|
|||||||
@@ -3,28 +3,15 @@
|
|||||||
Private Uuid As Integer = GetUuid()
|
Private Uuid As Integer = GetUuid()
|
||||||
|
|
||||||
'执行逐个进入动画的控件
|
'执行逐个进入动画的控件
|
||||||
Public AnimatedControl As FrameworkElement
|
Public Property AnimatedControl As String '需要在 Loaded 之后才能获取到控件,所以不能用 Binding 直接绑定(#6664)
|
||||||
Public Shared ReadOnly AnimatedControlProperty As DependencyProperty = DependencyProperty.RegisterAttached("AnimatedControl", GetType(String), GetType(MyPageLeft), New PropertyMetadata(Nothing, AddressOf OnAnimatedControlChanged))
|
Get
|
||||||
|
Return GetValue(AnimatedControlProperty)
|
||||||
Public Shared Sub SetAnimatedControl(obj As DependencyObject, value As String)
|
End Get
|
||||||
obj.SetValue(AnimatedControlProperty, value)
|
Set(value As String)
|
||||||
End Sub
|
SetValue(AnimatedControlProperty, value)
|
||||||
|
End Set
|
||||||
Private Shared Sub OnAnimatedControlChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
End Property
|
||||||
Dim control = TryCast(d, MyPageLeft)
|
Public Shared ReadOnly AnimatedControlProperty As DependencyProperty = DependencyProperty.Register("AnimatedControl", GetType(String), GetType(MyPageLeft), New PropertyMetadata(Nothing))
|
||||||
If control IsNot Nothing Then
|
|
||||||
Dim handler As RoutedEventHandler
|
|
||||||
handler = Sub(sender, args)
|
|
||||||
Dim targetName = CStr(e.NewValue)
|
|
||||||
Dim target = TryCast(control.FindName(targetName), FrameworkElement)
|
|
||||||
If target IsNot Nothing Then
|
|
||||||
control.AnimatedControl = target
|
|
||||||
End If
|
|
||||||
RemoveHandler control.Loaded, handler
|
|
||||||
End Sub
|
|
||||||
AddHandler control.Loaded, handler
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Public Sub TriggerShowAnimation()
|
Public Sub TriggerShowAnimation()
|
||||||
If AnimatedControl Is Nothing Then
|
If AnimatedControl Is Nothing Then
|
||||||
@@ -97,7 +84,7 @@
|
|||||||
'遍历获取所有需要生成动画的控件
|
'遍历获取所有需要生成动画的控件
|
||||||
Private Function GetAllAnimControls(Optional IgnoreInvisibility As Boolean = False) As List(Of FrameworkElement)
|
Private Function GetAllAnimControls(Optional IgnoreInvisibility As Boolean = False) As List(Of FrameworkElement)
|
||||||
Dim AllControls As New List(Of FrameworkElement)
|
Dim AllControls As New List(Of FrameworkElement)
|
||||||
GetAllAnimControls(AnimatedControl, AllControls, IgnoreInvisibility)
|
GetAllAnimControls(FindName(AnimatedControl), AllControls, IgnoreInvisibility)
|
||||||
Return AllControls
|
Return AllControls
|
||||||
End Function
|
End Function
|
||||||
Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
|
Private Sub GetAllAnimControls(Element As FrameworkElement, ByRef AllControls As List(Of FrameworkElement), IgnoreInvisibility As Boolean)
|
||||||
@@ -118,7 +105,3 @@
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|
||||||
Public Interface IRefreshable
|
|
||||||
Sub Refresh()
|
|
||||||
End Interface
|
|
||||||
@@ -3,29 +3,16 @@
|
|||||||
Public PageUuid As Integer = GetUuid()
|
Public PageUuid As Integer = GetUuid()
|
||||||
|
|
||||||
'“返回顶部” 按钮检测的滚动区域
|
'“返回顶部” 按钮检测的滚动区域
|
||||||
Public PanScroll As MyScrollViewer
|
Public Property PanScroll As String '需要在 Loaded 之后才能获取到控件,所以不能用 Binding 直接绑定(#6664)
|
||||||
|
Get
|
||||||
|
Return GetValue(PanScrollProperty)
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
SetValue(PanScrollProperty, value)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
Private Shared ReadOnly PanScrollProperty =
|
Private Shared ReadOnly PanScrollProperty =
|
||||||
DependencyProperty.RegisterAttached("PanScroll", GetType(String), GetType(MyPageRight), New PropertyMetadata(Nothing, AddressOf OnPanScrollChanged))
|
DependencyProperty.Register("PanScroll", GetType(String), GetType(MyPageRight), New PropertyMetadata(Nothing))
|
||||||
|
|
||||||
Public Shared Sub SetPanScroll(obj As DependencyObject, value As String)
|
|
||||||
obj.SetValue(PanScrollProperty, value)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Shared Sub OnPanScrollChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
|
||||||
Dim control = TryCast(d, MyPageRight)
|
|
||||||
If control IsNot Nothing Then
|
|
||||||
Dim handler As RoutedEventHandler
|
|
||||||
handler = Sub(sender, args)
|
|
||||||
Dim targetName = CStr(e.NewValue)
|
|
||||||
Dim target = TryCast(control.FindName(targetName), FrameworkElement)
|
|
||||||
If target IsNot Nothing Then
|
|
||||||
control.PanScroll = target
|
|
||||||
End If
|
|
||||||
RemoveHandler control.Loaded, handler
|
|
||||||
End Sub
|
|
||||||
AddHandler control.Loaded, handler
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
'当前状态
|
'当前状态
|
||||||
Public Enum PageStates
|
Public Enum PageStates
|
||||||
|
|||||||
@@ -96,6 +96,14 @@ Public Class FormMain
|
|||||||
'3:BUG+ IMP* FEAT-
|
'3:BUG+ IMP* FEAT-
|
||||||
'2:BUG* IMP-
|
'2:BUG* IMP-
|
||||||
'1:BUG-
|
'1:BUG-
|
||||||
|
If LastVersion < 368 Then 'Snapshot 2.10.7
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "新增:允许在版本设置中设置禁止更新 Mod,以防整合包玩家误操作"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:网络与下载稳定性优化"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化:若整合包需要 PCL 不兼容的加载器,允许选择跳过它的安装"))
|
||||||
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "删除:由于已不再需要,删除手动安装包下载功能"))
|
||||||
|
FeatureCount += 19
|
||||||
|
BugCount += 28
|
||||||
|
End If
|
||||||
If LastVersion < 366 Then 'Snapshot 2.10.6
|
If LastVersion < 366 Then 'Snapshot 2.10.6
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:启用 MCIM 社区资源镜像源,以缓解社区资源难以下载的问题"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:启用 MCIM 社区资源镜像源,以缓解社区资源难以下载的问题"))
|
||||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:正版登录出错时无法给出正确的错误信息"))
|
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:正版登录出错时无法给出正确的错误信息"))
|
||||||
@@ -1025,18 +1033,12 @@ Public Class FormMain
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Enum PageSubType
|
Public Enum PageSubType
|
||||||
[Default] = 0
|
[Default] = 0
|
||||||
DownloadInstall = 1
|
DownloadInstall = 0
|
||||||
DownloadClient = 4
|
DownloadMod = 2
|
||||||
DownloadOptiFine = 5
|
DownloadPack = 3
|
||||||
DownloadForge = 6
|
DownloadDataPack = 4
|
||||||
DownloadNeoForge = 7
|
DownloadResourcePack = 5
|
||||||
DownloadFabric = 8
|
DownloadShader = 6
|
||||||
DownloadLiteLoader = 9
|
|
||||||
DownloadMod = 11
|
|
||||||
DownloadPack = 12
|
|
||||||
DownloadDataPack = 13
|
|
||||||
DownloadResourcePack = 14
|
|
||||||
DownloadShader = 15
|
|
||||||
SetupLaunch = 0
|
SetupLaunch = 0
|
||||||
SetupUI = 1
|
SetupUI = 1
|
||||||
SetupSystem = 2
|
SetupSystem = 2
|
||||||
@@ -1514,7 +1516,8 @@ Public Class FormMain
|
|||||||
End Function
|
End Function
|
||||||
Private Function BtnExtraBack_GetRealChild() As MyScrollViewer
|
Private Function BtnExtraBack_GetRealChild() As MyScrollViewer
|
||||||
If PanMainRight.Child Is Nothing OrElse TypeOf PanMainRight.Child IsNot MyPageRight Then Return Nothing
|
If PanMainRight.Child Is Nothing OrElse TypeOf PanMainRight.Child IsNot MyPageRight Then Return Nothing
|
||||||
Return CType(PanMainRight.Child, MyPageRight).PanScroll
|
Dim Page As MyPageRight = PanMainRight.Child
|
||||||
|
Return Page.FindName(Page.PanScroll)
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ Public Module ModBase
|
|||||||
#Region "声明"
|
#Region "声明"
|
||||||
|
|
||||||
'下列版本信息由更新器自动修改
|
'下列版本信息由更新器自动修改
|
||||||
Public Const VersionBaseName As String = "2.10.6" '不含分支前缀的显示用版本名
|
Public Const VersionBaseName As String = "2.10.7" '不含分支前缀的显示用版本名
|
||||||
Public Const VersionStandardCode As String = "2.10.6." & VersionBranchCode '标准格式的四段式版本号
|
Public Const VersionStandardCode As String = "2.10.7." & 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 = 367 'Release
|
Public Const VersionCode As Integer = 367 'Release
|
||||||
#Else
|
#Else
|
||||||
Public Const VersionCode As Integer = 366 'Snapshot
|
Public Const VersionCode As Integer = 368 'Snapshot
|
||||||
#End If
|
#End If
|
||||||
'自动生成的版本信息
|
'自动生成的版本信息
|
||||||
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
|
||||||
@@ -1283,7 +1283,7 @@ Re:
|
|||||||
Return Nothing
|
Return Nothing
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "检查文件出错")
|
Log(ex, "检查文件出错")
|
||||||
Return GetExceptionSummary(ex)
|
Return ex.GetBrief()
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
@@ -1329,6 +1329,14 @@ Re:
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function DeleteDirectory(Path As String, Optional IgnoreIssue As Boolean = False) As Integer
|
Public Function DeleteDirectory(Path As String, Optional IgnoreIssue As Boolean = False) As Integer
|
||||||
If Not Directory.Exists(Path) Then Return 0
|
If Not Directory.Exists(Path) Then Return 0
|
||||||
|
If Not Path.EndsWithF("\") Then Path &= "\"
|
||||||
|
If Path.EndsWith(":\") OrElse
|
||||||
|
Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\" OrElse
|
||||||
|
Path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\" OrElse
|
||||||
|
Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\" Then '#7030
|
||||||
|
Throw New UnauthorizedAccessException("这是重要的系统文件夹,无法删除:" & Path)
|
||||||
|
End If
|
||||||
|
'实际删除
|
||||||
Dim DeletedCount As Integer = 0
|
Dim DeletedCount As Integer = 0
|
||||||
Dim Files As String()
|
Dim Files As String()
|
||||||
Try
|
Try
|
||||||
@@ -1364,6 +1372,7 @@ RetryFile:
|
|||||||
RetryDir:
|
RetryDir:
|
||||||
Try
|
Try
|
||||||
Directory.Delete(Path, True)
|
Directory.Delete(Path, True)
|
||||||
|
Catch ex As DirectoryNotFoundException
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If Not RetriedDir AndAlso Not RunInUi() Then
|
If Not RetriedDir AndAlso Not RunInUi() Then
|
||||||
RetriedDir = True
|
RetriedDir = True
|
||||||
@@ -1420,10 +1429,10 @@ RetryDir:
|
|||||||
Public vbRQ As Char = Convert.ToChar(8221)
|
Public vbRQ As Char = Convert.ToChar(8221)
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 提取 Exception 的具体描述与堆栈。
|
''' 提取 Exception 与 Inner Exception 的详细描述与堆栈信息。返回内容总是多于一行。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="ShowAllStacks">是否必须显示所有堆栈。通常用于判定堆栈信息。</param>
|
''' <param name="ShowAllStacks">是否必须显示所有堆栈。通常用于判定堆栈信息。</param>
|
||||||
Public Function GetExceptionDetail(Ex As Exception, Optional ShowAllStacks As Boolean = False) As String
|
<Extension> Public Function GetDetail(Ex As Exception, Optional ShowAllStacks As Boolean = False) As String
|
||||||
If Ex Is Nothing Then Return "无可用错误信息!"
|
If Ex Is Nothing Then Return "无可用错误信息!"
|
||||||
|
|
||||||
'获取最底层的异常
|
'获取最底层的异常
|
||||||
@@ -1450,17 +1459,17 @@ RetryDir:
|
|||||||
Loop
|
Loop
|
||||||
|
|
||||||
'构造输出信息
|
'构造输出信息
|
||||||
Dim CommonReason As String = AnalyzeCommonReason(InnerEx, DescList)
|
Dim UsualReason As String = AnalyzeUsualReason(InnerEx, Ex, DescList)
|
||||||
If CommonReason Is Nothing Then
|
If UsualReason Is Nothing Then
|
||||||
Return DescList.Join(vbCrLf)
|
Return DescList.Join(vbCrLf)
|
||||||
Else
|
Else
|
||||||
Return CommonReason & vbCrLf & vbCrLf & "————————————" & vbCrLf & "详细错误信息:" & vbCrLf & DescList.Join(vbCrLf)
|
Return UsualReason & vbCrLf & vbCrLf & "————————————" & vbCrLf & "详细错误信息:" & vbCrLf & DescList.Join(vbCrLf)
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 提取 Exception 描述,汇总到一行。
|
''' 提取 Exception 与 Inner Exception 的描述,汇总到一行。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function GetExceptionSummary(Ex As Exception) As String
|
<Extension> Public Function GetBrief(Ex As Exception) As String
|
||||||
If Ex Is Nothing Then Return "无可用错误信息!"
|
If Ex Is Nothing Then Return "无可用错误信息!"
|
||||||
|
|
||||||
'获取最底层的异常
|
'获取最底层的异常
|
||||||
@@ -1479,28 +1488,27 @@ RetryDir:
|
|||||||
Dim Desc As String = Join(DescList, vbCrLf & "→ ")
|
Dim Desc As String = Join(DescList, vbCrLf & "→ ")
|
||||||
|
|
||||||
'构造输出信息
|
'构造输出信息
|
||||||
Dim CommonReason As String = AnalyzeCommonReason(InnerEx, DescList)
|
Dim UsualReason As String = AnalyzeUsualReason(InnerEx, Ex, DescList)
|
||||||
If CommonReason IsNot Nothing Then
|
If UsualReason IsNot Nothing Then
|
||||||
Return CommonReason & "详细错误:" & DescList.First
|
Return UsualReason & "详细错误:" & DescList.First
|
||||||
Else
|
Else
|
||||||
DescList.Reverse() '让最深层错误在最左边
|
DescList.Reverse() '让最深层错误在最左边
|
||||||
Return Join(DescList, " ← ")
|
Return Join(DescList, " ← ")
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Private Function AnalyzeCommonReason(InnerEx As Exception, DescList As List(Of String)) As String
|
Private Function AnalyzeUsualReason(InnerEx As Exception, OuterEx As Exception, DescList As List(Of String)) As String
|
||||||
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
|
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
|
||||||
Return "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。"
|
Return "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。"
|
||||||
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
|
ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then
|
||||||
Return "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
Return "PCL 的权限不足。请尝试右键 PCL 选择以管理员身份运行,或将目标从 C 盘或桌面挪到其他硬盘。"
|
||||||
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
||||||
Return "你的电脑运行内存不足,导致 PCL 无法继续运行。请在关闭一部分不需要的程序后再试。"
|
Return "你的电脑运行内存不足,导致 PCL 无法继续运行。请在关闭一部分不需要的程序后再试。"
|
||||||
ElseIf TypeOf InnerEx Is Runtime.InteropServices.COMException Then
|
ElseIf TypeOf InnerEx Is Runtime.InteropServices.COMException Then
|
||||||
Return "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
|
Return "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
|
||||||
ElseIf TypeOf InnerEx Is SocketException AndAlso DescList.Any(Function(l) l.Contains("WSAStartup")) Then
|
ElseIf TypeOf InnerEx Is SocketException AndAlso DescList.Any(Function(l) l.Contains("WSAStartup")) Then
|
||||||
Return "请尝试卸载中国移动云盘,然后再试。"
|
Return "请尝试卸载中国移动云盘,然后再试。"
|
||||||
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
|
ElseIf OuterEx.IsNetworkRelated() Then
|
||||||
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) DescList.Any(Function(l) l.Contains(s))) Then
|
Return "你的网络环境不佳,请稍后再试,或使用 VPN 改善网络环境。"
|
||||||
Return "你的网络环境不佳,导致难以连接到服务器。请稍后重试,或使用 VPN 以改善网络环境。"
|
|
||||||
Else
|
Else
|
||||||
Return Nothing
|
Return Nothing
|
||||||
End If
|
End If
|
||||||
@@ -2981,10 +2989,10 @@ Retry:
|
|||||||
If TypeOf Ex Is ThreadInterruptedException Then Return
|
If TypeOf Ex Is ThreadInterruptedException Then Return
|
||||||
|
|
||||||
'获取错误信息
|
'获取错误信息
|
||||||
Dim ExFull As String = Desc & ":" & GetExceptionDetail(Ex)
|
Dim ExFull As String = $"{Desc}:{Ex.GetDetail()}"
|
||||||
|
|
||||||
'输出日志
|
'输出日志
|
||||||
Dim AppendText As String = $"[{GetTimeNow()}] <{If(Thread.CurrentThread.Name = "", "主线程", Thread.CurrentThread.Name)}> {Desc}:{GetExceptionDetail(Ex, True)}{vbCrLf}" '减轻同步锁占用
|
Dim AppendText As String = $"[{GetTimeNow()}] <{If(Thread.CurrentThread.Name = "", "主线程", Thread.CurrentThread.Name)}> {Desc}:{Ex.GetDetail(True)}{vbCrLf}" '减轻同步锁占用
|
||||||
If ModeDebug Then
|
If ModeDebug Then
|
||||||
SyncLock LogListLock
|
SyncLock LogListLock
|
||||||
LogList.Append(AppendText)
|
LogList.Append(AppendText)
|
||||||
@@ -3002,19 +3010,19 @@ Retry:
|
|||||||
Case LogLevel.Normal
|
Case LogLevel.Normal
|
||||||
#If DEBUG Then
|
#If DEBUG Then
|
||||||
Case LogLevel.Developer
|
Case LogLevel.Developer
|
||||||
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
|
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
|
||||||
Hint("[开发者模式] " & ExLine, HintType.Info, False)
|
Hint("[开发者模式] " & ExLine, HintType.Info, False)
|
||||||
Case LogLevel.Debug
|
Case LogLevel.Debug
|
||||||
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
|
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
|
||||||
Hint("[调试模式] " & ExLine, HintType.Info, False)
|
Hint("[调试模式] " & ExLine, HintType.Info, False)
|
||||||
#Else
|
#Else
|
||||||
Case LogLevel.Developer
|
Case LogLevel.Developer
|
||||||
Case LogLevel.Debug
|
Case LogLevel.Debug
|
||||||
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
|
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
|
||||||
If ModeDebug Then Hint("[调试模式] " & ExLine, HintType.Info, False)
|
If ModeDebug Then Hint("[调试模式] " & ExLine, HintType.Info, False)
|
||||||
#End If
|
#End If
|
||||||
Case LogLevel.Hint
|
Case LogLevel.Hint
|
||||||
Dim ExLine As String = Desc & ":" & GetExceptionSummary(Ex)
|
Dim ExLine As String = Desc & ":" & Ex.GetBrief()
|
||||||
Hint(ExLine, HintType.Critical, False)
|
Hint(ExLine, HintType.Critical, False)
|
||||||
Case LogLevel.Msgbox
|
Case LogLevel.Msgbox
|
||||||
MyMsgBox(ExFull, Title, IsWarn:=True)
|
MyMsgBox(ExFull, Title, IsWarn:=True)
|
||||||
@@ -3093,8 +3101,8 @@ Retry:
|
|||||||
Url &= "&" & WebUtility.UrlEncode(Datas(i)) & "=" & WebUtility.UrlEncode(Datas(i + 1).Replace(vbCrLf, vbLf))
|
Url &= "&" & WebUtility.UrlEncode(Datas(i)) & "=" & WebUtility.UrlEncode(Datas(i + 1).Replace(vbCrLf, vbLf))
|
||||||
Next
|
Next
|
||||||
NetRequestByClient(Url, MakeLog:=False)
|
NetRequestByClient(Url, MakeLog:=False)
|
||||||
Catch
|
Catch ex As Exception
|
||||||
Log("[System] 匿名数据上报失败", LogLevel.Debug)
|
Log(ex, "匿名数据上报失败")
|
||||||
End Try
|
End Try
|
||||||
End Sub, "Telemetry", ThreadPriority.Lowest)
|
End Sub, "Telemetry", ThreadPriority.Lowest)
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -290,11 +290,12 @@
|
|||||||
'检验输入以确定情况
|
'检验输入以确定情况
|
||||||
If IsForceRestart Then Return True '强制要求重启
|
If IsForceRestart Then Return True '强制要求重启
|
||||||
If ((Input Is Nothing) <> (Me.Input Is Nothing)) OrElse (Input IsNot Nothing AndAlso Not Input.Equals(Me.Input)) Then Return True '输入不同
|
If ((Input Is Nothing) <> (Me.Input Is Nothing)) OrElse (Input IsNot Nothing AndAlso Not Input.Equals(Me.Input)) Then Return True '输入不同
|
||||||
If (State = LoadState.Loading OrElse State = LoadState.Finished) AndAlso '正在加载或已结束
|
If (State = LoadState.Loading OrElse State = LoadState.Finished) AndAlso '正在加载或已结束…
|
||||||
(IgnoreReloadTimeout OrElse ReloadTimeout = -1 OrElse LastFinishedTime = 0 OrElse GetTimeTick() - LastFinishedTime < ReloadTimeout) Then '没有超时
|
(IgnoreReloadTimeout OrElse ReloadTimeout = -1 OrElse
|
||||||
Return False '则不重试
|
LastFinishedTime = 0 OrElse GetTimeTick() - LastFinishedTime < ReloadTimeout) Then '…且没有超时…
|
||||||
|
Return False '…则不重试
|
||||||
Else
|
Else
|
||||||
Return True '需要开始
|
Return True '否则需要重启
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Public Overrides Sub Start(Optional Input As Object = Nothing, Optional IsForceRestart As Boolean = False)
|
Public Overrides Sub Start(Optional Input As Object = Nothing, Optional IsForceRestart As Boolean = False)
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
Imports System.Net.Http.Headers
|
Imports System.Net.Http.Headers
|
||||||
|
Imports System.Net.Sockets
|
||||||
|
Imports System.Runtime.CompilerServices
|
||||||
|
Imports System.Security.Policy
|
||||||
Imports System.Threading.Tasks
|
Imports System.Threading.Tasks
|
||||||
Imports CacheCow.Client
|
Imports CacheCow.Client
|
||||||
|
|
||||||
@@ -11,15 +14,28 @@ Public Module ModNet
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function NetRequestByClient(Url As String, Optional Method As HttpMethod = Nothing,
|
Public Function NetRequestByClient(Url As String, Optional Method As HttpMethod = Nothing,
|
||||||
Optional Content As Object = Nothing, Optional ContentType As String = Nothing, Optional Accept As String = "*/*",
|
Optional Content As Object = Nothing, Optional ContentType As String = Nothing, Optional Accept As String = "*/*",
|
||||||
Optional Timeout As Integer = 25000, Optional Headers As String(,) = Nothing,
|
Optional Timeout As Integer = 25000, Optional Headers As String(,) = Nothing, Optional RequireJson As Boolean = False,
|
||||||
Optional Encoding As Encoding = Nothing, Optional UseBrowserUserAgent As Boolean = False, Optional MakeLog As Boolean = True) As String
|
Optional Encoding As Encoding = Nothing, Optional SimulateBrowserHeaders As Boolean = False, Optional MakeLog As Boolean = True) As String
|
||||||
If Method Is Nothing Then Method = HttpMethod.Get
|
If Method Is Nothing Then Method = HttpMethod.Get
|
||||||
If MakeLog Then Log("[Net] 发起网络请求(" & Method.Method & "," & Url & "),最大超时 " & Timeout)
|
If MakeLog Then Log("[Net] 发起网络请求(" & Method.Method & "," & Url & "),最大超时 " & Timeout)
|
||||||
Try
|
Try
|
||||||
Dim HeaderDictionary = If(Headers, {}).ToDictionary
|
Dim HeaderDictionary = If(Headers, {}).ToDictionary
|
||||||
If ContentType IsNot Nothing Then HeaderDictionary("Content-Type") = ContentType
|
If ContentType IsNot Nothing Then HeaderDictionary("Content-Type") = ContentType
|
||||||
If Accept IsNot Nothing Then HeaderDictionary("Accept") = Accept
|
If Accept IsNot Nothing Then HeaderDictionary("Accept") = Accept
|
||||||
Return If(Encoding, Encoding.UTF8).GetString(SendRequest(Url, Method, Content, HeaderDictionary, Timeout:=Timeout, Encoding:=Encoding, UseBrowserUserAgent:=UseBrowserUserAgent))
|
Dim Result = If(Encoding, Encoding.UTF8).GetString(SendRequest(Url, Method, Content, HeaderDictionary, Timeout:=Timeout, Encoding:=Encoding, SimulateBrowserHeaders:=SimulateBrowserHeaders))
|
||||||
|
'检查结果是否为完整 JSON(在 #6683 中可能返回空,在被 GFW 截断时可能不完整)
|
||||||
|
'在此处检查并报错,可以让 NetRequestByClientRetry 等方法进行重试
|
||||||
|
If RequireJson Then
|
||||||
|
Result = Result.Trim((vbCrLf & " ").ToCharArray) 'Authlib-Injector 的结果会在末尾附带一个空行
|
||||||
|
If Not (Result.StartsWithF("{") AndAlso Result.EndsWithF("}")) AndAlso
|
||||||
|
Not (Result.StartsWithF("[") AndAlso Result.EndsWithF("]")) Then
|
||||||
|
Throw New FormatException("返回结果并非 JSON 格式:" &
|
||||||
|
If(Result.Length > 2000, Result.Substring(0, 1000) & "..." & Result.Substring(Result.Length - 1000), Result))
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return Result
|
||||||
|
Catch ex As FormatException
|
||||||
|
Throw
|
||||||
Catch ex As ThreadInterruptedException
|
Catch ex As ThreadInterruptedException
|
||||||
Throw
|
Throw
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -34,8 +50,8 @@ Public Module ModNet
|
|||||||
''' <param name="BackupUrl">如果第一次尝试失败,换用的备用 URL。</param>
|
''' <param name="BackupUrl">如果第一次尝试失败,换用的备用 URL。</param>
|
||||||
Public Function NetRequestByClientRetry(Url As String, Optional Method As HttpMethod = Nothing, Optional BackupUrl As String = Nothing,
|
Public Function NetRequestByClientRetry(Url As String, Optional Method As HttpMethod = Nothing, Optional BackupUrl As String = Nothing,
|
||||||
Optional Content As Object = Nothing, Optional ContentType As String = Nothing, Optional Accept As String = "*/*",
|
Optional Content As Object = Nothing, Optional ContentType As String = Nothing, Optional Accept As String = "*/*",
|
||||||
Optional Headers As String(,) = Nothing,
|
Optional Headers As String(,) = Nothing, Optional RequireJson As Boolean = False,
|
||||||
Optional Encoding As Encoding = Nothing, Optional UseBrowserUserAgent As Boolean = False) As String
|
Optional Encoding As Encoding = Nothing, Optional SimulateBrowserHeaders As Boolean = False) As String
|
||||||
Dim RetryCount As Integer = 0
|
Dim RetryCount As Integer = 0
|
||||||
Dim RetryException As Exception = Nothing
|
Dim RetryException As Exception = Nothing
|
||||||
Dim StartTime As Long = GetTimeTick()
|
Dim StartTime As Long = GetTimeTick()
|
||||||
@@ -43,15 +59,15 @@ Public Module ModNet
|
|||||||
Retry:
|
Retry:
|
||||||
Select Case RetryCount
|
Select Case RetryCount
|
||||||
Case 0 '正常尝试
|
Case 0 '正常尝试
|
||||||
Return NetRequestByClient(Url, Method, Content, ContentType, Accept, 10000, Headers, Encoding, UseBrowserUserAgent)
|
Return NetRequestByClient(Url, Method, Content, ContentType, Accept, 10000, Headers, RequireJson, Encoding, SimulateBrowserHeaders)
|
||||||
Case 1 '慢速重试
|
Case 1 '慢速重试
|
||||||
Thread.Sleep(500)
|
Thread.Sleep(500)
|
||||||
Return NetRequestByClient(Url, Method, Content, ContentType, Accept, 30000, Headers, Encoding, UseBrowserUserAgent)
|
Return NetRequestByClient(Url, Method, Content, ContentType, Accept, 30000, Headers, RequireJson, Encoding, SimulateBrowserHeaders)
|
||||||
Case Else '快速重试
|
Case Else '快速重试
|
||||||
If GetTimeTick() - StartTime > 5500 Then
|
If GetTimeTick() - StartTime > 5500 Then
|
||||||
'若前两次加载耗费 5 秒以上,才进行重试
|
'若前两次加载耗费 5 秒以上,才进行重试
|
||||||
Thread.Sleep(500)
|
Thread.Sleep(500)
|
||||||
Return NetRequestByClient(Url, Method, Content, ContentType, Accept, 4000, Headers, Encoding, UseBrowserUserAgent)
|
Return NetRequestByClient(Url, Method, Content, ContentType, Accept, 4000, Headers, RequireJson, Encoding, SimulateBrowserHeaders)
|
||||||
Else
|
Else
|
||||||
Throw RetryException
|
Throw RetryException
|
||||||
End If
|
End If
|
||||||
@@ -78,8 +94,8 @@ Retry:
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function NetRequestByClientMultiple(Url As String, Optional Method As HttpMethod = Nothing, Optional ThreadCount As Integer = 3,
|
Public Function NetRequestByClientMultiple(Url As String, Optional Method As HttpMethod = Nothing, Optional ThreadCount As Integer = 3,
|
||||||
Optional Content As Object = Nothing, Optional ContentType As String = Nothing, Optional Accept As String = "*/*",
|
Optional Content As Object = Nothing, Optional ContentType As String = Nothing, Optional Accept As String = "*/*",
|
||||||
Optional Headers As String(,) = Nothing, Optional Timeout As Integer = 25000,
|
Optional Headers As String(,) = Nothing, Optional RequireJson As Boolean = False, Optional Timeout As Integer = 25000,
|
||||||
Optional Encoding As Encoding = Nothing, Optional UseBrowserUserAgent As Boolean = False) As String
|
Optional Encoding As Encoding = Nothing, Optional SimulateBrowserHeaders As Boolean = False) As String
|
||||||
Dim Threads As New List(Of Thread)
|
Dim Threads As New List(Of Thread)
|
||||||
Dim RequestResult = Nothing
|
Dim RequestResult = Nothing
|
||||||
Dim RequestEx As Exception = Nothing
|
Dim RequestEx As Exception = Nothing
|
||||||
@@ -88,7 +104,7 @@ Retry:
|
|||||||
Dim th As New Thread(
|
Dim th As New Thread(
|
||||||
Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
RequestResult = NetRequestByClient(Url, Method, Content, ContentType, Accept, Timeout, Headers, Encoding, UseBrowserUserAgent)
|
RequestResult = NetRequestByClient(Url, Method, Content, ContentType, Accept, Timeout, Headers, RequireJson, Encoding, SimulateBrowserHeaders)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
FailCount += 1
|
FailCount += 1
|
||||||
RequestEx = ex
|
RequestEx = ex
|
||||||
@@ -127,16 +143,16 @@ RequestFinished:
|
|||||||
''' 以多线程下载网页文件的方式获取内容。
|
''' 以多线程下载网页文件的方式获取内容。
|
||||||
''' 不支持缓存协商;若需缓存协商,需要换用 NetRequestByClient。
|
''' 不支持缓存协商;若需缓存协商,需要换用 NetRequestByClient。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function NetRequestByLoader(Url As String, Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional UseBrowserUserAgent As Boolean = False) As String
|
Public Function NetRequestByLoader(Url As String, Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional SimulateBrowserHeaders As Boolean = False) As String
|
||||||
Return NetRequestByLoader({Url}, Timeout, IsJson, UseBrowserUserAgent)
|
Return NetRequestByLoader({Url}, Timeout, IsJson, SimulateBrowserHeaders)
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 以多线程下载网页文件的方式获取内容。
|
''' 以多线程下载网页文件的方式获取内容。
|
||||||
''' 不支持缓存协商;若需缓存协商,需要换用 NetRequestByClient。
|
''' 不支持缓存协商;若需缓存协商,需要换用 NetRequestByClient。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function NetRequestByLoader(Urls As IEnumerable(Of String), Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional UseBrowserUserAgent As Boolean = False) As String
|
Public Function NetRequestByLoader(Urls As IEnumerable(Of String), Optional Timeout As Integer = 45000, Optional IsJson As Boolean = False, Optional SimulateBrowserHeaders As Boolean = False) As String
|
||||||
Dim Temp As String = RequestTaskTempFolder() & "download.txt"
|
Dim Temp As String = RequestTaskTempFolder() & "download.txt"
|
||||||
Dim NewTask As New LoaderDownload("源码获取 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile(Urls, Temp, New FileChecker With {.IsJson = IsJson}, UseBrowserUserAgent)})
|
Dim NewTask As New LoaderDownload("源码获取 " & GetUuid() & "#", New List(Of NetFile) From {New NetFile(Urls, Temp, New FileChecker With {.IsJson = IsJson}, SimulateBrowserHeaders)})
|
||||||
Try
|
Try
|
||||||
NewTask.WaitForExitTime(Timeout, TimeoutMessage:="连接服务器超时(第一下载源:" & Urls.First & ")")
|
NewTask.WaitForExitTime(Timeout, TimeoutMessage:="连接服务器超时(第一下载源:" & Urls.First & ")")
|
||||||
NetRequestByLoader = ReadFile(Temp)
|
NetRequestByLoader = ReadFile(Temp)
|
||||||
@@ -154,7 +170,7 @@ RequestFinished:
|
|||||||
''' 通过网络请求直接下载小文件,若文件已存在将被覆盖。
|
''' 通过网络请求直接下载小文件,若文件已存在将被覆盖。
|
||||||
''' 不建议用于下载大文件。
|
''' 不建议用于下载大文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Sub NetDownloadByClient(Url As String, LocalPath As String)
|
Public Sub NetDownloadByClient(Url As String, LocalPath As String, Optional SimulateBrowserHeaders As Boolean = False)
|
||||||
Log($"[Net] 通过网络请求直接下载小文件:{Url} → {LocalPath}")
|
Log($"[Net] 通过网络请求直接下载小文件:{Url} → {LocalPath}")
|
||||||
'初始化文件路径
|
'初始化文件路径
|
||||||
Try
|
Try
|
||||||
@@ -165,7 +181,7 @@ RequestFinished:
|
|||||||
End Try
|
End Try
|
||||||
'下载
|
'下载
|
||||||
Try
|
Try
|
||||||
File.WriteAllBytes(LocalPath, SendRequest(Url, HttpMethod.Get))
|
File.WriteAllBytes(LocalPath, SendRequest(Url, HttpMethod.Get, SimulateBrowserHeaders:=SimulateBrowserHeaders))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
File.Delete(LocalPath)
|
File.Delete(LocalPath)
|
||||||
Throw New WebException($"通过网络请求直接下载小文件失败({LocalPath})", ex)
|
Throw New WebException($"通过网络请求直接下载小文件失败({LocalPath})", ex)
|
||||||
@@ -175,16 +191,16 @@ RequestFinished:
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 通过多线程下载引擎下载文件。
|
''' 通过多线程下载引擎下载文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Sub NetDownloadByLoader(Url As String, LocalPath As String, Optional LoaderToSyncProgress As LoaderBase = Nothing, Optional Check As FileChecker = Nothing, Optional UseBrowserUserAgent As Boolean = False)
|
Public Sub NetDownloadByLoader(Url As String, LocalPath As String, Optional LoaderToSyncProgress As LoaderBase = Nothing, Optional Check As FileChecker = Nothing, Optional SimulateBrowserHeaders As Boolean = False)
|
||||||
NetDownloadByLoader({Url}, LocalPath, LoaderToSyncProgress, Check, UseBrowserUserAgent)
|
NetDownloadByLoader({Url}, LocalPath, LoaderToSyncProgress, Check, SimulateBrowserHeaders)
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 通过多线程下载引擎下载文件。
|
''' 通过多线程下载引擎下载文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="Urls">文件的 Url 列表。</param>
|
''' <param name="Urls">文件的 Url 列表。</param>
|
||||||
''' <param name="LocalPath">下载的本地地址。</param>
|
''' <param name="LocalPath">下载的本地地址。</param>
|
||||||
Public Sub NetDownloadByLoader(Urls As IEnumerable(Of String), LocalPath As String, Optional LoaderToSyncProgress As LoaderBase = Nothing, Optional Check As FileChecker = Nothing, Optional UseBrowserUserAgent As Boolean = False)
|
Public Sub NetDownloadByLoader(Urls As IEnumerable(Of String), LocalPath As String, Optional LoaderToSyncProgress As LoaderBase = Nothing, Optional Check As FileChecker = Nothing, Optional SimulateBrowserHeaders As Boolean = False)
|
||||||
Dim NewTask As New LoaderDownload($"文件下载 {GetUuid()}#", New List(Of NetFile) From {New NetFile(Urls, LocalPath, Check, UseBrowserUserAgent)})
|
Dim NewTask As New LoaderDownload($"文件下载 {GetUuid()}#", New List(Of NetFile) From {New NetFile(Urls, LocalPath, Check, SimulateBrowserHeaders)})
|
||||||
Try
|
Try
|
||||||
NewTask.WaitForExit(LoaderToSyncProgress:=LoaderToSyncProgress)
|
NewTask.WaitForExit(LoaderToSyncProgress:=LoaderToSyncProgress)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -201,36 +217,37 @@ RequestFinished:
|
|||||||
'基础请求函数
|
'基础请求函数
|
||||||
Private Function SendRequest(Url As String, Method As HttpMethod,
|
Private Function SendRequest(Url As String, Method As HttpMethod,
|
||||||
Optional Content As Object = Nothing, Optional Headers As Dictionary(Of String, String) = Nothing,
|
Optional Content As Object = Nothing, Optional Headers As Dictionary(Of String, String) = Nothing,
|
||||||
Optional UseBrowserUserAgent As Boolean = False, Optional Timeout As Integer = 25000, Optional Encoding As Encoding = Nothing) As Byte()
|
Optional SimulateBrowserHeaders As Boolean = False, Optional Timeout As Integer = 25000, Optional Encoding As Encoding = Nothing) As Byte()
|
||||||
If RunInUi() AndAlso Not Url.Contains("//127.") Then Throw New Exception("在 UI 线程执行了网络请求")
|
If RunInUi() AndAlso Not Url.Contains("//127.") Then Throw New Exception("在 UI 线程执行了网络请求")
|
||||||
Dim Request As HttpRequestMessage = Nothing, CancelToken As CancellationTokenSource = Nothing, Response As HttpResponseMessage = Nothing
|
Dim Request As HttpRequestMessage = Nothing, CancelToken As CancellationTokenSource = Nothing,
|
||||||
|
Response As HttpResponseMessage = Nothing, HostIp As String = Nothing
|
||||||
Try
|
Try
|
||||||
Static Client As HttpClient = ClientExtensions.CreateClient(New FileCacheStore.FileStore(PathTemp & "Cache/Http/"), New HttpClientHandler With {
|
|
||||||
.AutomaticDecompression = DecompressionMethods.Deflate Or DecompressionMethods.GZip Or DecompressionMethods.None,
|
|
||||||
.UseCookies = False '不设为 False 就不能从 Header 手动传入 Cookies
|
|
||||||
})
|
|
||||||
Url = SecretCdnSign(Url)
|
Url = SecretCdnSign(Url)
|
||||||
Request = New HttpRequestMessage(Method, Url)
|
Request = New HttpRequestMessage(Method, Url)
|
||||||
'写入 Content
|
'写入 Content
|
||||||
If Content IsNot Nothing AndAlso Request.Method <> HttpMethod.Get AndAlso Request.Method <> HttpMethod.Head Then
|
If Content IsNot Nothing AndAlso Request.Method <> HttpMethod.Get AndAlso Request.Method <> HttpMethod.Head Then
|
||||||
Dim Bytes As Byte() = If(TypeOf Content Is Byte(), Content, If(Encoding, Encoding.UTF8).GetBytes(Content.ToString))
|
If TypeOf Content Is HttpContent Then
|
||||||
Request.Content = New ByteArrayContent(Bytes)
|
Request.Content = DirectCast(Content, HttpContent)
|
||||||
Request.Content.Headers.ContentLength = Bytes.Length
|
ElseIf TypeOf Content Is Byte() Then
|
||||||
|
Request.Content = New ByteArrayContent(DirectCast(Content, Byte()))
|
||||||
|
ElseIf Content IsNot Nothing Then
|
||||||
|
Request.Content = New ByteArrayContent(If(Encoding, Encoding.UTF8).GetBytes(Content.ToString()))
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
'写入 Headers
|
'写入 Headers
|
||||||
If Headers IsNot Nothing Then
|
For Each Header In If(Headers, New Dictionary(Of String, String))
|
||||||
For Each Header In Headers
|
|
||||||
If Header.Key.ToLower = "content-type" Then
|
If Header.Key.ToLower = "content-type" Then
|
||||||
Request.Content?.Headers.TryAddWithoutValidation(Header.Key, Header.Value)
|
Request.Content?.Headers.TryAddWithoutValidation(Header.Key, Header.Value)
|
||||||
Else
|
Else
|
||||||
Request.Headers.Add(Header.Key, Header.Value)
|
Request.Headers.Add(Header.Key, Header.Value)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
SecretHeadersSign(Url, Request, SimulateBrowserHeaders)
|
||||||
SecretHeadersSign(Url, Request, UseBrowserUserAgent)
|
'DNS 解析
|
||||||
'发送请求
|
|
||||||
CancelToken = New CancellationTokenSource(Timeout)
|
CancelToken = New CancellationTokenSource(Timeout)
|
||||||
Response = Client.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetAwaiter().GetResult()
|
HostIp = DnsLookup(Request, CancelToken)
|
||||||
|
'发送请求
|
||||||
|
Response = RequestClient.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetAwaiter().GetResult()
|
||||||
Dim ResponseStream = Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
|
Dim ResponseStream = Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
|
||||||
Dim ResponseBytes As Byte()
|
Dim ResponseBytes As Byte()
|
||||||
Using Stream As New MemoryStream
|
Using Stream As New MemoryStream
|
||||||
@@ -239,28 +256,111 @@ RequestFinished:
|
|||||||
End Using
|
End Using
|
||||||
'输出
|
'输出
|
||||||
If Response.IsSuccessStatusCode Then
|
If Response.IsSuccessStatusCode Then
|
||||||
|
RecordIPReliability(HostIp, 0.5)
|
||||||
Return ResponseBytes
|
Return ResponseBytes
|
||||||
Else
|
Else
|
||||||
|
RecordIPReliability(HostIp, -0.7)
|
||||||
Dim ResponseMessage = If(Encoding, Encoding.UTF8).GetString(ResponseBytes)
|
Dim ResponseMessage = If(Encoding, Encoding.UTF8).GetString(ResponseBytes)
|
||||||
Throw New ResponsedWebException(
|
Throw New ResponsedWebException(
|
||||||
$"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Method},{Url}" &
|
$"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Method},{Url},{HostIp}" &
|
||||||
If(String.IsNullOrEmpty(ResponseMessage), "", vbCrLf & ResponseMessage), ResponseMessage)
|
If(String.IsNullOrEmpty(ResponseMessage), "", vbCrLf & ResponseMessage), ResponseMessage)
|
||||||
End If
|
End If
|
||||||
Catch ex As ThreadInterruptedException
|
Catch ex As ThreadInterruptedException
|
||||||
Throw
|
Throw
|
||||||
Catch ex As ResponsedWebException
|
Catch ex As ResponsedWebException
|
||||||
Throw
|
Throw
|
||||||
Catch ex As TaskCanceledException 'CancellationTokenSource 超时
|
Catch ex As DnsLookupException
|
||||||
Throw New WebException($"连接服务器超时,请检查你的网络环境是否良好({Method}, {Url})", WebExceptionStatus.Timeout)
|
Throw
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Throw New Exception($"网络请求出现意外异常({Method}, {Url})", ex)
|
RecordIPReliability(HostIp, -1)
|
||||||
|
If TypeOf ex Is OperationCanceledException Then 'CancellationToken 超时
|
||||||
|
Throw New WebException($"连接服务器超时,请稍后再试,或使用 VPN 改善网络环境({Method}, {Url},{HostIp})", WebExceptionStatus.Timeout)
|
||||||
|
Else
|
||||||
|
Throw New Exception($"网络请求出现意外异常({Method}, {Url},{HostIp})", ex)
|
||||||
|
End If
|
||||||
Finally
|
Finally
|
||||||
Request?.Dispose()
|
Request?.Dispose()
|
||||||
CancelToken?.Dispose()
|
CancelToken?.Dispose()
|
||||||
Response?.Dispose()
|
Response?.Dispose()
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
|
Private RequestClient As HttpClient = ClientExtensions.CreateClient(New FileCacheStore.FileStore(PathTemp & "Cache/Http/"), New HttpClientHandler With {
|
||||||
|
.AutomaticDecompression = DecompressionMethods.Deflate Or DecompressionMethods.GZip Or DecompressionMethods.None,
|
||||||
|
.UseCookies = False '不设为 False 就不能从 Header 手动传入 Cookies
|
||||||
|
})
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 进行 DNS 解析。它仅在选择的 IP 与系统默认的不一致时才对 URL 中的 Host 进行替换。
|
||||||
|
''' 返回请求时应使用的 IP;若为 IPv6,则加上了方括号。
|
||||||
|
''' </summary>
|
||||||
|
''' <exception cref="DnsLookupException"></exception>
|
||||||
|
Private Function DnsLookup(Request As HttpRequestMessage, CancelToken As CancellationTokenSource) As String
|
||||||
|
Dim GetIPReliability = Function(Key) IPReliability.GetOrDefault(Key.ToString, 0)
|
||||||
|
'初步 DNS 解析
|
||||||
|
Dim Host = Request.RequestUri.Host
|
||||||
|
Dim DnsTask As Task(Of IPAddress()) = Nothing
|
||||||
|
Try
|
||||||
|
DnsTask = Dns.GetHostAddressesAsync(Host)
|
||||||
|
DnsTask.Wait(CancelToken.Token)
|
||||||
|
Catch ex As Exception
|
||||||
|
Throw New DnsLookupException($"DNS 解析失败,请检查你的网络连接({Host})", ex)
|
||||||
|
End Try
|
||||||
|
Dim Candidates As IPAddress() = DnsTask.Result.ToArray
|
||||||
|
If Not Candidates.Any Then Throw New DnsLookupException($"DNS 解析无结果,请检查你的网络连接({Host})")
|
||||||
|
'若同时存在 IPv4 和 IPv6 地址,仅选择其中一类(因为 GFW 可能只屏蔽了 IPv4 或 IPv6)
|
||||||
|
Dim IPv4Targets = Candidates.Where(Function(i) i.AddressFamily = AddressFamily.InterNetwork).ToArray
|
||||||
|
Dim IPv6Targets = Candidates.Where(Function(i) i.AddressFamily = AddressFamily.InterNetworkV6).ToArray
|
||||||
|
If IPv4Targets.Any AndAlso IPv6Targets.Any Then
|
||||||
|
Dim IPv4Reliability = IPv4Targets.Average(Function(i) GetIPReliability(i))
|
||||||
|
Dim IPv6Reliability = IPv6Targets.Average(Function(i) GetIPReliability(i))
|
||||||
|
If Host = "api.modrinth.com" Then IPv6Reliability -= 0.1 '让 Modrinth 优先使用 IPv4 地址(#6887)
|
||||||
|
Candidates = If(IPv4Reliability >= IPv6Reliability, IPv4Targets, IPv6Targets)
|
||||||
|
End If
|
||||||
|
'选择可靠度最高的 IP
|
||||||
|
Dim MaxReliability As Double = Candidates.Max(Function(i) GetIPReliability(i))
|
||||||
|
Dim Target As IPAddress = Candidates.First(Function(i) GetIPReliability(i) = MaxReliability)
|
||||||
|
Dim TargetIp As String = If(Target.AddressFamily = AddressFamily.InterNetworkV6, $"[{Target}]", Target.ToString)
|
||||||
|
If Target IsNot Candidates.First Then
|
||||||
|
'优选结果与系统默认 IP 不一致,替换域名并设置 Host 头
|
||||||
|
If ModeDebug Then Log($"[Net] DNS 结果:{Host} → {Target},所有可能的 IP 与可靠度:{DnsTask.Result.Select(Function(i) $"{i} → {GetIPReliability(i):0.000}").Join(";")}")
|
||||||
|
Request.Headers.Host = Host
|
||||||
|
Dim Builder As New UriBuilder(Request.RequestUri)
|
||||||
|
Builder.Host = TargetIp
|
||||||
|
Request.RequestUri = Builder.Uri
|
||||||
|
End If
|
||||||
|
If Not IPReliability.ContainsKey(TargetIp) Then IPReliability(TargetIp) = -0.01 '预先降低一点,这样快速的重复请求会使用不同的 IP 以提高成功率
|
||||||
|
Return TargetIp
|
||||||
|
End Function
|
||||||
|
''' <summary>
|
||||||
|
''' 记录每个 IP 地址的请求可靠度。
|
||||||
|
''' 通常取值 -1 ~ +0.5,越高越好。未尝试过的 IP 应视为 0。
|
||||||
|
''' </summary>
|
||||||
|
Private IPReliability As New Dictionary(Of String, Double)
|
||||||
|
''' <summary>
|
||||||
|
''' 根据请求结果,记录 IP 地址的可靠度。
|
||||||
|
''' </summary>
|
||||||
|
Private Sub RecordIPReliability(IP As String, Result As Double)
|
||||||
|
If IP Is Nothing Then Return
|
||||||
|
If Not IPReliability.ContainsKey(IP) Then IPReliability(IP) = 0
|
||||||
|
IPReliability(IP) = (IPReliability(IP) + Result) / 2
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' DNS 解析失败引发的异常。
|
||||||
|
''' </summary>
|
||||||
|
Private Class DnsLookupException
|
||||||
|
Inherits Exception
|
||||||
|
Public Sub New(Message As String, Optional InnerException As Exception = Nothing)
|
||||||
|
MyBase.New(Message, InnerException)
|
||||||
|
End Sub
|
||||||
|
Public Sub New(Message As String)
|
||||||
|
MyBase.New(Message)
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>
|
||||||
|
''' 当网络请求失败时引发的异常。
|
||||||
|
''' 附带 Response 属性,可用于获取远程服务器给予的回复。
|
||||||
|
''' </summary>
|
||||||
Public Class ResponsedWebException
|
Public Class ResponsedWebException
|
||||||
Inherits WebException
|
Inherits WebException
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -277,6 +377,10 @@ RequestFinished:
|
|||||||
|
|
||||||
#Region "多线程下载引擎"
|
#Region "多线程下载引擎"
|
||||||
|
|
||||||
|
Private ThreadClient As New HttpClient(New HttpClientHandler With {
|
||||||
|
.AutomaticDecompression = DecompressionMethods.Deflate Or DecompressionMethods.GZip Or DecompressionMethods.None
|
||||||
|
})
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 最大线程数。
|
''' 最大线程数。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@@ -581,12 +685,12 @@ RequestFinished:
|
|||||||
End SyncLock
|
End SyncLock
|
||||||
End Function
|
End Function
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 是否已经没有可用源了。
|
''' 是否存在可用源。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function HasAvailableSource(Optional AllowOnceSource As Boolean = True) As Boolean
|
Public Function HasAvailableSource(Optional AllowOnceSource As Boolean = True) As Boolean
|
||||||
SyncLock LockSource
|
SyncLock LockSource
|
||||||
If AllowOnceSource AndAlso SourcesOnce.Any Then Return True
|
If Sources.Any(Function(s) Not s.IsFailed) Then Return True '存在多线程可用源
|
||||||
If Sources.Any(Function(s) Not s.IsFailed) Then Return True
|
If AllowOnceSource AndAlso SourcesOnce.Any Then Return True '存在单线程可用源
|
||||||
End SyncLock
|
End SyncLock
|
||||||
Return False
|
Return False
|
||||||
End Function
|
End Function
|
||||||
@@ -648,7 +752,7 @@ RequestFinished:
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 下载时是否添加浏览器 UA。
|
''' 下载时是否添加浏览器 UA。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public UseBrowserUserAgent As Boolean
|
Public SimulateBrowserHeaders As Boolean
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 上次记速时的时间。
|
''' 上次记速时的时间。
|
||||||
@@ -746,7 +850,7 @@ RequestFinished:
|
|||||||
''' 新建一个需要下载的文件。
|
''' 新建一个需要下载的文件。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="LocalPath">包含文件名的本地地址。</param>
|
''' <param name="LocalPath">包含文件名的本地地址。</param>
|
||||||
Public Sub New(Urls As IEnumerable(Of String), LocalPath As String, Optional Check As FileChecker = Nothing, Optional UseBrowserUserAgent As Boolean = False)
|
Public Sub New(Urls As IEnumerable(Of String), LocalPath As String, Optional Check As FileChecker = Nothing, Optional SimulateBrowserHeaders As Boolean = False)
|
||||||
Dim Sources As New List(Of NetSource)
|
Dim Sources As New List(Of NetSource)
|
||||||
Dim Count As Integer = 0
|
Dim Count As Integer = 0
|
||||||
Urls = Urls.Distinct.ToArray
|
Urls = Urls.Distinct.ToArray
|
||||||
@@ -757,7 +861,7 @@ RequestFinished:
|
|||||||
Me.Sources = Sources
|
Me.Sources = Sources
|
||||||
Me.LocalPath = LocalPath
|
Me.LocalPath = LocalPath
|
||||||
Me.Check = Check
|
Me.Check = Check
|
||||||
Me.UseBrowserUserAgent = UseBrowserUserAgent
|
Me.SimulateBrowserHeaders = SimulateBrowserHeaders
|
||||||
Me.LocalName = GetFileNameFromPath(LocalPath)
|
Me.LocalName = GetFileNameFromPath(LocalPath)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
@@ -768,7 +872,10 @@ RequestFinished:
|
|||||||
Public Function TryBeginThread() As NetThread
|
Public Function TryBeginThread() As NetThread
|
||||||
Try
|
Try
|
||||||
|
|
||||||
|
Dim StartPosition As Long, StartSource As NetSource = Nothing
|
||||||
|
Dim Th As Thread, ThreadInfo As NetThread
|
||||||
'条件检测
|
'条件检测
|
||||||
|
SyncLock LockSource
|
||||||
If NetTaskThreadCount >= NetTaskThreadLimit OrElse Not HasAvailableSource() OrElse
|
If NetTaskThreadCount >= NetTaskThreadLimit OrElse Not HasAvailableSource() OrElse
|
||||||
(IsNoSplit AndAlso Threads IsNot Nothing AndAlso Threads.State <> NetState.Error) Then Return Nothing
|
(IsNoSplit AndAlso Threads IsNot Nothing AndAlso Threads.State <> NetState.Error) Then Return Nothing
|
||||||
If State >= NetState.Merge OrElse State = NetState.WaitForCheck Then Return Nothing
|
If State >= NetState.Merge OrElse State = NetState.WaitForCheck Then Return Nothing
|
||||||
@@ -776,9 +883,6 @@ RequestFinished:
|
|||||||
If State < NetState.Connect Then State = NetState.Connect
|
If State < NetState.Connect Then State = NetState.Connect
|
||||||
End SyncLock
|
End SyncLock
|
||||||
'初始化参数
|
'初始化参数
|
||||||
Dim StartPosition As Long, StartSource As NetSource = Nothing
|
|
||||||
Dim Th As Thread, ThreadInfo As NetThread
|
|
||||||
SyncLock LockChain
|
|
||||||
'获取线程起点与下载源
|
'获取线程起点与下载源
|
||||||
'不分割
|
'不分割
|
||||||
If IsNoSplit Then GoTo StartSingleThreadDownload
|
If IsNoSplit Then GoTo StartSingleThreadDownload
|
||||||
@@ -789,6 +893,8 @@ StartSingleThreadDownload:
|
|||||||
Reset()
|
Reset()
|
||||||
State = NetState.Get
|
State = NetState.Get
|
||||||
End If
|
End If
|
||||||
|
End SyncLock
|
||||||
|
SyncLock LockChain
|
||||||
'首个开始点
|
'首个开始点
|
||||||
If Threads Is Nothing Then
|
If Threads Is Nothing Then
|
||||||
StartPosition = 0
|
StartPosition = 0
|
||||||
@@ -805,7 +911,9 @@ StartSingleThreadDownload:
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
'是否禁用多线程,以及规定碎片大小
|
'是否禁用多线程,以及规定碎片大小
|
||||||
Dim TargetUrl As String = GetSource().Url
|
Dim Source As NetSource = GetSource()
|
||||||
|
If Source Is Nothing Then Return Nothing
|
||||||
|
Dim TargetUrl As String = Source.Url
|
||||||
If TargetUrl.Contains("pcl2-server") OrElse TargetUrl.Contains("bmclapi") OrElse TargetUrl.Contains("github.com") OrElse
|
If TargetUrl.Contains("pcl2-server") OrElse TargetUrl.Contains("bmclapi") OrElse TargetUrl.Contains("github.com") OrElse
|
||||||
TargetUrl.Contains("optifine.net") OrElse TargetUrl.Contains("modrinth") OrElse TargetUrl.Contains("momot.rs") Then Return Nothing
|
TargetUrl.Contains("optifine.net") OrElse TargetUrl.Contains("modrinth") OrElse TargetUrl.Contains("momot.rs") Then Return Nothing
|
||||||
'寻找最大碎片
|
'寻找最大碎片
|
||||||
@@ -850,7 +958,7 @@ StartThread:
|
|||||||
Return ThreadInfo
|
Return ThreadInfo
|
||||||
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "尝试开始下载线程失败(" & If(LocalName, "Nothing") & ")", LogLevel.Hint)
|
Fail(New Exception($"尝试开始下载线程失败({LocalName})", ex))
|
||||||
Return Nothing
|
Return Nothing
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
@@ -859,7 +967,9 @@ StartThread:
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Private Sub Thread(Th As NetThread)
|
Private Sub Thread(Th As NetThread)
|
||||||
If ModeDebug OrElse Th.DownloadStart = 0 Then Log($"[Download] {LocalName}:开始,起始点 {Th.DownloadStart},{Th.Source.Url}")
|
If ModeDebug OrElse Th.DownloadStart = 0 Then Log($"[Download] {LocalName}:开始,起始点 {Th.DownloadStart},{Th.Source.Url}")
|
||||||
Dim ResultStream As Stream = Nothing
|
Dim ResultStream As Stream = Nothing, HttpRequest As HttpRequestMessage = Nothing,
|
||||||
|
Response As HttpResponseMessage = Nothing, ResponseStream As Stream = Nothing,
|
||||||
|
CancelToken As CancellationTokenSource = Nothing, HostIp As String = ""
|
||||||
'部分下载源真的特别慢,并且只需要一个请求,例如 Ping 为 20s,如果增长太慢,就会造成类似 2.5s 5s 7.5s 10s 12.5s... 的极大延迟
|
'部分下载源真的特别慢,并且只需要一个请求,例如 Ping 为 20s,如果增长太慢,就会造成类似 2.5s 5s 7.5s 10s 12.5s... 的极大延迟
|
||||||
'延迟过长会导致某些特别慢的链接迟迟不被掐死
|
'延迟过长会导致某些特别慢的链接迟迟不被掐死
|
||||||
Dim Timeout As Integer = Math.Min(Math.Max(ConnectAverage, 6000) * (1 + Th.Source.FailCount), 30000)
|
Dim Timeout As Integer = Math.Min(Math.Max(ConnectAverage, 6000) * (1 + Th.Source.FailCount), 30000)
|
||||||
@@ -867,15 +977,13 @@ StartThread:
|
|||||||
Try
|
Try
|
||||||
Dim HttpDataCount As Integer = 0
|
Dim HttpDataCount As Integer = 0
|
||||||
If SourcesOnce.Contains(Th.Source) AndAlso Th <> Th.Source.SingleThread Then GoTo SourceBreak
|
If SourcesOnce.Contains(Th.Source) AndAlso Th <> Th.Source.SingleThread Then GoTo SourceBreak
|
||||||
Dim HttpRequest As New HttpRequestMessage(HttpMethod.Get, Th.Source.Url)
|
HttpRequest = New HttpRequestMessage(HttpMethod.Get, Th.Source.Url)
|
||||||
SecretHeadersSign(Th.Source.Url, HttpRequest, UseBrowserUserAgent)
|
SecretHeadersSign(Th.Source.Url, HttpRequest, SimulateBrowserHeaders)
|
||||||
|
CancelToken = New CancellationTokenSource(Timeout)
|
||||||
|
HostIp = DnsLookup(HttpRequest, CancelToken) 'DNS 预解析
|
||||||
If Not Th.IsFirstThread Then HttpRequest.Headers.Range = New RangeHeaderValue(Th.DownloadStart, Nothing)
|
If Not Th.IsFirstThread Then HttpRequest.Headers.Range = New RangeHeaderValue(Th.DownloadStart, Nothing)
|
||||||
Dim ContentLength As Long = 0
|
Dim ContentLength As Long = 0
|
||||||
Using CancelToken As New CancellationTokenSource(Timeout)
|
Response = ThreadClient.SendAsync(HttpRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetAwaiter().GetResult()
|
||||||
Static Client As New HttpClient(New HttpClientHandler With {
|
|
||||||
.AutomaticDecompression = DecompressionMethods.Deflate Or DecompressionMethods.GZip Or DecompressionMethods.None
|
|
||||||
})
|
|
||||||
Using Response As HttpResponseMessage = Client.SendAsync(HttpRequest, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetAwaiter().GetResult()
|
|
||||||
If Not Response.IsSuccessStatusCode Then Throw New Exception($"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Th.Source.Url}") '状态码检查
|
If Not Response.IsSuccessStatusCode Then Throw New Exception($"错误码 {Response.StatusCode} ({CInt(Response.StatusCode)}),{Th.Source.Url}") '状态码检查
|
||||||
If State = NetState.Error Then GoTo SourceBreak '快速中断
|
If State = NetState.Error Then GoTo SourceBreak '快速中断
|
||||||
If ModeDebug AndAlso Response.RequestMessage.RequestUri.ToString <> Th.Source.Url Then Log($"[Download] {LocalName}:重定向至 {Response.RequestMessage.RequestUri}")
|
If ModeDebug AndAlso Response.RequestMessage.RequestUri.ToString <> Th.Source.Url Then Log($"[Download] {LocalName}:重定向至 {Response.RequestMessage.RequestUri}")
|
||||||
@@ -948,7 +1056,7 @@ NotSupportRange:
|
|||||||
ResultStream = New FileStream(Th.Temp, FileMode.Create, FileAccess.Write, FileShare.Read)
|
ResultStream = New FileStream(Th.Temp, FileMode.Create, FileAccess.Write, FileShare.Read)
|
||||||
End If
|
End If
|
||||||
'开始下载
|
'开始下载
|
||||||
Using ResponseStream = Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
|
ResponseStream = Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
|
||||||
If Setup.Get("SystemDebugDelay") Then Threading.Thread.Sleep(RandomInteger(50, 3000))
|
If Setup.Get("SystemDebugDelay") Then Threading.Thread.Sleep(RandomInteger(50, 3000))
|
||||||
Dim ResponseBytes As Byte() = New Byte(16384) {}
|
Dim ResponseBytes As Byte() = New Byte(16384) {}
|
||||||
HttpDataCount = ResponseStream.ReadAsync(ResponseBytes, 0, 16384, CancelToken.Token).GetAwaiter().GetResult()
|
HttpDataCount = ResponseStream.ReadAsync(ResponseBytes, 0, 16384, CancelToken.Token).GetAwaiter().GetResult()
|
||||||
@@ -963,7 +1071,7 @@ NotSupportRange:
|
|||||||
If NetTaskSpeedLimitHigh > 0 Then NetTaskSpeedLimitLeft -= RealDataCount
|
If NetTaskSpeedLimitHigh > 0 Then NetTaskSpeedLimitLeft -= RealDataCount
|
||||||
End SyncLock
|
End SyncLock
|
||||||
Dim DeltaTime = GetTimeTick() - Th.LastReceiveTime
|
Dim DeltaTime = GetTimeTick() - Th.LastReceiveTime
|
||||||
If DeltaTime > 1000000 Then DeltaTime = 1 '时间刻反转导致出现极大值
|
If DeltaTime > 1000000 Then DeltaTime = 1 '避免时间刻反转导致出现极大值
|
||||||
If RealDataCount > 0 Then
|
If RealDataCount > 0 Then
|
||||||
'有数据
|
'有数据
|
||||||
If Th.DownloadDone = 0 Then
|
If Th.DownloadDone = 0 Then
|
||||||
@@ -989,23 +1097,20 @@ NotSupportRange:
|
|||||||
End SyncLock
|
End SyncLock
|
||||||
Th.DownloadDone += RealDataCount
|
Th.DownloadDone += RealDataCount
|
||||||
ResultStream.Write(ResponseBytes, 0, RealDataCount)
|
ResultStream.Write(ResponseBytes, 0, RealDataCount)
|
||||||
|
'已完成
|
||||||
|
If Th.DownloadUndone = 0 AndAlso Not IsUnknownSize Then Exit While
|
||||||
'检查速度是否过慢
|
'检查速度是否过慢
|
||||||
If DeltaTime > 1500 AndAlso DeltaTime > RealDataCount AndAlso '数据包间隔大于 1.5s,且速度小于 1.5K/s
|
If DeltaTime > 5000 AndAlso DeltaTime > RealDataCount AndAlso '数据包间隔大于 5s,且速度小于 1K/s
|
||||||
Th.Source.SingleThread Is Nothing Then '并非单线程下载
|
Th.Source.SingleThread Is Nothing Then '且并非单线程下载
|
||||||
Throw New TimeoutException("由于速度过慢断开链接,下载 " & RealDataCount & " B,消耗 " & DeltaTime & " ms。")
|
Throw New TimeoutException("由于速度过慢断开链接,下载 " & RealDataCount & " B,消耗 " & DeltaTime & " ms。")
|
||||||
End If
|
End If
|
||||||
Th.LastReceiveTime = GetTimeTick()
|
Th.LastReceiveTime = GetTimeTick()
|
||||||
'已完成
|
|
||||||
If Th.DownloadUndone = 0 AndAlso Not IsUnknownSize Then Exit While
|
|
||||||
ElseIf Th.LastReceiveTime > 0 AndAlso DeltaTime > Timeout Then
|
ElseIf Th.LastReceiveTime > 0 AndAlso DeltaTime > Timeout Then
|
||||||
'无数据,且已超时
|
'无数据,且已超时
|
||||||
Throw New TimeoutException("操作超时,无数据。")
|
Throw New TimeoutException("操作超时,无数据。")
|
||||||
End If
|
End If
|
||||||
HttpDataCount = ResponseStream.Read(ResponseBytes, 0, 16384)
|
HttpDataCount = ResponseStream.Read(ResponseBytes, 0, 16384)
|
||||||
End While
|
End While
|
||||||
End Using
|
|
||||||
End Using
|
|
||||||
End Using
|
|
||||||
SourceBreak:
|
SourceBreak:
|
||||||
If State = NetState.Error OrElse (Th.Source.IsFailed AndAlso Th.Source.SingleThread <> Th) OrElse (Th.DownloadUndone > 0 AndAlso Not IsUnknownSize) Then
|
If State = NetState.Error OrElse (Th.Source.IsFailed AndAlso Th.Source.SingleThread <> Th) OrElse (Th.DownloadUndone > 0 AndAlso Not IsUnknownSize) Then
|
||||||
'被外部中断
|
'被外部中断
|
||||||
@@ -1018,16 +1123,24 @@ SourceBreak:
|
|||||||
'本线程完成
|
'本线程完成
|
||||||
Th.State = NetState.Finish
|
Th.State = NetState.Finish
|
||||||
If ModeDebug Then Log($"[Download] {LocalName}:完成,已下载 {Th.DownloadDone}({Th.DownloadStart}~{Th.DownloadEnd})")
|
If ModeDebug Then Log($"[Download] {LocalName}:完成,已下载 {Th.DownloadDone}({Th.DownloadStart}~{Th.DownloadEnd})")
|
||||||
|
RecordIPReliability(HostIp, 0.5)
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log($"[Download] {LocalName}:出错,{If(TypeOf ex Is TaskCanceledException, $"已超时({Timeout}ms)", GetExceptionDetail(ex))}")
|
Log($"[Download] {LocalName}:出错,{If(TypeOf ex Is OperationCanceledException, $"已超时({Timeout}ms)", ex.GetDetail())},{HostIp}")
|
||||||
|
RecordIPReliability(HostIp, -0.7)
|
||||||
SourceFail(Th, ex, False)
|
SourceFail(Th, ex, False)
|
||||||
Finally
|
Finally
|
||||||
|
'释放资源
|
||||||
|
HttpRequest?.Dispose()
|
||||||
|
Response?.Dispose()
|
||||||
|
ResponseStream?.Dispose()
|
||||||
|
CancelToken?.Dispose()
|
||||||
|
If Not IsNoSplit Then ResultStream?.Dispose()
|
||||||
|
'改变计数
|
||||||
SyncLock NetTaskThreadCountLock
|
SyncLock NetTaskThreadCountLock
|
||||||
NetTaskThreadCount -= 1
|
NetTaskThreadCount -= 1
|
||||||
End SyncLock
|
End SyncLock
|
||||||
'合并
|
'合并
|
||||||
If Not IsNoSplit Then ResultStream?.Dispose()
|
|
||||||
If ((FileSize >= 0 AndAlso DownloadDone >= FileSize) OrElse (FileSize = -1 AndAlso DownloadDone > 0)) AndAlso
|
If ((FileSize >= 0 AndAlso DownloadDone >= FileSize) OrElse (FileSize = -1 AndAlso DownloadDone > 0)) AndAlso
|
||||||
State < NetState.Merge AndAlso Th.State <> NetState.Error Then Merge(Th)
|
State < NetState.Merge AndAlso Th.State <> NetState.Error Then Merge(Th)
|
||||||
End Try
|
End Try
|
||||||
@@ -1046,7 +1159,7 @@ SourceBreak:
|
|||||||
If IsMergeFailure OrElse
|
If IsMergeFailure OrElse
|
||||||
ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse
|
ex.Message.Contains("该下载源不支持") OrElse ex.Message.Contains("未能解析") OrElse ex.Message.Contains("(404)") OrElse
|
||||||
ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse ex.Message.Contains("获取到的分段大小不一致") OrElse
|
ex.Message.Contains("(502)") OrElse ex.Message.Contains("无返回数据") OrElse ex.Message.Contains("空间不足") OrElse ex.Message.Contains("获取到的分段大小不一致") OrElse
|
||||||
(ex.Message.Contains("(403)") AndAlso Not Th.Source.Url.ContainsF("bmclapi")) OrElse 'BMCLAPI 的部分源在高频率请求下会返回 403,所以不应因此禁用下载源
|
((ex.Message.Contains("(403)") OrElse ex.Message.Contains("(429)")) AndAlso Not Th.Source.Url.ContainsF("bmclapi")) OrElse 'BMCLAPI 的部分源在高频率请求下会返回 403/429,所以不应因此禁用下载源
|
||||||
(Th.Source.FailCount >= MathClamp(NetTaskThreadLimit, 5, 30) AndAlso DownloadDone < 1) OrElse Th.Source.FailCount > NetTaskThreadLimit + 2 Then
|
(Th.Source.FailCount >= MathClamp(NetTaskThreadLimit, 5, 30) AndAlso DownloadDone < 1) OrElse Th.Source.FailCount > NetTaskThreadLimit + 2 Then
|
||||||
'当一个下载源有多个线程在下载时,只选择其中一个线程进行后续处理
|
'当一个下载源有多个线程在下载时,只选择其中一个线程进行后续处理
|
||||||
Dim IsThisFail As Boolean = False
|
Dim IsThisFail As Boolean = False
|
||||||
@@ -1140,10 +1253,10 @@ SourceBreak:
|
|||||||
Dim RetryCount As Integer = 0
|
Dim RetryCount As Integer = 0
|
||||||
Try
|
Try
|
||||||
Retry:
|
Retry:
|
||||||
SyncLock LockChain
|
|
||||||
'创建文件夹
|
'创建文件夹
|
||||||
If File.Exists(LocalPath) Then File.Delete(LocalPath)
|
If File.Exists(LocalPath) Then File.Delete(LocalPath)
|
||||||
Directory.CreateDirectory(GetPathFromFullPath(LocalPath))
|
Directory.CreateDirectory(GetPathFromFullPath(LocalPath))
|
||||||
|
SyncLock LockChain
|
||||||
'合并文件
|
'合并文件
|
||||||
If IsNoSplit Then
|
If IsNoSplit Then
|
||||||
'仅有一个线程,从缓存中输出
|
'仅有一个线程,从缓存中输出
|
||||||
@@ -1386,13 +1499,13 @@ NextElement:
|
|||||||
If File Is Nothing Then Throw New ArgumentException("存在空文件请求!")
|
If File Is Nothing Then Throw New ArgumentException("存在空文件请求!")
|
||||||
For Each Source As NetSource In File.Sources
|
For Each Source As NetSource In File.Sources
|
||||||
If Not (Source.Url.StartsWithF("https://", True) OrElse Source.Url.StartsWithF("http://", True)) Then
|
If Not (Source.Url.StartsWithF("https://", True) OrElse Source.Url.StartsWithF("http://", True)) Then
|
||||||
Source.Ex = New ArgumentException("输入的下载链接不正确!")
|
Source.Ex = New ArgumentException("输入的下载链接不正确:" & Source.Url)
|
||||||
Source.IsFailed = True
|
Source.IsFailed = True
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
If Not File.HasAvailableSource() Then Throw New ArgumentException("输入的下载链接不正确!")
|
If Not File.HasAvailableSource() Then Throw New ArgumentException("输入的下载链接不正确!")
|
||||||
If Not File.LocalPath.ToLower.Contains(":\") Then Throw New ArgumentException("输入的本地文件地址不正确!")
|
If Not File.LocalPath.ToLower.Contains(":\") Then Throw New ArgumentException("输入的本地文件地址不正确:" & File.LocalPath)
|
||||||
If File.LocalPath.EndsWithF("\") Then Throw New ArgumentException("请输入含文件名的完整文件路径!")
|
If File.LocalPath.EndsWithF("\") Then Throw New ArgumentException("请输入含文件名的完整文件路径:" & File.LocalPath)
|
||||||
'文件夹检测
|
'文件夹检测
|
||||||
Dim DirPath As String = New FileInfo(File.LocalPath).Directory.FullName
|
Dim DirPath As String = New FileInfo(File.LocalPath).Directory.FullName
|
||||||
If Not Directory.Exists(DirPath) Then Directory.CreateDirectory(DirPath)
|
If Not Directory.Exists(DirPath) Then Directory.CreateDirectory(DirPath)
|
||||||
@@ -1522,12 +1635,12 @@ Retry:
|
|||||||
If State > LoadState.Loading Then Return
|
If State > LoadState.Loading Then Return
|
||||||
If ExList Is Nothing OrElse Not ExList.Any() Then ExList = New List(Of Exception) From {New Exception("未知错误!")}
|
If ExList Is Nothing OrElse Not ExList.Any() Then ExList = New List(Of Exception) From {New Exception("未知错误!")}
|
||||||
'寻找有效的错误信息
|
'寻找有效的错误信息
|
||||||
Dim UsefulExs = ExList.Where(Function(e) TypeOf e IsNot TaskCanceledException AndAlso TypeOf e IsNot ThreadInterruptedException).ToList
|
Dim UsefulExs = ExList.Where(Function(e) TypeOf e IsNot OperationCanceledException AndAlso TypeOf e IsNot ThreadInterruptedException).ToList
|
||||||
[Error] = If(UsefulExs.FirstOrDefault, ExList.FirstOrDefault)
|
[Error] = If(UsefulExs.FirstOrDefault, ExList.FirstOrDefault)
|
||||||
'获取实际失败的文件
|
'获取实际失败的文件
|
||||||
For Each File In Files
|
For Each File In Files
|
||||||
If File.State <> NetState.Error Then Continue For
|
If File.State <> NetState.Error Then Continue For
|
||||||
Dim Detail As String = Join(File.Sources.Select(Function(s) $"{If(s.Ex?.Message, "无错误信息。")}({s.Url})"), vbCrLf)
|
Dim Detail As String = Join(File.Sources.Select(Function(s) $"{If(s.Ex Is Nothing, "无错误信息。", s.Ex.GetBrief())}({s.Url})"), vbCrLf)
|
||||||
[Error] = New Exception("文件下载失败:" & File.LocalPath & vbCrLf &
|
[Error] = New Exception("文件下载失败:" & File.LocalPath & vbCrLf &
|
||||||
"各下载源的错误如下:" & vbCrLf & Detail,
|
"各下载源的错误如下:" & vbCrLf & Detail,
|
||||||
[Error])
|
[Error])
|
||||||
@@ -1547,7 +1660,7 @@ Retry:
|
|||||||
'在退出同步锁后再进行日志输出
|
'在退出同步锁后再进行日志输出
|
||||||
Dim ErrOutput As New List(Of String)
|
Dim ErrOutput As New List(Of String)
|
||||||
For Each Ex As Exception In ExList
|
For Each Ex As Exception In ExList
|
||||||
ErrOutput.Add(GetExceptionDetail(Ex))
|
ErrOutput.Add(Ex.GetDetail())
|
||||||
Next
|
Next
|
||||||
Log("[Download] " & Join(ErrOutput.Distinct.ToArray, vbCrLf))
|
Log("[Download] " & Join(ErrOutput.Distinct.ToArray, vbCrLf))
|
||||||
End Sub
|
End Sub
|
||||||
@@ -1697,7 +1810,7 @@ Retry:
|
|||||||
For Each File As NetFile In WaitingFiles
|
For Each File As NetFile In WaitingFiles
|
||||||
If NetTaskThreadCount >= NetTaskThreadLimit Then Continue While '最大线程数检查
|
If NetTaskThreadCount >= NetTaskThreadLimit Then Continue While '最大线程数检查
|
||||||
Dim NewThread = File.TryBeginThread()
|
Dim NewThread = File.TryBeginThread()
|
||||||
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(30) '减少 BMCLAPI 请求频率(目前每分钟限制 4000 次)
|
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(40) '减少 BMCLAPI 请求频率(目前每分钟限制 4000 次)
|
||||||
Next
|
Next
|
||||||
'为进行中的文件追加线程
|
'为进行中的文件追加线程
|
||||||
If Speed >= NetTaskSpeedLimitLow Then Continue While '下载速度足够,无需新增
|
If Speed >= NetTaskSpeedLimitLow Then Continue While '下载速度足够,无需新增
|
||||||
@@ -1717,7 +1830,7 @@ Retry:
|
|||||||
'新增线程
|
'新增线程
|
||||||
If PreparingCount > DownloadingCount Then Continue For '准备中的线程已多于下载中的线程,不再新增
|
If PreparingCount > DownloadingCount Then Continue For '准备中的线程已多于下载中的线程,不再新增
|
||||||
Dim NewThread = File.TryBeginThread()
|
Dim NewThread = File.TryBeginThread()
|
||||||
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(30) '减少 BMCLAPI 请求频率(目前每分钟限制 4000 次)
|
If NewThread IsNot Nothing AndAlso NewThread.Source.Url.Contains("bmclapi") Then Thread.Sleep(40) '减少 BMCLAPI 请求频率(目前每分钟限制 4000 次)
|
||||||
Next
|
Next
|
||||||
End While
|
End While
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -1842,4 +1955,15 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' 判断某个 Exception 是否为网络问题所导致。
|
||||||
|
''' </summary>
|
||||||
|
<Extension> Public Function IsNetworkRelated(Ex As Exception) As Boolean
|
||||||
|
If TypeOf Ex Is DnsLookupException Then Return True
|
||||||
|
Dim Detail = Ex.GetDetail()
|
||||||
|
If Detail.Contains("(403)") Then Return False
|
||||||
|
Return {"(408)", "超时", "timeout", "网络请求失败", "连接尝试失败", "远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝"}.
|
||||||
|
Any(Function(k) Detail.ContainsF(k, True))
|
||||||
|
End Function
|
||||||
|
|
||||||
End Module
|
End Module
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ Public Class ValidateExceptSame
|
|||||||
Me.ErrorMessage = ErrorMessage
|
Me.ErrorMessage = ErrorMessage
|
||||||
Me.IgnoreCase = IgnoreCase
|
Me.IgnoreCase = IgnoreCase
|
||||||
End Sub
|
End Sub
|
||||||
Public Sub New(Excepts As IEnumerable, Optional ErrorMessage As String = "输入内容不能为 %", Optional IgnoreCase As Boolean = False)
|
Public Sub New(Excepts As IEnumerable(Of String), Optional ErrorMessage As String = "输入内容不能为 %", Optional IgnoreCase As Boolean = False)
|
||||||
Me.Excepts = New ObjectModel.Collection(Of String)
|
Me.Excepts = New ObjectModel.Collection(Of String)
|
||||||
For Each Data As String In Excepts
|
For Each Data As String In Excepts
|
||||||
Me.Excepts.Add(Data)
|
Me.Excepts.Add(Data)
|
||||||
@@ -199,6 +199,11 @@ Public Class ValidateExceptSame
|
|||||||
Me.ErrorMessage = ErrorMessage
|
Me.ErrorMessage = ErrorMessage
|
||||||
Me.IgnoreCase = IgnoreCase
|
Me.IgnoreCase = IgnoreCase
|
||||||
End Sub
|
End Sub
|
||||||
|
Public Sub New(Except As String, Optional ErrorMessage As String = "输入内容不能为 %", Optional IgnoreCase As Boolean = False)
|
||||||
|
Me.Excepts = New ObjectModel.Collection(Of String) From {Except}
|
||||||
|
Me.ErrorMessage = ErrorMessage
|
||||||
|
Me.IgnoreCase = IgnoreCase
|
||||||
|
End Sub
|
||||||
Public Overrides Function Validate(Str As String) As String
|
Public Overrides Function Validate(Str As String) As String
|
||||||
If Str Is Nothing Then Return ErrorMessage.Replace("%", "null")
|
If Str Is Nothing Then Return ErrorMessage.Replace("%", "null")
|
||||||
For Each Ch As String In Excepts
|
For Each Ch As String In Excepts
|
||||||
|
|||||||
@@ -347,7 +347,7 @@
|
|||||||
Case 4475 : Tags.Add("冒险")
|
Case 4475 : Tags.Add("冒险")
|
||||||
Case 4476 : Tags.Add("探索")
|
Case 4476 : Tags.Add("探索")
|
||||||
Case 4477 : Tags.Add("小游戏")
|
Case 4477 : Tags.Add("小游戏")
|
||||||
Case 4471 : Tags.Add("科幻")
|
Case 4474 : Tags.Add("科幻")
|
||||||
Case 4736 : Tags.Add("空岛")
|
Case 4736 : Tags.Add("空岛")
|
||||||
Case 5128 : Tags.Add("原版改良")
|
Case 5128 : Tags.Add("原版改良")
|
||||||
Case 4487 : Tags.Add("FTB")
|
Case 4487 : Tags.Add("FTB")
|
||||||
@@ -1161,9 +1161,9 @@ Retry:
|
|||||||
ElseIf [Error] IsNot Nothing Then
|
ElseIf [Error] IsNot Nothing Then
|
||||||
'有结果但是有错误
|
'有结果但是有错误
|
||||||
If CurseForgeFailed Then
|
If CurseForgeFailed Then
|
||||||
Storage.ErrorMessage = $"无法连接到 CurseForge,所以目前仅显示了来自 Modrinth 的内容,搜索结果可能不全。{vbCrLf}请稍后重试,或使用 VPN 以改善网络环境。"
|
Storage.ErrorMessage = $"无法连接到 CurseForge,所以目前仅显示了来自 Modrinth 的内容,搜索结果可能不全。{vbCrLf}请稍后再试,或使用 VPN 改善网络环境。"
|
||||||
Else
|
Else
|
||||||
Storage.ErrorMessage = $"无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,搜索结果可能不全。{vbCrLf}请稍后重试,或使用 VPN 以改善网络环境。"
|
Storage.ErrorMessage = $"无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,搜索结果可能不全。{vbCrLf}请稍后再试,或使用 VPN 改善网络环境。"
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
@@ -1354,7 +1354,7 @@ Retry:
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="LocalAddress">目标本地文件夹,或完整的文件路径。会自动判断类型。</param>
|
''' <param name="LocalAddress">目标本地文件夹,或完整的文件路径。会自动判断类型。</param>
|
||||||
Public Function ToNetFile(LocalAddress As String) As NetFile
|
Public Function ToNetFile(LocalAddress As String) As NetFile
|
||||||
Return New NetFile(DownloadUrls, LocalAddress & If(LocalAddress.EndsWithF("\"), FileName, ""), New FileChecker(Hash:=Hash), UseBrowserUserAgent:=True)
|
Return New NetFile(DownloadUrls, LocalAddress & If(LocalAddress.EndsWithF("\"), FileName, ""), New FileChecker(Hash:=Hash), SimulateBrowserHeaders:=True)
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
'实例化
|
'实例化
|
||||||
@@ -1395,10 +1395,9 @@ Retry:
|
|||||||
If Hash Is Nothing Then Hash = CType(Data("hashes"), JArray).ToList.FirstOrDefault(Function(s) s("algo").ToObject(Of Integer) = 2)?("value")
|
If Hash Is Nothing Then Hash = CType(Data("hashes"), JArray).ToList.FirstOrDefault(Function(s) s("algo").ToObject(Of Integer) = 2)?("value")
|
||||||
'DownloadAddress
|
'DownloadAddress
|
||||||
Dim Url = Data("downloadUrl").ToString
|
Dim Url = Data("downloadUrl").ToString
|
||||||
If Url = "" Then Url = $"https://media.forgecdn.net/files/{CInt(Id.ToString.Substring(0, 4))}/{CInt(Id.ToString.Substring(4))}/{FileName}"
|
If Url = "" Then Url = $"https://edge.forgecdn.net/files/{CInt(Id.ToString.Substring(0, 4))}/{CInt(Id.ToString.Substring(4))}/{FileName}"
|
||||||
Url = Url.Replace(FileName, WebUtility.UrlEncode(FileName)) '对文件名进行编码
|
DownloadUrls = HandleCurseForgeDownloadUrls(Url.Replace(FileName, WebUtility.UrlEncode(FileName))) '对脑残 CurseForge 的下载地址进行多种修正
|
||||||
DownloadUrls = HandleCurseForgeDownloadUrls(Url) '对脑残 CurseForge 的下载地址进行多种修正
|
DownloadUrls.Add(DlSourceModGet(Url)) '添加镜像源;注意 MCIM 源不支持 URL 编码后的文件名,必须传入 URL 编码前的文件名
|
||||||
DownloadUrls.AddRange(DownloadUrls.Select(Function(u) DlSourceModGet(u)).ToList) '添加镜像源,这个写法是为了让镜像源排在后面
|
|
||||||
DownloadUrls = DownloadUrls.Distinct.ToList '最终去重
|
DownloadUrls = DownloadUrls.Distinct.ToList '最终去重
|
||||||
'Dependencies
|
'Dependencies
|
||||||
If Data.ContainsKey("dependencies") Then
|
If Data.ContainsKey("dependencies") Then
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ Done:
|
|||||||
'崩溃报告分析,高优先级
|
'崩溃报告分析,高优先级
|
||||||
If LogCrash IsNot Nothing Then
|
If LogCrash IsNot Nothing Then
|
||||||
If LogCrash.Contains("Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass") Then AppendReason(CrashReason.Java版本过高)
|
If LogCrash.Contains("Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass") Then AppendReason(CrashReason.Java版本过高)
|
||||||
If LogCrash.Contains("Failed loading config file ") Then AppendReason(CrashReason.Mod配置文件导致游戏崩溃, {TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Failed loading config file .+ for modid )[^\n]+"), "").TrimEnd(vbCrLf)).First, If(RegexSeek(LogCrash, "(?<=Failed loading config file ).+(?= of type)"), "").TrimEnd(vbCrLf)})
|
If LogCrash.Contains("Failed loading config file ") Then AppendReason(CrashReason.Mod配置文件导致游戏崩溃, {TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Failed loading config file .+ for modid )[^\n]+"), "").TrimEnd(vbCrLf)).First, If(RegexSeek(LogCrash, "(?<=Failed loading config file ).+(?= of type)"), "").TrimEnd(vbCrLf)}) '#7071
|
||||||
End If
|
End If
|
||||||
|
|
||||||
'游戏日志分析
|
'游戏日志分析
|
||||||
@@ -542,8 +542,8 @@ Done:
|
|||||||
If LogMc.Contains("Found a duplicate mod") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(If(RegexSeek(LogMc, "Found a duplicate mod[^\n]+"), ""), "[^\\/]+.jar", RegularExpressions.RegexOptions.IgnoreCase))
|
If LogMc.Contains("Found a duplicate mod") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(If(RegexSeek(LogMc, "Found a duplicate mod[^\n]+"), ""), "[^\\/]+.jar", RegularExpressions.RegexOptions.IgnoreCase))
|
||||||
If LogMc.Contains("Found duplicate mods") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(LogMc, "(?<=Mod ID: ')\w+?(?=' from mod files:)").Distinct.ToList)
|
If LogMc.Contains("Found duplicate mods") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(LogMc, "(?<=Mod ID: ')\w+?(?=' from mod files:)").Distinct.ToList)
|
||||||
If LogMc.Contains("ModResolutionException: Duplicate") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(If(RegexSeek(LogMc, "ModResolutionException: Duplicate[^\n]+"), ""), "[^\\/]+.jar", RegularExpressions.RegexOptions.IgnoreCase))
|
If LogMc.Contains("ModResolutionException: Duplicate") Then AppendReason(CrashReason.Mod重复安装, RegexSearch(If(RegexSeek(LogMc, "ModResolutionException: Duplicate[^\n]+"), ""), "[^\\/]+.jar", RegularExpressions.RegexOptions.IgnoreCase))
|
||||||
If LogMc.Contains("Incompatible mods found!") Then '#5006
|
If LogMc.Contains("Incompatible mods found!") Then '#5006, #5115
|
||||||
AppendReason(CrashReason.Mod互不兼容, If(RegexSeek(LogMc, "(?<=Incompatible mods found![\s\S]+: )[\s\S]+?(?=\tat )"), ""))
|
AppendReason(CrashReason.Mod互不兼容, If(RegexSeek(LogMc, "(?<=Incompatible mods found![\s\S]+: )[\s\S]+?(?=\tat )"), "").BeforeFirst("更多信息:").Replace("Some of your mods are incompatible with the game or each other!", "").Trim((vbCrLf & " ").ToCharArray))
|
||||||
End If
|
End If
|
||||||
If LogMc.Contains("Missing or unsupported mandatory dependencies:") Then
|
If LogMc.Contains("Missing or unsupported mandatory dependencies:") Then
|
||||||
AppendReason(CrashReason.Mod缺少前置或MC版本错误,
|
AppendReason(CrashReason.Mod缺少前置或MC版本错误,
|
||||||
@@ -581,6 +581,7 @@ Done:
|
|||||||
End If
|
End If
|
||||||
If LogCrash.Contains("Multiple entries with same key: ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Multiple entries with same key: )[^=]+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
|
If LogCrash.Contains("Multiple entries with same key: ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Multiple entries with same key: )[^=]+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
|
||||||
If LogCrash.Contains("LoaderExceptionModCrash: Caught exception from ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=LoaderExceptionModCrash: Caught exception from )[^\n]+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
|
If LogCrash.Contains("LoaderExceptionModCrash: Caught exception from ") Then AppendReason(CrashReason.确定Mod导致游戏崩溃, TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=LoaderExceptionModCrash: Caught exception from )[^\n]+"), "").TrimEnd((vbCrLf & " ").ToCharArray)))
|
||||||
|
If LogCrash.Contains("Failed loading config file ") Then AppendReason(CrashReason.Mod配置文件导致游戏崩溃, {TryAnalyzeModName(If(RegexSeek(LogCrash, "(?<=Failed loading config file .+ for modid )[^\n]+"), "").TrimEnd(vbCrLf)).First, If(RegexSeek(LogCrash, "(?<=Failed loading config file ).+(?= of type)"), "").TrimEnd(vbCrLf)})
|
||||||
End If
|
End If
|
||||||
|
|
||||||
End Sub
|
End Sub
|
||||||
@@ -658,7 +659,7 @@ Done:
|
|||||||
End If
|
End If
|
||||||
'Mod 解析错误(常见于 Fabric 前置校验失败)
|
'Mod 解析错误(常见于 Fabric 前置校验失败)
|
||||||
If LogMc.Contains("Mod resolution failed") Then AppendReason(CrashReason.Mod加载器报错)
|
If LogMc.Contains("Mod resolution failed") Then AppendReason(CrashReason.Mod加载器报错)
|
||||||
'Mixin 失败可以导致大量 Mod 实例创建失败
|
'Mixin 失败可以导致大量 Mod 实例创建失败,因此需要放到低优先级中
|
||||||
If LogMc.Contains("Failed to create mod instance.") Then AppendReason(CrashReason.Mod初始化失败, TryAnalyzeModName(If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModID: )[^,]+"), If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModId )[^\n]+(?= for )"), "")).TrimEnd(vbCrLf)))
|
If LogMc.Contains("Failed to create mod instance.") Then AppendReason(CrashReason.Mod初始化失败, TryAnalyzeModName(If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModID: )[^,]+"), If(RegexSeek(LogMc, "(?<=Failed to create mod instance. ModId )[^\n]+(?= for )"), "")).TrimEnd(vbCrLf)))
|
||||||
'注意:Fabric 的 Warnings were found! 不一定是崩溃原因,它可能是单纯的警报
|
'注意:Fabric 的 Warnings were found! 不一定是崩溃原因,它可能是单纯的警报
|
||||||
End If
|
End If
|
||||||
@@ -717,7 +718,7 @@ NextStack:
|
|||||||
"preinit", "preload", "machine", "reflect", "channel", "general", "handler", "content", "systems", "modules", "service",
|
"preinit", "preload", "machine", "reflect", "channel", "general", "handler", "content", "systems", "modules", "service",
|
||||||
"fastutil", "optifine", "internal", "platform", "override", "fabricmc", "neoforge",
|
"fastutil", "optifine", "internal", "platform", "override", "fabricmc", "neoforge",
|
||||||
"injection", "listeners", "scheduler", "minecraft", "universal", "multipart", "neoforged", "microsoft",
|
"injection", "listeners", "scheduler", "minecraft", "universal", "multipart", "neoforged", "microsoft",
|
||||||
"transformer", "transformers", "minecraftforge", "blockentity", "spongepowered", "electronwill"
|
"transformer", "transformers", "minecraftforge", "blockentity", "spongepowered", "electronwill", "concurrent"
|
||||||
}.Contains(Word.ToLower) Then Continue For
|
}.Contains(Word.ToLower) Then Continue For
|
||||||
PossibleWords.Add(Word.Trim)
|
PossibleWords.Add(Word.Trim)
|
||||||
Next
|
Next
|
||||||
@@ -949,7 +950,7 @@ NextStack:
|
|||||||
Dim Additional As List(Of String) = Reason.Value
|
Dim Additional As List(Of String) = Reason.Value
|
||||||
Select Case Reason.Key
|
Select Case Reason.Key
|
||||||
Case CrashReason.Java虚拟机参数有误
|
Case CrashReason.Java虚拟机参数有误
|
||||||
Results.Add("由于 Java 虚拟机参数有误,导致游戏无法继续运行。\n请检查高级启动选项中设置的 Java 虚拟机参数是否有误。")
|
Results.Add("由于 Java 参数有误,导致游戏无法继续运行。\n请检查高级选项中的 Java 虚拟机参数和游戏参数设置是否有误。")
|
||||||
Case CrashReason.Mod文件被解压
|
Case CrashReason.Mod文件被解压
|
||||||
Results.Add("由于 Mod 文件被解压了,导致游戏无法继续运行。\n直接把整个 Mod 文件放进 Mod 文件夹中即可,若解压就会导致游戏出错。\n\n请删除 Mod 文件夹中已被解压的 Mod,然后再启动游戏。")
|
Results.Add("由于 Mod 文件被解压了,导致游戏无法继续运行。\n直接把整个 Mod 文件放进 Mod 文件夹中即可,若解压就会导致游戏出错。\n\n请删除 Mod 文件夹中已被解压的 Mod,然后再启动游戏。")
|
||||||
Case CrashReason.内存不足
|
Case CrashReason.内存不足
|
||||||
@@ -1030,14 +1031,17 @@ NextStack:
|
|||||||
End If
|
End If
|
||||||
Case CrashReason.特定实体导致崩溃
|
Case CrashReason.特定实体导致崩溃
|
||||||
If Additional.Count = 1 Then
|
If Additional.Count = 1 Then
|
||||||
Dim entityInfo As String = Additional.First
|
If Additional.First.Contains("minecraft:player") Then
|
||||||
If entityInfo.StartsWith("minecraft:player") Then
|
If Additional.First.Contains(" ") Then
|
||||||
Results.Add("游戏似乎因为玩家实体 " & entityInfo & " 出现了问题。\n\n这通常是因为玩家数据损坏或世界存档问题导致的。\n请尝试以下解决方案:\n - 创建一个新世界,观察游戏是否正常运行\n - 如果新世界正常,可能需要删除或修复当前世界的玩家数据文件\n - 也可能是某个 Mod 与玩家实体处理存在冲突,尝试逐个禁用近期安装的 Mod\n - 如果问题持续存在,建议备份重要数据后重新创建世界\h")
|
Results.Add($"游戏因为位于 {Additional.First.AfterFirst(" ")} 的玩家实体导致了崩溃。\h")
|
||||||
Else
|
Else
|
||||||
Results.Add("游戏似乎因为实体 " & entityInfo & " 出现了问题。\n\n请尝试以下解决方案:\n - 创建一个新世界,并尝试生成该类型的实体,观察游戏运行情况\n - 如果新世界中该实体正常,问题可能在于当前世界的数据损坏\n - 如果新世界中仍然崩溃,可能是某个 Mod 导致了实体处理异常\n - 尝试逐个禁用可能影响实体的 Mod(如生物类、AI 类 Mod)\n - 也可以尝试使用指令删除该坐标附近的实体\h")
|
Results.Add($"游戏因为玩家实体导致了崩溃。\h")
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
Results.Add("游戏似乎因为世界中的某些实体出现了问题。\n\n请尝试以下解决方案:\n - 创建一个新世界,观察游戏的运行情况\n - 如果新世界正常运行,则是当前世界的实体数据导致出错\n - 可以尝试使用指令清理异常实体\n - 如果问题持续存在,可能是某个处理实体的 Mod 存在问题\n - 建议逐个禁用近期安装的 Mod,特别是涉及生物、AI 或实体处理的 Mod\h")
|
Results.Add($"游戏因为实体 {Additional.First} 导致了崩溃。\h")
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Results.Add($"游戏因为下列实体导致了崩溃:{Additional.Join("、")}\h")
|
||||||
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 版本,并严格按照对应版本重新安装游戏。")
|
||||||
|
|||||||
@@ -198,7 +198,7 @@
|
|||||||
Private IsNewClientVersionHinted As Boolean = False
|
Private IsNewClientVersionHinted As Boolean = False
|
||||||
Private Sub DlClientListMojangMain(Loader As LoaderTask(Of String, DlClientListResult))
|
Private Sub DlClientListMojangMain(Loader As LoaderTask(Of String, DlClientListResult))
|
||||||
Dim StartTime As Long = GetTimeTick()
|
Dim StartTime As Long = GetTimeTick()
|
||||||
Dim Json As JObject = GetJson(NetRequestByClientRetry("https://launchermeta.mojang.com/mc/game/version_manifest.json"))
|
Dim Json As JObject = GetJson(NetRequestByClientRetry("https://launchermeta.mojang.com/mc/game/version_manifest.json", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Versions As JArray = Json("versions")
|
Dim Versions As JArray = Json("versions")
|
||||||
If Versions.Count < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Json.ToString & ")")
|
If Versions.Count < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Json.ToString & ")")
|
||||||
@@ -235,7 +235,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlClientListBmclapiLoader As New LoaderTask(Of String, DlClientListResult)("DlClientList Bmclapi", AddressOf DlClientListBmclapiMain)
|
Public DlClientListBmclapiLoader As New LoaderTask(Of String, DlClientListResult)("DlClientList Bmclapi", AddressOf DlClientListBmclapiMain)
|
||||||
Private Sub DlClientListBmclapiMain(Loader As LoaderTask(Of String, DlClientListResult))
|
Private Sub DlClientListBmclapiMain(Loader As LoaderTask(Of String, DlClientListResult))
|
||||||
Dim Json As JObject = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/mc/game/version_manifest.json"))
|
Dim Json As JObject = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/mc/game/version_manifest.json", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Versions As JArray = Json("versions")
|
Dim Versions As JArray = Json("versions")
|
||||||
If Versions.Count < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Json.ToString & ")")
|
If Versions.Count < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Json.ToString & ")")
|
||||||
@@ -413,7 +413,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlOptiFineListBmclapiLoader As New LoaderTask(Of Integer, DlOptiFineListResult)("DlOptiFineList Bmclapi", AddressOf DlOptiFineListBmclapiMain)
|
Public DlOptiFineListBmclapiLoader As New LoaderTask(Of Integer, DlOptiFineListResult)("DlOptiFineList Bmclapi", AddressOf DlOptiFineListBmclapiMain)
|
||||||
Private Sub DlOptiFineListBmclapiMain(Loader As LoaderTask(Of Integer, DlOptiFineListResult))
|
Private Sub DlOptiFineListBmclapiMain(Loader As LoaderTask(Of Integer, DlOptiFineListResult))
|
||||||
Dim Json As JArray = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/optifine/versionList"))
|
Dim Json As JArray = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/optifine/versionList", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Versions As New List(Of DlOptiFineListEntry)
|
Dim Versions As New List(Of DlOptiFineListEntry)
|
||||||
For Each Token As JObject In Json
|
For Each Token As JObject In Json
|
||||||
@@ -483,7 +483,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlForgeListOfficialLoader As New LoaderTask(Of Integer, DlForgeListResult)("DlForgeList Official", AddressOf DlForgeListOfficialMain)
|
Public DlForgeListOfficialLoader As New LoaderTask(Of Integer, DlForgeListResult)("DlForgeList Official", AddressOf DlForgeListOfficialMain)
|
||||||
Private Sub DlForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlForgeListResult))
|
Private Sub DlForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlForgeListResult))
|
||||||
Dim Result As String = NetRequestByClientRetry("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.2.4.html", Encoding:=Encoding.Default, Accept:="text/html", UseBrowserUserAgent:=True)
|
Dim Result As String = NetRequestByClientRetry("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.2.4.html", Encoding:=Encoding.Default, Accept:="text/html", SimulateBrowserHeaders:=True)
|
||||||
If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")")
|
If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")")
|
||||||
'获取所有版本信息
|
'获取所有版本信息
|
||||||
Dim Names As List(Of String) = RegexSearch(Result, "(?<=a href=""index_)[0-9.]+(_pre[0-9]?)?(?=.html)")
|
Dim Names As List(Of String) = RegexSearch(Result, "(?<=a href=""index_)[0-9.]+(_pre[0-9]?)?(?=.html)")
|
||||||
@@ -631,9 +631,9 @@
|
|||||||
Try
|
Try
|
||||||
Result = NetRequestByLoader("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" &
|
Result = NetRequestByLoader("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" &
|
||||||
Loader.Input.Replace("-", "_") & '兼容 Forge 1.7.10-pre4,#4057
|
Loader.Input.Replace("-", "_") & '兼容 Forge 1.7.10-pre4,#4057
|
||||||
".html", UseBrowserUserAgent:=True)
|
".html", SimulateBrowserHeaders:=True)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If GetExceptionSummary(ex).Contains("(404)") Then
|
If ex.GetBrief().Contains("(404)") Then
|
||||||
Throw New Exception("不可用")
|
Throw New Exception("不可用")
|
||||||
Else
|
Else
|
||||||
Throw
|
Throw
|
||||||
@@ -701,7 +701,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public Sub DlForgeVersionBmclapiMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
|
Public Sub DlForgeVersionBmclapiMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
|
||||||
Dim Json As JArray = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" &
|
Dim Json As JArray = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" &
|
||||||
Loader.Input.Replace("-", "_"))) '兼容 Forge 1.7.10-pre4,#4057
|
Loader.Input.Replace("-", "_"), RequireJson:=True)) '兼容 Forge 1.7.10-pre4,#4057
|
||||||
Dim Versions As New List(Of DlForgeVersionEntry)
|
Dim Versions As New List(Of DlForgeVersionEntry)
|
||||||
Try
|
Try
|
||||||
Dim Recommended As String = McDownloadForgeRecommendedGet(Loader.Input)
|
Dim Recommended As String = McDownloadForgeRecommendedGet(Loader.Input)
|
||||||
@@ -835,8 +835,8 @@
|
|||||||
Public DlNeoForgeListOfficialLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Official", AddressOf DlNeoForgeListOfficialMain)
|
Public DlNeoForgeListOfficialLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Official", AddressOf DlNeoForgeListOfficialMain)
|
||||||
Private Sub DlNeoForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
Private Sub DlNeoForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
||||||
'获取版本列表 JSON
|
'获取版本列表 JSON
|
||||||
Dim ResultLatest As String = NetRequestByClientRetry("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge")
|
Dim ResultLatest As String = NetRequestByClientRetry("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge", RequireJson:=True)
|
||||||
Dim ResultLegacy As String = NetRequestByClientRetry("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/forge")
|
Dim ResultLegacy As String = NetRequestByClientRetry("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/forge", RequireJson:=True)
|
||||||
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
||||||
'解析
|
'解析
|
||||||
Try
|
Try
|
||||||
@@ -853,8 +853,8 @@
|
|||||||
Public DlNeoForgeListBmclapiLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Bmclapi", AddressOf DlNeoForgeListBmclapiMain)
|
Public DlNeoForgeListBmclapiLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Bmclapi", AddressOf DlNeoForgeListBmclapiMain)
|
||||||
Public Sub DlNeoForgeListBmclapiMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
Public Sub DlNeoForgeListBmclapiMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
|
||||||
'获取版本列表 JSON
|
'获取版本列表 JSON
|
||||||
Dim ResultLatest As String = NetRequestByClientRetry("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/neoforge")
|
Dim ResultLatest As String = NetRequestByClientRetry("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/neoforge", RequireJson:=True)
|
||||||
Dim ResultLegacy As String = NetRequestByClientRetry("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/forge")
|
Dim ResultLegacy As String = NetRequestByClientRetry("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/forge", RequireJson:=True)
|
||||||
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
|
||||||
'解析
|
'解析
|
||||||
Try
|
Try
|
||||||
@@ -959,7 +959,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlLiteLoaderListOfficialLoader As New LoaderTask(Of Integer, DlLiteLoaderListResult)("DlLiteLoaderList Official", AddressOf DlLiteLoaderListOfficialMain)
|
Public DlLiteLoaderListOfficialLoader As New LoaderTask(Of Integer, DlLiteLoaderListResult)("DlLiteLoaderList Official", AddressOf DlLiteLoaderListOfficialMain)
|
||||||
Private Sub DlLiteLoaderListOfficialMain(Loader As LoaderTask(Of Integer, DlLiteLoaderListResult))
|
Private Sub DlLiteLoaderListOfficialMain(Loader As LoaderTask(Of Integer, DlLiteLoaderListResult))
|
||||||
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://dl.liteloader.com/versions/versions.json"))
|
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://dl.liteloader.com/versions/versions.json", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Json As JObject = Result("versions")
|
Dim Json As JObject = Result("versions")
|
||||||
Dim Versions As New List(Of DlLiteLoaderListEntry)
|
Dim Versions As New List(Of DlLiteLoaderListEntry)
|
||||||
@@ -987,7 +987,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlLiteLoaderListBmclapiLoader As New LoaderTask(Of Integer, DlLiteLoaderListResult)("DlLiteLoaderList Bmclapi", AddressOf DlLiteLoaderListBmclapiMain)
|
Public DlLiteLoaderListBmclapiLoader As New LoaderTask(Of Integer, DlLiteLoaderListResult)("DlLiteLoaderList Bmclapi", AddressOf DlLiteLoaderListBmclapiMain)
|
||||||
Private Sub DlLiteLoaderListBmclapiMain(Loader As LoaderTask(Of Integer, DlLiteLoaderListResult))
|
Private Sub DlLiteLoaderListBmclapiMain(Loader As LoaderTask(Of Integer, DlLiteLoaderListResult))
|
||||||
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json"))
|
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Json As JObject = Result("versions")
|
Dim Json As JObject = Result("versions")
|
||||||
Dim Versions As New List(Of DlLiteLoaderListEntry)
|
Dim Versions As New List(Of DlLiteLoaderListEntry)
|
||||||
@@ -1058,7 +1058,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlFabricListOfficialLoader As New LoaderTask(Of Integer, DlFabricListResult)("DlFabricList Official", AddressOf DlFabricListOfficialMain)
|
Public DlFabricListOfficialLoader As New LoaderTask(Of Integer, DlFabricListResult)("DlFabricList Official", AddressOf DlFabricListOfficialMain)
|
||||||
Private Sub DlFabricListOfficialMain(Loader As LoaderTask(Of Integer, DlFabricListResult))
|
Private Sub DlFabricListOfficialMain(Loader As LoaderTask(Of Integer, DlFabricListResult))
|
||||||
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://meta.fabricmc.net/v2/versions"))
|
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://meta.fabricmc.net/v2/versions", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Output = New DlFabricListResult With {.IsOfficial = True, .SourceName = "Fabric 官方源", .Value = Result}
|
Dim Output = New DlFabricListResult With {.IsOfficial = True, .SourceName = "Fabric 官方源", .Value = Result}
|
||||||
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
|
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
|
||||||
@@ -1073,7 +1073,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Public DlFabricListBmclapiLoader As New LoaderTask(Of Integer, DlFabricListResult)("DlFabricList Bmclapi", AddressOf DlFabricListBmclapiMain)
|
Public DlFabricListBmclapiLoader As New LoaderTask(Of Integer, DlFabricListResult)("DlFabricList Bmclapi", AddressOf DlFabricListBmclapiMain)
|
||||||
Private Sub DlFabricListBmclapiMain(Loader As LoaderTask(Of Integer, DlFabricListResult))
|
Private Sub DlFabricListBmclapiMain(Loader As LoaderTask(Of Integer, DlFabricListResult))
|
||||||
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/fabric-meta/v2/versions"))
|
Dim Result As JObject = GetJson(NetRequestByClientRetry("https://bmclapi2.bangbang93.com/fabric-meta/v2/versions", RequireJson:=True))
|
||||||
Try
|
Try
|
||||||
Dim Output = New DlFabricListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Result}
|
Dim Output = New DlFabricListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Result}
|
||||||
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
|
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
|
||||||
@@ -1130,7 +1130,7 @@
|
|||||||
Dim Exs As String = ""
|
Dim Exs As String = ""
|
||||||
For Each Source In Urls
|
For Each Source In Urls
|
||||||
Try
|
Try
|
||||||
Return GetJson(NetRequestByClient(Source.Key, Method, Content, ContentType, Timeout:=Source.Value * 1000, Encoding:=Encoding.UTF8))
|
Return GetJson(NetRequestByClient(Source.Key, Method, Content, ContentType, Timeout:=Source.Value * 1000, Encoding:=Encoding.UTF8, RequireJson:=True))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Exs += ex.Message + vbCrLf
|
Exs += ex.Message + vbCrLf
|
||||||
End Try
|
End Try
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
'路径
|
'路径
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Java.exe 文件的完整路径。
|
''' java.exe 文件的完整路径。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public ReadOnly Property PathJava As String
|
Public ReadOnly Property PathJava As String
|
||||||
Get
|
Get
|
||||||
@@ -18,15 +18,7 @@
|
|||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Javaw.exe 文件的完整路径。
|
''' java.exe 文件所在文件夹的路径,以 \ 结尾。
|
||||||
''' </summary>
|
|
||||||
Public ReadOnly Property PathJavaw As String
|
|
||||||
Get
|
|
||||||
Return PathFolder & "javaw.exe"
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
''' <summary>
|
|
||||||
''' Javaw.exe 文件所在文件夹的路径,以 \ 结尾。
|
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public PathFolder As String
|
Public PathFolder As String
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -102,20 +94,13 @@
|
|||||||
Dim Output As String = Nothing
|
Dim Output As String = Nothing
|
||||||
Try
|
Try
|
||||||
'确定文件存在
|
'确定文件存在
|
||||||
If Not File.Exists(PathJavaw) Then
|
If Not File.Exists(PathJava) Then Throw New FileNotFoundException("未找到 java.exe 文件", PathJava)
|
||||||
Throw New FileNotFoundException("未找到 javaw.exe 文件", PathJavaw)
|
If File.Exists(PathFolder & "pdf-bookmark") Then Throw New Exception("不兼容 PDF Bookmark 的 Java") '#5326
|
||||||
End If
|
|
||||||
If Not File.Exists(PathFolder & "java.exe") Then
|
|
||||||
Throw New FileNotFoundException("未找到 java.exe 文件", PathFolder & "java.exe")
|
|
||||||
End If
|
|
||||||
If File.Exists(PathFolder & "pdf-bookmark") Then
|
|
||||||
Throw New Exception("不兼容 PDF Bookmark 的 Java") '#5326
|
|
||||||
End If
|
|
||||||
IsJre = Not File.Exists(PathFolder & "javac.exe")
|
IsJre = Not File.Exists(PathFolder & "javac.exe")
|
||||||
'运行 -version
|
'运行 -version
|
||||||
Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 15000).ToLower
|
Output = ShellAndGetOutput(PathJava, "-version", 15000).ToLower
|
||||||
If Output = "" Then Throw New ApplicationException("尝试运行该 Java 失败")
|
If Output = "" Then Throw New ApplicationException("尝试运行该 Java 失败")
|
||||||
If ModeDebug Then Log("[Java] Java 检查输出:" & PathFolder & "java.exe" & vbCrLf & Output)
|
If ModeDebug Then Log("[Java] Java 检查输出:" & PathJava & vbCrLf & Output)
|
||||||
If Output.Contains("/lib/ext exists") Then Throw New ApplicationException("无法运行该 Java,请在删除 Java 文件夹中的 /lib/ext 文件夹后再试")
|
If Output.Contains("/lib/ext exists") Then Throw New ApplicationException("无法运行该 Java,请在删除 Java 文件夹中的 /lib/ext 文件夹后再试")
|
||||||
If Output.Contains("a fatal error") Then Throw New ApplicationException("无法运行该 Java,该 Java 或系统存在问题")
|
If Output.Contains("a fatal error") Then Throw New ApplicationException("无法运行该 Java,该 Java 或系统存在问题")
|
||||||
'获取详细信息
|
'获取详细信息
|
||||||
@@ -136,17 +121,17 @@
|
|||||||
End If
|
End If
|
||||||
Is64Bit = Output.Contains("64-bit")
|
Is64Bit = Output.Contains("64-bit")
|
||||||
If Version.Minor <= 4 OrElse Version.Minor >= 100 Then Throw New ApplicationException("分析详细信息失败,获取的版本为 " & Version.ToString)
|
If Version.Minor <= 4 OrElse Version.Minor >= 100 Then Throw New ApplicationException("分析详细信息失败,获取的版本为 " & Version.ToString)
|
||||||
'基于 #3649,在 64 位系统上禁用 32 位 Java
|
'#3649:在 64 位系统上禁用 32 位 Java
|
||||||
If Not Is64Bit AndAlso Not Is32BitSystem Then Throw New Exception("该 Java 为 32 位版本,请安装 64 位的 Java")
|
If Not Is64Bit AndAlso Not Is32BitSystem Then Throw New Exception("该 Java 为 32 位版本,请安装 64 位的 Java")
|
||||||
'基于 #2249 发现 JRE 17 似乎也导致了 Forge 安装失败,干脆禁用更多版本的 JRE
|
'#2249:JRE 17 似乎会导致 Forge 安装失败,干脆禁用更多版本的 JRE
|
||||||
If IsJre AndAlso VersionCode >= 16 Then Throw New Exception("由于高版本 JRE 对游戏的兼容性很差,因此不再允许使用。你可以使用对应版本的 JDK,而非 JRE!")
|
If IsJre AndAlso VersionCode >= 16 Then Throw New Exception("由于高版本 JRE 对游戏的兼容性很差,因此不再允许使用。你可以使用对应版本的 JDK,而非 JRE!")
|
||||||
Catch ex As ApplicationException
|
Catch ex As ApplicationException
|
||||||
Throw ex
|
Throw ex
|
||||||
Catch ex As ThreadInterruptedException
|
Catch ex As ThreadInterruptedException
|
||||||
Throw ex
|
Throw ex
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log("[Java] 检查失败的 Java 输出:" & PathFolder & "java.exe" & vbCrLf & If(Output, "无程序输出"))
|
Log("[Java] 检查失败的 Java 输出:" & If(PathJava, "Nothing") & vbCrLf & If(Output, "无程序输出"))
|
||||||
Throw New Exception("检查 Java 失败(" & If(PathJavaw, "Nothing") & ")", ex)
|
Throw New Exception("检查 Java 失败(" & If(PathJava, "Nothing") & ")", ex)
|
||||||
End Try
|
End Try
|
||||||
IsChecked = True
|
IsChecked = True
|
||||||
End Sub
|
End Sub
|
||||||
@@ -689,7 +674,7 @@ Wait:
|
|||||||
"应用", "运行", "前置", "mojang", "官启", "新建文件夹", "eclipse", "microsoft", "hotspot",
|
"应用", "运行", "前置", "mojang", "官启", "新建文件夹", "eclipse", "microsoft", "hotspot",
|
||||||
"runtime", "x86", "x64", "forge", "原版", "optifine", "官方", "启动", "hmcl", "mod", "高清",
|
"runtime", "x86", "x64", "forge", "原版", "optifine", "官方", "启动", "hmcl", "mod", "高清",
|
||||||
"download", "launch", "程序", "path", "version", "baka", "pcl", "zulu", "local", "packages",
|
"download", "launch", "程序", "path", "version", "baka", "pcl", "zulu", "local", "packages",
|
||||||
"4297127d64ec6", "1.", "启动", "jbr-"}
|
"4297127d64ec6", "1.", "启动", "jbr"}
|
||||||
For Each FolderInfo As DirectoryInfo In OriginalPath.EnumerateDirectories
|
For Each FolderInfo As DirectoryInfo In OriginalPath.EnumerateDirectories
|
||||||
If FolderInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) Then Continue For '跳过符号链接
|
If FolderInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) Then Continue For '跳过符号链接
|
||||||
Dim SearchEntry = GetFolderNameFromPath(FolderInfo.Name).ToLower '用于搜索的字符串
|
Dim SearchEntry = GetFolderNameFromPath(FolderInfo.Name).ToLower '用于搜索的字符串
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ NextInner:
|
|||||||
GoTo NextInner
|
GoTo NextInner
|
||||||
Else
|
Else
|
||||||
'没有特殊处理过的错误信息
|
'没有特殊处理过的错误信息
|
||||||
McLaunchLog("错误:" & GetExceptionDetail(ex))
|
McLaunchLog("错误:" & ex.GetDetail())
|
||||||
Log(ex,
|
Log(ex,
|
||||||
If(IsSavingBatch, "导出启动脚本失败", "Minecraft 启动失败"), LogLevel.Msgbox,
|
If(IsSavingBatch, "导出启动脚本失败", "Minecraft 启动失败"), LogLevel.Msgbox,
|
||||||
If(IsSavingBatch, "导出启动脚本失败", "启动失败"))
|
If(IsSavingBatch, "导出启动脚本失败", "启动失败"))
|
||||||
@@ -187,7 +187,7 @@ NextInner:
|
|||||||
Telemetry("Minecraft 启动失败",
|
Telemetry("Minecraft 启动失败",
|
||||||
"Version", McVersionCurrent.Version.ToString,
|
"Version", McVersionCurrent.Version.ToString,
|
||||||
"LoginType", GetStringFromEnum(CType(Setup.Get("LoginType"), McLoginType)),
|
"LoginType", GetStringFromEnum(CType(Setup.Get("LoginType"), McLoginType)),
|
||||||
"Exception", FilterUserName(FilterAccessToken(GetExceptionDetail(ex), "*"), "*"))
|
"Exception", FilterUserName(FilterAccessToken(ex.GetDetail(), "*"), "*"))
|
||||||
End If
|
End If
|
||||||
Throw
|
Throw
|
||||||
End If
|
End If
|
||||||
@@ -609,12 +609,8 @@ SkipLogin:
|
|||||||
McLoginRequestValidate(Data)
|
McLoginRequestValidate(Data)
|
||||||
GoTo LoginFinish
|
GoTo LoginFinish
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Dim AllMessage = GetExceptionDetail(ex)
|
Log(ex, "验证登录失败")
|
||||||
McLaunchLog("验证登录失败:" & AllMessage)
|
If IsNetworkRelated(ex) Then Throw New Exception("$登录失败:你的网络环境不佳,导致难以连接到海外服务器。" & vbCrLf & "请稍后再试,或使用加速器、VPN 改善网络环境。")
|
||||||
If (AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout")) AndAlso Not AllMessage.Contains("403") Then
|
|
||||||
McLaunchLog("已触发超时登录失败")
|
|
||||||
Throw New Exception("$登录失败:你的网络环境不佳,导致难以连接到海外服务器。" & vbCrLf & "请稍后重试,或使用加速器或 VPN 以改善网络环境。")
|
|
||||||
End If
|
|
||||||
End Try
|
End Try
|
||||||
Data.Progress = 0.25
|
Data.Progress = 0.25
|
||||||
'尝试刷新登录
|
'尝试刷新登录
|
||||||
@@ -624,7 +620,7 @@ Refresh:
|
|||||||
McLoginRequestRefresh(Data, NeedRefresh)
|
McLoginRequestRefresh(Data, NeedRefresh)
|
||||||
GoTo LoginFinish
|
GoTo LoginFinish
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
McLaunchLog("刷新登录失败:" & GetExceptionDetail(ex))
|
McLaunchLog("刷新登录失败:" & ex.GetDetail())
|
||||||
If WasRefreshed Then Throw New Exception("二轮刷新登录失败", ex)
|
If WasRefreshed Then Throw New Exception("二轮刷新登录失败", ex)
|
||||||
End Try
|
End Try
|
||||||
Data.Progress = If(NeedRefresh, 0.85, 0.45)
|
Data.Progress = If(NeedRefresh, 0.85, 0.45)
|
||||||
@@ -634,7 +630,7 @@ Refresh:
|
|||||||
If Data.IsAborted Then Throw New ThreadInterruptedException
|
If Data.IsAborted Then Throw New ThreadInterruptedException
|
||||||
NeedRefresh = McLoginRequestLogin(Data)
|
NeedRefresh = McLoginRequestLogin(Data)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
McLaunchLog("登录失败:" & GetExceptionDetail(ex))
|
McLaunchLog("登录失败:" & ex.GetDetail())
|
||||||
Throw
|
Throw
|
||||||
End Try
|
End Try
|
||||||
If NeedRefresh Then
|
If NeedRefresh Then
|
||||||
@@ -699,7 +695,7 @@ LoginFinish:
|
|||||||
'发送登录请求
|
'发送登录请求
|
||||||
Dim RequestData As New JObject(
|
Dim RequestData As New JObject(
|
||||||
New JProperty("accessToken", AccessToken), New JProperty("clientToken", ClientToken), New JProperty("requestUser", True))
|
New JProperty("accessToken", AccessToken), New JProperty("clientToken", ClientToken), New JProperty("requestUser", True))
|
||||||
NetRequestByClientRetry(
|
NetRequestByClient(
|
||||||
Data.Input.BaseUrl & "/validate", HttpMethod.Post,
|
Data.Input.BaseUrl & "/validate", HttpMethod.Post,
|
||||||
Content:=RequestData.ToString(Newtonsoft.Json.Formatting.None),
|
Content:=RequestData.ToString(Newtonsoft.Json.Formatting.None),
|
||||||
Headers:={{"Accept-Language", "zh-CN"}},
|
Headers:={{"Accept-Language", "zh-CN"}},
|
||||||
@@ -726,7 +722,7 @@ LoginFinish:
|
|||||||
New JProperty("requestUser", True)
|
New JProperty("requestUser", True)
|
||||||
).ToString(Newtonsoft.Json.Formatting.None),
|
).ToString(Newtonsoft.Json.Formatting.None),
|
||||||
Headers:={{"Accept-Language", "zh-CN"}},
|
Headers:={{"Accept-Language", "zh-CN"}},
|
||||||
ContentType:="application/json; charset=utf-8"))
|
ContentType:="application/json; charset=utf-8", RequireJson:=True))
|
||||||
'将登录结果输出
|
'将登录结果输出
|
||||||
If LoginJson("selectedProfile") Is Nothing Then Throw New Exception("选择的角色 " & Setup.Get("Cache" & Data.Input.Token & "Name") & " 无效!")
|
If LoginJson("selectedProfile") Is Nothing Then Throw New Exception("选择的角色 " & Setup.Get("Cache" & Data.Input.Token & "Name") & " 无效!")
|
||||||
Data.Output.AccessToken = LoginJson("accessToken").ToString
|
Data.Output.AccessToken = LoginJson("accessToken").ToString
|
||||||
@@ -756,7 +752,7 @@ LoginFinish:
|
|||||||
Data.Input.BaseUrl & "/authenticate", HttpMethod.Post,
|
Data.Input.BaseUrl & "/authenticate", HttpMethod.Post,
|
||||||
Content:=RequestData.ToString(Newtonsoft.Json.Formatting.None),
|
Content:=RequestData.ToString(Newtonsoft.Json.Formatting.None),
|
||||||
Headers:={{"Accept-Language", "zh-CN"}},
|
Headers:={{"Accept-Language", "zh-CN"}},
|
||||||
ContentType:="application/json; charset=utf-8"))
|
ContentType:="application/json; charset=utf-8", RequireJson:=True))
|
||||||
'检查登录结果
|
'检查登录结果
|
||||||
If LoginJson("availableProfiles").Count = 0 Then
|
If LoginJson("availableProfiles").Count = 0 Then
|
||||||
If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色,无法更换!", HintType.Critical)
|
If Data.Input.ForceReselectProfile Then Hint("你还没有创建角色,无法更换!", HintType.Critical)
|
||||||
@@ -814,13 +810,14 @@ LoginFinish:
|
|||||||
McLaunchLog("登录成功(Login, " & Data.Input.Token & ")")
|
McLaunchLog("登录成功(Login, " & Data.Input.Token & ")")
|
||||||
Return NeedRefresh
|
Return NeedRefresh
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Dim AllMessage As String = GetExceptionSummary(ex)
|
Dim AllMessage As String = ex.GetBrief()
|
||||||
Log(ex, "登录失败原始错误信息", LogLevel.Normal)
|
Log(ex, "登录失败原始错误信息", LogLevel.Normal)
|
||||||
'读取服务器返回的错误
|
'读取服务器返回的错误
|
||||||
If TypeOf ex Is ResponsedWebException Then
|
If TypeOf ex Is ResponsedWebException Then
|
||||||
Dim ErrorMessage As String = Nothing
|
Dim ErrorMessage As String = Nothing
|
||||||
Try
|
Try
|
||||||
ErrorMessage = GetJson(DirectCast(ex, ResponsedWebException).Response)("errorMessage")
|
Dim Response = DirectCast(ex, ResponsedWebException).Response
|
||||||
|
If ErrorMessage.ContainsF("errorMessage", True) Then ErrorMessage = GetJson(Response)("errorMessage")
|
||||||
Catch
|
Catch
|
||||||
End Try
|
End Try
|
||||||
If Not String.IsNullOrWhiteSpace(ErrorMessage) Then
|
If Not String.IsNullOrWhiteSpace(ErrorMessage) Then
|
||||||
@@ -838,7 +835,7 @@ LoginFinish:
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
'通用关键字检测
|
'通用关键字检测
|
||||||
If AllMessage.Contains("403") Then
|
If AllMessage.Contains("(403)") Then
|
||||||
Select Case Data.Input.Type
|
Select Case Data.Input.Type
|
||||||
Case McLoginType.Auth
|
Case McLoginType.Auth
|
||||||
Throw New Exception("$登录失败,以下为可能的原因:" & vbCrLf &
|
Throw New Exception("$登录失败,以下为可能的原因:" & vbCrLf &
|
||||||
@@ -852,8 +849,8 @@ LoginFinish:
|
|||||||
If(Data.Input.UserName.Contains("@"), "", " - 登录账号应为邮箱或统一通行证账号,而非游戏角色 ID。" & vbCrLf) &
|
If(Data.Input.UserName.Contains("@"), "", " - 登录账号应为邮箱或统一通行证账号,而非游戏角色 ID。" & vbCrLf) &
|
||||||
" - 只注册了账号,但没有加入对应服务器。")
|
" - 只注册了账号,但没有加入对应服务器。")
|
||||||
End Select
|
End Select
|
||||||
ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") OrElse AllMessage.Contains("网络请求失败") OrElse AllMessage.Contains("408") OrElse AllMessage.Contains("由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。") Then
|
ElseIf ex.IsNetworkRelated() Then
|
||||||
Throw New Exception("$登录失败:你的网络环境不佳,导致难以连接到海外服务器。" & vbCrLf & "请稍后重试,或使用加速器或 VPN 以改善网络环境。")
|
Throw New Exception("$登录失败:你的网络环境不佳,导致难以连接到海外服务器。" & vbCrLf & "请稍后再试,或使用加速器、VPN 改善网络环境。")
|
||||||
ElseIf ex.Message.StartsWithF("$") Then
|
ElseIf ex.Message.StartsWithF("$") Then
|
||||||
Throw
|
Throw
|
||||||
Else
|
Else
|
||||||
@@ -872,7 +869,7 @@ Retry:
|
|||||||
McLaunchLog("开始微软登录步骤 1/6(原始登录)")
|
McLaunchLog("开始微软登录步骤 1/6(原始登录)")
|
||||||
Dim PrepareJson As JObject = GetJson(NetRequestByClientRetry("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode", HttpMethod.Post,
|
Dim PrepareJson As JObject = GetJson(NetRequestByClientRetry("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode", HttpMethod.Post,
|
||||||
Content:=$"client_id={OAuthClientId}&tenant=/consumers&scope=XboxLive.signin%20offline_access",
|
Content:=$"client_id={OAuthClientId}&tenant=/consumers&scope=XboxLive.signin%20offline_access",
|
||||||
ContentType:="application/x-www-form-urlencoded"))
|
ContentType:="application/x-www-form-urlencoded", RequireJson:=True))
|
||||||
McLaunchLog("网页登录地址:" & PrepareJson("verification_uri").ToString)
|
McLaunchLog("网页登录地址:" & PrepareJson("verification_uri").ToString)
|
||||||
|
|
||||||
'弹窗
|
'弹窗
|
||||||
@@ -907,6 +904,7 @@ Retry:
|
|||||||
Headers:={{"Accept-Language", "en-US,en;q=0.5"}, {"X-Requested-With", "XMLHttpRequest"}},
|
Headers:={{"Accept-Language", "en-US,en;q=0.5"}, {"X-Requested-With", "XMLHttpRequest"}},
|
||||||
ThreadCount:=2)
|
ThreadCount:=2)
|
||||||
Catch ex As ResponsedWebException
|
Catch ex As ResponsedWebException
|
||||||
|
'修改错误列表时,同时检查 MyMsgLogin.xaml.vb 中的对应代码
|
||||||
Dim Response = ex.Response
|
Dim Response = ex.Response
|
||||||
If Response.ContainsF("must sign in again", True) OrElse Response.ContainsF("password expired", True) OrElse
|
If Response.ContainsF("must sign in again", True) OrElse Response.ContainsF("password expired", True) OrElse
|
||||||
(Response.Contains("refresh_token") AndAlso Response.Contains("is not valid")) Then '#269
|
(Response.Contains("refresh_token") AndAlso Response.Contains("is not valid")) Then '#269
|
||||||
@@ -941,7 +939,7 @@ Retry:
|
|||||||
""TokenType"": ""JWT""
|
""TokenType"": ""JWT""
|
||||||
}"
|
}"
|
||||||
Dim Result As String = NetRequestByClientMultiple("https://user.auth.xboxlive.com/user/authenticate", HttpMethod.Post,
|
Dim Result As String = NetRequestByClientMultiple("https://user.auth.xboxlive.com/user/authenticate", HttpMethod.Post,
|
||||||
Content:=Request, ContentType:="application/json")
|
Content:=Request, ContentType:="application/json", RequireJson:=True)
|
||||||
Dim ResultJson As JObject = GetJson(Result)
|
Dim ResultJson As JObject = GetJson(Result)
|
||||||
Dim XBLToken As String = ResultJson("Token").ToString
|
Dim XBLToken As String = ResultJson("Token").ToString
|
||||||
Return XBLToken
|
Return XBLToken
|
||||||
@@ -963,7 +961,7 @@ Retry:
|
|||||||
Dim Result As String
|
Dim Result As String
|
||||||
Try
|
Try
|
||||||
Result = NetRequestByClientMultiple("https://xsts.auth.xboxlive.com/xsts/authorize", HttpMethod.Post,
|
Result = NetRequestByClientMultiple("https://xsts.auth.xboxlive.com/xsts/authorize", HttpMethod.Post,
|
||||||
Content:=Request, ContentType:="application/json")
|
Content:=Request, ContentType:="application/json", RequireJson:=True)
|
||||||
Catch ex As ResponsedWebException
|
Catch ex As ResponsedWebException
|
||||||
'参考 https://github.com/PrismarineJS/prismarine-auth/blob/master/src/common/Constants.js
|
'参考 https://github.com/PrismarineJS/prismarine-auth/blob/master/src/common/Constants.js
|
||||||
If ex.Response.Contains("2148916227") Then
|
If ex.Response.Contains("2148916227") Then
|
||||||
@@ -975,7 +973,7 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
Throw New Exception("$$")
|
Throw New Exception("$$")
|
||||||
ElseIf ex.Response.Contains("2148916235") Then
|
ElseIf ex.Response.Contains("2148916235") Then
|
||||||
MyMsgBox($"你的网络所在的国家或地区无法登录微软账号。{vbCrLf}请使用加速器或 VPN。", "登录失败", "我知道了")
|
MyMsgBox($"你的网络所在的国家或地区无法登录微软账号。{vbCrLf}请使用加速器或 VPN,然后再试。", "登录失败", "我知道了")
|
||||||
Throw New Exception("$$")
|
Throw New Exception("$$")
|
||||||
ElseIf ex.Response.Contains("2148916238") Then
|
ElseIf ex.Response.Contains("2148916238") Then
|
||||||
If MyMsgBox("该账号年龄不足,你需要先修改出生日期,然后才能登录。" & vbCrLf &
|
If MyMsgBox("该账号年龄不足,你需要先修改出生日期,然后才能登录。" & vbCrLf &
|
||||||
@@ -994,15 +992,11 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
|
|
||||||
Try '这个 Try 块仅为了追踪 #6683 而添加
|
|
||||||
Dim ResultJson As JObject = GetJson(Result)
|
Dim ResultJson As JObject = GetJson(Result)
|
||||||
Dim XSTSToken As String = ResultJson("Token").ToString
|
Return {
|
||||||
Dim UHS As String = ResultJson("DisplayClaims")("xui")(0)("uhs").ToString
|
ResultJson("Token"), 'XSTSToken
|
||||||
Return {XSTSToken, UHS}
|
ResultJson("DisplayClaims")("xui")(0)("uhs") 'UHS
|
||||||
Catch
|
}
|
||||||
Log("[Launch] 返回内容:" & vbCrLf & Result)
|
|
||||||
Throw
|
|
||||||
End Try
|
|
||||||
End Function
|
End Function
|
||||||
'微软登录步骤 4:从 {XSTSToken, UHS} 获取 Minecraft AccessToken
|
'微软登录步骤 4:从 {XSTSToken, UHS} 获取 Minecraft AccessToken
|
||||||
Private Function MsLoginStep4(Tokens As String()) As String
|
Private Function MsLoginStep4(Tokens As String()) As String
|
||||||
@@ -1012,9 +1006,9 @@ Retry:
|
|||||||
Dim Result As String
|
Dim Result As String
|
||||||
Try
|
Try
|
||||||
Result = NetRequestByClientRetry("https://api.minecraftservices.com/authentication/login_with_xbox", HttpMethod.Post,
|
Result = NetRequestByClientRetry("https://api.minecraftservices.com/authentication/login_with_xbox", HttpMethod.Post,
|
||||||
Content:=Request, ContentType:="application/json")
|
Content:=Request, ContentType:="application/json", RequireJson:=True)
|
||||||
Catch ex As Net.WebException
|
Catch ex As Net.WebException
|
||||||
Dim Message As String = GetExceptionSummary(ex)
|
Dim Message As String = ex.GetBrief()
|
||||||
If Message.Contains("(429)") Then
|
If Message.Contains("(429)") Then
|
||||||
Log(ex, "微软登录第 4 步汇报 429")
|
Log(ex, "微软登录第 4 步汇报 429")
|
||||||
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
|
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
|
||||||
@@ -1026,16 +1020,14 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
|
|
||||||
Dim ResultJson As JObject = GetJson(Result)
|
Return GetJson(Result)("access_token").ToString
|
||||||
Dim AccessToken As String = ResultJson("access_token").ToString
|
|
||||||
Return AccessToken
|
|
||||||
End Function
|
End Function
|
||||||
'微软登录步骤 5:验证微软账号是否持有 MC,这也会刷新 XGP
|
'微软登录步骤 5:验证微软账号是否持有 MC,这也会刷新 XGP
|
||||||
Private Sub MsLoginStep5(AccessToken As String)
|
Private Sub MsLoginStep5(AccessToken As String)
|
||||||
McLaunchLog("开始微软登录步骤 5/6")
|
McLaunchLog("开始微软登录步骤 5/6")
|
||||||
|
|
||||||
Dim Result As String = NetRequestByClientMultiple("https://api.minecraftservices.com/entitlements/mcstore",
|
Dim Result As String = NetRequestByClientMultiple("https://api.minecraftservices.com/entitlements/mcstore",
|
||||||
ContentType:="application/json", ThreadCount:=2, Headers:={{"Authorization", "Bearer " & AccessToken}})
|
ContentType:="application/json", ThreadCount:=2, Headers:={{"Authorization", "Bearer " & AccessToken}}, RequireJson:=True)
|
||||||
Try
|
Try
|
||||||
Dim ResultJson As JObject = GetJson(Result)
|
Dim ResultJson As JObject = GetJson(Result)
|
||||||
If Not (ResultJson.ContainsKey("items") AndAlso ResultJson("items").Any) Then
|
If Not (ResultJson.ContainsKey("items") AndAlso ResultJson("items").Any) Then
|
||||||
@@ -1057,9 +1049,9 @@ Retry:
|
|||||||
Dim Result As String
|
Dim Result As String
|
||||||
Try
|
Try
|
||||||
Result = NetRequestByClientMultiple("https://api.minecraftservices.com/minecraft/profile",
|
Result = NetRequestByClientMultiple("https://api.minecraftservices.com/minecraft/profile",
|
||||||
ContentType:="application/json", ThreadCount:=2, Headers:={{"Authorization", "Bearer " & AccessToken}})
|
ContentType:="application/json", ThreadCount:=2, Headers:={{"Authorization", "Bearer " & AccessToken}}, RequireJson:=True)
|
||||||
Catch ex As Net.WebException
|
Catch ex As WebException
|
||||||
Dim Message As String = GetExceptionSummary(ex)
|
Dim Message As String = ex.GetBrief()
|
||||||
If Message.Contains("(429)") Then
|
If Message.Contains("(429)") Then
|
||||||
Log(ex, "微软登录第 6 步汇报 429")
|
Log(ex, "微软登录第 6 步汇报 429")
|
||||||
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
|
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
|
||||||
@@ -1130,7 +1122,7 @@ Retry:
|
|||||||
If Len(Uuid) = 32 Then Return Uuid
|
If Len(Uuid) = 32 Then Return Uuid
|
||||||
'从官网获取
|
'从官网获取
|
||||||
Try
|
Try
|
||||||
Dim GotJson As JObject = GetJson(NetRequestByClientRetry("https://api.mojang.com/users/profiles/minecraft/" & Name))
|
Dim GotJson As JObject = GetJson(NetRequestByClientRetry("https://api.mojang.com/users/profiles/minecraft/" & Name, RequireJson:=True))
|
||||||
If GotJson Is Nothing Then Throw New FileNotFoundException("正版玩家档案不存在(" & Name & ")")
|
If GotJson Is Nothing Then Throw New FileNotFoundException("正版玩家档案不存在(" & Name & ")")
|
||||||
Uuid = If(GotJson("id"), "")
|
Uuid = If(GotJson("id"), "")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -1495,6 +1487,9 @@ Retry:
|
|||||||
DataList.Add(Version.JsonObject("mainClass"))
|
DataList.Add(Version.JsonObject("mainClass"))
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
'处理 DataList 的换行符
|
||||||
|
DataList = DataList.Select(Function(d) d.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr, " ").Trim).ToList
|
||||||
|
|
||||||
Return Join(DataList, " ")
|
Return Join(DataList, " ")
|
||||||
End Function
|
End Function
|
||||||
Private Function McLaunchArgumentsJvmNew(Version As McVersion) As String
|
Private Function McLaunchArgumentsJvmNew(Version As McVersion) As String
|
||||||
@@ -1538,9 +1533,7 @@ NextVersion:
|
|||||||
'Authlib-Injector
|
'Authlib-Injector
|
||||||
If McLoginLoader.Output.Type = "Auth" Then
|
If McLoginLoader.Output.Type = "Auth" Then
|
||||||
If McLaunchJavaSelected.VersionCode >= 6 Then DataList.Add("-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT") '信任系统根证书(5252#)
|
If McLaunchJavaSelected.VersionCode >= 6 Then DataList.Add("-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT") '信任系统根证书(5252#)
|
||||||
Dim Server As String = If(McLoginLoader.Input.Type = McLoginType.Legacy,
|
Dim Server As String = Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)
|
||||||
"http://hiperauth.tech/api/yggdrasil-hiper/", 'HiPer 登录
|
|
||||||
Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent))
|
|
||||||
Try
|
Try
|
||||||
Dim Response As String = NetRequestByClientRetry(Server, Encoding:=Encoding.UTF8)
|
Dim Response As String = NetRequestByClientRetry(Server, Encoding:=Encoding.UTF8)
|
||||||
DataList.Insert(0, "-javaagent:""" & PathPure & "authlib-injector.jar""=" & Server &
|
DataList.Insert(0, "-javaagent:""" & PathPure & "authlib-injector.jar""=" & Server &
|
||||||
@@ -1562,7 +1555,7 @@ NextVersion:
|
|||||||
'如果不合并,会导致 Forge 1.17 启动无效,它有两个 --add-exports,进一步导致其中一个在后面被去重
|
'如果不合并,会导致 Forge 1.17 启动无效,它有两个 --add-exports,进一步导致其中一个在后面被去重
|
||||||
Dim DeDuplicateDataList As New List(Of String)
|
Dim DeDuplicateDataList As New List(Of String)
|
||||||
For i = 0 To DataList.Count - 1
|
For i = 0 To DataList.Count - 1
|
||||||
Dim CurrentEntry As String = DataList(i)
|
Dim CurrentEntry As String = DataList(i).Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr, " ").Trim
|
||||||
If DataList(i).StartsWithF("-") Then
|
If DataList(i).StartsWithF("-") Then
|
||||||
Do While i < DataList.Count - 1
|
Do While i < DataList.Count - 1
|
||||||
If DataList(i + 1).StartsWithF("-") Then
|
If DataList(i + 1).StartsWithF("-") Then
|
||||||
@@ -1803,7 +1796,7 @@ NextVersion:
|
|||||||
File.Delete(FilePath)
|
File.Delete(FilePath)
|
||||||
Catch ex As UnauthorizedAccessException
|
Catch ex As UnauthorizedAccessException
|
||||||
McLaunchLog("删除原 dll 访问被拒绝,这通常代表有一个 MC 正在运行,跳过解压:" & FilePath)
|
McLaunchLog("删除原 dll 访问被拒绝,这通常代表有一个 MC 正在运行,跳过解压:" & FilePath)
|
||||||
McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
|
McLaunchLog("实际的错误信息:" & ex.GetDetail())
|
||||||
Exit For
|
Exit For
|
||||||
End Try
|
End Try
|
||||||
End If
|
End If
|
||||||
@@ -1823,7 +1816,7 @@ NextVersion:
|
|||||||
File.Delete(FileName)
|
File.Delete(FileName)
|
||||||
Catch ex As UnauthorizedAccessException
|
Catch ex As UnauthorizedAccessException
|
||||||
McLaunchLog("删除多余文件访问被拒绝,跳过删除步骤")
|
McLaunchLog("删除多余文件访问被拒绝,跳过删除步骤")
|
||||||
McLaunchLog("实际的错误信息:" & GetExceptionSummary(ex))
|
McLaunchLog("实际的错误信息:" & ex.GetDetail())
|
||||||
Return
|
Return
|
||||||
End Try
|
End Try
|
||||||
Next
|
Next
|
||||||
@@ -1849,7 +1842,7 @@ NextVersion:
|
|||||||
'要求 Java 使用高性能显卡
|
'要求 Java 使用高性能显卡
|
||||||
If Setup.Get("LaunchAdvanceGraphicCard") Then
|
If Setup.Get("LaunchAdvanceGraphicCard") Then
|
||||||
Try
|
Try
|
||||||
SetGPUPreference(McLaunchJavaSelected.PathJavaw)
|
SetGPUPreference(McLaunchJavaSelected.PathJava)
|
||||||
SetGPUPreference(PathWithName)
|
SetGPUPreference(PathWithName)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If IsAdmin() Then
|
If IsAdmin() Then
|
||||||
@@ -1857,7 +1850,7 @@ NextVersion:
|
|||||||
Else
|
Else
|
||||||
Log(ex, "直接调整显卡设置失败,将以管理员权限重启 PCL 再次尝试")
|
Log(ex, "直接调整显卡设置失败,将以管理员权限重启 PCL 再次尝试")
|
||||||
Try
|
Try
|
||||||
If RunAsAdmin($"--gpu ""{McLaunchJavaSelected.PathJavaw}""") = ProcessReturnValues.TaskDone Then
|
If RunAsAdmin($"--gpu ""{McLaunchJavaSelected.PathJava}""") = ProcessReturnValues.TaskDone Then
|
||||||
McLaunchLog("以管理员权限重启 PCL 并调整显卡设置成功")
|
McLaunchLog("以管理员权限重启 PCL 并调整显卡设置成功")
|
||||||
Else
|
Else
|
||||||
Throw New Exception("调整过程中出现异常")
|
Throw New Exception("调整过程中出现异常")
|
||||||
@@ -2218,7 +2211,7 @@ IgnoreCustomSkin:
|
|||||||
|
|
||||||
'启动信息
|
'启动信息
|
||||||
Dim GameProcess = New Process()
|
Dim GameProcess = New Process()
|
||||||
Dim StartInfo As New ProcessStartInfo(McLaunchJavaSelected.PathJavaw)
|
Dim StartInfo As New ProcessStartInfo(McLaunchJavaSelected.PathJava) '使用 javaw.exe 会导致 #6263
|
||||||
|
|
||||||
'设置环境变量
|
'设置环境变量
|
||||||
Dim Paths As New List(Of String)(StartInfo.EnvironmentVariables("Path").Split(";"))
|
Dim Paths As New List(Of String)(StartInfo.EnvironmentVariables("Path").Split(";"))
|
||||||
@@ -2231,13 +2224,13 @@ IgnoreCustomSkin:
|
|||||||
StartInfo.UseShellExecute = False
|
StartInfo.UseShellExecute = False
|
||||||
StartInfo.RedirectStandardOutput = True
|
StartInfo.RedirectStandardOutput = True
|
||||||
StartInfo.RedirectStandardError = True
|
StartInfo.RedirectStandardError = True
|
||||||
StartInfo.CreateNoWindow = False
|
StartInfo.CreateNoWindow = True
|
||||||
StartInfo.Arguments = McLaunchArgument
|
StartInfo.Arguments = McLaunchArgument
|
||||||
GameProcess.StartInfo = StartInfo
|
GameProcess.StartInfo = StartInfo
|
||||||
|
|
||||||
'开始进程
|
'开始进程
|
||||||
GameProcess.Start()
|
GameProcess.Start()
|
||||||
McLaunchLog("已启动游戏进程:" & McLaunchJavaSelected.PathJavaw)
|
McLaunchLog("已启动游戏进程:" & McLaunchJavaSelected.PathJava)
|
||||||
If Loader.IsAborted Then
|
If Loader.IsAborted Then
|
||||||
McLaunchLog("由于取消启动,已强制结束游戏进程") '#1631
|
McLaunchLog("由于取消启动,已强制结束游戏进程") '#1631
|
||||||
GameProcess.Kill()
|
GameProcess.Kill()
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ Public Module ModMinecraft
|
|||||||
Next
|
Next
|
||||||
If Not Renamed Then CacheMcFolderList.Add(New McFolder With {.Name = Name, .Path = Path, .Type = McFolderType.Custom})
|
If Not Renamed Then CacheMcFolderList.Add(New McFolder With {.Name = Name, .Path = Path, .Type = McFolderType.Custom})
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
MyMsgBox("失效的 Minecraft 文件夹:" & vbCrLf & Path & vbCrLf & vbCrLf & GetExceptionSummary(ex), "Minecraft 文件夹失效", IsWarn:=True)
|
MyMsgBox("失效的 Minecraft 文件夹:" & vbCrLf & Path & vbCrLf & vbCrLf & ex.GetBrief(), "Minecraft 文件夹失效", IsWarn:=True)
|
||||||
Log(ex, $"无法访问 Minecraft 文件夹 {Path}")
|
Log(ex, $"无法访问 Minecraft 文件夹 {Path}")
|
||||||
End Try
|
End Try
|
||||||
Next
|
Next
|
||||||
@@ -695,7 +695,7 @@ Recheck:
|
|||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "依赖版本检查出错(" & Name & ")")
|
Log(ex, "依赖版本检查出错(" & Name & ")")
|
||||||
State = McVersionState.Error
|
State = McVersionState.Error
|
||||||
Info = "未知错误:" & GetExceptionSummary(ex)
|
Info = "未知错误:" & ex.GetBrief()
|
||||||
Return False
|
Return False
|
||||||
End Try
|
End Try
|
||||||
|
|
||||||
@@ -808,7 +808,7 @@ ExitDataLoad:
|
|||||||
WriteIni(Path & "PCL\Setup.ini", "VersionOriginalSub", Version.McCodeSub)
|
WriteIni(Path & "PCL\Setup.ini", "VersionOriginalSub", Version.McCodeSub)
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Info = "未知错误:" & GetExceptionSummary(ex)
|
Info = "未知错误:" & ex.GetBrief()
|
||||||
Logo = PathImage & "Blocks/RedstoneBlock.png"
|
Logo = PathImage & "Blocks/RedstoneBlock.png"
|
||||||
State = McVersionState.Error
|
State = McVersionState.Error
|
||||||
Log(ex, "加载版本失败(" & Name & ")", LogLevel.Feedback)
|
Log(ex, "加载版本失败(" & Name & ")", LogLevel.Feedback)
|
||||||
@@ -1186,6 +1186,7 @@ OnLoaded:
|
|||||||
If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(200, 3000))
|
If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(200, 3000))
|
||||||
Catch ex As ThreadInterruptedException
|
Catch ex As ThreadInterruptedException
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
If Loader.IsAborted Then Return '#5617
|
||||||
WriteIni(Path & "PCL.ini", "VersionCache", "") '要求下次重新加载
|
WriteIni(Path & "PCL.ini", "VersionCache", "") '要求下次重新加载
|
||||||
Log(ex, "加载 .minecraft 版本列表失败", LogLevel.Feedback)
|
Log(ex, "加载 .minecraft 版本列表失败", LogLevel.Feedback)
|
||||||
End Try
|
End Try
|
||||||
@@ -1592,11 +1593,11 @@ OnLoaded:
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 获取 Uuid 对应的皮肤文件地址,失败将抛出异常。
|
''' 获取 Uuid 对应的皮肤文件地址,失败将抛出异常。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Function McSkinGetAddress(Uuid As String, Type As String) As String
|
Public Function McSkinGetAddress(UUID As String, Type As String) As String
|
||||||
If Uuid = "" Then Throw New Exception("Uuid 为空。")
|
If UUID = "" Then Throw New Exception("UUID 为空。")
|
||||||
If Uuid.StartsWithF("00000") Then Throw New Exception("离线 Uuid 无正版皮肤文件。")
|
If UUID.StartsWithF("00000") AndAlso Type <> "Auth" Then Throw New Exception("离线 UUID 无正版皮肤文件:" & UUID)
|
||||||
'尝试读取缓存
|
'尝试读取缓存
|
||||||
Dim CacheSkinAddress As String = ReadIni(PathTemp & "Cache\Skin\Index" & Type & ".ini", Uuid)
|
Dim CacheSkinAddress As String = ReadIni(PathTemp & "Cache\Skin\Index" & Type & ".ini", UUID)
|
||||||
If Not CacheSkinAddress = "" Then Return CacheSkinAddress
|
If Not CacheSkinAddress = "" Then Return CacheSkinAddress
|
||||||
'获取皮肤地址
|
'获取皮肤地址
|
||||||
Dim Url As String
|
Dim Url As String
|
||||||
@@ -1610,7 +1611,7 @@ OnLoaded:
|
|||||||
Case Else
|
Case Else
|
||||||
Throw New ArgumentException("皮肤地址种类无效:" & If(Type, "null"))
|
Throw New ArgumentException("皮肤地址种类无效:" & If(Type, "null"))
|
||||||
End Select
|
End Select
|
||||||
Dim SkinString = NetRequestByClientRetry(Url & Uuid)
|
Dim SkinString = NetRequestByClientRetry(Url & UUID, RequireJson:=True)
|
||||||
If SkinString = "" Then Throw New Exception("皮肤返回值为空,可能是未设置自定义皮肤的用户")
|
If SkinString = "" Then Throw New Exception("皮肤返回值为空,可能是未设置自定义皮肤的用户")
|
||||||
'处理皮肤地址
|
'处理皮肤地址
|
||||||
Dim SkinValue As String
|
Dim SkinValue As String
|
||||||
@@ -1635,8 +1636,8 @@ OnLoaded:
|
|||||||
SkinValue = If(SkinUrl.Contains("minecraft.net/"), SkinUrl.Replace("http://", "https://"), SkinUrl)
|
SkinValue = If(SkinUrl.Contains("minecraft.net/"), SkinUrl.Replace("http://", "https://"), SkinUrl)
|
||||||
End If
|
End If
|
||||||
'保存缓存
|
'保存缓存
|
||||||
WriteIni(PathTemp & "Cache\Skin\Index" & Type & ".ini", Uuid, SkinValue)
|
WriteIni(PathTemp & "Cache\Skin\Index" & Type & ".ini", UUID, SkinValue)
|
||||||
Log("[Skin] UUID " & Uuid & " 对应的皮肤文件为 " & SkinValue)
|
Log("[Skin] UUID " & UUID & " 对应的皮肤文件为 " & SkinValue)
|
||||||
Return SkinValue
|
Return SkinValue
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
@@ -1966,7 +1967,7 @@ OnLoaded:
|
|||||||
Try
|
Try
|
||||||
Log("[Minecraft] 开始获取统一通行证下载信息")
|
Log("[Minecraft] 开始获取统一通行证下载信息")
|
||||||
'测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/
|
'测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/
|
||||||
DownloadInfo = GetJson(NetRequestByClientRetry("https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version)))
|
DownloadInfo = GetJson(NetRequestByClientRetry("https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version), RequireJson:=True))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "获取统一通行证下载信息失败")
|
Log(ex, "获取统一通行证下载信息失败")
|
||||||
End Try
|
End Try
|
||||||
@@ -1983,16 +1984,20 @@ OnLoaded:
|
|||||||
|
|
||||||
'Authlib-Injector 文件
|
'Authlib-Injector 文件
|
||||||
If Setup.Get("VersionServerLogin", Version:=Version) = 4 Then
|
If Setup.Get("VersionServerLogin", Version:=Version) = 4 Then
|
||||||
Dim TargetFile = PathPure & "\authlib-injector.jar"
|
Dim TargetFile = PathPure & "authlib-injector.jar"
|
||||||
Dim DownloadInfo As JObject = Nothing
|
Dim DownloadInfo As JObject = Nothing
|
||||||
'获取下载信息
|
'获取下载信息
|
||||||
Try
|
Try
|
||||||
Log("[Minecraft] 开始获取 Authlib-Injector 下载信息")
|
Log("[Minecraft] 开始获取 Authlib-Injector 下载信息")
|
||||||
DownloadInfo = GetJson(NetRequestByClientRetry(
|
DownloadInfo = GetJson(NetRequestByClientRetry(
|
||||||
"https://authlib-injector.yushi.moe/artifact/latest.json",
|
"https://authlib-injector.yushi.moe/artifact/latest.json",
|
||||||
BackupUrl:="https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json"))
|
BackupUrl:="https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json", RequireJson:=True))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
If File.Exists(TargetFile) Then
|
||||||
Log(ex, "获取 Authlib-Injector 下载信息失败")
|
Log(ex, "获取 Authlib-Injector 下载信息失败")
|
||||||
|
Else
|
||||||
|
Throw New Exception("获取 Authlib-Injector 下载信息失败", ex)
|
||||||
|
End If
|
||||||
End Try
|
End Try
|
||||||
'校验文件
|
'校验文件
|
||||||
If DownloadInfo IsNot Nothing Then
|
If DownloadInfo IsNot Nothing Then
|
||||||
@@ -2415,7 +2420,12 @@ NextEntry:
|
|||||||
Public Function FilterUserName(Raw As String, FilterChar As Char) As String
|
Public Function FilterUserName(Raw As String, FilterChar As Char) As String
|
||||||
If Raw.Contains(":\Users\") Then
|
If Raw.Contains(":\Users\") Then
|
||||||
For Each Token In RegexSearch(Raw, "(?<=:\\Users\\)[^\\]+")
|
For Each Token In RegexSearch(Raw, "(?<=:\\Users\\)[^\\]+")
|
||||||
Raw = Raw.Replace("\" & Token, "\" & New String(FilterChar, Token.Count))
|
Raw = Raw.Replace("\Users\" & Token, "\Users\" & New String(FilterChar, Token.Count))
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
If Raw.Contains(":/Users/") Then
|
||||||
|
For Each Token In RegexSearch(Raw, "(?<=:/Users/)[^/]+")
|
||||||
|
Raw = Raw.Replace("/Users/" & Token, "/Users/" & New String(FilterChar, Token.Count))
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
Return Raw
|
Return Raw
|
||||||
|
|||||||
@@ -1113,8 +1113,8 @@ Finished:
|
|||||||
End Sub, "Mod List Detail Loader CurseForge")
|
End Sub, "Mod List Detail Loader CurseForge")
|
||||||
'等待线程结束
|
'等待线程结束
|
||||||
Do Until EndedThreadCount = 2
|
Do Until EndedThreadCount = 2
|
||||||
If Loader.IsAborted Then Return
|
|
||||||
Thread.Sleep(10)
|
Thread.Sleep(10)
|
||||||
|
If Loader.IsAborted Then Return
|
||||||
Loop
|
Loop
|
||||||
'保存缓存
|
'保存缓存
|
||||||
Mods = Mods.Where(Function(m) m.Comp IsNot Nothing).ToList()
|
Mods = Mods.Where(Function(m) m.Comp IsNot Nothing).ToList()
|
||||||
@@ -1126,6 +1126,7 @@ Finished:
|
|||||||
Next
|
Next
|
||||||
WriteFile(PathTemp & "Cache\LocalMod.json", Cache.ToString(If(ModeDebug, Newtonsoft.Json.Formatting.Indented, Newtonsoft.Json.Formatting.None)))
|
WriteFile(PathTemp & "Cache\LocalMod.json", Cache.ToString(If(ModeDebug, Newtonsoft.Json.Formatting.Indented, Newtonsoft.Json.Formatting.None)))
|
||||||
'刷新边栏
|
'刷新边栏
|
||||||
|
If Loader.IsAborted Then Return
|
||||||
If FrmVersionMod?.Filter = PageVersionMod.FilterType.CanUpdate Then
|
If FrmVersionMod?.Filter = PageVersionMod.FilterType.CanUpdate Then
|
||||||
RunInUi(Sub() FrmVersionMod?.RefreshUI()) '同步 “可更新” 列表 (#4677)
|
RunInUi(Sub() FrmVersionMod?.RefreshUI()) '同步 “可更新” 列表 (#4677)
|
||||||
Else
|
Else
|
||||||
@@ -1212,7 +1213,7 @@ Finished:
|
|||||||
If ReqVersionHead = ReqVersionTail Then
|
If ReqVersionHead = ReqVersionTail Then
|
||||||
VersionRequire = "应为 " & ReqVersionHead
|
VersionRequire = "应为 " & ReqVersionHead
|
||||||
ElseIf ReqVersionHead.Contains(".") AndAlso ReqVersionTail.Contains(".") Then
|
ElseIf ReqVersionHead.Contains(".") AndAlso ReqVersionTail.Contains(".") Then
|
||||||
VersionRequire = "应为 " & ReqVersionHead & " 至 " & ReqVersionTail
|
VersionRequire = $"应为 {ReqVersionHead} 至 {ReqVersionTail}"
|
||||||
ElseIf ReqVersionHead.Contains(".") Then
|
ElseIf ReqVersionHead.Contains(".") Then
|
||||||
If ReqVersionHeadCanEqual Then
|
If ReqVersionHeadCanEqual Then
|
||||||
VersionRequire = "最低应为 " & ReqVersionHead
|
VersionRequire = "最低应为 " & ReqVersionHead
|
||||||
@@ -1230,7 +1231,7 @@ Finished:
|
|||||||
End If
|
End If
|
||||||
'检查前置 Mod 是否存在,并获取其版本
|
'检查前置 Mod 是否存在,并获取其版本
|
||||||
If Not CurrentDependencies.ContainsKey(ReqId) Then
|
If Not CurrentDependencies.ContainsKey(ReqId) Then
|
||||||
Result.Add("缺少前置 Mod:" & ReqId & If(VersionRequire = "", "", ",其版本" & VersionRequire) & "。" & vbCrLf & " - " & ModEntity.FileName)
|
Result.Add($"缺少前置 Mod:{ReqId}{If(VersionRequire = "", "", ",其版本" & VersionRequire)}。{vbCrLf} - {ModEntity.FileName}")
|
||||||
Continue For
|
Continue For
|
||||||
End If
|
End If
|
||||||
Dim CurrentVersion As String = If(CurrentDependencies(ReqId)(0), "0.0")
|
Dim CurrentVersion As String = If(CurrentDependencies(ReqId)(0), "0.0")
|
||||||
@@ -1239,7 +1240,7 @@ Finished:
|
|||||||
If ReqVersionHead.Contains(".") Then
|
If ReqVersionHead.Contains(".") Then
|
||||||
If VersionSortInteger(ReqVersionHead, CurrentVersion) > If(ReqVersionHeadCanEqual, 0, -1) Then
|
If VersionSortInteger(ReqVersionHead, CurrentVersion) > If(ReqVersionHeadCanEqual, 0, -1) Then
|
||||||
Result.Add(ReqId.Substring(0, 1).ToUpper & ReqId.Substring(1) & " 版本过低,其版本" & VersionRequire & ",而当前版本为 " & CurrentVersion & "。" & vbCrLf &
|
Result.Add(ReqId.Substring(0, 1).ToUpper & ReqId.Substring(1) & " 版本过低,其版本" & VersionRequire & ",而当前版本为 " & CurrentVersion & "。" & vbCrLf &
|
||||||
" - " & ModEntity.FileName & If(ReqId <> "minecraft" AndAlso ReqId <> "forge", vbCrLf & " - 前置:" & CurrentDependencies(ReqId)(1), ""))
|
" - " & ModEntity.FileName & If(ReqId <> "minecraft" AndAlso ReqId <> "forge", $"{vbCrLf} - 前置:{CurrentDependencies(ReqId)(1)}", ""))
|
||||||
Continue For
|
Continue For
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -1247,26 +1248,26 @@ Finished:
|
|||||||
If ReqVersionTail.Contains(".") Then
|
If ReqVersionTail.Contains(".") Then
|
||||||
If VersionSortInteger(CurrentVersion, ReqVersionTail) > If(ReqVersionTailCanEqual, 0, -1) Then
|
If VersionSortInteger(CurrentVersion, ReqVersionTail) > If(ReqVersionTailCanEqual, 0, -1) Then
|
||||||
Result.Add(ReqId.Substring(0, 1).ToUpper & ReqId.Substring(1) & " 版本过高,其版本" & VersionRequire & ",而当前版本为 " & CurrentVersion & "。" & vbCrLf &
|
Result.Add(ReqId.Substring(0, 1).ToUpper & ReqId.Substring(1) & " 版本过高,其版本" & VersionRequire & ",而当前版本为 " & CurrentVersion & "。" & vbCrLf &
|
||||||
" - " & ModEntity.FileName & If(ReqId <> "minecraft" AndAlso ReqId <> "forge", vbCrLf & " - 前置:" & CurrentDependencies(ReqId)(1), ""))
|
" - " & ModEntity.FileName & If(ReqId <> "minecraft" AndAlso ReqId <> "forge", $"{vbCrLf} - 前置:{CurrentDependencies(ReqId)(1)}", ""))
|
||||||
Continue For
|
Continue For
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
If Not CurrentDependencies.ContainsKey(Dependency.Key) Then
|
If Not CurrentDependencies.ContainsKey(Dependency.Key) Then
|
||||||
Result.Add("缺少前置 Mod:" & Dependency.Key & "。" & vbCrLf & " - " & ModEntity.FileName)
|
Result.Add($"缺少前置 Mod:{Dependency.Key}。{vbCrLf} - {ModEntity.FileName}")
|
||||||
Continue For
|
Continue For
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Result.Add("检查 Mod 时出错:" & GetExceptionSummary(ex) & vbCrLf & " - " & ModEntity.FileName)
|
Result.Add($"检查 Mod 时出错:{ex.GetBrief()}{vbCrLf} - {ModEntity.FileName}")
|
||||||
Log(ex, "检查 Mod 时出错")
|
Log(ex, "检查 Mod 时出错")
|
||||||
End Try
|
End Try
|
||||||
Next
|
Next
|
||||||
If Not Result.Any() Then
|
If Not Result.Any() Then
|
||||||
Log("[Minecraft] Mod 检查未发现异常")
|
Log("[Minecraft] Mod 检查未发现异常")
|
||||||
Else
|
Else
|
||||||
Log("[Minecraft] Mod 检查异常结果:" & vbCrLf & Join(Result, vbCrLf))
|
Log($"[Minecraft] Mod 检查异常结果:{vbCrLf}{Join(Result, vbCrLf)}")
|
||||||
End If
|
End If
|
||||||
Return Result
|
Return Result
|
||||||
End Function
|
End Function
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ Public Module ModModpack
|
|||||||
If FullNames(1) = "modpack.zip" OrElse FullNames(1) = "modpack.mrpack" Then PackType = 9 : Exit Try '带启动器的压缩包
|
If FullNames(1) = "modpack.zip" OrElse FullNames(1) = "modpack.mrpack" Then PackType = 9 : Exit Try '带启动器的压缩包
|
||||||
Next
|
Next
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If GetExceptionDetail(ex, True).Contains("Error.WinIOError") Then
|
If ex.GetDetail(True).Contains("Error.WinIOError") Then
|
||||||
Throw New Exception("打开整合包文件失败", ex)
|
Throw New Exception("打开整合包文件失败", ex)
|
||||||
ElseIf File.EndsWithF(".rar", True) Then
|
ElseIf File.EndsWithF(".rar", True) Then
|
||||||
Throw New Exception("PCL 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试", ex)
|
Throw New Exception("PCL 无法处理 rar 格式的压缩包,请在解压后重新压缩为 zip 格式再试", ex)
|
||||||
@@ -166,6 +166,15 @@ Retry:
|
|||||||
End If
|
End If
|
||||||
IniClearCache(VersionIni) '重置缓存,避免被安装过程中写入的 ini 覆盖
|
IniClearCache(VersionIni) '重置缓存,避免被安装过程中写入的 ini 覆盖
|
||||||
End Sub
|
End Sub
|
||||||
|
''' <summary>
|
||||||
|
''' 弹窗提示整合包中存在不兼容的加载器。
|
||||||
|
''' 如果取消,则抛出 CancelledException。
|
||||||
|
''' </summary>
|
||||||
|
''' <exception cref="CancelledException" />
|
||||||
|
Private Sub NotifyIncompatibleLoader(LoaderName As String)
|
||||||
|
If MyMsgBox($"整合包中存在不兼容的加载器:{LoaderName}{vbCrLf}如果你知道如何手动安装它,可以先选择跳过,然后在整合包下载结束后手动安装。",
|
||||||
|
"不兼容的加载器", "取消", $"不安装 {LoaderName} 并继续") = 1 Then Throw New CancelledException
|
||||||
|
End Sub
|
||||||
|
|
||||||
#Region "不同类型整合包的安装方法"
|
#Region "不同类型整合包的安装方法"
|
||||||
|
|
||||||
@@ -211,7 +220,8 @@ Retry:
|
|||||||
Log("[ModPack] 整合包 Fabric 版本:" & Id)
|
Log("[ModPack] 整合包 Fabric 版本:" & Id)
|
||||||
FabricVersion = Id.Replace("fabric-", "")
|
FabricVersion = Id.Replace("fabric-", "")
|
||||||
Else
|
Else
|
||||||
Log("[ModPack] 未知 Mod 加载器:" & Id)
|
'ElseIf Id.StartsWithF("quilt-") Then
|
||||||
|
NotifyIncompatibleLoader(Id)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
'解压
|
'解压
|
||||||
@@ -376,12 +386,9 @@ Retry:
|
|||||||
Case "fabric-loader" 'eg. 0.14.14
|
Case "fabric-loader" 'eg. 0.14.14
|
||||||
FabricVersion = Entry.Value.ToString
|
FabricVersion = Entry.Value.ToString
|
||||||
Log("[ModPack] 整合包 Fabric 版本:" & FabricVersion)
|
Log("[ModPack] 整合包 Fabric 版本:" & FabricVersion)
|
||||||
Case "quilt-loader" 'eg. 1.0.0
|
|
||||||
Hint("PCL 暂不支持安装需要 Quilt 的整合包!", HintType.Critical)
|
|
||||||
Throw New CancelledException
|
|
||||||
Case Else
|
Case Else
|
||||||
Hint($"无法安装整合包,其中出现了未知的 Mod 加载器 {Entry.Value}!", HintType.Critical)
|
'Case "quilt-loader" 'eg. 1.0.0
|
||||||
Throw New CancelledException
|
NotifyIncompatibleLoader(Entry.Name)
|
||||||
End Select
|
End Select
|
||||||
Next
|
Next
|
||||||
'获取版本名
|
'获取版本名
|
||||||
@@ -633,7 +640,8 @@ Retry:
|
|||||||
If PackJson("components") Is Nothing Then Throw New Exception("该 MMC 整合包未提供游戏版本信息,无法安装!")
|
If PackJson("components") Is Nothing Then Throw New Exception("该 MMC 整合包未提供游戏版本信息,无法安装!")
|
||||||
Dim Request As New McInstallRequest With {.TargetVersionName = VersionName, .TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\"}
|
Dim Request As New McInstallRequest With {.TargetVersionName = VersionName, .TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\"}
|
||||||
For Each Component In PackJson("components")
|
For Each Component In PackJson("components")
|
||||||
Select Case If(Component("uid"), "").ToString
|
If Not Component.Contains("uid") Then Continue For
|
||||||
|
Select Case Component("uid").ToString
|
||||||
Case "org.lwjgl"
|
Case "org.lwjgl"
|
||||||
Log("[ModPack] 已跳过 LWJGL 项")
|
Log("[ModPack] 已跳过 LWJGL 项")
|
||||||
Case "net.minecraft"
|
Case "net.minecraft"
|
||||||
@@ -644,9 +652,9 @@ Retry:
|
|||||||
Request.NeoForgeVersion = Component("version")
|
Request.NeoForgeVersion = Component("version")
|
||||||
Case "net.fabricmc.fabric-loader"
|
Case "net.fabricmc.fabric-loader"
|
||||||
Request.FabricVersion = Component("version")
|
Request.FabricVersion = Component("version")
|
||||||
Case "org.quiltmc.quilt-loader" 'eg. 1.0.0
|
Case Else
|
||||||
Hint("PCL 暂不支持安装需要 Quilt 的整合包!", HintType.Critical)
|
'Case "org.quiltmc.quilt-loader" 'eg. 1.0.0
|
||||||
Throw New CancelledException
|
NotifyIncompatibleLoader(Component("uid"))
|
||||||
End Select
|
End Select
|
||||||
Next
|
Next
|
||||||
'构造加载器
|
'构造加载器
|
||||||
|
|||||||
@@ -397,12 +397,6 @@ EndHint:
|
|||||||
'下载页面声明
|
'下载页面声明
|
||||||
Public FrmDownloadLeft As PageDownloadLeft
|
Public FrmDownloadLeft As PageDownloadLeft
|
||||||
Public FrmDownloadInstall As PageDownloadInstall
|
Public FrmDownloadInstall As PageDownloadInstall
|
||||||
Public FrmDownloadClient As PageDownloadClient
|
|
||||||
Public FrmDownloadOptiFine As PageDownloadOptiFine
|
|
||||||
Public FrmDownloadLiteLoader As PageDownloadLiteLoader
|
|
||||||
Public FrmDownloadForge As PageDownloadForge
|
|
||||||
Public FrmDownloadNeoForge As PageDownloadNeoForge
|
|
||||||
Public FrmDownloadFabric As PageDownloadFabric
|
|
||||||
Public FrmDownloadMod As PageDownloadMod
|
Public FrmDownloadMod As PageDownloadMod
|
||||||
Public FrmDownloadPack As PageDownloadPack
|
Public FrmDownloadPack As PageDownloadPack
|
||||||
Public FrmDownloadDataPack As PageDownloadDataPack
|
Public FrmDownloadDataPack As PageDownloadDataPack
|
||||||
|
|||||||
@@ -80,15 +80,16 @@ Friend Module ModSecret
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 设置 Headers 的 UA、Referer。
|
''' 设置 Headers 的 UA、Referer。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Friend Sub SecretHeadersSign(Url As String, ByRef Req As HttpRequestMessage, Optional UseBrowserUserAgent As Boolean = False)
|
Friend Sub SecretHeadersSign(Url As String, ByRef Req As HttpRequestMessage, Optional SimulateBrowserHeaders As Boolean = False)
|
||||||
|
If Req.Headers.UserAgent.Any Then Return
|
||||||
If Url.Contains("baidupcs.com") OrElse Url.Contains("baidu.com") Then
|
If Url.Contains("baidupcs.com") OrElse Url.Contains("baidu.com") Then
|
||||||
Req.Headers.Add("User-Agent", "LogStatistic") '#4951
|
Req.Headers.Add("User-Agent", "LogStatistic") '#4951
|
||||||
ElseIf UseBrowserUserAgent Then
|
ElseIf SimulateBrowserHeaders Then
|
||||||
Req.Headers.Add("User-Agent", $"PCL2/{VersionStandardCode} Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36")
|
Req.Headers.Add("User-Agent", $"PCL2/{VersionStandardCode} Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36")
|
||||||
Else
|
Else
|
||||||
Req.Headers.Add("User-Agent", $"PCL2/{VersionStandardCode}")
|
Req.Headers.Add("User-Agent", $"PCL2/{VersionStandardCode}")
|
||||||
End If
|
End If
|
||||||
Req.Headers.Add("Referer", $"http://{VersionCode}.open.pcl2.server/")
|
If Not SimulateBrowserHeaders Then Req.Headers.Add("Referer", $"http://{VersionCode}.open.pcl2.server/")
|
||||||
If Url.Contains("api.curseforge.com") Then Req.Headers.Add("x-api-key", CurseForgeAPIKey)
|
If Url.Contains("api.curseforge.com") Then Req.Headers.Add("x-api-key", CurseForgeAPIKey)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||||
' 方法是按如下所示使用“*”
|
' 方法是按如下所示使用“*”
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2.10.6.0")>
|
<Assembly: AssemblyVersion("2.10.7.0")>
|
||||||
<Assembly: AssemblyFileVersion("2.10.6.0")>
|
<Assembly: AssemblyFileVersion("2.10.7.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("")>
|
<Assembly: NeutralResourcesLanguage("")>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
<StackPanel x:Name="PanContent">
|
<StackPanel x:Name="PanContent">
|
||||||
<local:MyHint x:Name="HintError" HasBorder="True" Text="无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,搜索结果可能不全。
请稍后重试,或使用 VPN 以改善网络环境。" Theme="Yellow" Margin="0,0,0,15" />
|
<local:MyHint x:Name="HintError" HasBorder="True" Text="无法连接到 Modrinth,所以目前仅显示了来自 CurseForge 的内容,搜索结果可能不全。
请稍后再试,或使用 VPN 改善网络环境。" Theme="Yellow" Margin="0,0,0,15" />
|
||||||
<local:MyCard x:Name="CardProjects" UseAnimation="False">
|
<local:MyCard x:Name="CardProjects" UseAnimation="False">
|
||||||
<StackPanel x:Name="PanProjects" Margin="12" />
|
<StackPanel x:Name="PanProjects" Margin="12" />
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|||||||
@@ -290,7 +290,7 @@
|
|||||||
Sub(MyLoader)
|
Sub(MyLoader)
|
||||||
Select Case MyLoader.State
|
Select Case MyLoader.State
|
||||||
Case LoadState.Failed
|
Case LoadState.Failed
|
||||||
Hint(MyLoader.Name & "失败:" & GetExceptionSummary(MyLoader.Error), HintType.Critical)
|
Hint(MyLoader.Name & "失败:" & MyLoader.Error.GetBrief(), HintType.Critical)
|
||||||
Case LoadState.Aborted
|
Case LoadState.Aborted
|
||||||
Hint(MyLoader.Name & "已取消!", HintType.Info)
|
Hint(MyLoader.Name & "已取消!", HintType.Info)
|
||||||
Case LoadState.Loading
|
Case LoadState.Loading
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<local:MyComboBoxItem Tag="/kitchen-sink" Content="水槽包" />
|
<local:MyComboBoxItem Tag="/kitchen-sink" Content="水槽包" />
|
||||||
<local:MyComboBoxItem Tag="4476/" Content="探索" />
|
<local:MyComboBoxItem Tag="4476/" Content="探索" />
|
||||||
<local:MyComboBoxItem Tag="4477/" Content="小游戏" />
|
<local:MyComboBoxItem Tag="4477/" Content="小游戏" />
|
||||||
<local:MyComboBoxItem Tag="4471/" Content="科幻" />
|
<local:MyComboBoxItem Tag="4474/" Content="科幻" />
|
||||||
<local:MyComboBoxItem Tag="4736/" Content="空岛" />
|
<local:MyComboBoxItem Tag="4736/" Content="空岛" />
|
||||||
<local:MyComboBoxItem Tag="5128/" Content="原版改良" />
|
<local:MyComboBoxItem Tag="5128/" Content="原版改良" />
|
||||||
<local:MyComboBoxItem Tag="4487/" Content="FTB" ToolTip="由 FTB 官方发布" ToolTipService.HorizontalOffset="70" />
|
<local:MyComboBoxItem Tag="4487/" Content="FTB" ToolTip="由 FTB 官方发布" ToolTipService.HorizontalOffset="70" />
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ pause"
|
|||||||
'开始启动
|
'开始启动
|
||||||
SyncLock InstallSyncLock
|
SyncLock InstallSyncLock
|
||||||
Dim Info = New ProcessStartInfo With {
|
Dim Info = New ProcessStartInfo With {
|
||||||
.FileName = Java.PathJavaw,
|
.FileName = Java.PathJava,
|
||||||
.Arguments = Arguments,
|
.Arguments = Arguments,
|
||||||
.UseShellExecute = False,
|
.UseShellExecute = False,
|
||||||
.CreateNoWindow = True,
|
.CreateNoWindow = True,
|
||||||
@@ -571,7 +571,7 @@ pause"
|
|||||||
Dim PageData As String
|
Dim PageData As String
|
||||||
Try
|
Try
|
||||||
PageData = NetRequestByClient("https://optifine.net/adloadx?f=" & DownloadInfo.NameFile,
|
PageData = NetRequestByClient("https://optifine.net/adloadx?f=" & DownloadInfo.NameFile,
|
||||||
Encoding:=New UTF8Encoding(False), Timeout:=15000, Accept:="text/html", UseBrowserUserAgent:=True)
|
Encoding:=New UTF8Encoding(False), Timeout:=15000, Accept:="text/html", SimulateBrowserHeaders:=True)
|
||||||
Task.Progress = 0.8
|
Task.Progress = 0.8
|
||||||
Sources.Add("https://optifine.net/" & RegexSearch(PageData, "downloadx\?f=[^""']+")(0))
|
Sources.Add("https://optifine.net/" & RegexSearch(PageData, "downloadx\?f=[^""']+")(0))
|
||||||
Log("[Download] OptiFine " & DownloadInfo.NameDisplay & " 官方下载地址:" & Sources.Last)
|
Log("[Download] OptiFine " & DownloadInfo.NameDisplay & " 官方下载地址:" & Sources.Last)
|
||||||
@@ -735,7 +735,7 @@ Retry:
|
|||||||
Dim PageData As String
|
Dim PageData As String
|
||||||
Try
|
Try
|
||||||
PageData = NetRequestByClient("https://optifine.net/adloadx?f=" & DownloadInfo.NameFile,
|
PageData = NetRequestByClient("https://optifine.net/adloadx?f=" & DownloadInfo.NameFile,
|
||||||
Encoding:=New UTF8Encoding(False), Timeout:=15000, Accept:="text/html", UseBrowserUserAgent:=True)
|
Encoding:=New UTF8Encoding(False), Timeout:=15000, Accept:="text/html", SimulateBrowserHeaders:=True)
|
||||||
Task.Progress = 0.8
|
Task.Progress = 0.8
|
||||||
Sources.Add("https://optifine.net/" & RegexSearch(PageData, "downloadx\?f=[^""']+")(0))
|
Sources.Add("https://optifine.net/" & RegexSearch(PageData, "downloadx\?f=[^""']+")(0))
|
||||||
Log("[Download] OptiFine " & DownloadInfo.NameDisplay & " 官方下载地址:" & Sources.Last)
|
Log("[Download] OptiFine " & DownloadInfo.NameDisplay & " 官方下载地址:" & Sources.Last)
|
||||||
@@ -1120,7 +1120,7 @@ Retry:
|
|||||||
'开始启动
|
'开始启动
|
||||||
SyncLock InstallSyncLock
|
SyncLock InstallSyncLock
|
||||||
Dim Info = New ProcessStartInfo With {
|
Dim Info = New ProcessStartInfo With {
|
||||||
.FileName = Java.PathJavaw,
|
.FileName = Java.PathJava,
|
||||||
.Arguments = Arguments,
|
.Arguments = Arguments,
|
||||||
.UseShellExecute = False,
|
.UseShellExecute = False,
|
||||||
.CreateNoWindow = True,
|
.CreateNoWindow = True,
|
||||||
@@ -1647,7 +1647,7 @@ Retry:
|
|||||||
Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
Log("[Download] 刷新 Forge 推荐版本缓存开始")
|
Log("[Download] 刷新 Forge 推荐版本缓存开始")
|
||||||
Dim Result As String = NetRequestByClientRetry("https://bmclapi2.bangbang93.com/forge/promos")
|
Dim Result As String = NetRequestByClientRetry("https://bmclapi2.bangbang93.com/forge/promos", RequireJson:=True)
|
||||||
If Result.Length < 1000 Then Throw New Exception("获取的结果过短(" & Result & ")")
|
If Result.Length < 1000 Then Throw New Exception("获取的结果过短(" & Result & ")")
|
||||||
Dim ResultJson As JContainer = GetJson(Result)
|
Dim ResultJson As JContainer = GetJson(Result)
|
||||||
'获取所有推荐版本列表
|
'获取所有推荐版本列表
|
||||||
@@ -1991,7 +1991,7 @@ Retry:
|
|||||||
Case LoadState.Finished
|
Case LoadState.Finished
|
||||||
Hint(Loader.Name & "成功!", HintType.Finish)
|
Hint(Loader.Name & "成功!", HintType.Finish)
|
||||||
Case LoadState.Failed
|
Case LoadState.Failed
|
||||||
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
|
Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Critical)
|
||||||
Case LoadState.Aborted
|
Case LoadState.Aborted
|
||||||
Hint(Loader.Name & "已取消!", HintType.Info)
|
Hint(Loader.Name & "已取消!", HintType.Info)
|
||||||
End Select
|
End Select
|
||||||
@@ -2005,7 +2005,7 @@ Retry:
|
|||||||
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '清空缓存(合并安装会先生成文件夹,这会在刷新时误判为可以使用缓存)
|
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '清空缓存(合并安装会先生成文件夹,这会在刷新时误判为可以使用缓存)
|
||||||
Hint(Loader.Name & "成功!", HintType.Finish)
|
Hint(Loader.Name & "成功!", HintType.Finish)
|
||||||
Case LoadState.Failed
|
Case LoadState.Failed
|
||||||
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
|
Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Critical)
|
||||||
Case LoadState.Aborted
|
Case LoadState.Aborted
|
||||||
Hint(Loader.Name & "已取消!", HintType.Info)
|
Hint(Loader.Name & "已取消!", HintType.Info)
|
||||||
Case LoadState.Loading
|
Case LoadState.Loading
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
<local:MyPageRight
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d" x:Class="PageDownloadClient"
|
|
||||||
PanScroll="PanBack">
|
|
||||||
<Grid>
|
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
|
||||||
<StackPanel Orientation="Vertical" Margin="5">
|
|
||||||
<!--<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="自动安装提示" x:Name="CardTip">
|
|
||||||
<StackPanel Margin="25,40,15,20">
|
|
||||||
<TextBlock Margin="0,0,0,2" Text="本页只提供需要在下载后手动进行安装的游戏 jar 与 json 下载。" TextWrapping="Wrap" />
|
|
||||||
<TextBlock Margin="0,0,0,11" Text="如果你想要进行自动安装,在游戏安装页选择游戏版本,然后直接安装即可。" TextWrapping="Wrap" />
|
|
||||||
<Grid Height="35">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
|
|
||||||
<local:MyButton x:Name="BtnInstall" Grid.Column="1" MinWidth="140" Text="转到游戏安装页" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>-->
|
|
||||||
<StackPanel Name="PanMain" Margin="20,20,20,5" Grid.IsSharedSizeScope="True" />
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyScrollViewer>
|
|
||||||
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40,0" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
|
|
||||||
<local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</local:MyCard>
|
|
||||||
</Grid>
|
|
||||||
</local:MyPageRight>
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
Public Class PageDownloadClient
|
|
||||||
|
|
||||||
Private Sub LoaderInit() Handles Me.Initialized
|
|
||||||
PageLoaderInit(Load, PanLoad, PanBack, Nothing, DlClientListLoader, AddressOf Load_OnFinish)
|
|
||||||
End Sub
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
|
||||||
PanBack.ScrollToHome()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Load_OnFinish()
|
|
||||||
'结果数据化
|
|
||||||
Try
|
|
||||||
'归类
|
|
||||||
Dim Dict As New Dictionary(Of String, List(Of JObject)) From {
|
|
||||||
{"正式版", New List(Of JObject)}, {"预览版", New List(Of JObject)}, {"远古版", New List(Of JObject)}, {"愚人节版", New List(Of JObject)}
|
|
||||||
}
|
|
||||||
Dim Versions As JArray = DlClientListLoader.Output.Value("versions")
|
|
||||||
For Each Version As JObject In Versions
|
|
||||||
'确定分类
|
|
||||||
Dim Type As String = Version("type")
|
|
||||||
Select Case Type
|
|
||||||
Case "release"
|
|
||||||
Type = "正式版"
|
|
||||||
Case "snapshot"
|
|
||||||
Type = "预览版"
|
|
||||||
'Mojang 误分类
|
|
||||||
If Version("id").ToString.StartsWith("1.") AndAlso
|
|
||||||
Not Version("id").ToString.ToLower.Contains("combat") AndAlso
|
|
||||||
Not Version("id").ToString.ToLower.Contains("rc") AndAlso
|
|
||||||
Not Version("id").ToString.ToLower.Contains("experimental") AndAlso
|
|
||||||
Not Version("id").ToString.ToLower.Contains("pre") Then
|
|
||||||
Type = "正式版"
|
|
||||||
Version("type") = "release"
|
|
||||||
End If
|
|
||||||
'愚人节版本
|
|
||||||
Select Case Version("id").ToString.ToLower
|
|
||||||
Case "20w14infinite", "20w14∞"
|
|
||||||
Type = "愚人节版"
|
|
||||||
Version("id") = "20w14∞"
|
|
||||||
Version("type") = "special"
|
|
||||||
Version.Add("lore", GetMcFoolName(Version("id")))
|
|
||||||
Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime", "23w13a_or_b", "24w14potato", "25w14craftmine"
|
|
||||||
Type = "愚人节版"
|
|
||||||
Version("type") = "special"
|
|
||||||
Version.Add("lore", GetMcFoolName(Version("id")))
|
|
||||||
Case Else '4/1 自动视作愚人节版
|
|
||||||
Dim ReleaseDate = Version("releaseTime").Value(Of Date).ToUniversalTime().AddHours(2)
|
|
||||||
If ReleaseDate.Month = 4 AndAlso ReleaseDate.Day = 1 Then
|
|
||||||
Type = "愚人节版"
|
|
||||||
Version("type") = "special"
|
|
||||||
End If
|
|
||||||
End Select
|
|
||||||
Case "special"
|
|
||||||
'已被处理的愚人节版
|
|
||||||
Type = "愚人节版"
|
|
||||||
Case Else
|
|
||||||
Type = "远古版"
|
|
||||||
End Select
|
|
||||||
'加入辞典
|
|
||||||
Dict(Type).Add(Version)
|
|
||||||
Next
|
|
||||||
'排序
|
|
||||||
For i = 0 To Dict.Keys.Count - 1
|
|
||||||
Dict(Dict.Keys(i)) = Dict.Values(i).OrderByDescending(Function(v) v("releaseTime").Value(Of Date)).ToList
|
|
||||||
Next
|
|
||||||
'清空当前
|
|
||||||
PanMain.Children.Clear()
|
|
||||||
'添加最新版本
|
|
||||||
Dim CardInfo As New MyCard With {.Title = "最新版本", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 2}
|
|
||||||
Dim TopestVersions As New List(Of JObject)
|
|
||||||
Dim Release As JObject = Dict("正式版")(0).DeepClone()
|
|
||||||
Release("lore") = "最新正式版,发布于 " & Release("releaseTime").Value(Of Date).ToString("yyyy'/'MM'/'dd HH':'mm")
|
|
||||||
TopestVersions.Add(Release)
|
|
||||||
If Dict("正式版")(0)("releaseTime").Value(Of Date) < Dict("预览版")(0)("releaseTime").Value(Of Date) Then
|
|
||||||
Dim Snapshot As JObject = Dict("预览版")(0).DeepClone()
|
|
||||||
Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").Value(Of Date).ToString("yyyy'/'MM'/'dd HH':'mm")
|
|
||||||
TopestVersions.Add(Snapshot)
|
|
||||||
End If
|
|
||||||
Dim PanInfo As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = TopestVersions}
|
|
||||||
MyCard.StackInstall(PanInfo, 2)
|
|
||||||
CardInfo.Children.Add(PanInfo)
|
|
||||||
PanMain.Children.Add(CardInfo)
|
|
||||||
'添加其他版本
|
|
||||||
For Each Pair As KeyValuePair(Of String, List(Of JObject)) In Dict
|
|
||||||
If Not Pair.Value.Any() Then Continue For
|
|
||||||
'增加卡片
|
|
||||||
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 2}
|
|
||||||
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
|
|
||||||
NewCard.Children.Add(NewStack)
|
|
||||||
NewCard.SwapControl = NewStack
|
|
||||||
NewCard.IsSwapped = True
|
|
||||||
PanMain.Children.Add(NewCard)
|
|
||||||
Next
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "可视化 MC 版本列表出错", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Public Sub DownloadStart(sender As MyListItem, e As Object)
|
|
||||||
McDownloadClient(NetPreDownloadBehaviour.HintWhileExists, sender.Title, sender.Tag("url").ToString)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
''介绍栏
|
|
||||||
'Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
|
|
||||||
' OpenWebsite("https://www.minecraft.net/zh-hans")
|
|
||||||
'End Sub
|
|
||||||
'Private Sub BtnInstall_Click(sender As Object, e As EventArgs) Handles BtnInstall.Click
|
|
||||||
' FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
|
|
||||||
'End Sub
|
|
||||||
|
|
||||||
End Class
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<local:MyPageRight
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d" x:Class="PageDownloadFabric"
|
|
||||||
PanScroll="PanBack">
|
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
|
||||||
<StackPanel Orientation="Vertical" Margin="5">
|
|
||||||
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="Fabric 简介" x:Name="CardTip">
|
|
||||||
<StackPanel Margin="25,40,15,20">
|
|
||||||
<TextBlock Margin="0,0,0,11" Text="Fabric Loader 是新版 Minecraft 下的轻量化 Mod 加载器,你需要先安装它才能安装各种 Fabric 模组。
本页面提供 Fabric 安装器下载,在下载后你需要手动打开安装器进行安装。" TextWrapping="Wrap" />
|
|
||||||
<Grid Height="35">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
<local:MyCard x:Name="CardVersions" Margin="20,15,20,20" Title="版本列表">
|
|
||||||
<StackPanel x:Name="PanVersions" Margin="20,40,18,20" />
|
|
||||||
</local:MyCard>
|
|
||||||
<local:MyCard HorizontalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
|
|
||||||
<local:MyLoading Text="正在获取 Fabric 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</local:MyCard>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyScrollViewer>
|
|
||||||
</local:MyPageRight>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
Public Class PageDownloadFabric
|
|
||||||
|
|
||||||
Private Sub LoaderInit() Handles Me.Initialized
|
|
||||||
PageLoaderInit(Load, PanLoad, CardVersions, CardTip, DlFabricListLoader, AddressOf Load_OnFinish)
|
|
||||||
End Sub
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
|
||||||
PanBack.ScrollToHome()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Load_OnFinish()
|
|
||||||
'结果数据化
|
|
||||||
Try
|
|
||||||
Dim Versions As JArray = DlFabricListLoader.Output.Value("installer")
|
|
||||||
PanVersions.Children.Clear()
|
|
||||||
For Each Version In Versions
|
|
||||||
PanVersions.Children.Add(FabricDownloadListItem(Version, AddressOf Fabric_Selected))
|
|
||||||
Next
|
|
||||||
CardVersions.Title = "版本列表 (" & Versions.Count & ")"
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "可视化 Fabric 版本列表出错", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Fabric_Selected(sender As MyListItem, e As EventArgs)
|
|
||||||
McDownloadFabricLoaderSave(sender.Tag)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
|
|
||||||
OpenWebsite("https://www.fabricmc.net")
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
End Class
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<local:MyPageRight
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d" x:Class="PageDownloadForge"
|
|
||||||
PanScroll="PanBack">
|
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
|
||||||
<StackPanel Orientation="Vertical" Margin="5">
|
|
||||||
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="Forge 简介" x:Name="CardTip">
|
|
||||||
<StackPanel Margin="25,40,15,20">
|
|
||||||
<TextBlock Name="LabConnect" Margin="0,0,0,11" Text="Forge 是一个 Mod 加载器,你需要先安装 Forge 才能安装各种 Forge 模组。" TextWrapping="Wrap" />
|
|
||||||
<Grid Height="35">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
|
|
||||||
<local:MyCard HorizontalAlignment="Center" Margin="40,50" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
|
|
||||||
<local:MyLoading Text="正在获取 Forge 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</local:MyCard>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyScrollViewer>
|
|
||||||
</local:MyPageRight>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
Public Class PageDownloadForge
|
|
||||||
|
|
||||||
Private Sub LoaderInit() Handles Me.Initialized
|
|
||||||
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlForgeListLoader, AddressOf Load_OnFinish)
|
|
||||||
End Sub
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
|
||||||
PanBack.ScrollToHome()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Load_OnFinish()
|
|
||||||
'结果数据化
|
|
||||||
Try
|
|
||||||
'清空当前
|
|
||||||
PanMain.Children.Clear()
|
|
||||||
'转化为 UI
|
|
||||||
For Each Version As String In DlForgeListLoader.Output.Value.Sort(AddressOf VersionSortBoolean)
|
|
||||||
'增加卡片
|
|
||||||
Dim NewCard As New MyCard With {.Title = Version.Replace("_p", " P"), .Margin = New Thickness(0, 0, 0, 15), .SwapType = 5}
|
|
||||||
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Version}
|
|
||||||
NewCard.Children.Add(NewStack)
|
|
||||||
NewCard.SwapControl = NewStack
|
|
||||||
NewCard.IsSwapped = True
|
|
||||||
PanMain.Children.Add(NewCard)
|
|
||||||
Next
|
|
||||||
''非官方源警示
|
|
||||||
'If Setup.Get("ToolDownloadOutOfDate") AndAlso Not DlForgeListLoader.Output.IsOfficial Then
|
|
||||||
' Dim CardWarn As New MyCard With {.Title = "过期提示", .Margin = New Thickness(0, 0, 0, 15)}
|
|
||||||
' CardWarn.Children.Add(New TextBlock With {
|
|
||||||
' .Margin = New Thickness(25, MyCard.SwapedHeight, 15, 15), .VerticalAlignment = VerticalAlignment.Top, .HorizontalAlignment = HorizontalAlignment.Left, .TextTrimming = TextTrimming.None, .TextWrapping = TextWrapping.Wrap,
|
|
||||||
' .Text = "获取官方源失败,正在使用 " & DlForgeListLoader.Output.SourceName & " 镜像源,版本列表可能并非最新。" & vbCrLf & "官方源错误原因:" & If(DlForgeListLoader.Output.OfficialError, New Exception("连接服务器超时")).Message})
|
|
||||||
' PanMain.Children.Insert(0, CardWarn)
|
|
||||||
'End If
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "可视化 Forge 版本列表出错", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
'Forge 版本列表加载
|
|
||||||
Public Sub Forge_Click(sender As MyLoading, e As MouseButtonEventArgs)
|
|
||||||
If sender.State.LoadingState = MyLoading.MyLoadingState.Error Then
|
|
||||||
CType(sender.State, LoaderTask(Of String, List(Of DlForgeVersionEntry))).Start(IsForceRestart:=True)
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
Public Sub Forge_StateChanged(sender As MyLoading, newState As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState)
|
|
||||||
If newState <> MyLoading.MyLoadingState.Stop Then Return
|
|
||||||
|
|
||||||
Dim Card As MyCard = CType(sender.Parent, FrameworkElement).Parent
|
|
||||||
Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = sender.State
|
|
||||||
'载入列表
|
|
||||||
Card.SwapControl.Children.Clear()
|
|
||||||
Card.SwapControl.Tag = Loader.Output
|
|
||||||
Card.SwapType = 6
|
|
||||||
Card.StackInstall()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
'介绍栏
|
|
||||||
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
|
|
||||||
OpenWebsite("https://files.minecraftforge.net")
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
End Class
|
|
||||||
@@ -5,110 +5,55 @@
|
|||||||
<local:MyScrollViewer PanningMode="VerticalOnly" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Style="{StaticResource ScrollViewerFullMargin}">
|
<local:MyScrollViewer PanningMode="VerticalOnly" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Style="{StaticResource ScrollViewerFullMargin}">
|
||||||
<StackPanel Margin="0,12,0,0" Name="PanItem">
|
<StackPanel Margin="0,12,0,0" Name="PanItem">
|
||||||
|
|
||||||
<TextBlock x:Name="LabGame" Text="Minecraft" Margin="13,6,5,4" Opacity="0.6" FontSize="12" />
|
<local:MyListItem x:Name="ItemInstall" Checked="True" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="0" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Minecraft"
|
||||||
<local:MyListItem x:Name="ItemInstall" Checked="True" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="1" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="游戏下载"
|
Logo="m351.9,801.7c-8.6,0-17-3-23.7-8.4L18.9,614.7c-12.5-7.2-19.7-20.5-18.8-34.9V221c-.7-15,6.6-28.8,19.2-36L325.2,8.3c6.6-5.3,15.1-8.3,24-8.3s17.3,2.9,23.9,8.2l308.3,178c.2.1.5.3.8.5h0c12,6.7,19.4,19.8,19.4,34.1,0,13.9-7.1,26-18.7,32.5l-290.1,167.5v276l234-135.1v-168.9c0-20.8,17-37.8,37.8-37.8s37.8,17,37.8,37.8v191.7c0,16.4-10.9,31.2-26.5,36.1l-299.4,172.8c-6.7,5.4-15.1,8.3-23.7,8.3h-.9Zm-34.8-101.9v-276l-241.4-139.4v276l241.4,139.4Zm35.3-342.8l236.8-136.7-240-138.6L112.4,218.3l240,138.6Z">
|
||||||
Logo="M12 0l-11 6v12.131l11 5.869 11-5.869v-12.066l-11-6.065zm-1 21.2l-6.664-3.555 4.201-2.801c1.08-.719-.066-2.359-1.243-1.575l-4.294 2.862v-7.901l8 4.363v8.607zm-6.867-14.63l6.867-3.746v4.426c0 1.323 2 1.324 2 0v-4.415l6.91 3.811-7.905 4.218-7.872-4.294zm8.867 6.03l8-4.269v7.8l-4.263-2.842c-1.181-.785-2.323.855-1.245 1.574l4.172 2.781-6.664 3.556v-8.6z">
|
|
||||||
<local:MyListItem.Buttons>
|
<local:MyListItem.Buttons>
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
<local:MyIconButton Tag="1" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
<local:MyIconButton Tag="0" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
</x:Array>
|
</x:Array>
|
||||||
</local:MyListItem.Buttons>
|
</local:MyListItem.Buttons>
|
||||||
</local:MyListItem>
|
</local:MyListItem>
|
||||||
<local:MyListItem x:Name="ItemHand" IsScaleAnimationEnabled="False" Type="RadioBox" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="手动安装包"
|
<TextBlock Text="社区资源" Margin="13,20,5,4" Opacity="0.6" FontSize="12" />
|
||||||
Logo="M1000 241c-2-5-4-11-6-17-0-6-4-12-8-17-7-9-18-15-31-15-6 0-13 1-19 5l-15 15-17 17-21 21L749 381c-14 14-38 14-52 0l-54-54c-14-14-14-38 0-52l132-132 14-14 20-20 16-16c3-5 5-11 5-19 0-12-5-24-16-32-5-4-11-6-18-7-5-2-10-4-16-5-36-12-76-19-117-19-7 0-14 0-22 0-188 11-337 168-337 360 0 16 0 32 3 48L56 663c-73 74-73 193 0 267l33 33c73 73 193 73 267 0l240-241c21 4 42 5 64 5 190 0 346-146 360-333 0-8 0-17 0-27 0-44-6-86-21-125zM658 639c-28 0-54-4-79-11-4 7-10 14-16 21l-258 258c-43 43-115 43-158 0l-29-29c-43-44-43-115 0-158l212-212 46-46c5-5 12-11 19-15-8-26-12-54-12-83v-1c0-152 123-275 276-275 18 0 37 1 55 5L597 207c-52 52-52 137 0 189l29 29c52 52 137 52 189 0L930 312c2 16 4 33 4 50 0 152-123 276-276 276z" />
|
<local:MyListItem x:Name="ItemMod" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="2" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod"
|
||||||
<TextBlock x:Name="LabHand" Visibility="Collapsed" Text="▼ 手动安装包" Padding="11,18,5,4" Opacity="0.6" FontSize="12" />
|
LogoScale="0.97" Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">
|
||||||
<local:MyListItem x:Name="ItemClient" Visibility="Collapsed" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="4" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Minecraft"
|
<local:MyListItem.Buttons>
|
||||||
LogoScale="0.98" Logo="M989.7 510.8l-202.3-101c-10.8-5.4-17.7-16.5-17.7-28.6V172.7c0-26.7-16.6-50.6-41.6-59.9L550.5 46.3c-24.2-9-50.8-9-74.9 0.1l-176.9 66.8c-24.9 9.4-41.4 33.2-41.4 59.9v207.1c0 12.1-6.9 23.2-17.7 28.6l-204 101.9C13.9 521.6 0.1 543.8 0.2 568.1l0.5 226c0 23.2 12.6 44.5 32.9 55.8l223.8 124.6 1.2 0.7c18.9 10.5 41.9 10.4 60.8-0.2l2-1.1L497 873.2c9.9-5.7 22.1-5.6 32 0.1l176.7 102.5c18.9 10.7 42 10.8 61 0.3l3-1.7L992.4 851c20.4-11.3 33-32.8 33-56l-0.3-226.9c0-24.3-13.7-46.5-35.4-57.3zM321 192l115.3 46.1c27 10.8 44.7 36.9 44.7 66v163c0 5.9-6.2 9.8-11.6 7.2L339 409.5c-10.9-5.4-17.7-16.5-17.8-28.6L321 192z m-63.7 703.4L82.5 809.6c-10.9-5.4-17.9-16.5-17.9-28.7l-0.4-189.5L217.9 668c24.1 12 39.4 36.7 39.4 63.6v163.8z m64-274.3c-20.1 10.1-43.7 10-63.8 0l-0.2-0.1-149.1-75 149.1-74.4 16.8-8.4c9.2-4.6 20-4.5 29.1 0.3l18.1 9.4 129.8 64.3c5.8 2.9 6 11.1 0.2 14.2l-130 69.7z m141.9 203.8l-141.8 70.6-0.8-163.6c-0.1-27 15.1-51.8 39.2-63.9l108.8-54.5c5.3-2.7 11.6 1.2 11.6 7.1l0.8 175.6c0 12.1-6.9 23.2-17.8 28.7zM385 144l128-48 128 48-103 38.6c-16.1 6-33.8 6-49.9 0L385 144z m320 48l0.6 187.8c0 12.2-6.8 23.3-17.7 28.7l-131.4 65.7c-5.3 2.7-11.6-1.2-11.6-7.2V304.1c0-29.1 17.7-55.2 44.7-66L705 192z m0.7 710.3l-143.8-77.2c-10.4-5.6-16.9-16.4-16.9-28.2v-176c0-5.9 6.3-9.8 11.6-7.2l109.3 54.6c24 12 39.2 36.5 39.3 63.4l0.5 170.6z m-2-280.5l-129.2-70.5c-5.7-3.1-5.5-11.3 0.3-14.2l131-65.3 16.1-8.5c9.1-4.8 19.9-4.9 29.1-0.3l18.7 9.3L916.9 546l-146.2 76.4c-21.1 11-46.2 10.8-67-0.6z m66 279.4l-0.6-169.1c-0.1-27 15.1-51.7 39.3-63.8L961 592v188.7c0 11.9-6.6 22.7-17 28.3l-174.3 92.2z">
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
<!--Logo="M469.333333 213.333333V128a42.666667 42.666667 0 1 1 85.333334 0v85.333333h127.829333C847.722667 213.333333 981.333333 347.029333 981.333333 512.149333v319.936A106.496 106.496 0 0 1 874.730667 938.666667h-85.461334c-48.661333 0-107.221333-29.290667-136.469333-68.266667l-64-85.333333c-6.144-8.170667-23.957333-17.066667-34.24-17.066667h-85.12c-10.282667 0-28.096 8.896-34.24 17.066667l-64 85.333333c-29.226667 38.976-87.808 68.266667-136.469333 68.266667H149.269333A106.496 106.496 0 0 1 42.666667 832.085333V512.149333C42.666667 347.029333 176.277333 213.333333 341.504 213.333333H469.333333z m213.162667 85.333334H341.504A213.333333 213.333333 0 0 0 128 512.149333v319.936c0 11.818667 9.450667 21.248 21.269333 21.248h85.461334c21.802667 0 55.082667-16.64 68.202666-34.133333l64-85.333333c22.272-29.696 65.408-51.2 102.506667-51.2h85.12c37.098667 0 80.213333 21.504 102.506667 51.2l64 85.333333c13.12 17.493333 46.4 34.133333 68.202666 34.133333h85.461334a21.162667 21.162667 0 0 0 21.269333-21.248V512.149333A213.333333 213.333333 0 0 0 682.496 298.666667zM362.666667 469.333333h42.666666a42.666667 42.666667 0 1 1 0 85.333334h-42.666666v42.666666a42.666667 42.666667 0 1 1-85.333334 0v-42.666666h-42.666666a42.666667 42.666667 0 1 1 0-85.333334h42.666666v-42.666666a42.666667 42.666667 0 1 1 85.333334 0v42.666666z m341.333333-21.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m0 213.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m-106.666667-106.666666a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z m213.333334 0a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z">-->
|
<local:MyIconButton Tag="2" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
|
</x:Array>
|
||||||
|
</local:MyListItem.Buttons>
|
||||||
|
</local:MyListItem>
|
||||||
|
<local:MyListItem x:Name="ItemPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="3" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="整合包"
|
||||||
|
LogoScale="0.98" Logo="M511 995a128 128 0 0 1-57-13L70 791a126 126 0 0 1-70-113V311a126 126 0 0 1 15-60V248c1-2 3-5 5-8a127 127 0 0 1 49-42L454 13a128 128 0 0 1 112 0l383 190a126 126 0 0 1 72 113v360a126 126 0 0 1-70 115L568 984c-17 7-37 11-57 11z m42-470v370l360-178c14-7 23-21 23-38v-335L554 524zM85 330v347a42 42 0 0 0 23 38l360 178V523L85 330zM135 260l375 189 137-65L286 188 135 260z m245-118l363 197 150-71-365-180a42 42 0 0 0-37 0l-111 53z">
|
||||||
|
<local:MyListItem.Buttons>
|
||||||
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
|
<local:MyIconButton Tag="3" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
|
</x:Array>
|
||||||
|
</local:MyListItem.Buttons>
|
||||||
|
</local:MyListItem>
|
||||||
|
<local:MyListItem x:Name="ItemDataPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="4" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="数据包"
|
||||||
|
LogoScale="0.96" Logo="M445 545c18 0 33 14 33 33v149a182 182 0 1 1-182-182z m282 0a182 182 0 1 1-182 182v-149c0-18 14-33 33-33zM412 611H296a116 116 0 1 0 116 116V611z m315 0H611v116a116 116 0 1 0 116-116zM296 113a182 182 0 0 1 182 182v149a33 33 0 0 1-33 33H296a182 182 0 0 1 0-365z m431 0a182 182 0 0 1 0 365h-149a33 33 0 0 1-33-33V296A182 182 0 0 1 727 113zM296 180a116 116 0 0 0 0 232H412V296c0-62-48-112-109-115z m431 0a116 116 0 0 0-116 116V412h116c62 0 112-48 115-109l0-6a116 116 0 0 0-116-116z">
|
||||||
<local:MyListItem.Buttons>
|
<local:MyListItem.Buttons>
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
<local:MyIconButton Tag="4" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
<local:MyIconButton Tag="4" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
</x:Array>
|
</x:Array>
|
||||||
</local:MyListItem.Buttons>
|
</local:MyListItem.Buttons>
|
||||||
</local:MyListItem>
|
</local:MyListItem>
|
||||||
<local:MyListItem x:Name="ItemOptiFine" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="5" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="OptiFine"
|
<local:MyListItem x:Name="ItemResourcePack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="5" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="资源包"
|
||||||
LogoScale="1.00" Logo="M439.667 538.133l-323.311-174.763c-6.554-3.641-13.836-5.098-20.389-5.098-23.301 0-45.147 20.389-45.147 48.788v341.516c0 35.681 18.205 67.721 48.060 83.741l323.311 174.763c6.554 3.641 13.836 5.825 20.389 5.825 23.301 0 45.147-21.117 45.147-49.516v-341.516c0-34.953-18.205-67.721-48.060-83.741zM414.909 920.427l-281.805-152.189c-4.369-2.913-9.467-9.467-9.467-19.661v-298.553l281.805 152.189c5.825 3.641 9.467 11.651 9.467 19.661v298.553zM952.304 358.274c-6.554 0-13.836 1.456-20.389 5.098l-323.311 175.491c-29.855 16.020-48.060 48.788-48.060 84.468v340.059c0 28.399 21.845 49.516 45.147 49.516 6.554 0 13.836-1.456 20.389-5.098l323.311-175.491c29.127-16.020 48.060-48.060 48.060-83.741v-341.516c0-28.399-21.845-48.788-45.147-48.788zM924.634 747.849c0 10.194-5.098 17.476-9.467 19.661l-281.805 152.917v-297.097c0-10.194 5.098-17.476 9.467-19.661l281.805-153.646v297.825zM902.060 283.272c15.292-8.010 22.574-21.845 21.117-34.953 1.456-13.836-5.825-26.943-21.117-34.953l-329.136-171.85c-14.563-8.010-31.312-11.651-48.788-11.651 0 0 0 0 0 0 0 0 0 0 0 0s-34.224 3.641-49.516 11.651l-329.865 171.122c-15.292 8.010-21.845 21.845-21.117 35.681-0.729 13.107 5.825 26.943 21.117 34.953l329.136 171.122c14.563 8.010 32.039 11.651 49.516 11.651 0 0 0 0 0.729 0 0 0 0 0 0.729 0s34.224-3.641 49.516-11.651l327.68-171.122zM523.407 393.227c-5.825 0-11.651-1.456-16.020-3.641l-272.338-141.266 272.338-141.995c4.369-2.185 10.194-3.641 16.748-3.641 5.825 0 11.651 1.456 16.020 3.641l272.338 141.995-273.067 141.266c-3.641 2.185-9.467 3.641-16.020 3.641z">
|
LogoScale="0.81" Logo="M884.4 130.6H140.6c-41.9 0-76 34.1-76 76v613.3c0 41.9 34.1 76 76 76h743.8c41.9 0 76-34.1 76-76V206.6c0-41.9-34.1-76-76-76z m-743.8 72h743.8c2.2 0 4 1.8 4 4v371.3L796 461.7c-21.7-27.3-54.1-43.7-88.8-45-34.7-1.3-68.1 12.7-91.7 38.3L454 630c-2.8 3-7.2 3.5-10.5 1.3l-103-70.3c-31.5-21.5-72.8-22.5-105.3-2.7l-98.6 60.1V206.6c0-2.2 1.8-4 4-4z m743.8 621.3H140.6c-2.2 0-4-1.8-4-4V702.7l136.1-83c8.4-5.1 19.1-4.8 27.2 0.7l103 70.3c15.9 10.8 35.1 15.6 54.2 13.4 19-2.2 36.7-11.2 49.8-25.3l161.6-175c9.5-10.3 22.3-15.7 36.2-15.1 13.9 0.5 26.3 6.8 35.1 17.8l148.7 187v126.3c-0.1 2.3-1.9 4.1-4.1 4.1z M231.8 400.6a69.6 69.6 0 1 0 98.4-98.4 69.6 69.6 0 1 0-98.4 98.4Z">
|
||||||
<!--Logo="M12 0l-11 6v12.131l11 5.869 11-5.869v-12.066l-11-6.065zm-1 21.2l-6.664-3.555 4.201-2.801c1.08-.719-.066-2.359-1.243-1.575l-4.294 2.862v-7.901l8 4.363v8.607zm-6.867-14.63l6.867-3.746v4.426c0 1.323 2 1.324 2 0v-4.415l6.91 3.811-7.905 4.218-7.872-4.294zm8.867 6.03l8-4.269v7.8l-4.263-2.842c-1.181-.785-2.323.855-1.245 1.574l4.172 2.781-6.664 3.556v-8.6z">-->
|
|
||||||
<local:MyListItem.Buttons>
|
<local:MyListItem.Buttons>
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
<local:MyIconButton Tag="5" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
<local:MyIconButton Tag="5" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
</x:Array>
|
</x:Array>
|
||||||
</local:MyListItem.Buttons>
|
</local:MyListItem.Buttons>
|
||||||
</local:MyListItem>
|
</local:MyListItem>
|
||||||
<local:MyListItem x:Name="ItemForge" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="6" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Forge"
|
<local:MyListItem x:Name="ItemShader" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="6" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="光影包"
|
||||||
LogoScale="1.00" Logo="M402.807089 481.189274c-12.040221-6.991228-27.412326-2.797719-34.397415 9.242502l-8.387018 14.512529c-6.987135 12.035104-2.793626 27.40721 9.246595 34.392298 12.040221 6.985088 27.408233 2.797719 34.393321-9.242502l8.387018-14.511505C418.930301 503.437997 414.842193 488.063845 402.807089 481.189274L402.807089 481.189274zM495.028467 919.955342 59.056024 919.955342c-18.485003 0-33.532721 15.046694-33.532721 33.536814 0 18.485003 15.046694 33.532721 33.532721 33.532721l435.972443 0c18.49012 0 33.537837-15.046694 33.537837-33.532721C528.566304 935.002037 513.518586 919.955342 495.028467 919.955342L495.028467 919.955342zM997.431901 660.155295 590.482469 446.039729l90.935082-157.474544c18.485003-32.031531 7.520277-73.090669-24.51023-91.581812L395.496589 46.070268c-32.031531-18.485003-73.094762-7.520277-91.579765 24.51023L18.74697 564.277644c-18.485003 32.031531-7.521301 73.089645 24.51023 91.579765l261.408685 150.907988c32.031531 18.491143 73.095785 7.526417 91.581812-24.505114l91.364871-158.330028 392.332527 239.48128c16.016789 9.247618 36.544311 3.76372 45.792952-12.249999l83.838454-145.219429C1019.033895 689.930435 1013.444597 669.39882 997.431901 660.155295L997.431901 660.155295zM355.078041 719.704552c-9.242502 16.012695-29.774117 21.497617-45.787836 12.251022L105.923448 614.57826c-16.016789-9.242502-21.497617-29.774117-12.255115-45.787836l251.522524-435.653171c9.246595-16.012695 29.774117-21.497617 45.792952-12.249999l203.25624 117.376291c16.018835 9.242502 21.497617 29.774117 12.255115 45.786813L355.078041 719.704552 355.078041 719.704552zM884.568391 788.601712 522.115382 564.492538l33.537837-58.048067L934.875147 701.539844 884.568391 788.601712 884.568391 788.601712zM520.184403 277.8174c-12.040221-6.987135-27.41335-2.792603-34.399461 9.246595l-75.456552 130.702807c-6.985088 12.040221-2.791579 27.412326 9.242502 34.397415 12.040221 6.987135 27.412326 2.791579 34.397415-9.242502l75.458599-130.706901C536.307615 300.174594 532.219507 284.807604 520.184403 277.8174L520.184403 277.8174zM520.184403 277.8174">
|
LogoScale="1.04" Logo="M512 0c25 0 42 17 42 42v85c0 25-17 42-42 42s-42-17-42-42V42c0-25 17-42 42-42zM512 853c25 0 42 17 42 42v85c0 25-17 42-42 42s-42-17-42-42v-85c0-25 17-42 42-42zM209 149c-17-17-42-17-59 0-17 17-17 42 0 59l59 59c17 17 42 17 59 0 17-17 17-42 0-59L209 149zM755 755c17-17 42-17 59 0l59 59c17 17 17 42 0 59s-42 17-59 0l-59-59c-17-17-17-46 0-59zM42 469c-25 0-42 17-42 42s17 42 42 42h85c25 0 42-17 42-42s-17-42-42-42H42zM853 512c0-25 17-42 42-42h85c25 0 42 17 42 42s-17 42-42 42h-85c-25 0-42-17-42-42zM149 814c-17 17-17 42 0 59 17 17 42 17 59 0l59-59c17-17 17-42 0-59-17-17-42-17-59 0l-59 59zM755 268c-17-17-17-42 0-59l59-59c17-17 42-17 59 0s17 42 0 59l-59 59c-17 17-46 17-59 0z M512 213c-166 0-298 132-298 298s132 298 298 298 298-132 298-298-132-298-298-298z m0 512c-119 0-213-93-213-213s93-213 213-213 213 93 213 213-93 213-213 213z">
|
||||||
<!--Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">-->
|
|
||||||
<local:MyListItem.Buttons>
|
<local:MyListItem.Buttons>
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
<x:Array Type="{x:Type local:MyIconButton}">
|
||||||
<local:MyIconButton Tag="6" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
<local:MyIconButton Tag="6" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
||||||
</x:Array>
|
</x:Array>
|
||||||
</local:MyListItem.Buttons>
|
</local:MyListItem.Buttons>
|
||||||
</local:MyListItem>
|
</local:MyListItem>
|
||||||
<local:MyListItem x:Name="ItemNeoForge" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="7" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="NeoForge"
|
|
||||||
LogoScale="0.95" Logo="M544.6 921.2l-23.7 32.6c14.1 10.2 33.3 10.2 47.5 0l-23.7-32.6zM114.6 608.5l-23.9 32.5 0.2 0.1 23.6-32.6z m-12.0-38.0l38.3 12.7v-0.2l-38.3-12.4z m49.2-152.6l-38.4-12.4 38.4 12.4zM250.2 114.4l-37.6-14.6a40.2 40.2 0 0 0-0.7 2.1l38.4 12.4z m4.3-6.4l27.0 29.9 0.2-0.2-27.2-29.7z m11.7-4.5V63.0v40.4z m11.7 4.5l28.0-29.0a40.5 40.5 0 0 0-0.8-0.8l-27.2 29.8z m4.4 7.3l-38.6 11.7a40.5 40.5 0 0 0 0.2 0.7l38.3-12.4zM381.0 417.7l-38.4 12.5a40.3 40.3 0 0 0 38.4 27.8v-40.3z m327.0 0v40.3c17.5 0 32.9-11.2 38.4-27.8L708.1 417.7z m98.5-303.3l-37.6-14.6a38.4 38.4 0 0 0-0.7 2.1l38.4 12.4z m4.3-6.4l27.1 29.9 0.1-0.2-27.2-29.7z m11.7-4.5v0z m11.7 4.5l28.0-29.0a38.4 38.4 0 0 0-0.8-0.8l-27.2 29.8z m4.3 7.3l-38.6 11.7a47.5 47.5 0 0 0 0.2 0.7l38.4-12.4z m98.5 303.3l-38.4 12.4 0.1 0.5 38.2-12.9z m51.2 151.9l38.7-11.3a34.5 34.5 0 0 0-0.5-1.6l-38.1 12.9z m-37.8 5.2l-430.0 312.6 47.5 65.3 429.9-312.6-47.5-65.3z m-382.5 312.6L138.3 575.8l-47.5 65.3L520.9 953.9l47.3-65.3zM138.5 576a6.4 6.4 0 0 1 2.3 3.2l-76.9 24.5c4.7 14.9 14.1 28.0 26.7 37.3l47.8-65.0z m2.3 3.2a6.4 6.4 0 0 1 0 4.0L64.1 557.9a74.3 74.3 0 0 0-0.2 45.8l76.9-24.5z m0 3.7l49.2-152.6-76.8-24.8L64.0 558.2l76.8 24.8z m49.2-152.5l98.5-303.3-76.8-25.0L113.3 405.3l76.8 25.0z m97.7-301.3a23.4 23.4 0 0 1-6.1 8.9L227.6 78.0a57.3 57.3 0 0 0-15.0 21.8l75.3 29.1z m-5.9 8.7a23.0 23.0 0 0 1-15.5 6.0V63.0a57.7 57.7 0 0 0-38.9 15.1l54.4 59.6z m-15.5 6.0a23.0 23.0 0 0 1-15.5-6.0l54.4-59.6A57.7 57.7 0 0 0 266.4 63.0v80.8z m-16.3-6.8a23.4 23.4 0 0 1-6.1-10.0l77.3-23.4a57.3 57.3 0 0 0-15.0-24.5l-56.1 58.0z m-5.8-9.2l98.4 302.5 76.8-25.0-98.5-302.5-76.8 25.0z m136.8 330.4H708.1V377.5H381.2v80.7z m365.4-27.8l98.5-303.3-76.8-25.0L669.6 405.3l76.8 25.0z m97.7-301.3a23.4 23.4 0 0 1-6.1 8.9l-54.1-59.9a57.3 57.3 0 0 0-15.0 21.8l75.3 29.1z m-5.9 8.7a23.0 23.0 0 0 1-15.5 6.0V63.0a57.7 57.7 0 0 0-38.9 15.1l54.4 59.6z m-15.5 6.0a23.0 23.0 0 0 1-15.5-6.0l54.4-59.6a57.7 57.7 0 0 0-38.9-15.1v80.8z m-16.3-6.8a23.4 23.4 0 0 1-6.1-10.0l77.3-23.4a57.4 57.4 0 0 0-14.9-24.5l-56.1 58.0z m-5.8-9.2l98.5 303.3 76.8-25.0-98.5-303.3-76.8 25.0z m98.6 303.8l51.2 151.9 76.5-25.8-51.2-151.9-76.5 25.8z m50.7 150.2a6.5 6.5 0 0 1 0.1-4.0l75.6 28.1c5.5-14.9 6.2-31.3 1.6-46.7l-77.5 22.6z m0.1-4.0a6.4 6.4 0 0 1 2.4-3.2l43.8 67.8c13.4-8.7 23.6-21.5 29.2-36.4l-75.6-28.1z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="7" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<local:MyListItem x:Name="ItemFabric" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="8" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Fabric"
|
|
||||||
LogoScale="1.02" Logo="M826.453333 170.666667c-100.266667-93.866667-248.96-76.373333-256-75.52a31.786667 31.786667 0 0 0-26.666666 22.613333c-1.066667 3.2-101.546667 330.666667-426.666667 445.013333a29.013333 29.013333 0 0 0-7.893333 4.48l-1.493334 1.066667a29.44 29.44 0 0 0-5.973333 6.613333 31.786667 31.786667 0 0 0-3.626667 7.68 5.333333 5.333333 0 0 1 0 1.493334 30.506667 30.506667 0 0 0 0 8.96c7.466667 116.266667 45.013333 204.586667 112 262.826666a303.36 303.36 0 0 0 194.773334 71.466667h11.52a32.426667 32.426667 0 0 0 27.093333-19.626667 694.186667 694.186667 0 0 1 159.36-234.666666l-7.68 55.466666A31.786667 31.786667 0 0 0 621.44 768h4.48a32.213333 32.213333 0 0 0 31.786667-27.733333l15.573333-112.426667 112.426667 8.32a32 32 0 1 0 4.693333-64l-56.96-4.266667c36.48-25.813333 74.026667-50.56 112-75.52l51.626667-34.133333a31.573333 31.573333 0 0 0 14.08-24.746667c6.186667-115.2-21.76-203.306667-84.693334-262.826666zM620.8 573.013333l-1.706667 1.493334a219.093333 219.093333 0 0 0-87.466666-116.693334 222.933333 222.933333 0 0 0-95.146667-33.28c18.986667-21.333333 36.266667-42.666667 51.626667-64a198.613333 198.613333 0 0 1 202.453333 158.08c-20.053333 14.506667-39.893333 29.44-59.52 45.226667a29.866667 29.866667 0 0 0-10.24 9.173333z m-228.693333 292.266667a238.72 238.72 0 0 1-141.44-55.893333 213.333333 213.333333 0 0 1-34.986667-39.466667 123.946667 123.946667 0 0 0 44.373333 8.106667 168.533333 168.533333 0 0 0 69.12-16.213334 29.44 29.44 0 0 0 7.04-4.266666l106.666667-85.333334a32 32 0 1 0-39.893333-49.92L298.666667 704a78.293333 78.293333 0 0 1-69.546667 1.706667c-32.426667-17.066667-52.693333-61.653333-62.506667-93.44a709.333333 709.333333 0 0 0 202.453334-123.733334 187.52 187.52 0 0 1 128 21.333334 171.946667 171.946667 0 0 1 68.906666 109.653333 756.48 756.48 0 0 0-173.866666 245.76zM810.666667 438.4l-64 42.666667A256 256 0 0 0 529.706667 298.666667a810.666667 810.666667 0 0 0 69.12-140.8c37.973333-1.066667 123.946667 4.053333 183.68 59.946666 45.866667 42.666667 67.84 108.8 65.493333 195.84z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="8" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<local:MyListItem x:Name="ItemLiteLoader" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="9" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="LiteLoader"
|
|
||||||
LogoScale="1.06" Logo="M517.41 186.99l22.45 83.78h-55.04l-18.76-70.02c-2.85-10.63-13.78-16.95-24.42-14.1-10.63 2.85-16.95 13.78-14.1 24.42l16 59.71H388.5l-12.31-45.95c-10.45-38.99 12.69-79.08 51.69-89.52s79.08 12.68 89.53 51.68z M538.58 98c40.37 0 73.1 32.73 73.1 73.1v79.74h-53.16V171.1c0-11.01-8.93-19.94-19.94-19.94-11.01 0-19.94 8.93-19.94 19.94v79.74h-53.16V171.1c0-40.37 32.73-73.1 73.1-73.1z M512 224.26c191.58 0 346.88 155.3 346.88 346.88v61.8c0 28.85 3.33 59.94 9.98 93.27l1.29 6.28c12.43 59.1-21.15 118.2-78.28 137.78C691.18 904.75 597.9 922 512 922c-83.94 0-174.95-16.47-273.01-49.41l-6.85-2.32c-56.4-19.32-89.85-77.16-78.74-135.5l0.46-2.27c7.51-35.71 11.27-68.89 11.27-99.55v-61.8c0-189.66 152.21-343.77 341.14-346.83l5.73-0.06z m-4.64 66.49c-151.21 2.45-273.32 124.58-275.75 275.8l-0.04 4.59v61.8l-0.04 5.93c-0.45 33.74-4.7 69.49-12.65 107.3-5.53 26.27 9.4 52.53 34.79 61.23 94.08 32.23 180.19 48.15 258.32 48.15s164.25-15.92 258.32-48.15c25.39-8.7 40.32-34.97 34.79-61.23-7.95-37.81-12.2-73.56-12.65-107.3l-0.04-5.93v-61.8c0-153.33-123.05-277.91-275.79-280.39l-4.64-0.04-4.62 0.04z M500.66 717.38l-53.28-87.19c-3.83-6.26-1.85-14.44 4.41-18.27 0.76-0.46 1.56-0.85 2.39-1.15L512 589.74l57.82 21.03c6.9 2.51 10.46 10.13 7.95 17.03-0.3 0.83-0.69 1.63-1.15 2.39l-53.28 87.19c-3.83 6.26-12.01 8.24-18.27 4.41-1.8-1.1-3.31-2.61-4.41-4.41z M684.77 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z M339.23 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="9" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<TextBlock Text="社区资源" Margin="13,30,5,4" Opacity="0.6" FontSize="12" />
|
|
||||||
<local:MyListItem x:Name="ItemMod" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="11" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod"
|
|
||||||
LogoScale="0.97" Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="11" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<local:MyListItem x:Name="ItemPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="12" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="整合包"
|
|
||||||
LogoScale="0.98" Logo="M511 995a128 128 0 0 1-57-13L70 791a126 126 0 0 1-70-113V311a126 126 0 0 1 15-60V248c1-2 3-5 5-8a127 127 0 0 1 49-42L454 13a128 128 0 0 1 112 0l383 190a126 126 0 0 1 72 113v360a126 126 0 0 1-70 115L568 984c-17 7-37 11-57 11z m42-470v370l360-178c14-7 23-21 23-38v-335L554 524zM85 330v347a42 42 0 0 0 23 38l360 178V523L85 330zM135 260l375 189 137-65L286 188 135 260z m245-118l363 197 150-71-365-180a42 42 0 0 0-37 0l-111 53z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="12" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<local:MyListItem x:Name="ItemDataPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="13" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="数据包"
|
|
||||||
LogoScale="0.96" Logo="M445 545c18 0 33 14 33 33v149a182 182 0 1 1-182-182z m282 0a182 182 0 1 1-182 182v-149c0-18 14-33 33-33zM412 611H296a116 116 0 1 0 116 116V611z m315 0H611v116a116 116 0 1 0 116-116zM296 113a182 182 0 0 1 182 182v149a33 33 0 0 1-33 33H296a182 182 0 0 1 0-365z m431 0a182 182 0 0 1 0 365h-149a33 33 0 0 1-33-33V296A182 182 0 0 1 727 113zM296 180a116 116 0 0 0 0 232H412V296c0-62-48-112-109-115z m431 0a116 116 0 0 0-116 116V412h116c62 0 112-48 115-109l0-6a116 116 0 0 0-116-116z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="13" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<local:MyListItem x:Name="ItemResourcePack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="14" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="资源包"
|
|
||||||
LogoScale="0.81" Logo="M884.4 130.6H140.6c-41.9 0-76 34.1-76 76v613.3c0 41.9 34.1 76 76 76h743.8c41.9 0 76-34.1 76-76V206.6c0-41.9-34.1-76-76-76z m-743.8 72h743.8c2.2 0 4 1.8 4 4v371.3L796 461.7c-21.7-27.3-54.1-43.7-88.8-45-34.7-1.3-68.1 12.7-91.7 38.3L454 630c-2.8 3-7.2 3.5-10.5 1.3l-103-70.3c-31.5-21.5-72.8-22.5-105.3-2.7l-98.6 60.1V206.6c0-2.2 1.8-4 4-4z m743.8 621.3H140.6c-2.2 0-4-1.8-4-4V702.7l136.1-83c8.4-5.1 19.1-4.8 27.2 0.7l103 70.3c15.9 10.8 35.1 15.6 54.2 13.4 19-2.2 36.7-11.2 49.8-25.3l161.6-175c9.5-10.3 22.3-15.7 36.2-15.1 13.9 0.5 26.3 6.8 35.1 17.8l148.7 187v126.3c-0.1 2.3-1.9 4.1-4.1 4.1z M231.8 400.6a69.6 69.6 0 1 0 98.4-98.4 69.6 69.6 0 1 0-98.4 98.4Z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="14" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
<local:MyListItem x:Name="ItemShader" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="15" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="光影包"
|
|
||||||
LogoScale="1.04" Logo="M512 0c25 0 42 17 42 42v85c0 25-17 42-42 42s-42-17-42-42V42c0-25 17-42 42-42zM512 853c25 0 42 17 42 42v85c0 25-17 42-42 42s-42-17-42-42v-85c0-25 17-42 42-42zM209 149c-17-17-42-17-59 0-17 17-17 42 0 59l59 59c17 17 42 17 59 0 17-17 17-42 0-59L209 149zM755 755c17-17 42-17 59 0l59 59c17 17 17 42 0 59s-42 17-59 0l-59-59c-17-17-17-46 0-59zM42 469c-25 0-42 17-42 42s17 42 42 42h85c25 0 42-17 42-42s-17-42-42-42H42zM853 512c0-25 17-42 42-42h85c25 0 42 17 42 42s-17 42-42 42h-85c-25 0-42-17-42-42zM149 814c-17 17-17 42 0 59 17 17 42 17 59 0l59-59c17-17 17-42 0-59-17-17-42-17-59 0l-59 59zM755 268c-17-17-17-42 0-59l59-59c17-17 42-17 59 0s17 42 0 59l-59 59c-17 17-46 17-59 0z M512 213c-166 0-298 132-298 298s132 298 298 298 298-132 298-298-132-298-298-298z m0 512c-119 0-213-93-213-213s93-213 213-213 213 93 213 213-93 213-213 213z">
|
|
||||||
<local:MyListItem.Buttons>
|
|
||||||
<x:Array Type="{x:Type local:MyIconButton}">
|
|
||||||
<local:MyIconButton Tag="15" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
|
|
||||||
</x:Array>
|
|
||||||
</local:MyListItem.Buttons>
|
|
||||||
</local:MyListItem>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyScrollViewer>
|
</local:MyScrollViewer>
|
||||||
</local:MyPageLeft>
|
</local:MyPageLeft>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
''' <summary>
|
''' <summary>
|
||||||
''' 勾选事件改变页面。
|
''' 勾选事件改变页面。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemInstall.Check, ItemClient.Check, ItemOptiFine.Check, ItemForge.Check, ItemNeoForge.Check, ItemLiteLoader.Check, ItemMod.Check, ItemFabric.Check, ItemPack.Check, ItemResourcePack.Check, ItemShader.Check, ItemDataPack.Check
|
Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemInstall.Check, ItemMod.Check, ItemPack.Check, ItemResourcePack.Check, ItemShader.Check, ItemDataPack.Check
|
||||||
'尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0
|
'尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0
|
||||||
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
|
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
|
||||||
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
|
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
|
||||||
@@ -23,24 +23,6 @@
|
|||||||
Case FormMain.PageSubType.DownloadInstall
|
Case FormMain.PageSubType.DownloadInstall
|
||||||
If FrmDownloadInstall Is Nothing Then FrmDownloadInstall = New PageDownloadInstall
|
If FrmDownloadInstall Is Nothing Then FrmDownloadInstall = New PageDownloadInstall
|
||||||
Return FrmDownloadInstall
|
Return FrmDownloadInstall
|
||||||
Case FormMain.PageSubType.DownloadClient
|
|
||||||
If FrmDownloadClient Is Nothing Then FrmDownloadClient = New PageDownloadClient
|
|
||||||
Return FrmDownloadClient
|
|
||||||
Case FormMain.PageSubType.DownloadOptiFine
|
|
||||||
If FrmDownloadOptiFine Is Nothing Then FrmDownloadOptiFine = New PageDownloadOptiFine
|
|
||||||
Return FrmDownloadOptiFine
|
|
||||||
Case FormMain.PageSubType.DownloadForge
|
|
||||||
If FrmDownloadForge Is Nothing Then FrmDownloadForge = New PageDownloadForge
|
|
||||||
Return FrmDownloadForge
|
|
||||||
Case FormMain.PageSubType.DownloadNeoForge
|
|
||||||
If FrmDownloadNeoForge Is Nothing Then FrmDownloadNeoForge = New PageDownloadNeoForge
|
|
||||||
Return FrmDownloadNeoForge
|
|
||||||
Case FormMain.PageSubType.DownloadLiteLoader
|
|
||||||
If FrmDownloadLiteLoader Is Nothing Then FrmDownloadLiteLoader = New PageDownloadLiteLoader
|
|
||||||
Return FrmDownloadLiteLoader
|
|
||||||
Case FormMain.PageSubType.DownloadFabric
|
|
||||||
If FrmDownloadFabric Is Nothing Then FrmDownloadFabric = New PageDownloadFabric
|
|
||||||
Return FrmDownloadFabric
|
|
||||||
Case FormMain.PageSubType.DownloadMod
|
Case FormMain.PageSubType.DownloadMod
|
||||||
If FrmDownloadMod Is Nothing Then FrmDownloadMod = New PageDownloadMod
|
If FrmDownloadMod Is Nothing Then FrmDownloadMod = New PageDownloadMod
|
||||||
Return FrmDownloadMod
|
Return FrmDownloadMod
|
||||||
@@ -163,24 +145,6 @@
|
|||||||
FrmDownloadDataPack.PageLoaderRestart()
|
FrmDownloadDataPack.PageLoaderRestart()
|
||||||
End If
|
End If
|
||||||
ItemDataPack.Checked = True
|
ItemDataPack.Checked = True
|
||||||
Case FormMain.PageSubType.DownloadClient
|
|
||||||
DlClientListLoader.Start(IsForceRestart:=True)
|
|
||||||
ItemClient.Checked = True
|
|
||||||
Case FormMain.PageSubType.DownloadOptiFine
|
|
||||||
DlOptiFineListLoader.Start(IsForceRestart:=True)
|
|
||||||
ItemOptiFine.Checked = True
|
|
||||||
Case FormMain.PageSubType.DownloadForge
|
|
||||||
DlForgeListLoader.Start(IsForceRestart:=True)
|
|
||||||
ItemForge.Checked = True
|
|
||||||
Case FormMain.PageSubType.DownloadNeoForge
|
|
||||||
DlNeoForgeListLoader.Start(IsForceRestart:=True)
|
|
||||||
ItemNeoForge.Checked = True
|
|
||||||
Case FormMain.PageSubType.DownloadLiteLoader
|
|
||||||
DlLiteLoaderListLoader.Start(IsForceRestart:=True)
|
|
||||||
ItemLiteLoader.Checked = True
|
|
||||||
Case FormMain.PageSubType.DownloadFabric
|
|
||||||
DlFabricListLoader.Start(IsForceRestart:=True)
|
|
||||||
ItemFabric.Checked = True
|
|
||||||
End Select
|
End Select
|
||||||
Hint("正在刷新……", Log:=False)
|
Hint("正在刷新……", Log:=False)
|
||||||
End Sub
|
End Sub
|
||||||
@@ -191,55 +155,4 @@
|
|||||||
FrmDownloadInstall.ExitSelectPage()
|
FrmDownloadInstall.ExitSelectPage()
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
'展开手动安装
|
|
||||||
Private Sub ItemHand_Click(sender As Object, e As RouteEventArgs) Handles ItemHand.Changed
|
|
||||||
If ItemHand.Checked = False Then Return
|
|
||||||
e.Handled = True
|
|
||||||
AniControlEnabled += 1
|
|
||||||
If Not Setup.Get("HintHandInstall") Then
|
|
||||||
Setup.Set("HintHandInstall", True)
|
|
||||||
If MyMsgBox("手动安装包功能提供了 OptiFine、Forge 等组件的 .jar 安装文件下载,但无法自动安装。" & vbCrLf &
|
|
||||||
"在自动安装页面先选择 MC 版本,然后就可以选择 OptiFine、Forge 等组件,让 PCL 自动进行安装了。", "自动安装提示", "返回自动安装", "继续下载手动安装包") = 1 Then
|
|
||||||
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.Download}, FormMain.PageSubType.DownloadInstall)
|
|
||||||
AniControlEnabled -= 1
|
|
||||||
Return
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
ItemHand.Visibility = Visibility.Collapsed
|
|
||||||
LabGame.Visibility = Visibility.Collapsed
|
|
||||||
LabHand.Visibility = Visibility.Visible
|
|
||||||
ItemClient.Visibility = Visibility.Visible
|
|
||||||
ItemOptiFine.Visibility = Visibility.Visible
|
|
||||||
ItemFabric.Visibility = Visibility.Visible
|
|
||||||
ItemForge.Visibility = Visibility.Visible
|
|
||||||
ItemNeoForge.Visibility = Visibility.Visible
|
|
||||||
ItemLiteLoader.Visibility = Visibility.Visible
|
|
||||||
RunInThread(
|
|
||||||
Sub()
|
|
||||||
Thread.Sleep(20)
|
|
||||||
RunInUiWait(Sub() ItemClient.SetChecked(True, True, True))
|
|
||||||
AniControlEnabled -= 1
|
|
||||||
End Sub)
|
|
||||||
End Sub
|
|
||||||
'折叠手动安装
|
|
||||||
Private Sub LabHand_Click(sender As Object, e As MouseButtonEventArgs) Handles LabHand.MouseLeftButtonUp
|
|
||||||
e.Handled = True
|
|
||||||
AniControlEnabled += 1
|
|
||||||
ItemHand.Visibility = Visibility.Visible
|
|
||||||
LabGame.Visibility = Visibility.Visible
|
|
||||||
LabHand.Visibility = Visibility.Collapsed
|
|
||||||
ItemClient.Visibility = Visibility.Collapsed
|
|
||||||
ItemOptiFine.Visibility = Visibility.Collapsed
|
|
||||||
ItemNeoForge.Visibility = Visibility.Collapsed
|
|
||||||
ItemFabric.Visibility = Visibility.Collapsed
|
|
||||||
ItemForge.Visibility = Visibility.Collapsed
|
|
||||||
ItemLiteLoader.Visibility = Visibility.Collapsed
|
|
||||||
RunInThread(
|
|
||||||
Sub()
|
|
||||||
Thread.Sleep(20)
|
|
||||||
RunInUiWait(Sub() ItemInstall.SetChecked(True, True, True))
|
|
||||||
AniControlEnabled -= 1
|
|
||||||
End Sub)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
<local:MyPageRight
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d" x:Class="PageDownloadLiteLoader"
|
|
||||||
PanScroll="PanBack">
|
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
|
||||||
<StackPanel Orientation="Vertical" Margin="5">
|
|
||||||
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="LiteLoader 简介" x:Name="CardTip">
|
|
||||||
<StackPanel Margin="25,40,15,20">
|
|
||||||
<TextBlock Name="LabConnect" Margin="0,0,0,11" Text="与 Forge 类似,LiteLoader 可以用于加载老版本 Minecraft 中的 LiteLoader 模组。" TextWrapping="Wrap" />
|
|
||||||
<Grid Height="35">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
|
|
||||||
<local:MyCard HorizontalAlignment="Center" Margin="40,50" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
|
|
||||||
<local:MyLoading Text="正在获取 LiteLoader 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</local:MyCard>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyScrollViewer>
|
|
||||||
</local:MyPageRight>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
Public Class PageDownloadLiteLoader
|
|
||||||
|
|
||||||
Private Sub LoaderInit() Handles Me.Initialized
|
|
||||||
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlLiteLoaderListLoader, AddressOf Load_OnFinish)
|
|
||||||
End Sub
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
|
||||||
PanBack.ScrollToHome()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Load_OnFinish()
|
|
||||||
'结果数据化
|
|
||||||
Try
|
|
||||||
'归类
|
|
||||||
Dim Dict As New Dictionary(Of String, List(Of DlLiteLoaderListEntry))
|
|
||||||
For VersionCode As Integer = 30 To 0 Step -1
|
|
||||||
Dict.Add("1." & VersionCode, New List(Of DlLiteLoaderListEntry))
|
|
||||||
Next
|
|
||||||
Dict.Add("未知版本", New List(Of DlLiteLoaderListEntry))
|
|
||||||
For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
|
|
||||||
Dim MainVersion As String = "1." & Version.Inherit.Split(".")(1)
|
|
||||||
If Dict.ContainsKey(MainVersion) Then
|
|
||||||
Dict(MainVersion).Add(Version)
|
|
||||||
Else
|
|
||||||
Dict("未知版本").Add(Version)
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
'清空当前
|
|
||||||
PanMain.Children.Clear()
|
|
||||||
'转化为 UI
|
|
||||||
For Each Pair As KeyValuePair(Of String, List(Of DlLiteLoaderListEntry)) In Dict
|
|
||||||
If Not Pair.Value.Any() Then Continue For
|
|
||||||
'增加卡片
|
|
||||||
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 10}
|
|
||||||
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
|
|
||||||
NewCard.Children.Add(NewStack)
|
|
||||||
NewCard.SwapControl = NewStack
|
|
||||||
NewCard.IsSwapped = True
|
|
||||||
PanMain.Children.Add(NewCard)
|
|
||||||
Next
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "可视化 LiteLoader 版本列表出错", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Public Sub DownloadStart(sender As MyListItem, e As Object)
|
|
||||||
McDownloadLiteLoader(sender.Tag)
|
|
||||||
End Sub
|
|
||||||
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
|
|
||||||
OpenWebsite("https://www.liteloader.com")
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
End Class
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<local:MyPageRight
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d" x:Class="PageDownloadNeoForge"
|
|
||||||
PanScroll="PanBack">
|
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
|
||||||
<StackPanel Orientation="Vertical" Margin="5">
|
|
||||||
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="NeoForge 简介" x:Name="CardTip">
|
|
||||||
<StackPanel Margin="25,40,15,20">
|
|
||||||
<TextBlock Margin="0,0,0,11" Text="NeoForge 是 Minecraft 1.20.1+ 的 Mod 加载器,你需要先安装它才能安装各种 NeoForge 模组,它也兼容一些 Forge 模组。
本页面提供 NeoForge 安装器下载,在下载后你需要手动打开安装器进行安装。" TextWrapping="Wrap" />
|
|
||||||
<Grid Height="35">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight"
|
|
||||||
EventType="打开网页" EventData="https://neoforged.net/" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
|
|
||||||
<local:MyCard HorizontalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
|
|
||||||
<local:MyLoading Text="正在获取 NeoForge 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</local:MyCard>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyScrollViewer>
|
|
||||||
</local:MyPageRight>
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
Public Class PageDownloadNeoForge
|
|
||||||
|
|
||||||
Private Sub LoaderInit() Handles Me.Initialized
|
|
||||||
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlNeoForgeListLoader, AddressOf Load_OnFinish)
|
|
||||||
End Sub
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
|
||||||
PanBack.ScrollToHome()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Load_OnFinish()
|
|
||||||
'结果数据化
|
|
||||||
Try
|
|
||||||
'归类
|
|
||||||
Dim Dict = DlNeoForgeListLoader.Output.Value.GroupBy(Function(d) d.Inherit).OrderByDescending(Function(g) g.Key).
|
|
||||||
ToDictionary(Function(g) g.Key, Function(g) g.ToList())
|
|
||||||
'清空当前
|
|
||||||
PanMain.Children.Clear()
|
|
||||||
'转化为 UI
|
|
||||||
For Each Pair As KeyValuePair(Of String, List(Of DlNeoForgeListEntry)) In Dict
|
|
||||||
If Not Pair.Value.Any() Then Continue For
|
|
||||||
'增加卡片
|
|
||||||
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 13}
|
|
||||||
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
|
|
||||||
NewCard.Children.Add(NewStack)
|
|
||||||
NewCard.SwapControl = NewStack
|
|
||||||
NewCard.IsSwapped = True
|
|
||||||
PanMain.Children.Add(NewCard)
|
|
||||||
Next
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "可视化 NeoForge 版本列表出错", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
End Class
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<local:MyPageRight
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d" x:Class="PageDownloadOptiFine"
|
|
||||||
PanScroll="PanBack">
|
|
||||||
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
|
|
||||||
<StackPanel Orientation="Vertical" Margin="5">
|
|
||||||
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="OptiFine 简介" x:Name="CardTip">
|
|
||||||
<StackPanel Margin="25,40,15,20">
|
|
||||||
<TextBlock Name="LabConnect" Margin="0,0,0,11" Text="OptiFine 又称为高清修复,以允许安装光影、使用高清材质、提高游戏性能,但与 Mod 的兼容性不佳。" TextWrapping="Wrap" />
|
|
||||||
<Grid Height="35">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyCard>
|
|
||||||
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
|
|
||||||
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
|
|
||||||
<local:MyLoading Text="正在获取 OptiFine 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</local:MyCard>
|
|
||||||
</StackPanel>
|
|
||||||
</local:MyScrollViewer>
|
|
||||||
</local:MyPageRight>
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
Public Class PageDownloadOptiFine
|
|
||||||
|
|
||||||
Private Sub LoaderInit() Handles Me.Initialized
|
|
||||||
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlOptiFineListLoader, AddressOf Load_OnFinish)
|
|
||||||
End Sub
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
|
||||||
PanBack.ScrollToHome()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub Load_OnFinish()
|
|
||||||
'结果数据化
|
|
||||||
Try
|
|
||||||
'归类
|
|
||||||
Dim Dict As New Dictionary(Of String, List(Of DlOptiFineListEntry))
|
|
||||||
Dict.Add("快照版本", New List(Of DlOptiFineListEntry))
|
|
||||||
For VersionCode As Integer = 50 To 0 Step -1
|
|
||||||
Dict.Add("1." & VersionCode, New List(Of DlOptiFineListEntry))
|
|
||||||
Next
|
|
||||||
For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
|
|
||||||
If Version.Inherit.StartsWith("1.") Then
|
|
||||||
Dim MainVersion As String = "1." & Version.NameDisplay.Split(".")(1).Split(" ")(0)
|
|
||||||
If Dict.ContainsKey(MainVersion) Then
|
|
||||||
Dict(MainVersion).Add(Version)
|
|
||||||
Else
|
|
||||||
Dict("快照版本").Add(Version)
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
Dict("快照版本").Add(Version)
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
'清空当前
|
|
||||||
PanMain.Children.Clear()
|
|
||||||
'转化为 UI
|
|
||||||
For Each Pair As KeyValuePair(Of String, List(Of DlOptiFineListEntry)) In Dict
|
|
||||||
If Not Pair.Value.Any() Then Continue For
|
|
||||||
'增加卡片
|
|
||||||
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 3}
|
|
||||||
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
|
|
||||||
NewCard.Children.Add(NewStack)
|
|
||||||
NewCard.SwapControl = NewStack
|
|
||||||
NewCard.IsSwapped = True
|
|
||||||
PanMain.Children.Add(NewCard)
|
|
||||||
Next
|
|
||||||
Catch ex As Exception
|
|
||||||
Log(ex, "可视化 OptiFine 版本列表出错", LogLevel.Feedback)
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
|
|
||||||
OpenWebsite("https://www.optifine.net/")
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
End Class
|
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
LabTitle.Text = "登录 Minecraft"
|
LabTitle.Text = "登录 Minecraft"
|
||||||
LabCaption.Text =
|
LabCaption.Text =
|
||||||
$"登录网页将自动开启,请在网页中输入 {UserCode}(已自动复制)。" & vbCrLf & vbCrLf &
|
$"登录网页将自动开启,请在网页中输入 {UserCode}(已自动复制)。" & vbCrLf & vbCrLf &
|
||||||
$"如果网络环境不佳,网页可能一直加载不出来,届时请使用加速器或 VPN 以改善网络环境。" & vbCrLf &
|
$"如果网络环境不佳,网页可能一直加载不出来,届时请使用加速器或 VPN 改善网络环境。" & vbCrLf &
|
||||||
$"你也可以用其他设备打开 {Website} 并输入上述代码。"
|
$"你也可以用其他设备打开 {Website} 并输入上述代码。"
|
||||||
Btn1.EventData = Website
|
Btn1.EventData = Website
|
||||||
Btn2.EventData = UserCode
|
Btn2.EventData = UserCode
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
"scope=XboxLive.signin%20offline_access",
|
"scope=XboxLive.signin%20offline_access",
|
||||||
ContentType:="application/x-www-form-urlencoded",
|
ContentType:="application/x-www-form-urlencoded",
|
||||||
Timeout:=5000 + UnknownFailureCount * 5000,
|
Timeout:=5000 + UnknownFailureCount * 5000,
|
||||||
MakeLog:=False)
|
MakeLog:=False, RequireJson:=True)
|
||||||
'获取结果
|
'获取结果
|
||||||
Dim ResultJson As JObject = GetJson(Result)
|
Dim ResultJson As JObject = GetJson(Result)
|
||||||
McLaunchLog($"令牌过期时间:{ResultJson("expires_in")} 秒")
|
McLaunchLog($"令牌过期时间:{ResultJson("expires_in")} 秒")
|
||||||
@@ -122,6 +122,7 @@
|
|||||||
Finished({ResultJson("access_token").ToString, ResultJson("refresh_token").ToString})
|
Finished({ResultJson("access_token").ToString, ResultJson("refresh_token").ToString})
|
||||||
Return
|
Return
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
'修改错误列表时,同时修改 ModLaunch.MsLoginStep1Refresh 中的对应代码
|
||||||
If TypeOf ex Is ResponsedWebException Then
|
If TypeOf ex Is ResponsedWebException Then
|
||||||
Dim Response = CType(ex, ResponsedWebException).Response
|
Dim Response = CType(ex, ResponsedWebException).Response
|
||||||
If Response.Contains("authorization_declined") Then
|
If Response.Contains("authorization_declined") Then
|
||||||
|
|||||||
@@ -392,14 +392,14 @@ UnknownType:
|
|||||||
Result = McSkinDownload(Result)
|
Result = McSkinDownload(Result)
|
||||||
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
||||||
Data.Output = Result
|
Data.Output = Result
|
||||||
Catch ex As Exception
|
Catch ex As ThreadInterruptedException
|
||||||
If ex.GetType.Name = "ThreadInterruptedException" Then
|
|
||||||
Data.Output = ""
|
Data.Output = ""
|
||||||
Return
|
Return
|
||||||
ElseIf GetExceptionSummary(ex).Contains("429") Then
|
Catch ex As Exception
|
||||||
|
If ex.GetBrief.Contains("(429)") Then
|
||||||
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
|
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
|
||||||
Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
|
Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
|
||||||
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
|
ElseIf ex.GetBrief.Contains("未设置自定义皮肤") Then
|
||||||
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
|
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
|
||||||
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
|
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
|
||||||
Else
|
Else
|
||||||
@@ -462,11 +462,11 @@ UseDefault:
|
|||||||
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
|
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
|
||||||
Data.Output = Result
|
Data.Output = Result
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As ThreadInterruptedException
|
||||||
If ex.GetType.Name = "ThreadInterruptedException" Then
|
|
||||||
Data.Output = ""
|
Data.Output = ""
|
||||||
Return
|
Return
|
||||||
ElseIf GetExceptionSummary(ex).Contains("429") Then
|
Catch ex As Exception
|
||||||
|
If ex.GetBrief.Contains("(429)") Then
|
||||||
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
|
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
|
||||||
Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
|
Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
|
||||||
Else
|
Else
|
||||||
@@ -514,14 +514,14 @@ UseDefault:
|
|||||||
Result = McSkinDownload(Result)
|
Result = McSkinDownload(Result)
|
||||||
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
||||||
Data.Output = Result
|
Data.Output = Result
|
||||||
Catch ex As Exception
|
Catch ex As ThreadInterruptedException
|
||||||
If ex.GetType.Name = "ThreadInterruptedException" Then
|
|
||||||
Data.Output = ""
|
Data.Output = ""
|
||||||
Return
|
Return
|
||||||
ElseIf GetExceptionSummary(ex).Contains("429") Then
|
Catch ex As Exception
|
||||||
|
If ex.GetBrief.Contains("(429)") Then
|
||||||
Data.Output = PathImage & "Skins/Steve.png"
|
Data.Output = PathImage & "Skins/Steve.png"
|
||||||
Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
|
Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
|
||||||
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
|
ElseIf ex.GetBrief.Contains("未设置自定义皮肤") Then
|
||||||
Data.Output = PathImage & "Skins/Steve.png"
|
Data.Output = PathImage & "Skins/Steve.png"
|
||||||
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
|
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
|
||||||
Else
|
Else
|
||||||
@@ -550,26 +550,26 @@ Finish:
|
|||||||
RunInUi(Sub() If FrmLoginAuthSkin IsNot Nothing AndAlso FrmLoginAuthSkin.Skin IsNot Nothing Then FrmLoginAuthSkin.Skin.Clear())
|
RunInUi(Sub() If FrmLoginAuthSkin IsNot Nothing AndAlso FrmLoginAuthSkin.Skin IsNot Nothing Then FrmLoginAuthSkin.Skin.Clear())
|
||||||
'获取 Url
|
'获取 Url
|
||||||
Dim UserName As String = Data.Input(0)
|
Dim UserName As String = Data.Input(0)
|
||||||
Dim Uuid As String = Data.Input(1)
|
Dim UUID As String = Data.Input(1)
|
||||||
If UserName = "" Then
|
If UserName = "" Then
|
||||||
Data.Output = PathImage & "Skins/Steve.png"
|
Data.Output = PathImage & "Skins/Steve.png"
|
||||||
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败,ID 为空")
|
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败,ID 为空")
|
||||||
GoTo Finish
|
GoTo Finish
|
||||||
End If
|
End If
|
||||||
Try
|
Try
|
||||||
Dim Result As String = McSkinGetAddress(Uuid, "Auth")
|
Dim Result As String = McSkinGetAddress(UUID, "Auth")
|
||||||
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
||||||
Result = McSkinDownload(Result)
|
Result = McSkinDownload(Result)
|
||||||
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
|
||||||
Data.Output = Result
|
Data.Output = Result
|
||||||
Catch ex As Exception
|
Catch ex As ThreadInterruptedException
|
||||||
If ex.GetType.Name = "ThreadInterruptedException" Then
|
|
||||||
Data.Output = ""
|
Data.Output = ""
|
||||||
Return
|
Return
|
||||||
ElseIf GetExceptionSummary(ex).Contains("429") Then
|
Catch ex As Exception
|
||||||
|
If ex.GetBrief.Contains("(429)") Then
|
||||||
Data.Output = PathImage & "Skins/Steve.png"
|
Data.Output = PathImage & "Skins/Steve.png"
|
||||||
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
|
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
|
||||||
ElseIf GetExceptionSummary(ex).Contains("未设置自定义皮肤") Then
|
ElseIf ex.GetBrief.Contains("未设置自定义皮肤") Then
|
||||||
Data.Output = PathImage & "Skins/Steve.png"
|
Data.Output = PathImage & "Skins/Steve.png"
|
||||||
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
|
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
|
||||||
Else
|
Else
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
Public Class PageLaunchRight
|
Imports System.Windows.Threading
|
||||||
Implements IRefreshable
|
|
||||||
|
Public Class PageLaunchRight
|
||||||
|
Implements IRefreshable, IDispatcherUnhandledException
|
||||||
|
|
||||||
Private Sub Init() Handles Me.Loaded
|
Private Sub Init() Handles Me.Loaded
|
||||||
PanBack.ScrollToHome()
|
PanBack.ScrollToHome()
|
||||||
@@ -27,7 +29,7 @@
|
|||||||
''' 刷新主页。
|
''' 刷新主页。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Private Sub Refresh() Handles Me.Loaded
|
Private Sub Refresh() Handles Me.Loaded
|
||||||
RunInNewThread(
|
RunInThread(
|
||||||
Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
SyncLock RefreshLock
|
SyncLock RefreshLock
|
||||||
@@ -36,37 +38,20 @@
|
|||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "加载 PCL 主页自定义信息失败", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
|
Log(ex, "加载 PCL 主页自定义信息失败", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
|
||||||
End Try
|
End Try
|
||||||
End Sub, $"刷新主页 #{GetUuid()}")
|
End Sub)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub RefreshReal()
|
Private Sub RefreshReal()
|
||||||
Dim Content As String = ""
|
Dim Content As String = Nothing, Url As String = Nothing
|
||||||
Dim Url As String
|
|
||||||
Select Case Setup.Get("UiCustomType")
|
Select Case Setup.Get("UiCustomType")
|
||||||
Case 1
|
Case 1
|
||||||
'加载本地文件
|
'加载本地文件
|
||||||
Log("[Page] 主页自定义数据来源:本地文件")
|
Log("[Page] 主页自定义数据来源:本地文件")
|
||||||
Content = ReadFile(Path & "PCL\Custom.xaml") 'ReadFile 会进行存在检测
|
Content = ReadFile(Path & "PCL\Custom.xaml") 'ReadFile 会进行存在检测
|
||||||
Case 2
|
Case 2
|
||||||
|
'联网下载
|
||||||
Url = Setup.Get("UiCustomNet")
|
Url = Setup.Get("UiCustomNet")
|
||||||
Download:
|
|
||||||
'加载联网文件
|
|
||||||
If String.IsNullOrWhiteSpace(Url) Then Exit Select
|
|
||||||
If Url = Setup.Get("CacheSavedPageUrl") AndAlso File.Exists(PathTemp & "Cache\Custom.xaml") Then
|
|
||||||
'缓存可用
|
|
||||||
Log("[Page] 主页自定义数据来源:联网缓存文件")
|
|
||||||
Content = ReadFile(PathTemp & "Cache\Custom.xaml")
|
|
||||||
'后台更新缓存
|
|
||||||
OnlineLoader.Start(Url)
|
|
||||||
Else
|
|
||||||
'缓存不可用
|
|
||||||
Log("[Page] 主页自定义数据来源:联网全新下载")
|
|
||||||
Hint("正在加载主页……")
|
|
||||||
RunInUiWait(Sub() LoadContent("")) '在加载结束前清空页面
|
|
||||||
Setup.Set("CacheSavedPageVersion", "")
|
|
||||||
OnlineLoader.Start(Url) '下载完成后将会再次触发更新
|
|
||||||
Return
|
|
||||||
End If
|
|
||||||
Case 3
|
Case 3
|
||||||
|
'预设
|
||||||
Select Case Setup.Get("UiCustomPreset")
|
Select Case Setup.Get("UiCustomPreset")
|
||||||
Case 0
|
Case 0
|
||||||
Log("[Page] 主页预设:你知道吗")
|
Log("[Page] 主页预设:你知道吗")
|
||||||
@@ -88,50 +73,58 @@ Download:
|
|||||||
</local:MyCard>"
|
</local:MyCard>"
|
||||||
Case 2
|
Case 2
|
||||||
Log("[Page] 主页预设:Minecraft 新闻")
|
Log("[Page] 主页预设:Minecraft 新闻")
|
||||||
Url = "https://pcl.mcnews.thestack.top"
|
Url = "https://mcnews.meloong.com"
|
||||||
GoTo Download
|
|
||||||
Case 3
|
Case 3
|
||||||
Log("[Page] 主页预设:简单主页")
|
Log("[Page] 主页预设:简单主页")
|
||||||
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/MFn233/Custom.xaml"
|
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/MFn233/Custom.xaml"
|
||||||
GoTo Download
|
|
||||||
Case 4
|
Case 4
|
||||||
Log("[Page] 主页预设:每日整合包推荐")
|
Log("[Page] 主页预设:每日整合包推荐")
|
||||||
Url = "https://pclsub.sodamc.com/"
|
Url = "https://pclsub.sodamc.com/"
|
||||||
GoTo Download
|
|
||||||
Case 5
|
Case 5
|
||||||
Log("[Page] 主页预设:Minecraft 皮肤推荐")
|
Log("[Page] 主页预设:Minecraft 皮肤推荐")
|
||||||
Url = "https://forgepixel.com/pcl_sub_file"
|
Url = "https://forgepixel.com/pcl_sub_file"
|
||||||
GoTo Download
|
|
||||||
Case 6
|
Case 6
|
||||||
Log("[Page] 主页预设:OpenBMCLAPI 仪表盘 Lite")
|
Log("[Page] 主页预设:OpenBMCLAPI 仪表盘 Lite")
|
||||||
Url = "https://pcl-bmcl.milu.ink/"
|
Url = "https://pcl-bmcl.milu.ink/"
|
||||||
GoTo Download
|
|
||||||
Case 7
|
Case 7
|
||||||
Log("[Page] 主页预设:主页市场")
|
Log("[Page] 主页预设:主页市场")
|
||||||
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/JingHai-Lingyun/Custom.xaml"
|
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/JingHai-Lingyun/Custom.xaml"
|
||||||
GoTo Download
|
|
||||||
Case 8
|
Case 8
|
||||||
Log("[Page] 主页预设:更新日志")
|
Log("[Page] 主页预设:更新日志")
|
||||||
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/Joker2184/UpdateHomepage.xaml"
|
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/Joker2184/UpdateHomepage.xaml"
|
||||||
GoTo Download
|
|
||||||
Case 9
|
Case 9
|
||||||
Log("[Page] 主页预设:PCL 新功能说明书")
|
Log("[Page] 主页预设:PCL 新功能说明书")
|
||||||
Url = "https://raw.gitcode.com/WForst-Breeze/WhatsNewPCL/raw/main/Custom.xaml"
|
Url = "https://raw.gitcode.com/WForst-Breeze/WhatsNewPCL/raw/main/Custom.xaml"
|
||||||
GoTo Download
|
|
||||||
Case 10
|
Case 10
|
||||||
Log("[Page] 主页预设:OpenMCIM Dashboard")
|
Log("[Page] 主页预设:OpenMCIM Dashboard")
|
||||||
Url = "https://files.mcimirror.top/PCL"
|
Url = "https://files.mcimirror.top/PCL"
|
||||||
GoTo Download
|
|
||||||
Case 11
|
Case 11
|
||||||
Log("[Page] 主页预设:杂志主页")
|
Log("[Page] 主页预设:杂志主页")
|
||||||
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/Ext1nguisher/Custom.xaml"
|
Url = "https://pclhomeplazaoss.lingyunawa.top:26994/d/Homepages/Ext1nguisher/Custom.xaml"
|
||||||
GoTo Download
|
|
||||||
Case 12
|
Case 12
|
||||||
Log("[Page] 主页预设:PCL GitHub 仪表盘")
|
Log("[Page] 主页预设:PCL GitHub 仪表盘")
|
||||||
Url = "https://ddf.pcl-community.org/Custom.xaml"
|
Url = "https://ddf.pcl-community.org/Custom.xaml"
|
||||||
GoTo Download
|
|
||||||
End Select
|
End Select
|
||||||
End Select
|
End Select
|
||||||
|
'联网下载
|
||||||
|
If Not String.IsNullOrWhiteSpace(Url) Then
|
||||||
|
If Url = Setup.Get("CacheSavedPageUrl") AndAlso File.Exists(PathTemp & "Cache\Custom.xaml") Then
|
||||||
|
'缓存可用
|
||||||
|
Log("[Page] 主页自定义数据来源:联网缓存文件")
|
||||||
|
Content = ReadFile(PathTemp & "Cache\Custom.xaml")
|
||||||
|
'后台更新缓存
|
||||||
|
OnlineLoader.Start(Url)
|
||||||
|
Else
|
||||||
|
'缓存不可用
|
||||||
|
Log("[Page] 主页自定义数据来源:联网全新下载")
|
||||||
|
Hint("正在加载主页……")
|
||||||
|
RunInUiWait(Sub() LoadContent(Nothing)) '在加载结束前清空页面
|
||||||
|
Setup.Set("CacheSavedPageVersion", "")
|
||||||
|
OnlineLoader.Start(Url) '下载完成后将会再次触发更新
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
'同步到 UI
|
||||||
RunInUi(Sub() LoadContent(Content))
|
RunInUi(Sub() LoadContent(Content))
|
||||||
End Sub
|
End Sub
|
||||||
Private RefreshLock As New Object
|
Private RefreshLock As New Object
|
||||||
@@ -169,15 +162,13 @@ Download:
|
|||||||
Log($"[Page] 无法检查联网主页版本,将直接下载,检查源:{VersionAddress}")
|
Log($"[Page] 无法检查联网主页版本,将直接下载,检查源:{VersionAddress}")
|
||||||
End Try
|
End Try
|
||||||
'实际下载
|
'实际下载
|
||||||
If NeedDownload Then
|
If Not NeedDownload Then Return
|
||||||
Dim FileContent As String = NetRequestByClientRetry(Address)
|
Dim FileContent As String = NetRequestByClientRetry(Address)
|
||||||
Log($"[Page] 已联网下载主页,内容长度:{FileContent.Length},来源:{Address}")
|
Log($"[Page] 已联网下载主页,内容长度:{FileContent.Length},来源:{Address}")
|
||||||
Setup.Set("CacheSavedPageUrl", Address)
|
Setup.Set("CacheSavedPageUrl", Address)
|
||||||
Setup.Set("CacheSavedPageVersion", Version)
|
Setup.Set("CacheSavedPageVersion", Version)
|
||||||
WriteFile(PathTemp & "Cache\Custom.xaml", FileContent)
|
WriteFile(PathTemp & "Cache\Custom.xaml", FileContent)
|
||||||
End If
|
Refresh() '要求刷新
|
||||||
'要求刷新
|
|
||||||
RunInUi(AddressOf Refresh) '不直接调用 Refresh,以防止死循环(#6245)
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, $"下载主页失败({Address})", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
|
Log(ex, $"下载主页失败({Address})", If(ModeDebug, LogLevel.Msgbox, LogLevel.Hint))
|
||||||
End Try
|
End Try
|
||||||
@@ -215,9 +206,10 @@ Download:
|
|||||||
''' 必须在 UI 线程调用。
|
''' 必须在 UI 线程调用。
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Private Sub LoadContent(Content As String)
|
Private Sub LoadContent(Content As String)
|
||||||
|
Try
|
||||||
SyncLock LoadContentLock
|
SyncLock LoadContentLock
|
||||||
'如果加载目标内容一致则不加载
|
'如果加载目标内容一致则不加载
|
||||||
Dim Hash = Content.GetHashCode()
|
Dim Hash = If(Content, "").GetHashCode()
|
||||||
If Hash = LoadedContentHash Then Return
|
If Hash = LoadedContentHash Then Return
|
||||||
LoadedContentHash = Hash
|
LoadedContentHash = Hash
|
||||||
'实际加载内容
|
'实际加载内容
|
||||||
@@ -227,7 +219,6 @@ Download:
|
|||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
Dim LoadStartTime As Date = Date.Now
|
Dim LoadStartTime As Date = Date.Now
|
||||||
Try
|
|
||||||
'修改时应同时修改 PageOtherHelpDetail.Init
|
'修改时应同时修改 PageOtherHelpDetail.Init
|
||||||
Content = HelpArgumentReplace(Content)
|
Content = HelpArgumentReplace(Content)
|
||||||
Do While Content.Contains("xmlns")
|
Do While Content.Contains("xmlns")
|
||||||
@@ -236,26 +227,38 @@ Download:
|
|||||||
Content = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:sys=""clr-namespace:System;assembly=mscorlib"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"">" & Content & "</StackPanel>"
|
Content = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:sys=""clr-namespace:System;assembly=mscorlib"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"">" & Content & "</StackPanel>"
|
||||||
Log($"[Page] 实例化:加载主页 UI 开始,最终内容长度:{Content.Count}")
|
Log($"[Page] 实例化:加载主页 UI 开始,最终内容长度:{Content.Count}")
|
||||||
PanCustom.Children.Add(GetObjectFromXML(Content))
|
PanCustom.Children.Add(GetObjectFromXML(Content))
|
||||||
Catch ex As Exception
|
'加载计时
|
||||||
If ModeDebug Then
|
|
||||||
Log(ex, "加载失败的主页内容:" & vbCrLf & Content)
|
|
||||||
If MyMsgBox(If(TypeOf ex Is UnauthorizedAccessException, ex.Message, $"主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{GetExceptionSummary(ex)}"),
|
|
||||||
"加载主页界面失败", "重试", "取消") = 1 Then
|
|
||||||
GoTo Refresh '防止 SyncLock 死锁
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
Log(ex, "加载主页界面失败", LogLevel.Hint)
|
|
||||||
End If
|
|
||||||
Return
|
|
||||||
End Try
|
|
||||||
Dim LoadCostTime = (Date.Now - LoadStartTime).Milliseconds
|
Dim LoadCostTime = (Date.Now - LoadStartTime).Milliseconds
|
||||||
Log($"[Page] 实例化:加载主页 UI 完成,耗时 {LoadCostTime}ms")
|
Log($"[Page] 实例化:加载主页 UI 完成,耗时 {LoadCostTime}ms")
|
||||||
If LoadCostTime > 3000 Then Hint($"主页加载过于缓慢(花费了 {Math.Round(LoadCostTime / 1000, 1)} 秒),请向主页作者反馈此问题,或暂时停止使用该主页")
|
If LoadCostTime > 3000 Then Hint($"主页加载过于缓慢(花费了 {Math.Round(LoadCostTime / 1000, 1)} 秒),请向主页作者反馈此问题,或暂时停止使用该主页")
|
||||||
End SyncLock
|
End SyncLock
|
||||||
Return
|
Catch ex As Exception
|
||||||
Refresh:
|
Log(ex, "加载失败的主页内容:" & vbCrLf & Content)
|
||||||
ForceRefresh()
|
OnLoadContentFailed(ex)
|
||||||
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
''' <summary>
|
||||||
|
''' 加载主页失败时调用。
|
||||||
|
''' </summary>
|
||||||
|
Private Sub OnLoadContentFailed(ex As Exception)
|
||||||
|
If ModeDebug OrElse Setup.Get("UiCustomType") = 1 Then
|
||||||
|
Log(ex, "加载主页失败")
|
||||||
|
If MyMsgBox(If(TypeOf ex Is UnauthorizedAccessException, ex.Message, $"主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{ex.GetBrief}"),
|
||||||
|
"加载主页失败", "重试", "取消") = 1 Then ForceRefresh()
|
||||||
|
Else
|
||||||
|
Log(ex, "加载主页失败", LogLevel.Hint)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
''' <summary>
|
||||||
|
''' 捕获主页在 Measure 和 Arrange 阶段抛出的异常。
|
||||||
|
''' </summary>
|
||||||
|
Private Sub DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Implements IDispatcherUnhandledException.DispatcherUnhandledException
|
||||||
|
If TypeOf e.Exception IsNot Markup.XamlParseException Then Return
|
||||||
|
e.Handled = True
|
||||||
|
LoadContent(Nothing)
|
||||||
|
OnLoadContentFailed(e.Exception)
|
||||||
|
End Sub
|
||||||
|
|
||||||
Private LoadedContentHash As Integer = -1
|
Private LoadedContentHash As Integer = -1
|
||||||
Private LoadContentLock As New Object
|
Private LoadContentLock As New Object
|
||||||
|
|
||||||
|
|||||||
@@ -86,22 +86,21 @@
|
|||||||
IsChanging = True
|
IsChanging = True
|
||||||
'开始实际获取
|
'开始实际获取
|
||||||
RunInNewThread(
|
RunInNewThread(
|
||||||
Async Sub()
|
Sub()
|
||||||
Try
|
Try
|
||||||
Retry:
|
Retry:
|
||||||
If McLoginMsLoader.State = LoadState.Loading Then McLoginMsLoader.WaitForExit() '等待登录结束
|
Do While McLoginMsLoader.State = LoadState.Loading '等待登录结束
|
||||||
|
Thread.Sleep(10)
|
||||||
|
Loop
|
||||||
|
If McLoginMsLoader.State = LoadState.Failed Then Throw New Exception("登录失败", McLoginMsLoader.Error)
|
||||||
Dim AccessToken As String = Setup.Get("CacheMsV2Access")
|
Dim AccessToken As String = Setup.Get("CacheMsV2Access")
|
||||||
Dim Uuid As String = Setup.Get("CacheMsV2Uuid")
|
Dim Uuid As String = Setup.Get("CacheMsV2Uuid")
|
||||||
|
Dim Result As String = NetRequestByClientRetry("https://api.minecraftservices.com/minecraft/profile/skins", HttpMethod.Post,
|
||||||
Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 30)}
|
Content:=New Net.Http.MultipartFormDataContent From {
|
||||||
Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken)
|
|
||||||
Client.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"))
|
|
||||||
Client.DefaultRequestHeaders.UserAgent.Add(New Net.Http.Headers.ProductInfoHeaderValue("MojangSharp", "0.1"))
|
|
||||||
Dim Contents As New Net.Http.MultipartFormDataContent From {
|
|
||||||
{New Net.Http.StringContent(If(SkinInfo.IsSlim, "slim", "classic")), "variant"},
|
{New Net.Http.StringContent(If(SkinInfo.IsSlim, "slim", "classic")), "variant"},
|
||||||
{New Net.Http.ByteArrayContent(ReadFileBytes(SkinInfo.LocalFile)), "file", GetFileNameFromPath(SkinInfo.LocalFile)}
|
{New Net.Http.ByteArrayContent(ReadFileBytes(SkinInfo.LocalFile)), "file", GetFileNameFromPath(SkinInfo.LocalFile)}
|
||||||
}
|
},
|
||||||
Dim Result As String = Await (Await Client.PostAsync(New Uri("https://api.minecraftservices.com/minecraft/profile/skins"), Contents)).Content.ReadAsStringAsync
|
Headers:={{"Authorization", "Bearer " & AccessToken}, {"Accept", "*/*"}, {"User-Agent", "MojangSharp/0.1"}})
|
||||||
If Result.Contains("request requires user authentication") Then
|
If Result.Contains("request requires user authentication") Then
|
||||||
Hint("正在登录,将在登录完成后继续更改皮肤……")
|
Hint("正在登录,将在登录完成后继续更改皮肤……")
|
||||||
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
|
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
|
||||||
@@ -122,8 +121,8 @@ Retry:
|
|||||||
Next
|
Next
|
||||||
Throw New Exception("未知错误(" & Result & ")")
|
Throw New Exception("未知错误(" & Result & ")")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
If ex.GetType.Equals(GetType(Tasks.TaskCanceledException)) Then
|
If TypeOf ex Is OperationCanceledException Then
|
||||||
Hint("更改皮肤失败:与 Mojang 皮肤服务器的连接超时,请检查你的网络是否通畅!", HintType.Critical)
|
Hint("更改皮肤失败:连接皮肤服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Critical)
|
||||||
Else
|
Else
|
||||||
Log(ex, "更改皮肤失败", LogLevel.Hint)
|
Log(ex, "更改皮肤失败", LogLevel.Hint)
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -105,246 +105,287 @@
|
|||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
<local:MyCard Margin="0,0,0,15" Title="赞助者">
|
<local:MyCard Margin="0,0,0,15" Title="赞助者">
|
||||||
<StackPanel Margin="25,40,10,20">
|
<StackPanel Margin="25,40,10,20">
|
||||||
<TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 7 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
|
<TextBlock HorizontalAlignment="Left" Text="以下是 2025 年 8 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
|
||||||
<WrapPanel Margin="0,0,0,10">
|
<WrapPanel Margin="0,0,0,10">
<TextBlock Width="120" Margin="0,1.5" Text="粒子鹰" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ZSF" />
|
<TextBlock Width="120" Margin="0,1.5" Text="暮色黄昏" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="TizhleF" />
|
<TextBlock Width="120" Margin="0,1.5" Text="未殃" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="方源" />
|
<TextBlock Width="120" Margin="0,1.5" Text="咸鱼" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="日月空呵" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Claud_9527" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="贾明志" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Qqsnd" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="百瑞" />
|
<TextBlock Width="120" Margin="0,1.5" Text="☆Kiana☆" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Flying___pig" />
|
<TextBlock Width="120" Margin="0,1.5" Text="晓枫-橘味C" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="绝世" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Ferderica" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Jwac" />
|
<TextBlock Width="120" Margin="0,1.5" Text="过路人" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="万玖" />
|
<TextBlock Width="120" Margin="0,1.5" Text="寒溪" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="墨忆" />
|
<TextBlock Width="120" Margin="0,1.5" Text="小咪vv" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="天刹" />
|
<TextBlock Width="120" Margin="0,1.5" Text="容小狸" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Cess" />
|
<TextBlock Width="120" Margin="0,1.5" Text="南宫流溪" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ender_glass" />
|
<TextBlock Width="120" Margin="0,1.5" Text="懒包子" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="TT" />
|
<TextBlock Width="120" Margin="0,1.5" Text="王家有政" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="白玄.雪狼" />
|
<TextBlock Width="120" Margin="0,1.5" Text="??????" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="MUCT" />
|
<TextBlock Width="120" Margin="0,1.5" Text="念念" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="崇昀" />
|
<TextBlock Width="120" Margin="0,1.5" Text="启233" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="绪" />
|
<TextBlock Width="120" Margin="0,1.5" Text="爱小黎" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="吾皇万岁" />
|
<TextBlock Width="120" Margin="0,1.5" Text="北笙T-T" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Ander·Les" />
|
<TextBlock Width="120" Margin="0,1.5" Text="listpmater" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Eoctopus" />
|
<TextBlock Width="120" Margin="0,1.5" Text="朝朝超级の好运" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="时光飞逝一下午" />
|
<TextBlock Width="120" Margin="0,1.5" Text="低调" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Carl7412" />
|
<TextBlock Width="120" Margin="0,1.5" Text="老公" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ShinyChariot" />
|
<TextBlock Width="120" Margin="0,1.5" Text="雍仕" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="骨故谷" />
|
<TextBlock Width="120" Margin="0,1.5" Text="AAboss" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="?" />
|
<TextBlock Width="120" Margin="0,1.5" Text="闲来无事" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Jinji希子" />
|
<TextBlock Width="120" Margin="0,1.5" Text="omgddcsl" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="自然选择" />
|
<TextBlock Width="120" Margin="0,1.5" Text="轻舟" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="云念" />
|
<TextBlock Width="120" Margin="0,1.5" Text="浮生Yui" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="钱尹鹏" />
|
<TextBlock Width="120" Margin="0,1.5" Text="YangFK" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="TBONC" />
|
<TextBlock Width="120" Margin="0,1.5" Text="一曲勺" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="祈农" />
|
<TextBlock Width="120" Margin="0,1.5" Text="时白Herhilo" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="凤凰院凶真" />
|
<TextBlock Width="120" Margin="0,1.5" Text="寒冬落雨" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ShuangDaoRen" />
|
<TextBlock Width="120" Margin="0,1.5" Text="柯基0v0" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="PXZ233" />
|
<TextBlock Width="120" Margin="0,1.5" Text="月兔" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="二十二今天有没有" />
|
<TextBlock Width="120" Margin="0,1.5" Text="qkowo" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="天魕" />
|
<TextBlock Width="120" Margin="0,1.5" Text="沐白" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="南华清" />
|
<TextBlock Width="120" Margin="0,1.5" Text="每雨天" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="66112447" />
|
<TextBlock Width="120" Margin="0,1.5" Text="AiNo" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="夏行子" />
|
<TextBlock Width="120" Margin="0,1.5" Text="木叶飞舞之处" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="周俊成" />
|
<TextBlock Width="120" Margin="0,1.5" Text="wilbert_laogao" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="乌漆嘛黑" />
|
<TextBlock Width="120" Margin="0,1.5" Text="悠芸" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="肘击恶魔佐巴扬" />
|
<TextBlock Width="120" Margin="0,1.5" Text="黑白盗贼" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Pari~" />
|
<TextBlock Width="120" Margin="0,1.5" Text="PotCatawa" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="红云" />
|
<TextBlock Width="120" Margin="0,1.5" Text="小王" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Link-an" />
|
<TextBlock Width="120" Margin="0,1.5" Text="花还没开" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="想要钱用不完" />
|
<TextBlock Width="240" Margin="0,1.5" Text="PixelFrontier像素边界" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="花宝" />
|
<TextBlock Width="120" Margin="0,1.5" Text="坊之岬" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="生于春天的雷电" />
|
<TextBlock Width="120" Margin="0,1.5" Text="HuTu" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="被偷去的睡眠" />
|
<TextBlock Width="120" Margin="0,1.5" Text="爱言叶ray" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="liuxuan" />
|
<TextBlock Width="120" Margin="0,1.5" Text="lenrin" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="寒枫凌" />
|
<TextBlock Width="120" Margin="0,1.5" Text="." />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="雀色时" />
|
<TextBlock Width="120" Margin="0,1.5" Text="这是一头灯笼花" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="架" />
|
<TextBlock Width="120" Margin="0,1.5" Text="肖然星辰" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="终成究竟觉" />
|
<TextBlock Width="120" Margin="0,1.5" Text="QMX" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="S0D1UM" />
|
<TextBlock Width="120" Margin="0,1.5" Text="山外诗" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="吞仔送命" />
|
<TextBlock Width="120" Margin="0,1.5" Text="刘" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="白浪宇宙" />
|
<TextBlock Width="120" Margin="0,1.5" Text="萧风溪水" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Crimson" />
|
<TextBlock Width="120" Margin="0,1.5" Text="风落" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Mibo_MkIX" />
|
<TextBlock Width="120" Margin="0,1.5" Text="星星绒绒" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="G.snine18^7" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Ciallo~(∠?ω" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="两把雨伞" />
|
<TextBlock Width="120" Margin="0,1.5" Text="九十九" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="古明地苑" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Guuzen" />
|
||||||
<TextBlock Width="240" Margin="0,1.5" Text="MarbleMionshevic" />
|
<TextBlock Width="120" Margin="0,1.5" Text="9331" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text=":〈" />
|
<TextBlock Width="120" Margin="0,1.5" Text="钱程" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="紫罗兰" />
|
<TextBlock Width="120" Margin="0,1.5" Text="杏坂和人" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="asai" />
|
<TextBlock Width="120" Margin="0,1.5" Text="jinlijsbjaj" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="隔壁小明" />
|
<TextBlock Width="120" Margin="0,1.5" Text="海豹" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="就爱唱歌" />
|
<TextBlock Width="120" Margin="0,1.5" Text="洛玉衡kale" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="沫神鹤" />
|
<TextBlock Width="120" Margin="0,1.5" Text="柠乔" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="风已消逝" />
|
<TextBlock Width="120" Margin="0,1.5" Text="N0NiL" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="光意留闪" />
|
<TextBlock Width="120" Margin="0,1.5" Text="阿卡零" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="我们长征的路上" />
|
<TextBlock Width="120" Margin="0,1.5" Text="ADAA" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="芸芷" />
|
<TextBlock Width="120" Margin="0,1.5" Text="岚瑬" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="函数极限" />
|
<TextBlock Width="120" Margin="0,1.5" Text="爱料理的猫" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="冰川泥" />
|
<TextBlock Width="120" Margin="0,1.5" Text="01B8" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="XunWei" />
|
<TextBlock Width="120" Margin="0,1.5" Text="MCDJ喜羊羊" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="sirous" />
|
<TextBlock Width="120" Margin="0,1.5" Text="hwch55" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="路过某打酱油的" />
|
<TextBlock Width="120" Margin="0,1.5" Text="棉花糖十五" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Gnight07" />
|
<TextBlock Width="120" Margin="0,1.5" Text="鱼头" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="结构德古拉" />
|
<TextBlock Width="120" Margin="0,1.5" Text="拉普兰德天下第一" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="myyukee" />
|
<TextBlock Width="120" Margin="0,1.5" Text="KGIKUY" />
|
||||||
<TextBlock Width="240" Margin="0,1.5" Text="云之彼端约定的地方" />
|
<TextBlock Width="120" Margin="0,1.5" Text="初洛" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="苏玖" />
|
<TextBlock Width="120" Margin="0,1.5" Text="z .e.r.o" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="赤沃净" />
|
<TextBlock Width="120" Margin="0,1.5" Text="独孤真菜" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="YYC" />
|
<TextBlock Width="120" Margin="0,1.5" Text="阿囊" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="晨曦酒庄高冷男" />
|
<TextBlock Width="120" Margin="0,1.5" Text="rrrwcsza" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="herald112" />
|
<TextBlock Width="120" Margin="0,1.5" Text="守卫军的杂鱼兵" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Foxman" />
|
<TextBlock Width="120" Margin="0,1.5" Text="念安" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="KoreQAQ" />
|
<TextBlock Width="120" Margin="0,1.5" Text="叶" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="TechOfRevo" />
|
<TextBlock Width="120" Margin="0,1.5" Text="rreorr" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="lqs" />
|
<TextBlock Width="120" Margin="0,1.5" Text="星辰大海" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="简某" />
|
<TextBlock Width="120" Margin="0,1.5" Text="随便" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="源起于此" />
|
<TextBlock Width="120" Margin="0,1.5" Text="烤着吃的鱼" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="大概是" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="闹山麻雀" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="我是(⊙o⊙)啥?笔" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="北纬44" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="呼呼呼" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="嘎嘎不咕咕" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="kronos" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="有个好梦,同志" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Amojun" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="bat-744" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="那谁" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="AYOSO" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="抽抽" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="柚子皮皮皮" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="白玉京" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="ALPSL" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="我爱喝兽奶" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="wwq557" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="爱莉希雅" />
|
<TextBlock Width="120" Margin="0,1.5" Text="爱莉希雅" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text=" 和忧" />
|
<TextBlock Width="120" Margin="0,1.5" Text="上善若水" />
|
||||||
<TextBlock Width="240" Margin="0,1.5" Text="全明星小面包批发商DIO" />
|
<TextBlock Width="120" Margin="0,1.5" Text="zztzzy" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="碎序" />
|
<TextBlock Width="120" Margin="0,1.5" Text="SHiao_Yui" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="U" />
|
<TextBlock Width="120" Margin="0,1.5" Text="一只花生" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Dumlet" />
|
<TextBlock Width="120" Margin="0,1.5" Text="黑凤梨熊?" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="johnqian" />
|
<TextBlock Width="120" Margin="0,1.5" Text="sdad" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="KANG" />
|
<TextBlock Width="120" Margin="0,1.5" Text="BLONG" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="owod" />
|
<TextBlock Width="120" Margin="0,1.5" Text="787878" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="九" />
|
<TextBlock Width="120" Margin="0,1.5" Text="myry668" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="苑煜" />
|
<TextBlock Width="120" Margin="0,1.5" Text="f三文鱼f" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="壹" />
|
<TextBlock Width="120" Margin="0,1.5" Text="apqow" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="UA-Ming" />
|
<TextBlock Width="120" Margin="0,1.5" Text="懒梦棉花糖" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="可爱小探姬" />
|
<TextBlock Width="120" Margin="0,1.5" Text="HaiMing" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="霜月" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Evernight" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="bud" />
|
<TextBlock Width="120" Margin="0,1.5" Text="CieloNeet" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="小虐SAIKYO" />
|
<TextBlock Width="120" Margin="0,1.5" Text="不青盆" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="zealotand" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Purelimiter" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="comico" />
|
<TextBlock Width="120" Margin="0,1.5" Text="丨白丨" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="万山松" />
|
<TextBlock Width="120" Margin="0,1.5" Text="喵" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="依梦明天" />
|
<TextBlock Width="120" Margin="0,1.5" Text="雨过山秋" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="化形彧九尾" />
|
<TextBlock Width="120" Margin="0,1.5" Text="急了" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="知崎" />
|
<TextBlock Width="120" Margin="0,1.5" Text="歌斐木" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="LOG175" />
|
<TextBlock Width="120" Margin="0,1.5" Text="公子天邪" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="绵" />
|
<TextBlock Width="120" Margin="0,1.5" Text="爱发癫" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="scp00813" />
|
<TextBlock Width="120" Margin="0,1.5" Text="洪某某" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="宝宝" />
|
<TextBlock Width="120" Margin="0,1.5" Text="漫卡洛樱" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="9527" />
|
<TextBlock Width="120" Margin="0,1.5" Text="云与海" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ICE_xwx" />
|
<TextBlock Width="120" Margin="0,1.5" Text="子曰" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="羽笙喵喵" />
|
<TextBlock Width="120" Margin="0,1.5" Text="CyrilZ" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ssvgg(☉ x ☉)" />
|
<TextBlock Width="120" Margin="0,1.5" Text="笑颜如花兮" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Happymeals" />
|
<TextBlock Width="120" Margin="0,1.5" Text="咸鱼超人FF酱!" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="shen12244" />
|
<TextBlock Width="120" Margin="0,1.5" Text="达达利鸭" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="一般路过AAA" />
|
<TextBlock Width="120" Margin="0,1.5" Text="TFofN" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Kumo" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="江俞白" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="聆风忘年" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="五符临门" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="亭书浅墨" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="翀归滉" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Anmuer" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="青天揽明月" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="鲫鱼崽" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="PPTNPC" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="vIccvI" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="GOOD" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="归零之诗" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="ppp" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Ethanhmm1234" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="库里斯库拉" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="被伪安全软件坑害的普通人" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="无元亓" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Raven" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="看看你的jjp" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="日月皆如水" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="gzwmmm" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="早上鸥" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="CJT" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="幽永森" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="东海帝皇" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="三岁" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="shui12dkhigl" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="豪猪" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="再相遇" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="?白樱Hakura" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="IssacPyromaniac" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="纯真丁一郎" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="岩之龙" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="星之金白" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="laocao" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="DLC...是什么" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="我家老米" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="TINY" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="只会coding的农民工" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="明月一行" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="nanako" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="辛霏Aiwx" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="奇妙的白给之旅" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="你咋不上天呢^_^" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="冰糕" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="sadas" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小叮当搞快点" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="leu" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="休伯利安本来的舰长" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="天诺一字号仓鼠" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="真爱粉只因龙" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="绝望的温度" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="busituteng" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="SiC" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="契特卡拉概念机" />
|
||||||
|
<TextBlock Width="240" Margin="0,1.5" Text="我还能再在死线挣扎一会" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="02_G1nTonic" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="渊" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="1" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小楠" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="阿冰" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="EliasG" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="jhx" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="zyccmyk" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="luxin" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="我是我" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="13462738215" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="minecraft java" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="那是小林吖" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="GITATIG" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Musketeer" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="AuraSpeedJerry" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="luckymore" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="hcrmhj" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="我好焦灼啊" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="小王同学" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="MoDust2131" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="啊超" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Ander·Les" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Niko" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Niko" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="qroiwopqri" />
|
<TextBlock Width="120" Margin="0,1.5" Text="五个麦卷" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="TringDron" />
|
<TextBlock Width="120" Margin="0,1.5" Text="b0Ard" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="有屳則名" />
|
<TextBlock Width="120" Margin="0,1.5" Text="龙猫的专属粉丝" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="TX2006" />
|
<TextBlock Width="120" Margin="0,1.5" Text="雾念~" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="滑天下之大稽" />
|
<TextBlock Width="120" Margin="0,1.5" Text="烬灵梦" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="中东悍匪" />
|
<TextBlock Width="120" Margin="0,1.5" Text="蝶落染花香" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="鬼泣々离殇" />
|
<TextBlock Width="120" Margin="0,1.5" Text="照井黎Terui_Rei" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="蒼崎青子" />
|
<TextBlock Width="120" Margin="0,1.5" Text="???狼??王?" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="wyh114514" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Zik yeung" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="飞飞在睡觉。" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Coco" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="柚西" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Ricardo" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="XIAOSHUAI" />
|
<TextBlock Width="120" Margin="0,1.5" Text="2969307002" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="saxioh" />
|
<TextBlock Width="120" Margin="0,1.5" Text="鬼卿" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="baibaibai" />
|
<TextBlock Width="120" Margin="0,1.5" Text="李白" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="事屑Jerry" />
|
<TextBlock Width="120" Margin="0,1.5" Text="霜木翔凤" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Rs32" />
|
<TextBlock Width="120" Margin="0,1.5" Text="岽龙" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="SPDish" />
|
<TextBlock Width="120" Margin="0,1.5" Text="joksqp" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="风早九夜" />
|
<TextBlock Width="240" Margin="0,1.5" Text="what are you 说啥嘞?" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Reg" />
|
<TextBlock Width="120" Margin="0,1.5" Text="木得爱_没人疼" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="hellord" />
|
<TextBlock Width="120" Margin="0,1.5" Text="小黑子?" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="时本ki" />
|
<TextBlock Width="240" Margin="0,1.5" Text="删除线Strikethrough" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="mamana" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="放肆的微笑" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="人没逝" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="wddjww" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="xiao澄" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="银狼碎片" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="OniKata_Kayoko" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="曦" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Echo" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="画卿颜" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="夏 " />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="jiege45" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="甜食先生" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="虚莫妄玄" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="天恒" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="我有馄饨" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="布布曼" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="qwqewe" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="114514" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="YJ_42" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Xricron" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="抛弃大脑" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="10455885" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="羽渡白砂" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="沙" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="sukous" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="册那" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="KMYLS" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="kakadeso" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="懒猫" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="清岚" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Atopos" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="苦尽柑来" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="脑洞大开的血魔" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ももかわるこ" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="空中的风" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="黑夜幽灵" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="H1saNe" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="故风" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="臭氧化碳" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="云阿云" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="小命" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="南宫若兮" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Landsilde" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="zzz" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="星期三" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Ashburn" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="123" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="九日" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="古神" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="月宫星耀" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="郁子恒是FW" />
|
|
||||||
<TextBlock Width="240" Margin="0,1.5" Text="每天吃吃吃吃吃不饱" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Freezhao" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="ZHypocrite" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="十下小雨" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="九 十" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="RuthlessXdream" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="zv-vz" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="汐沄的随记" />
|
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="REMOTE" />
|
<TextBlock Width="120" Margin="0,1.5" Text="REMOTE" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="昔阳" />
|
<TextBlock Width="120" Margin="0,1.5" Text="H" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="七度ユキノ" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Parapha" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="KNISX" />
|
<TextBlock Width="120" Margin="0,1.5" Text="南吕十三" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="RainbowDashRD" />
|
<TextBlock Width="120" Margin="0,1.5" Text="米帝" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="夢曦" />
|
<TextBlock Width="120" Margin="0,1.5" Text="zdxff" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="跳雨风" />
|
<TextBlock Width="120" Margin="0,1.5" Text="蔚空" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="望言苏" />
|
<TextBlock Width="120" Margin="0,1.5" Text="cleverboy1066" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="四分白Fortenz" />
|
<TextBlock Width="120" Margin="0,1.5" Text="烤老鼠" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="UUZ" />
|
<TextBlock Width="120" Margin="0,1.5" Text="TS彦祖" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Ankairis" />
|
<TextBlock Width="120" Margin="0,1.5" Text="狮某人" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Jn1E" />
|
<TextBlock Width="120" Margin="0,1.5" Text="lmst_myh" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="云山如昨好" />
|
<TextBlock Width="120" Margin="0,1.5" Text="耐·若何" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="LYJ0415" />
|
<TextBlock Width="120" Margin="0,1.5" Text="qvq" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="空?" />
|
<TextBlock Width="120" Margin="0,1.5" Text="刀客塔" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="Awfrlu+" />
|
<TextBlock Width="120" Margin="0,1.5" Text="mika" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="懒帝" />
|
<TextBlock Width="120" Margin="0,1.5" Text="金尘" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="北安丶七叔" />
|
<TextBlock Width="120" Margin="0,1.5" Text="喜之狼与灰太羊" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="xkw" />
|
<TextBlock Width="120" Margin="0,1.5" Text="天才小宋" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="KINO" />
|
<TextBlock Width="120" Margin="0,1.5" Text="MdsR" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="POTATO" />
|
<TextBlock Width="120" Margin="0,1.5" Text="诗和雨夜" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="少昊氏" />
|
<TextBlock Width="120" Margin="0,1.5" Text="Samueldong" />
|
||||||
<TextBlock Width="240" Margin="0,1.5" Text="狂踹瘸子那條好腿丶" />
|
<TextBlock Width="120" Margin="0,1.5" Text="BBK" />
|
||||||
<TextBlock Width="240" Margin="0,1.5" Text="Thallium_Ash【铊尘】(坨坨)" />
|
<TextBlock Width="120" Margin="0,1.5" Text="雪枫Sople" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="陌雨泠涯" />
|
<TextBlock Width="120" Margin="0,1.5" Text="一坨灰" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="bajie79" />
|
<TextBlock Width="120" Margin="0,1.5" Text="RI_CK" />
|
||||||
<TextBlock Width="120" Margin="0,1.5" Text="紘垰" />
|
<TextBlock Width="120" Margin="0,1.5" Text="ximeng22" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="天天122_" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="李小浩&mod" />
|
||||||
|
<TextBlock Width="120" Margin="0,1.5" Text="Southsheng" />
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<Grid Height="35">
|
<Grid Height="35">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -362,7 +403,7 @@
|
|||||||
<local:MyCard Margin="0,0,0,15" Title="法律信息" IsSwapped="True" CanSwap="True">
|
<local:MyCard Margin="0,0,0,15" Title="法律信息" IsSwapped="True" CanSwap="True">
|
||||||
<StackPanel Margin="25,39,23,20">
|
<StackPanel Margin="25,39,23,20">
|
||||||
<TextBlock Text="匿名数据收集" TextWrapping="Wrap" Margin="0,6,0,4" FontWeight="Bold" />
|
<TextBlock Text="匿名数据收集" TextWrapping="Wrap" Margin="0,6,0,4" FontWeight="Bold" />
|
||||||
<TextBlock Margin="0,0,0,2" LineHeight="17" Text="当下载失败、PCL 出错、游戏崩溃等事件时,PCL 会匿名上报信息,以通知龙猫 “哦吼,出错了”,让龙猫能更好地修 Bug……(PCL 不会上传或收集任何个人信息,包括上报的东西里面也没有!)
你可以在 设置 → 其他 → 启动器 中关闭上报,不过龙猫就不知道你遇到了什么 Bug 了……" TextWrapping="Wrap" />
|
<TextBlock Margin="0,0,0,2" LineHeight="17" Text="当下载失败、PCL 出错、游戏崩溃等事件时,PCL 会匿名上报信息,以通知龙猫 “哦吼,出错了”,让龙猫能更好地修 Bug……(PCL 不会上传或收集任何个人信息,包括上报的东西里面也没有!)
你可以在 设置 → 其他 → 启动器 中关闭上报,不过龙猫就不知道你遇到了什么 Bug 了……
详情:https://github.com/Meloong-Git/PCL/discussions/7036" TextWrapping="Wrap" />
|
||||||
<TextBlock Text="隐私声明与个人信息保护政策" TextWrapping="Wrap" Margin="0,10,0,4" FontWeight="Bold" />
|
<TextBlock Text="隐私声明与个人信息保护政策" TextWrapping="Wrap" Margin="0,10,0,4" FontWeight="Bold" />
|
||||||
<TextBlock Margin="0,0,0,2" LineHeight="17" Text="PCL 没有收集个人信息,所以这里其实啥都不用写……
留个这个其实只是为了让你知道 PCL 没有收集个人信息,诶嘿。" TextWrapping="Wrap" />
|
<TextBlock Margin="0,0,0,2" LineHeight="17" Text="PCL 没有收集个人信息,所以这里其实啥都不用写……
留个这个其实只是为了让你知道 PCL 没有收集个人信息,诶嘿。" TextWrapping="Wrap" />
|
||||||
<TextBlock Text="其他信息" TextWrapping="Wrap" Margin="0,10,0,4" FontWeight="Bold" />
|
<TextBlock Text="其他信息" TextWrapping="Wrap" Margin="0,10,0,4" FontWeight="Bold" />
|
||||||
|
|||||||
@@ -132,7 +132,7 @@
|
|||||||
End Sub
|
End Sub
|
||||||
Public Shared Sub TryFeedback()
|
Public Shared Sub TryFeedback()
|
||||||
If Not CanFeedback(True) Then Return
|
If Not CanFeedback(True) Then Return
|
||||||
Select Case MyMsgBox("在提交新反馈前,建议先搜索反馈列表,以避免重复提交。" & vbCrLf & "如果无法打开该网页,请使用 VPN 以改善网络环境。",
|
Select Case MyMsgBox("在提交新反馈前,建议先搜索反馈列表,以避免重复提交。" & vbCrLf & "如果无法打开该网页,请使用 VPN 改善网络环境。",
|
||||||
"反馈", "提交新反馈", "查看反馈列表", "取消")
|
"反馈", "提交新反馈", "查看反馈列表", "取消")
|
||||||
Case 1
|
Case 1
|
||||||
Feedback(True, False)
|
Feedback(True, False)
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
e.Handled = True
|
e.Handled = True
|
||||||
End Sub
|
End Sub
|
||||||
Public Shared Sub TryVote()
|
Public Shared Sub TryVote()
|
||||||
If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请使用 VPN 以改善网络环境。",
|
If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请使用 VPN 改善网络环境。",
|
||||||
"新功能投票", "打开", "取消") = 2 Then Return
|
"新功能投票", "打开", "取消") = 2 Then Return
|
||||||
OpenWebsite("https://github.com/Meloong-Git/PCL/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/Meloong-Git/PCL/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
|
||||||
|
|||||||
@@ -317,9 +317,6 @@
|
|||||||
Public Sub Delete_Click(sender As Object, e As RoutedEventArgs)
|
Public Sub Delete_Click(sender As Object, e As RoutedEventArgs)
|
||||||
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
|
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
|
||||||
Dim DeleteText As String = If((Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1, "清空", "删除")
|
Dim DeleteText As String = If((Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1, "清空", "删除")
|
||||||
If Folder.Path.EndsWith(":\") OrElse Folder.Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\" OrElse Folder.Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\" Then '#7030
|
|
||||||
If MyMsgBox("将要删除的游戏文件夹是系统关键目录(" & Folder.Path & "),确定要删除吗?", "删除警告", "取消", "确认", "取消", IsWarn:=True) <> 2 Then Return
|
|
||||||
End If
|
|
||||||
If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久丢失,且不可恢复!", "删除警告", "取消", "确认", "取消") <> 2 Then Return
|
If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久丢失,且不可恢复!", "删除警告", "取消", "确认", "取消") <> 2 Then Return
|
||||||
If MyMsgBox("如果你在该文件夹中存放了除 MC 以外的其他文件,这些文件也会被一同删除!" & vbCrLf & "继续删除会导致该文件夹中的所有文件永久丢失,请在仔细确认后再继续!" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这是最后一次警告!", "删除警告", "确认" & DeleteText, "取消", IsWarn:=True) <> 1 Then Return
|
If MyMsgBox("如果你在该文件夹中存放了除 MC 以外的其他文件,这些文件也会被一同删除!" & vbCrLf & "继续删除会导致该文件夹中的所有文件永久丢失,请在仔细确认后再继续!" & vbCrLf & "目标文件夹:" & Folder.Path & vbCrLf & vbCrLf & "这是最后一次警告!", "删除警告", "确认" & DeleteText, "取消", IsWarn:=True) <> 1 Then Return
|
||||||
'移出列表
|
'移出列表
|
||||||
|
|||||||
@@ -218,7 +218,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
<local:MyCard Margin="0,0,0,15" Title="高级启动选项" IsSwapped="True" CanSwap="True">
|
<local:MyCard Margin="0,0,0,15" Title="高级选项" IsSwapped="True" CanSwap="True">
|
||||||
<Grid Margin="25,40,25,15">
|
<Grid Margin="25,40,25,15">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -255,7 +255,7 @@
|
|||||||
<local:MyCheckBox Height="28" Text="要求 Java 使用高性能显卡" x:Name="CheckAdvanceGraphicCard" Tag="LaunchAdvanceGraphicCard"
|
<local:MyCheckBox Height="28" Text="要求 Java 使用高性能显卡" x:Name="CheckAdvanceGraphicCard" Tag="LaunchAdvanceGraphicCard"
|
||||||
ToolTipService.Placement="Right" ToolTip="自动在 Windows 设置 → 系统 → 屏幕 → 显示卡 中将 Java 改为使用高性能显卡。
如果电脑同时有集显和独显,这能确保 MC 使用独显进行渲染,以大幅提高性能。" />
|
ToolTipService.Placement="Right" ToolTip="自动在 Windows 设置 → 系统 → 屏幕 → 显示卡 中将 Java 改为使用高性能显卡。
如果电脑同时有集显和独显,这能确保 MC 使用独显进行渲染,以大幅提高性能。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<local:MyHint Text="你还可以在版本独立设置中找到更多高级启动选项。" Margin="0,5,0,10" Theme="Blue" Grid.Row="7" Grid.ColumnSpan="2"
|
<local:MyHint Text="版本独立设置中还有更多高级选项可供调整。" Margin="0,5,0,10" Theme="Blue" Grid.Row="7" Grid.ColumnSpan="2"
|
||||||
CanClose="True" RelativeSetup="HintMoreAdvancedSetup" />
|
CanClose="True" RelativeSetup="HintMoreAdvancedSetup" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
Try
|
Try
|
||||||
Setup.Reset("LaunchArgumentTitle")
|
Setup.Reset("LaunchArgumentTitle")
|
||||||
Setup.Reset("LaunchArgumentInfo")
|
Setup.Reset("LaunchArgumentInfo")
|
||||||
Setup.Reset("LaunchArgumentIndieV2")
|
Setup.Set("LaunchArgumentIndieV2", Setup.GetDefault("LaunchArgumentIndieV2"))
|
||||||
Setup.Reset("LaunchArgumentVisible")
|
Setup.Reset("LaunchArgumentVisible")
|
||||||
Setup.Reset("LaunchArgumentWindowType")
|
Setup.Reset("LaunchArgumentWindowType")
|
||||||
Setup.Reset("LaunchArgumentWindowWidth")
|
Setup.Reset("LaunchArgumentWindowWidth")
|
||||||
@@ -585,4 +585,12 @@ PreFin:
|
|||||||
FrmMain.PageChange(FormMain.PageType.VersionSetup, FormMain.PageSubType.VersionSetup)
|
FrmMain.PageChange(FormMain.PageType.VersionSetup, FormMain.PageSubType.VersionSetup)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
'去除参数中的回车
|
||||||
|
Private Sub ReplaceEnter(sender As MyTextBox, e As TextChangedEventArgs) Handles TextAdvanceJvm.TextChanged, TextAdvanceGame.TextChanged
|
||||||
|
Dim NewText = sender.Text.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr, " ")
|
||||||
|
If NewText = sender.Text Then Return
|
||||||
|
Dim CaretIndex = sender.CaretIndex
|
||||||
|
sender.Text = NewText
|
||||||
|
sender.CaretIndex = Math.Max(0, CaretIndex - 1)
|
||||||
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -150,7 +150,7 @@
|
|||||||
</local:MyTextBox>
|
</local:MyTextBox>
|
||||||
<local:MyCheckBox Margin="0,5,0,4" Text="匿名数据收集" Grid.Row="6" Height="22" Grid.ColumnSpan="2"
|
<local:MyCheckBox Margin="0,5,0,4" Text="匿名数据收集" Grid.Row="6" Height="22" Grid.ColumnSpan="2"
|
||||||
x:Name="CheckSystemTelemetry" Tag="SystemSystemTelemetry"
|
x:Name="CheckSystemTelemetry" Tag="SystemSystemTelemetry"
|
||||||
ToolTip="当下载失败、PCL 出错、游戏崩溃等事件时,PCL 会匿名上报情况,以通知龙猫 “哦吼,出错了”,让龙猫能更好地修 Bug……
你可以关闭上报,不过龙猫就不知道你遇到了什么 Bug 了…… PCL 不会上传或收集任何个人信息,包括上报的东西里面也没有!" />
|
ToolTip="当下载失败、PCL 出错、游戏崩溃等事件时,PCL 会匿名上报情况,以通知龙猫 “哦吼,出错了”,让龙猫能更好地修 Bug……
你可以关闭上报,不过龙猫就不知道你遇到了什么 Bug 了…… PCL 不会上传或收集任何个人信息,包括上报的东西里面也没有!
详情:https://github.com/Meloong-Git/PCL/discussions/7036" />
|
||||||
<Grid Height="35" Grid.Row="7" Grid.ColumnSpan="5" Margin="0,12,0,0">
|
<Grid Height="35" Grid.Row="7" Grid.ColumnSpan="5" Margin="0,12,0,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ Public Class PageSpeedLeft
|
|||||||
Card.Children.Clear()
|
Card.Children.Clear()
|
||||||
Card.Children.Add(GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""0"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"))
|
Card.Children.Add(GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""0"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"))
|
||||||
Dim Tb As TextBlock = GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" TextWrapping=""Wrap"" HorizontalAlignment=""Left"" ToolTip=""单击复制错误详情"" Grid.Column=""1"" Grid.Row=""0"" Margin=""0,0,0,5"" />")
|
Dim Tb As TextBlock = GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" TextWrapping=""Wrap"" HorizontalAlignment=""Left"" ToolTip=""单击复制错误详情"" Grid.Column=""1"" Grid.Row=""0"" Margin=""0,0,0,5"" />")
|
||||||
Tb.Text = GetExceptionDetail(Loader.Error)
|
Tb.Text = Loader.Error.GetDetail()
|
||||||
AddHandler Tb.MouseLeftButtonDown,
|
AddHandler Tb.MouseLeftButtonDown,
|
||||||
Sub(sender As TextBlock, e As EventArgs)
|
Sub(sender As TextBlock, e As EventArgs)
|
||||||
ClipboardSet(sender.Text, False)
|
ClipboardSet(sender.Text, False)
|
||||||
|
|||||||
@@ -106,6 +106,14 @@
|
|||||||
DefaultChecked="True" />
|
DefaultChecked="True" />
|
||||||
</local:MyCheckBox.Tag>
|
</local:MyCheckBox.Tag>
|
||||||
</local:MyCheckBox>
|
</local:MyCheckBox>
|
||||||
|
<local:MyCheckBox>
|
||||||
|
<local:MyCheckBox.Tag>
|
||||||
|
<local:ExportOption
|
||||||
|
Title="TaCZ 枪包"
|
||||||
|
Rules="tacz/|config/tacz/custom/"
|
||||||
|
DefaultChecked="True" />
|
||||||
|
</local:MyCheckBox.Tag>
|
||||||
|
</local:MyCheckBox>
|
||||||
<local:MyCheckBox>
|
<local:MyCheckBox>
|
||||||
<local:MyCheckBox.Tag>
|
<local:MyCheckBox.Tag>
|
||||||
<local:ExportOption
|
<local:ExportOption
|
||||||
@@ -133,14 +141,6 @@
|
|||||||
DefaultChecked="False" />
|
DefaultChecked="False" />
|
||||||
</local:MyCheckBox.Tag>
|
</local:MyCheckBox.Tag>
|
||||||
</local:MyCheckBox>
|
</local:MyCheckBox>
|
||||||
<local:MyCheckBox>
|
|
||||||
<local:MyCheckBox.Tag>
|
|
||||||
<local:ExportOption
|
|
||||||
Title="TaCZ 枪包"
|
|
||||||
Rules="tacz/|config/tacz/custom/"
|
|
||||||
DefaultChecked="False" />
|
|
||||||
</local:MyCheckBox.Tag>
|
|
||||||
</local:MyCheckBox>
|
|
||||||
<local:MyCheckBox>
|
<local:MyCheckBox>
|
||||||
<local:MyCheckBox.Tag>
|
<local:MyCheckBox.Tag>
|
||||||
<local:ExportOption
|
<local:ExportOption
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ Public Class PageVersionExport
|
|||||||
Log($"[Export] 使用配置文件中指定的导出路径:{ConfigPackPath}")
|
Log($"[Export] 使用配置文件中指定的导出路径:{ConfigPackPath}")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, $"无法使用配置文件中指定的导出路径({ConfigPackPath})", LogLevel.Debug)
|
Log(ex, $"无法使用配置文件中指定的导出路径({ConfigPackPath})", LogLevel.Debug)
|
||||||
If MyMsgBox($"指定的路径:{ConfigPackPath}{vbCrLf}{vbCrLf}{GetExceptionDetail(ex)}", "无法使用配置文件中指定的导出路径", "确定", "取消") = 2 Then Return
|
If MyMsgBox($"指定的路径:{ConfigPackPath}{vbCrLf}{vbCrLf}{ex.GetDetail}", "无法使用配置文件中指定的导出路径", "确定", "取消") = 2 Then Return
|
||||||
End Try
|
End Try
|
||||||
End If
|
End If
|
||||||
If PackPath Is Nothing Then
|
If PackPath Is Nothing Then
|
||||||
@@ -530,6 +530,7 @@ Public Class PageVersionExport
|
|||||||
Loader.Progress = 0.97
|
Loader.Progress = 0.97
|
||||||
'复制 PCL 版本设置
|
'复制 PCL 版本设置
|
||||||
CopyDirectory(McVersion.Path & "PCL\", OverridesFolder & "PCL\")
|
CopyDirectory(McVersion.Path & "PCL\", OverridesFolder & "PCL\")
|
||||||
|
WriteIni(OverridesFolder & "PCL\Setup.ini", "IsStar", False)
|
||||||
#If BETA Then
|
#If BETA Then
|
||||||
'复制 PCL 本体
|
'复制 PCL 本体
|
||||||
If IncludePCL Then CopyFile(PathWithName, CacheFolder & "Plain Craft Launcher.exe")
|
If IncludePCL Then CopyFile(PathWithName, CacheFolder & "Plain Craft Launcher.exe")
|
||||||
|
|||||||
@@ -681,7 +681,7 @@ Install:
|
|||||||
Hint($"已成功更新 {FinishedFileNames.Count} 个 Mod!", HintType.Finish)
|
Hint($"已成功更新 {FinishedFileNames.Count} 个 Mod!", HintType.Finish)
|
||||||
End Select
|
End Select
|
||||||
Case LoadState.Failed
|
Case LoadState.Failed
|
||||||
Hint("Mod 更新失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
|
Hint("Mod 更新失败:" & Loader.Error.GetBrief(), HintType.Critical)
|
||||||
Case LoadState.Aborted
|
Case LoadState.Aborted
|
||||||
Hint("Mod 更新已中止!", HintType.Info)
|
Hint("Mod 更新已中止!", HintType.Info)
|
||||||
Case Else
|
Case Else
|
||||||
@@ -808,7 +808,7 @@ Install:
|
|||||||
Dim ModEntry As McMod = CType(If(TypeOf sender Is MyIconButton, sender.Tag, sender), MyLocalModItem).Entry
|
Dim ModEntry As McMod = CType(If(TypeOf sender Is MyIconButton, sender.Tag, sender), MyLocalModItem).Entry
|
||||||
'加载失败信息
|
'加载失败信息
|
||||||
If ModEntry.State = McMod.McModState.Unavailable Then
|
If ModEntry.State = McMod.McModState.Unavailable Then
|
||||||
MyMsgBox("无法读取此 Mod 的信息。" & vbCrLf & vbCrLf & "详细的错误信息:" & GetExceptionDetail(ModEntry.FileUnavailableReason), "Mod 读取失败")
|
MyMsgBox("无法读取此 Mod 的信息。" & vbCrLf & vbCrLf & "详细的错误信息:" & ModEntry.FileUnavailableReason.GetDetail(), "Mod 读取失败")
|
||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
If ModEntry.Comp IsNot Nothing Then
|
If ModEntry.Comp IsNot Nothing Then
|
||||||
|
|||||||
@@ -109,25 +109,23 @@
|
|||||||
Dim OldName As String = PageVersionLeft.Version.Name
|
Dim OldName As String = PageVersionLeft.Version.Name
|
||||||
Dim OldPath As String = PageVersionLeft.Version.Path
|
Dim OldPath As String = PageVersionLeft.Version.Path
|
||||||
'修改此部分的同时修改快速安装的版本名检测*
|
'修改此部分的同时修改快速安装的版本名检测*
|
||||||
Dim NewName As String = MyMsgBoxInput("重命名版本", "", OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)})
|
Dim NewName As String = MyMsgBoxInput("重命名版本", "", OldName, New ObjectModel.Collection(Of Validate) From {
|
||||||
|
New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False), New ValidateExceptSame(OldName & "_temp", "不能使用该名称!")})
|
||||||
If String.IsNullOrWhiteSpace(NewName) Then Return
|
If String.IsNullOrWhiteSpace(NewName) Then Return
|
||||||
Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
|
Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
|
||||||
'获取临时中间名,以防止仅修改大小写的重命名失败
|
'获取临时中间名,以防止仅修改大小写的重命名失败
|
||||||
Dim TempName As String = NewName & "_temp"
|
Dim TempName As String = NewName & "_temp"
|
||||||
Dim TempPath As String = PathMcFolder & "versions\" & TempName & "\"
|
Dim TempPath As String = PathMcFolder & "versions\" & TempName & "\"
|
||||||
Dim IsCaseChangedOnly As Boolean = NewName.ToLower = OldName.ToLower
|
Dim OnlyChangedCase As Boolean = NewName.ToLower = OldName.ToLower
|
||||||
|
'重新读取版本 JSON 信息,避免 JsonObject 中已被合并的项被重新存储
|
||||||
'读取版本 JSON 信息
|
|
||||||
Dim JsonObject As JObject
|
Dim JsonObject As JObject
|
||||||
Dim OldJsonPath As String = ""
|
Dim OldJsonPath As String = PageVersionLeft.Version.GetJsonPath()
|
||||||
Try
|
Try
|
||||||
OldJsonPath = PageVersionLeft.Version.GetJsonPath()
|
|
||||||
JsonObject = GetJson(ReadFile(OldJsonPath))
|
JsonObject = GetJson(ReadFile(OldJsonPath))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "在重命名读取 json 时失败")
|
Log(ex, "在重命名读取 json 时失败")
|
||||||
JsonObject = PageVersionLeft.Version.JsonObject
|
JsonObject = PageVersionLeft.Version.JsonObject
|
||||||
End Try
|
End Try
|
||||||
|
|
||||||
'重命名主文件夹
|
'重命名主文件夹
|
||||||
My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
|
My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
|
||||||
My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
|
My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
|
||||||
@@ -137,7 +135,7 @@
|
|||||||
'重命名 jar 文件与 natives 文件夹
|
'重命名 jar 文件与 natives 文件夹
|
||||||
'不能进行遍历重命名,否则在版本名很短的时候容易误伤其他文件(#6443)
|
'不能进行遍历重命名,否则在版本名很短的时候容易误伤其他文件(#6443)
|
||||||
If Directory.Exists($"{NewPath}{OldName}-natives") Then
|
If Directory.Exists($"{NewPath}{OldName}-natives") Then
|
||||||
If IsCaseChangedOnly Then
|
If OnlyChangedCase Then
|
||||||
My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives", $"{OldName}natives_temp")
|
My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives", $"{OldName}natives_temp")
|
||||||
My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives_temp", $"{NewName}-natives")
|
My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives_temp", $"{NewName}-natives")
|
||||||
Else
|
Else
|
||||||
@@ -146,7 +144,7 @@
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
If File.Exists($"{NewPath}{OldName}.jar") Then
|
If File.Exists($"{NewPath}{OldName}.jar") Then
|
||||||
If IsCaseChangedOnly Then
|
If OnlyChangedCase Then
|
||||||
My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}.jar", $"{OldName}_temp.jar")
|
My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}.jar", $"{OldName}_temp.jar")
|
||||||
My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}_temp.jar", $"{NewName}.jar")
|
My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}_temp.jar", $"{NewName}.jar")
|
||||||
Else
|
Else
|
||||||
@@ -162,48 +160,14 @@
|
|||||||
If ReadIni(PathMcFolder & "PCL.ini", "Version") = OldName Then
|
If ReadIni(PathMcFolder & "PCL.ini", "Version") = OldName Then
|
||||||
WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
|
WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
|
||||||
End If
|
End If
|
||||||
|
'更新版本 Json
|
||||||
'处理JSON文件:先写入新文件,再删除旧文件
|
|
||||||
Try
|
Try
|
||||||
'更新JSON内容中的id
|
|
||||||
JsonObject("id") = NewName
|
JsonObject("id") = NewName
|
||||||
'写入新的JSON文件
|
|
||||||
WriteFile(NewPath & NewName & ".json", JsonObject.ToString)
|
WriteFile(NewPath & NewName & ".json", JsonObject.ToString)
|
||||||
|
File.Delete(NewPath & GetFileNameFromPath(OldJsonPath))
|
||||||
'删除旧的JSON文件(现在在新路径下)
|
|
||||||
Dim OldJsonInNewPath As String = NewPath & OldName & ".json"
|
|
||||||
If File.Exists(OldJsonInNewPath) Then
|
|
||||||
File.Delete(OldJsonInNewPath)
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Log(ex, "重命名版本 json 失败")
|
Log(ex, "重命名版本 json 失败")
|
||||||
'如果JSON处理失败,尝试回滚整个操作
|
|
||||||
If Directory.Exists(NewPath) AndAlso Not Directory.Exists(OldPath) Then
|
|
||||||
Try
|
|
||||||
'还原jar文件名
|
|
||||||
If File.Exists($"{NewPath}{NewName}.jar") Then
|
|
||||||
My.Computer.FileSystem.RenameFile($"{NewPath}{NewName}.jar", $"{OldName}.jar")
|
|
||||||
End If
|
|
||||||
'还原natives文件夹名
|
|
||||||
If Directory.Exists($"{NewPath}{NewName}-natives") Then
|
|
||||||
My.Computer.FileSystem.RenameDirectory($"{NewPath}{NewName}-natives", $"{OldName}-natives")
|
|
||||||
End If
|
|
||||||
Catch
|
|
||||||
' 忽略 jar 文件, natives 文件夹还原失败
|
|
||||||
End Try
|
End Try
|
||||||
End If
|
|
||||||
Try
|
|
||||||
'还原文件夹名
|
|
||||||
My.Computer.FileSystem.RenameDirectory(NewPath, OldName)
|
|
||||||
Hint("重命名失败:无法处理版本配置文件,已回滚更改", HintType.Critical)
|
|
||||||
Return
|
|
||||||
Catch rollbackEx As Exception
|
|
||||||
Log(rollbackEx, "重命名失败后尝试回滚也失败")
|
|
||||||
Hint("重命名失败:版本文件可能已损坏,请检查版本文件夹", HintType.Critical)
|
|
||||||
Return
|
|
||||||
End Try
|
|
||||||
End Try
|
|
||||||
|
|
||||||
'刷新与提示
|
'刷新与提示
|
||||||
Hint("重命名成功!", HintType.Finish)
|
Hint("重命名成功!", HintType.Finish)
|
||||||
PageVersionLeft.Version = New McVersion(NewName).Load()
|
PageVersionLeft.Version = New McVersion(NewName).Load()
|
||||||
@@ -337,7 +301,7 @@
|
|||||||
Case LoadState.Finished
|
Case LoadState.Finished
|
||||||
Hint(Loader.Name & "成功!", HintType.Finish)
|
Hint(Loader.Name & "成功!", HintType.Finish)
|
||||||
Case LoadState.Failed
|
Case LoadState.Failed
|
||||||
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
|
Hint(Loader.Name & "失败:" & Loader.Error.GetBrief(), HintType.Critical)
|
||||||
Case LoadState.Aborted
|
Case LoadState.Aborted
|
||||||
Hint(Loader.Name & "已取消!", HintType.Info)
|
Hint(Loader.Name & "已取消!", HintType.Info)
|
||||||
End Select
|
End Select
|
||||||
|
|||||||
@@ -192,7 +192,7 @@
|
|||||||
<local:MyButton x:Name="BtnServerAuthLittle" Height="35" MinWidth="150" Margin="0,12,0,0" Text="设置为 LittleSkin" HorizontalAlignment="Left" ColorType="Highlight" />
|
<local:MyButton x:Name="BtnServerAuthLittle" Height="35" MinWidth="150" Margin="0,12,0,0" Text="设置为 LittleSkin" HorizontalAlignment="Left" ColorType="Highlight" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</local:MyCard>
|
</local:MyCard>
|
||||||
<local:MyCard x:Name="CardAdvance" Margin="0,0,0,15" Title="高级启动选项" IsSwapped="True" CanSwap="True">
|
<local:MyCard x:Name="CardAdvance" Margin="0,0,0,15" Title="高级选项" IsSwapped="True" CanSwap="True">
|
||||||
<Grid Margin="25,40,25,15">
|
<Grid Margin="25,40,25,15">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
|
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
|
||||||
@@ -219,7 +219,8 @@
|
|||||||
<local:MyCheckBox Grid.Row="5" Grid.Column="1" x:Name="CheckAdvanceRunWait" Tag="VersionAdvanceRunWait" Visibility="Collapsed"
|
<local:MyCheckBox Grid.Row="5" Grid.Column="1" x:Name="CheckAdvanceRunWait" Tag="VersionAdvanceRunWait" Visibility="Collapsed"
|
||||||
Text="等待命令执行完成后再继续启动" Margin="0,5,0,0" />
|
Text="等待命令执行完成后再继续启动" Margin="0,5,0,0" />
|
||||||
<StackPanel Margin="0,12,0,4" Grid.Row="6" Grid.ColumnSpan="2" HorizontalAlignment="Left">
|
<StackPanel Margin="0,12,0,4" Grid.Row="6" Grid.ColumnSpan="2" HorizontalAlignment="Left">
|
||||||
<local:MyCheckBox Height="28" Text="禁止 Mod 更新" x:Name="CheckAdvanceDisableModUpdate" Tag="VersionAdvanceDisableModUpdate"
|
<local:MyCheckBox Height="28" Text="禁止更新 Mod" x:Name="CheckAdvanceDisableModUpdate" Tag="VersionAdvanceDisableModUpdate"
|
||||||
|
ToolTip="禁止为此版本更新 Mod,以防止整合包玩家误操作"
|
||||||
ToolTipService.Placement="Right" />
|
ToolTipService.Placement="Right" />
|
||||||
<local:MyCheckBox Height="28" Text="忽略 Java 兼容性警告" x:Name="CheckAdvanceJava" Tag="VersionAdvanceJava"
|
<local:MyCheckBox Height="28" Text="忽略 Java 兼容性警告" x:Name="CheckAdvanceJava" Tag="VersionAdvanceJava"
|
||||||
ToolTipService.Placement="Right"
|
ToolTipService.Placement="Right"
|
||||||
|
|||||||
@@ -517,4 +517,12 @@ PreFin:
|
|||||||
FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupLaunch)
|
FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupLaunch)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
'去除参数中的回车
|
||||||
|
Private Sub ReplaceEnter(sender As MyTextBox, e As TextChangedEventArgs) Handles TextAdvanceJvm.TextChanged, TextAdvanceGame.TextChanged
|
||||||
|
Dim NewText = sender.Text.Replace(vbCrLf, vbCr).Replace(vbLf, vbCr).Replace(vbCr, " ")
|
||||||
|
If NewText = sender.Text Then Return
|
||||||
|
Dim CaretIndex = sender.CaretIndex
|
||||||
|
sender.Text = NewText
|
||||||
|
sender.CaretIndex = Math.Max(0, CaretIndex - 1)
|
||||||
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -207,6 +207,7 @@
|
|||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Compile Include="Controls\Behaviors\ClipboardInterceptor.vb" />
|
<Compile Include="Controls\Behaviors\ClipboardInterceptor.vb" />
|
||||||
<Compile Include="Controls\IMyRadio.vb" />
|
<Compile Include="Controls\IMyRadio.vb" />
|
||||||
|
<Compile Include="Controls\Interfaces.vb" />
|
||||||
<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" />
|
||||||
@@ -282,18 +283,12 @@
|
|||||||
<Compile Include="Pages\PageDownload\Comp\PageDownloadMod.xaml.vb">
|
<Compile Include="Pages\PageDownload\Comp\PageDownloadMod.xaml.vb">
|
||||||
<DependentUpon>PageDownloadMod.xaml</DependentUpon>
|
<DependentUpon>PageDownloadMod.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadFabric.xaml.vb">
|
|
||||||
<DependentUpon>PageDownloadFabric.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadInstall.xaml.vb">
|
<Compile Include="Pages\PageDownload\PageDownloadInstall.xaml.vb">
|
||||||
<DependentUpon>PageDownloadInstall.xaml</DependentUpon>
|
<DependentUpon>PageDownloadInstall.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Pages\PageDownload\Comp\PageDownloadCompDetail.xaml.vb">
|
<Compile Include="Pages\PageDownload\Comp\PageDownloadCompDetail.xaml.vb">
|
||||||
<DependentUpon>PageDownloadCompDetail.xaml</DependentUpon>
|
<DependentUpon>PageDownloadCompDetail.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadNeoForge.xaml.vb">
|
|
||||||
<DependentUpon>PageDownloadNeoForge.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Pages\PageLaunch\MyMsgLogin.xaml.vb">
|
<Compile Include="Pages\PageLaunch\MyMsgLogin.xaml.vb">
|
||||||
<DependentUpon>MyMsgLogin.xaml</DependentUpon>
|
<DependentUpon>MyMsgLogin.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -352,15 +347,6 @@
|
|||||||
<Compile Include="Modules\Minecraft\ModDownload.vb" />
|
<Compile Include="Modules\Minecraft\ModDownload.vb" />
|
||||||
<Compile Include="Modules\Minecraft\ModLaunch.vb" />
|
<Compile Include="Modules\Minecraft\ModLaunch.vb" />
|
||||||
<Compile Include="Modules\Minecraft\ModMinecraft.vb" />
|
<Compile Include="Modules\Minecraft\ModMinecraft.vb" />
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadForge.xaml.vb">
|
|
||||||
<DependentUpon>PageDownloadForge.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadLiteLoader.xaml.vb">
|
|
||||||
<DependentUpon>PageDownloadLiteLoader.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadOptiFine.xaml.vb">
|
|
||||||
<DependentUpon>PageDownloadOptiFine.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Pages\PageOther\PageOtherTest.xaml.vb">
|
<Compile Include="Pages\PageOther\PageOtherTest.xaml.vb">
|
||||||
<DependentUpon>PageOtherTest.xaml</DependentUpon>
|
<DependentUpon>PageOtherTest.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -394,9 +380,6 @@
|
|||||||
<Compile Include="Pages\PageDownload\PageDownloadLeft.xaml.vb">
|
<Compile Include="Pages\PageDownload\PageDownloadLeft.xaml.vb">
|
||||||
<DependentUpon>PageDownloadLeft.xaml</DependentUpon>
|
<DependentUpon>PageDownloadLeft.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Pages\PageDownload\PageDownloadClient.xaml.vb">
|
|
||||||
<DependentUpon>PageDownloadClient.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Pages\PageOther\PageOtherLeft.xaml.vb">
|
<Compile Include="Pages\PageOther\PageOtherLeft.xaml.vb">
|
||||||
<DependentUpon>PageOtherLeft.xaml</DependentUpon>
|
<DependentUpon>PageOtherLeft.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -556,10 +539,6 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Pages\PageDownload\PageDownloadFabric.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Pages\PageDownload\PageDownloadInstall.xaml">
|
<Page Include="Pages\PageDownload\PageDownloadInstall.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -568,10 +547,6 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Pages\PageDownload\PageDownloadNeoForge.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Pages\PageLaunch\MyMsgLogin.xaml">
|
<Page Include="Pages\PageLaunch\MyMsgLogin.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -625,18 +600,6 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Pages\PageDownload\PageDownloadForge.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Pages\PageDownload\PageDownloadLiteLoader.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Pages\PageDownload\PageDownloadOptiFine.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Pages\PageOther\PageOtherTest.xaml">
|
<Page Include="Pages\PageOther\PageOtherTest.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@@ -681,10 +644,6 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Pages\PageDownload\PageDownloadClient.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Pages\PageOther\PageOtherLeft.xaml">
|
<Page Include="Pages\PageOther\PageOtherLeft.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user