2.5.3
This commit is contained in:
@@ -155,6 +155,8 @@
|
||||
Stack.Children.Add(LiteLoaderDownloadListItem(Data, AddressOf LiteLoaderSave_Click, True))
|
||||
Case 11
|
||||
Stack.Children.Add(CType(Data, HelpEntry).ToListItem)
|
||||
Case 12
|
||||
Stack.Children.Add(FabricDownloadListItem(CType(Data, JObject), AddressOf FrmDownloadInstall.Fabric_Selected))
|
||||
Case Else
|
||||
Log("未知的虚拟化种类:" & Type, LogLevel.Feedback)
|
||||
End Select
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.2" />
|
||||
</Border.Effect>
|
||||
</Border>
|
||||
<Border x:Name="PanProgress" CornerRadius="1000" BorderThickness="0.001" Background="#2AFFFFFF" ClipToBounds="True" Visibility="Collapsed">
|
||||
<Border.Clip>
|
||||
<RectangleGeometry x:Name="RectProgress" Rect="0,0,40,25" />
|
||||
</Border.Clip>
|
||||
</Border>
|
||||
<Path x:Name="Path" Stretch="Uniform" Margin="12" Fill="{DynamicResource ColorBrush8}" RenderTransformOrigin="0.5,0.5">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform />
|
||||
|
||||
@@ -4,6 +4,24 @@
|
||||
Public Event Click(sender As Object, e As MouseButtonEventArgs) '自定义事件
|
||||
Public Event RightClick(sender As Object, e As MouseButtonEventArgs)
|
||||
|
||||
'进度条
|
||||
Private _Progress As Double = 0
|
||||
Public Property Progress As Double
|
||||
Get
|
||||
Return _Progress
|
||||
End Get
|
||||
Set(value As Double)
|
||||
If _Progress = value Then Exit Property
|
||||
_Progress = value
|
||||
If value < 0.0001 Then
|
||||
PanProgress.Visibility = Visibility.Collapsed
|
||||
Else
|
||||
PanProgress.Visibility = Visibility.Visible
|
||||
RectProgress.Rect = New Rect(0, 0, 40, 40 * (1 - value))
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
'自定义属性
|
||||
Public Uuid As Integer = GetUuid()
|
||||
Private _Logo As String = ""
|
||||
|
||||
@@ -89,52 +89,19 @@ Public Class FormMain
|
||||
FeatureCount += 8
|
||||
BugCount += 33
|
||||
End If
|
||||
If LastVersion < 246 Then 'Release 2.2.9
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 下载支持筛选 Forge Mod 与 Fabric Mod"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod、整合包下载的综合优化"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复使用离线登录进入 Forge 的存档可能导致游戏崩溃"))
|
||||
FeatureCount += 13
|
||||
BugCount += 11
|
||||
End If
|
||||
If LastVersion < 242 Then 'Release 2.2.7
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复 MC 所包含的一个严重安全漏洞"))
|
||||
If LastVersion >= 236 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复可能无法更改登录信息的 Bug"))
|
||||
End If
|
||||
If LastVersion < 238 Then 'Release 2.2.6
|
||||
If LastVersion = 236 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用联机模块的 Bug"))
|
||||
FeatureCount += 1
|
||||
BugCount += 2
|
||||
End If
|
||||
If LastVersion < 236 Then 'Release 2.2.5
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "网络状态检测支持检测 Windows 防火墙与网络延迟"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重制右侧页面的切换动画,卡片与提示条将逐个进入退出,并具有独特的位移动画"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 MC 1.18 中要求 Java 17 的检测与提醒"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化页面切换、下载的性能"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "允许拖拽按钮设置第三方登录"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "修复无法下载新版本的 Forge 的 Bug"))
|
||||
FeatureCount += 25
|
||||
BugCount += 22
|
||||
End If
|
||||
If LastVersion < 233 Then 'Release 2.2.3
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "微软账号支持更换皮肤与披风"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持拖拽整合包文件到 PCL 进行快捷安装"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 下载支持显示对应的 MC 版本与 Mod 加载器,且可以跳转到 MCBBS 介绍页"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持安装 1.17 OptiFine + Forge"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "使用 Mojang 账号登录将会显示迁移提醒"))
|
||||
FeatureCount += 12
|
||||
BugCount += 26
|
||||
End If
|
||||
If LastVersion < 231 Then 'Release 2.2.1, Also 229
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "添加 1.18 实验性快照 5 的特供下载,且支持列表的联网更新"))
|
||||
FeatureCount += 11
|
||||
BugCount += 3
|
||||
End If
|
||||
#Else
|
||||
'5: FEAT+
|
||||
'4: IMP+ FEAT*
|
||||
'3:BUG+ IMP* FEAT-
|
||||
'2:BUG* IMP-
|
||||
'1:BUG-
|
||||
If LastVersion < 287 Then 'Snapshot 2.5.3
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "在缺少 Java 时会自动下载所需的 Java"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条"))
|
||||
FeatureCount += 8
|
||||
BugCount += 8
|
||||
End If
|
||||
If LastVersion < 285 Then 'Snapshot 2.5.2
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "重做资源下载的资源项界面"))
|
||||
If LastVersion = 284 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复打开部分帮助报错的 Bug"))
|
||||
@@ -260,70 +227,6 @@ Public Class FormMain
|
||||
FeatureCount += 2
|
||||
BugCount += 16
|
||||
End If
|
||||
If LastVersion < 249 Then 'Snapshot 2.2.10
|
||||
If LastVersion = 247 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法使用中文搜索 Mod 的 Bug"))
|
||||
FeatureCount += 6
|
||||
BugCount += 17
|
||||
End If
|
||||
If LastVersion < 247 Then 'Snapshot 2.2.9
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 下载支持筛选 Forge Mod 与 Fabric Mod"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod、整合包下载的综合优化"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复使用离线登录进入 Forge 的存档可能导致游戏崩溃"))
|
||||
FeatureCount += 8
|
||||
BugCount += 4
|
||||
End If
|
||||
If LastVersion < 245 Then 'Snapshot 2.2.8
|
||||
FeatureCount += 5
|
||||
BugCount += 7
|
||||
End If
|
||||
If LastVersion < 243 Then 'Snapshot 2.2.7
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复 MC 所包含的一个严重安全漏洞"))
|
||||
If LastVersion >= 236 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复可能无法更改登录信息的 Bug"))
|
||||
End If
|
||||
If LastVersion < 239 Then 'Snapshot 2.2.6
|
||||
If LastVersion >= 235 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复自动更新由于路径错误失败的 Bug"))
|
||||
If LastVersion = 237 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "修复无法使用联机模块的 Bug"))
|
||||
FeatureCount += 1
|
||||
BugCount += 1
|
||||
End If
|
||||
If LastVersion < 237 Then 'Snapshot 2.2.5
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "允许拖拽按钮设置第三方登录"))
|
||||
If LastVersion = 235 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复在启动游戏时有可能卡死的 Bug"))
|
||||
FeatureCount += 2
|
||||
BugCount += 3
|
||||
End If
|
||||
If LastVersion < 235 Then 'Snapshot 2.2.4
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "网络状态检测支持检测 Windows 防火墙与网络延迟"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重制右侧页面的切换动画,卡片与提示条将逐个进入退出,并具有独特的位移动画"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 MC 1.18 中要求 Java 17 的检测与提醒"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "优化页面切换、下载的性能"))
|
||||
FeatureCount += 23
|
||||
BugCount += 19
|
||||
End If
|
||||
If LastVersion < 234 Then 'Snapshot 2.2.3
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持拖拽整合包文件到 PCL 进行快捷安装"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持安装 1.17 OptiFine + Forge"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod 详情页面支持跳转 MCBBS 介绍页"))
|
||||
FeatureCount += 10
|
||||
BugCount += 17
|
||||
End If
|
||||
If LastVersion < 232 Then 'Snapshot 2.2.2
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "微软账号支持更换皮肤与披风"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持显示 Mod 与整合包对应的 MC 版本与 Mod 加载器名称"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "使用 Mojang 账号登录将会显示迁移提醒"))
|
||||
FeatureCount += 2
|
||||
BugCount += 9
|
||||
End If
|
||||
If LastVersion < 230 Then 'Snapshot 2.2.1, Also 228
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 1.18 实验性快照 5 的特供下载,且支持列表的联网更新"))
|
||||
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复 Win7 上 IOI 联机导致日志文件极大,占用硬盘空间的 Bug"))
|
||||
FeatureCount += 12
|
||||
BugCount += 4
|
||||
End If
|
||||
If LastVersion < 227 Then 'Snapshot 2.2.0
|
||||
FeatureCount += 2
|
||||
BugCount += 2
|
||||
End If
|
||||
#End If
|
||||
'整理更新日志文本
|
||||
Dim ContentList As New List(Of String)
|
||||
|
||||
@@ -11,10 +11,10 @@ Public Module ModBase
|
||||
#Region "声明"
|
||||
|
||||
'下列版本信息由更新器自动修改
|
||||
Public Const VersionBaseName As String = "2.5.2" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.5.2." & VersionBranchCode '标准格式的四段式版本号
|
||||
Public Const VersionBaseName As String = "2.5.3" '不含分支前缀的显示用版本名
|
||||
Public Const VersionStandardCode As String = "2.5.3." & VersionBranchCode '标准格式的四段式版本号
|
||||
#If BETA Then
|
||||
Public Const VersionCode As Integer = 286 'Release
|
||||
Public Const VersionCode As Integer = 287 'Release
|
||||
#Else
|
||||
Public Const VersionCode As Integer = 285 'Snapshot
|
||||
#End If
|
||||
@@ -1360,6 +1360,8 @@ Re:
|
||||
CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
||||
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
||||
CommonReason = "你的电脑运行内存不足,导致 PCL 无法继续运行。请在关闭一部分不需要的程序后再试。"
|
||||
ElseIf TypeOf InnerEx Is Runtime.InteropServices.COMException Then
|
||||
CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
|
||||
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
|
||||
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
|
||||
CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
|
||||
@@ -1406,6 +1408,8 @@ Re:
|
||||
CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。"
|
||||
ElseIf TypeOf InnerEx Is OutOfMemoryException Then
|
||||
CommonReason = "你的电脑运行内存不足,导致 PCL 无法继续运行。请在关闭一部分不需要的程序后再试。"
|
||||
ElseIf TypeOf InnerEx Is Runtime.InteropServices.COMException Then
|
||||
CommonReason = "由于操作系统或显卡存在问题,导致出现错误。请尝试重启 PCL。"
|
||||
ElseIf {"远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝",
|
||||
"操作已超时", "操作超时", "服务器超时", "连接超时"}.Any(Function(s) Desc.Contains(s)) Then
|
||||
CommonReason = "你的网络环境不佳,导致难以连接到服务器。请检查网络,多重试几次,或尝试使用 VPN。"
|
||||
|
||||
@@ -602,6 +602,7 @@ Restart:
|
||||
Else
|
||||
LoaderTaskbarProgress = LoaderTaskbarProgress * 0.9 + NewProgress * 0.1
|
||||
End If
|
||||
RunInUi(Sub() FrmMain.BtnExtraDownload.Progress = LoaderTaskbarProgress)
|
||||
'更新任务栏信息
|
||||
If LoaderTaskbar.Count = 0 OrElse LoaderTaskbarProgress = 1 Then
|
||||
NewState = Shell.TaskbarItemProgressState.None
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
Fabric = 4
|
||||
Quilt = 5
|
||||
End Enum
|
||||
<Flags> Public Enum CompSourceType
|
||||
CurseForge = 1
|
||||
Modrinth = 2
|
||||
Any = CurseForge Or Modrinth
|
||||
End Enum
|
||||
|
||||
#Region "CompDatabase | Mod 数据库"
|
||||
|
||||
@@ -383,7 +388,7 @@
|
||||
'获取版本描述
|
||||
Dim GameVersionDescription As String
|
||||
If GameVersions Is Nothing OrElse GameVersions.Count = 0 Then
|
||||
GameVersionDescription = ""
|
||||
GameVersionDescription = "未知"
|
||||
Else
|
||||
Dim SpaVersions As New List(Of String)
|
||||
For i = 0 To GameVersions.Count - 1
|
||||
@@ -414,20 +419,24 @@
|
||||
'实例化 UI
|
||||
Dim NewItem As New MyCompItem With {.Tag = Me}
|
||||
'标题
|
||||
Dim FinalName As String = TranslatedName.Split(" | ").First.Split(" - ").First.Split(" (").First.Split(" [").First
|
||||
Dim FinalName As String = TranslatedName.Split(" | ").First.Split(" - ").First.Split("(").First.Split("[").First
|
||||
Dim ExNameList As List(Of String) = TranslatedName.Split({" | ", " - ", "(", ")", "[", "]", "{", "}"}, StringSplitOptions.RemoveEmptyEntries).
|
||||
Select(Function(s) s.Trim(" /".ToCharArray)).Where(Function(w) Not String.IsNullOrEmpty(w)).ToList
|
||||
ExNameList.RemoveAt(0)
|
||||
If TranslatedName = RawName AndAlso '没有中文翻译
|
||||
Not ExNameList.Any(Function(s) s.Contains("orge") OrElse s.Contains("abric") OrElse s.Contains("uilt")) AndAlso '不是标注 XX 版
|
||||
Not (ExNameList.Count = 1 AndAlso ExNameList.First.ToUpper <> ExNameList.First) Then '不是缩写
|
||||
FinalName = RawName '使用原名
|
||||
ExNameList.Clear()
|
||||
End If
|
||||
NewItem.LabTitle.Text = FinalName
|
||||
Dim ExNameList As New List(Of String)
|
||||
If TranslatedName.Contains(" (") Then ExNameList.Add(TranslatedName.Split(" (").Last.Split(")").First)
|
||||
If TranslatedName.Contains(" [") Then ExNameList.Add(TranslatedName.Split(" [").Last.Split("]").First)
|
||||
If TranslatedName.Contains(" - ") Then ExNameList.Add(TranslatedName.Split(" - ").Last.Split(" | ").First.Split(" (").First.Split(" [").First)
|
||||
If TranslatedName.Contains(" | ") Then ExNameList.Add(TranslatedName.Split(" | ").Last.Split(" - ").First.Split(" (").First.Split(" [").First)
|
||||
If ExNameList.Count = 0 Then
|
||||
NoExName:
|
||||
CType(NewItem.LabTitleRaw.Parent, StackPanel).Children.Remove(NewItem.LabTitleRaw)
|
||||
Else
|
||||
Dim ExName As String = ""
|
||||
For Each Ex In ExNameList
|
||||
'去除 “Forge/Fabric” 一类的无意义提示
|
||||
'去除 “Forge/Fabric” 这一无意义提示
|
||||
If Ex.Length < 19 AndAlso Ex.ToLower.Contains("fabric") AndAlso Ex.ToLower.Contains("forge") Then Continue For
|
||||
'将 “Forge” 等提示改为 “Forge 版”
|
||||
If (Ex.ToLower.Contains("forge") OrElse Ex.ToLower.Contains("fabric") OrElse Ex.ToLower.Contains("quilt")) AndAlso
|
||||
@@ -452,7 +461,9 @@ NoExName:
|
||||
'全部隐藏
|
||||
CType(NewItem.PathVersion.Parent, Grid).Children.Remove(NewItem.PathVersion)
|
||||
CType(NewItem.LabVersion.Parent, Grid).Children.Remove(NewItem.LabVersion)
|
||||
NewItem.ColumnVersionMargin.Width = New GridLength(0)
|
||||
NewItem.ColumnVersion1.Width = New GridLength(0)
|
||||
NewItem.ColumnVersion2.MaxWidth = 0
|
||||
NewItem.ColumnVersion3.Width = New GridLength(0)
|
||||
ElseIf ShowMcVersionDesc AndAlso ShowMcVersionDesc Then
|
||||
'全部显示
|
||||
Dim ModLoaderDesc As String = If(ModLoaders.Count > 0 AndAlso ModLoaders.Count < 3 AndAlso
|
||||
@@ -491,6 +502,11 @@ NoExName:
|
||||
NewItem.LabSource.Text = If(FromCurseForge, "CurseForge", "Modrinth")
|
||||
If LastUpdate IsNot Nothing Then
|
||||
NewItem.LabTime.Text = GetTimeSpanString(LastUpdate - Date.Now, True)
|
||||
Else
|
||||
NewItem.LabTime.Visibility = Visibility.Collapsed
|
||||
NewItem.ColumnTime1.Width = New GridLength(0)
|
||||
NewItem.ColumnTime2.Width = New GridLength(0)
|
||||
NewItem.ColumnTime3.Width = New GridLength(0)
|
||||
End If
|
||||
NewItem.LabDownload.Text =
|
||||
If(DownloadCount > 100000000, Math.Round(DownloadCount / 100000000, 2) & " 亿",
|
||||
@@ -610,6 +626,10 @@ NoExName:
|
||||
''' </summary>
|
||||
Public SearchText As String = Nothing
|
||||
''' <summary>
|
||||
''' 允许的来源。
|
||||
''' </summary>
|
||||
Public Source As CompSourceType = CompSourceType.Any
|
||||
''' <summary>
|
||||
''' 构造函数。
|
||||
''' </summary>
|
||||
Public Sub New(Type As CompType, Storage As CompProjectStorage, TargetResultCount As Integer)
|
||||
@@ -624,6 +644,7 @@ NoExName:
|
||||
''' 获取对应的 CurseForge API 请求链接。若返回 Nothing 则为不进行 CurseForge 请求。
|
||||
''' </summary>
|
||||
Public Function GetCurseForgeAddress() As String
|
||||
If Not Source.HasFlag(CompSourceType.CurseForge) Then Return Nothing
|
||||
If Tag.StartsWith("/") Then Storage.CurseForgeTotal = 0
|
||||
If Storage.CurseForgeTotal > -1 AndAlso Storage.CurseForgeTotal <= Storage.CurseForgeOffset Then Return Nothing
|
||||
'应用筛选参数
|
||||
@@ -647,6 +668,7 @@ NoExName:
|
||||
''' 获取对应的 Modrinth API 请求链接。若返回 Nothing 则为不进行 Modrinth 请求。
|
||||
''' </summary>
|
||||
Public Function GetModrinthAddress() As String
|
||||
If Not Source.HasFlag(CompSourceType.Modrinth) Then Return Nothing
|
||||
If Tag.EndsWith("/") Then Storage.ModrinthTotal = 0
|
||||
If Storage.ModrinthTotal > -1 AndAlso Storage.ModrinthTotal <= Storage.ModrinthOffset Then Return Nothing
|
||||
'应用筛选参数
|
||||
@@ -668,7 +690,7 @@ NoExName:
|
||||
Dim request = TryCast(obj, CompProjectRequest)
|
||||
Return request IsNot Nothing AndAlso
|
||||
Type = request.Type AndAlso TargetResultCount = request.TargetResultCount AndAlso
|
||||
Tag = request.Tag AndAlso ModLoader = request.ModLoader AndAlso
|
||||
Tag = request.Tag AndAlso ModLoader = request.ModLoader AndAlso Source = request.Source AndAlso
|
||||
GameVersion = request.GameVersion AndAlso SearchText = request.SearchText
|
||||
End Function
|
||||
Public Shared Operator =(left As CompProjectRequest, right As CompProjectRequest) As Boolean
|
||||
@@ -888,6 +910,10 @@ Retry:
|
||||
Else
|
||||
If IsChineseSearch AndAlso Task.Input.Type <> CompType.Mod Then
|
||||
Throw New Exception($"{If(Task.Input.Type = CompType.ModPack, "整合包", "资源包")}搜索仅支持英文")
|
||||
ElseIf Task.Input.Source = CompSourceType.CurseForge AndAlso Task.Input.Tag.StartsWith("/") Then
|
||||
Throw New Exception("CurseForge 不兼容所选的类型")
|
||||
ElseIf Task.Input.Source = CompSourceType.Modrinth AndAlso Task.Input.Tag.EndsWith("/") Then
|
||||
Throw New Exception("Modrinth 不兼容所选的类型")
|
||||
Else
|
||||
Throw New Exception("没有符合条件的结果")
|
||||
End If
|
||||
@@ -1127,7 +1153,7 @@ Retry:
|
||||
'可能为空
|
||||
If CType(Data("files"), JArray).Count > 0 Then
|
||||
FileName = Data("files")(0)("filename")
|
||||
DownloadAddress = {Data("files")(0)("url").ToString.Replace(FileName, Net.WebUtility.UrlEncode(FileName))}
|
||||
DownloadAddress = {Data("files")(0)("url").ToString.Replace(FileName, FileName)}
|
||||
End If
|
||||
'Dependencies
|
||||
If Type = CompType.Mod Then
|
||||
@@ -1311,7 +1337,7 @@ Retry:
|
||||
Stack.Children.Add(New TextBlock With {.Text = "前置 Mod", .FontSize = 14, .HorizontalAlignment = HorizontalAlignment.Left, .Margin = New Thickness(6, 2, 0, 5)})
|
||||
'添加前置 Mod 列表
|
||||
For Each Dep In Deps
|
||||
Dim Item = CompProjectCache(Dep).ToCompItem(True, True, AddressOf FrmDownloadMod.ProjectClick)
|
||||
Dim Item = CompProjectCache(Dep).ToCompItem(False, False, AddressOf FrmDownloadMod.ProjectClick)
|
||||
Stack.Children.Add(Item)
|
||||
Next
|
||||
'添加结尾间隔
|
||||
|
||||
@@ -330,6 +330,7 @@
|
||||
使用OpenJ9
|
||||
Java版本过高
|
||||
Java版本不兼容
|
||||
Mod名称包含特殊字符
|
||||
显卡驱动不支持导致无法设置像素格式
|
||||
极短的程序输出
|
||||
Intel驱动不兼容导致EXCEPTION_ACCESS_VIOLATION 'https://bugs.mojang.com/browse/MC-32606
|
||||
@@ -482,6 +483,7 @@ Done:
|
||||
If LogMc.Contains("Maybe try a lower resolution resourcepack?") Then AppendReason(CrashReason.材质过大或显卡配置不足)
|
||||
If LogMc.Contains("java.lang.NoSuchMethodError: net.minecraft.world.server.ChunkManager$ProxyTicketManager.shouldForceTicks(J)Z") AndAlso LogMc.Contains("OptiFine") Then AppendReason(CrashReason.OptiFine导致无法加载世界)
|
||||
If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本不兼容)
|
||||
If LogMc.Contains("Invalid module name: '' is not a Java identifier") Then AppendReason(CrashReason.Mod名称包含特殊字符)
|
||||
If LogMc.Contains("java.lang.UnsupportedClassVersionError: net/fabricmc/loader/impl/launch/knot/KnotClient : Unsupported major.minor version") Then AppendReason(CrashReason.Java版本不兼容)
|
||||
If LogMc.Contains("Could not reserve enough space") Then
|
||||
If LogMc.Contains("for 1048576KB object heap") Then
|
||||
@@ -799,6 +801,8 @@ NextStack:
|
||||
Results.Add("游戏似乎因为你所使用的 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用较低版本的 Java,然后再启动游戏。\n如果没有,可以从网络中下载、安装一个。")
|
||||
Case CrashReason.Java版本不兼容
|
||||
Results.Add("游戏不兼容你当前使用的 Java。\n如果没有合适的 Java,可以从网络中下载、安装一个。")
|
||||
Case CrashReason.Mod名称包含特殊字符
|
||||
Results.Add("由于有 Mod 的名称包含特殊字符,导致游戏崩溃。\n请尝试修改 Mod 文件名,让它只包含英文字母、数字、减号(-)、下划线(_)和小数点,然后再启动游戏。")
|
||||
Case CrashReason.使用32位Java导致JVM无法分配足够多的内存
|
||||
If Environment.Is64BitOperatingSystem Then
|
||||
Results.Add("你似乎正在使用 32 位 Java,这会导致 Minecraft 无法使用 1GB 以上的内存,进而造成崩溃。\n\n请在启动设置的 Java 选择一项中改用 64 位的 Java 再启动游戏,然后再启动游戏。\n如果你没有安装 64 位的 Java,你可以从网络中下载、安装一个。")
|
||||
|
||||
@@ -0,0 +1,747 @@
|
||||
Public Module ModJava
|
||||
Public JavaListCacheVersion As Integer = 4
|
||||
|
||||
''' <summary>
|
||||
''' 目前所有可用的 Java。
|
||||
''' </summary>
|
||||
Public JavaList As New List(Of JavaEntry)
|
||||
|
||||
Public Class JavaEntry
|
||||
|
||||
'路径
|
||||
''' <summary>
|
||||
''' Java.exe 文件的完整路径。
|
||||
''' </summary>
|
||||
Public ReadOnly Property PathJava As String
|
||||
Get
|
||||
Return PathFolder & "java.exe"
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' Javaw.exe 文件的完整路径。
|
||||
''' </summary>
|
||||
Public ReadOnly Property PathJavaw As String
|
||||
Get
|
||||
Return PathFolder & "javaw.exe"
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' Javaw.exe 文件所在文件夹的路径,以 \ 结尾。
|
||||
''' </summary>
|
||||
Public PathFolder As String
|
||||
''' <summary>
|
||||
''' 是否为用户手动导入的 Java。
|
||||
''' </summary>
|
||||
Public IsUserImport As Boolean
|
||||
|
||||
'版本信息
|
||||
''' <summary>
|
||||
''' Java 的详细版本。若不足 4 位会在前方补 1,例如 1.16.0.1。
|
||||
''' 其大版本号为 Minor。
|
||||
''' </summary>
|
||||
Public Version As Version
|
||||
''' <summary>
|
||||
''' Java 的大版本号。
|
||||
''' </summary>
|
||||
Public ReadOnly Property VersionCode As Integer
|
||||
Get
|
||||
Return Version.Minor
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' 是否为 Java Runtime Environment。
|
||||
''' </summary>
|
||||
Public IsJre As Boolean
|
||||
''' <summary>
|
||||
''' 是否为 64 位 Java。
|
||||
''' </summary>
|
||||
Public Is64Bit As Boolean
|
||||
''' <summary>
|
||||
''' 是否已设置环境变量。
|
||||
''' </summary>
|
||||
Public ReadOnly Property HasEnvironment As Boolean
|
||||
Get
|
||||
If PathFolder Is Nothing OrElse PathEnv Is Nothing Then Return False
|
||||
Return PathEnv.Replace("\", "").Replace("/", "").ToLower.Contains(PathFolder.Replace("\", "").ToLower)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'序列化
|
||||
Public Function ToJson() As JObject
|
||||
Return New JObject({New JProperty("Path", PathFolder), New JProperty("VersionString", Version.ToString), New JProperty("IsJre", IsJre), New JProperty("Is64Bit", Is64Bit), New JProperty("IsUserImport", IsUserImport)})
|
||||
End Function
|
||||
Public Shared Function FromJson(Data As JObject) As JavaEntry
|
||||
Return New JavaEntry(Data("Path"), Data("IsUserImport")) With {.Version = New Version(Data("VersionString")), .IsJre = Data("IsJre"), .Is64Bit = Data("Is64Bit")}
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 转化为用户友好的字符串输出。
|
||||
''' </summary>
|
||||
Public Overrides Function ToString() As String
|
||||
Dim VersionString = Version.ToString
|
||||
If VersionString.StartsWith("1.") Then VersionString = Mid(VersionString, 3)
|
||||
Return If(IsJre, "JRE ", "JDK ") & VersionCode & " (" & VersionString & ")," & If(Is64Bit, "64", "32") & " 位" & If(IsUserImport, ",手动导入", "") & ":" & PathFolder
|
||||
End Function
|
||||
|
||||
'构造
|
||||
''' <summary>
|
||||
''' 输入 javaw.exe 文件所在文件夹的路径,不限制结尾。
|
||||
''' </summary>
|
||||
Public Sub New(Folder As String, IsUserImport As Boolean)
|
||||
If Not Folder.EndsWith("\") Then Folder += "\"
|
||||
PathFolder = Folder.Replace("/", "\")
|
||||
Me.IsUserImport = IsUserImport
|
||||
End Sub
|
||||
|
||||
'方法
|
||||
Private IsChecked As Boolean = False
|
||||
''' <summary>
|
||||
''' 检查并获取 Java 详细信息。在 Java 存在异常时抛出错误。
|
||||
''' </summary>
|
||||
Public Sub Check()
|
||||
If IsChecked Then Exit Sub
|
||||
Dim Output As String = Nothing
|
||||
Try
|
||||
'确定文件存在
|
||||
If Not File.Exists(PathJavaw) Then
|
||||
Throw New FileNotFoundException("未找到 javaw.exe 文件", PathJavaw)
|
||||
End If
|
||||
If Not File.Exists(PathFolder & "java.exe") Then
|
||||
Throw New FileNotFoundException("未找到 java.exe 文件", PathFolder & "java.exe")
|
||||
End If
|
||||
IsJre = Not File.Exists(PathFolder & "javac.exe")
|
||||
'运行 -version
|
||||
Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 15000).ToLower
|
||||
If Output = "" Then Throw New Exception("尝试运行该 Java 失败")
|
||||
If ModeDebug Then Log("[Java] Java 检查输出:" & PathFolder & "java.exe" & vbCrLf & Output)
|
||||
'获取详细信息
|
||||
Dim VersionString = If(RegexSeek(Output, "(?<=version "")[^""]+"), If(RegexSeek(Output, "(?<=openjdk )[0-9]+"), "")).Replace("_", ".").Split("-").First
|
||||
Do While VersionString.Split(".").Count < 4
|
||||
If VersionString.StartsWith("1.") Then
|
||||
VersionString = VersionString & ".0"
|
||||
Else
|
||||
VersionString = "1." & VersionString
|
||||
End If
|
||||
Loop
|
||||
Version = New Version(VersionString)
|
||||
If Version.Minor = 0 Then
|
||||
Log("[Java] 疑似 X.0.X.X 格式版本号:" & Version.ToString)
|
||||
Version = New Version(1, Version.Major, Version.Build, Version.Revision)
|
||||
End If
|
||||
Is64Bit = Output.Contains("64-bit")
|
||||
If Version.Minor <= 4 OrElse Version.Minor >= 25 Then Throw New Exception("分析详细信息失败,获取的版本为 " & Version.ToString)
|
||||
'无论如何不允许使用 JRE 16,它完全是炸的,安 OptiFine、Forge 和启动 MC 都会炸
|
||||
If IsJre AndAlso VersionCode = 16 Then Throw New Exception("由于 JRE 16 对 Minecraft 的兼容性很差,因此不再允许使用")
|
||||
Catch ex As Exception
|
||||
Log("[Java] 检查失败的 Java 输出:" & PathFolder & "java.exe" & vbCrLf & If(Output, "无程序输出"))
|
||||
Throw New Exception("检查 Java 失败(" & If(PathJavaw, "Nothing") & ")", ex)
|
||||
End Try
|
||||
IsChecked = True
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
''' <summary>
|
||||
''' Path 环境变量。
|
||||
''' </summary>
|
||||
Private ReadOnly Property PathEnv As String
|
||||
Get
|
||||
If _PathEnv Is Nothing Then _PathEnv = If(Environment.GetEnvironmentVariable("Path"), "")
|
||||
Return _PathEnv
|
||||
End Get
|
||||
End Property
|
||||
Private _PathEnv As String = Nothing
|
||||
|
||||
''' <summary>
|
||||
''' JAVA_HOME 环境变量。
|
||||
''' </summary>
|
||||
Private ReadOnly Property PathJavaHome As String
|
||||
Get
|
||||
If _PathJavaHome Is Nothing Then _PathJavaHome = If(Environment.GetEnvironmentVariable("JAVA_HOME"), "")
|
||||
Return _PathJavaHome
|
||||
End Get
|
||||
End Property
|
||||
Private _PathJavaHome As String = Nothing
|
||||
|
||||
''' <summary>
|
||||
''' 初始化 Java 列表,但除非没有 Java,否则不进行检查。
|
||||
''' </summary>
|
||||
Public Sub JavaListInit()
|
||||
JavaList = New List(Of JavaEntry)
|
||||
Try
|
||||
If Setup.Get("CacheJavaListVersion") < JavaListCacheVersion Then
|
||||
'不使用缓存
|
||||
Log("[Java] 要求 Java 列表缓存更新")
|
||||
Setup.Set("CacheJavaListVersion", JavaListCacheVersion)
|
||||
Else
|
||||
'使用缓存
|
||||
For Each JsonEntry In GetJson(Setup.Get("LaunchArgumentJavaAll"))
|
||||
JavaList.Add(JavaEntry.FromJson(JsonEntry))
|
||||
Next
|
||||
End If
|
||||
If JavaList.Count = 0 Then
|
||||
Log("[Java] 初始化未找到可用的 Java,将自动触发搜索", LogLevel.Developer)
|
||||
JavaSearchLoader.Start(0)
|
||||
Else
|
||||
Log("[Java] 缓存中有 " & JavaList.Count & " 个可用的 Java")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log(ex, "初始化 Java 列表失败", LogLevel.Feedback)
|
||||
Setup.Set("LaunchArgumentJavaAll", "[]")
|
||||
End Try
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 根据要求返回最适合的 Java,若找不到则返回 Nothing。
|
||||
''' 最小与最大版本在与输入相同时也会通过。
|
||||
''' 必须在工作线程调用。
|
||||
''' </summary>
|
||||
Public Function JavaSelect(CancelException As String, Optional MinVersion As Version = Nothing, Optional MaxVersion As Version = Nothing,
|
||||
Optional RelatedVersion As McVersion = Nothing) As JavaEntry
|
||||
Try
|
||||
Dim AllowedJavaList As New List(Of JavaEntry)
|
||||
|
||||
'添加特定的 Java
|
||||
Dim JavaPreList As New Dictionary(Of String, Boolean)
|
||||
If PathMcFolder.Split("\").Count > 3 Then JavaSearchFolder(GetPathFromFullPath(PathMcFolder), JavaPreList, False, True) 'Minecraft 文件夹的父文件夹(如果不是根目录的话)
|
||||
JavaSearchFolder(PathMcFolder, JavaPreList, False, True) 'Minecraft 文件夹
|
||||
If RelatedVersion IsNot Nothing Then JavaSearchFolder(RelatedVersion.Path, JavaPreList, False, True) '所选版本文件夹
|
||||
Dim TargetJavaList As New List(Of JavaEntry)
|
||||
For Each Entry In JavaPreList
|
||||
TargetJavaList.Add(New JavaEntry(Entry.Key, Entry.Value))
|
||||
Next
|
||||
|
||||
#Region "添加用户指定的 Java,储存到 UserJava 中"
|
||||
|
||||
Dim UserJava As JavaEntry = Nothing
|
||||
|
||||
'获取版本独立设置中指定的 Java
|
||||
If RelatedVersion IsNot Nothing AndAlso Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion).ToString.StartsWith("{") Then
|
||||
Try
|
||||
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)))
|
||||
'确保版本独立设置中指定的 Java 在 Java 列表中(#978)
|
||||
If Not JavaList.Any(Function(j) j.PathFolder = UserJava.PathFolder) Then
|
||||
UserJava = Nothing
|
||||
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
|
||||
Log("版本独立设置中指定的 Java 不在主 Java 列表中,此设置已重置", LogLevel.Debug)
|
||||
Exit Try
|
||||
End If
|
||||
Catch ex As Exception
|
||||
UserJava = Nothing
|
||||
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
|
||||
Log(ex, "版本独立设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
|
||||
End Try
|
||||
End If
|
||||
|
||||
'获取全局设置中指定的 Java
|
||||
If UserJava Is Nothing AndAlso Setup.Get("LaunchArgumentJavaSelect") <> "" Then
|
||||
Try
|
||||
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("LaunchArgumentJavaSelect")))
|
||||
Catch ex As Exception
|
||||
UserJava = Nothing
|
||||
Setup.Reset("LaunchArgumentJavaSelect")
|
||||
Log(ex, "设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
|
||||
End Try
|
||||
End If
|
||||
|
||||
'添加到特定 Java 列表
|
||||
If UserJava IsNot Nothing Then
|
||||
Log($"[Java] 用户指定的 Java:{UserJava}")
|
||||
TargetJavaList.Add(UserJava)
|
||||
End If
|
||||
|
||||
#End Region
|
||||
|
||||
'检查特定的 Java
|
||||
If TargetJavaList.Count > 0 Then
|
||||
TargetJavaList = JavaCheckList(TargetJavaList)
|
||||
Log("[Java] 检查后找到 " & TargetJavaList.Count & " 个特定的 Java")
|
||||
End If
|
||||
|
||||
RetryGet:
|
||||
'等待进行中的搜索结束
|
||||
If JavaSearchLoader.State <> LoadState.Finished AndAlso JavaSearchLoader.State <> LoadState.Waiting Then JavaSearchLoader.WaitForExit()
|
||||
Select Case JavaSearchLoader.State
|
||||
Case LoadState.Failed
|
||||
Throw JavaSearchLoader.Error
|
||||
Case LoadState.Aborted
|
||||
Throw New ThreadInterruptedException("Java 搜索加载器已中断")
|
||||
End Select
|
||||
|
||||
'生成完整的 Java 列表
|
||||
Dim AllJavaList As New List(Of JavaEntry)
|
||||
AllJavaList.AddRange(TargetJavaList)
|
||||
AllJavaList.AddRange(JavaList)
|
||||
|
||||
'根据选定条件进行过滤
|
||||
For Each Java In AllJavaList
|
||||
If MinVersion IsNot Nothing AndAlso Java.Version < MinVersion Then Continue For
|
||||
If MaxVersion IsNot Nothing AndAlso Java.Version > MaxVersion Then Continue For
|
||||
If Java.Is64Bit AndAlso Is32BitSystem Then Continue For
|
||||
AllowedJavaList.Add(Java)
|
||||
Next
|
||||
|
||||
'若未找到适合的 Java,尝试触发搜索
|
||||
If AllowedJavaList.Count = 0 AndAlso JavaSearchLoader.State = LoadState.Waiting Then
|
||||
Log("[Java] 未找到满足条件的 Java,尝试进行搜索")
|
||||
JavaSearchLoader.Start(IsForceRestart:=True)
|
||||
GoTo RetryGet
|
||||
End If
|
||||
|
||||
#Region "检查用户指定的 Java 是否可用"
|
||||
|
||||
'确保指定的 Java 可用
|
||||
If UserJava Is Nothing Then GoTo ExitUserJavaCheck
|
||||
If AllowedJavaList.Any(Function(j) j.PathFolder = UserJava.PathFolder) Then
|
||||
Log("[Java] 使用用户指定的 Java:" & UserJava.PathFolder)
|
||||
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
|
||||
GoTo UserPass
|
||||
End If
|
||||
|
||||
'指定的 Java 不可用,弹窗要求选择
|
||||
Log("[Java] 发现用户指定的不兼容 Java:" & UserJava.ToString)
|
||||
For Each Java In AllowedJavaList
|
||||
Log($"[Java] 实际可用的 Java:{Java.ToString}")
|
||||
Next
|
||||
Dim Requirement As String = ""
|
||||
Dim ShowRevision As Boolean = False
|
||||
If (MinVersion Is Nothing OrElse MinVersion.Minor = 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 999) Then
|
||||
ShowRevision = MaxVersion.MinorRevision < 999
|
||||
Requirement = "最高兼容到 Java " & MaxVersion.Minor & If(ShowRevision, "." & MaxVersion.MajorRevision & "." & MaxVersion.MinorRevision, "")
|
||||
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion Is Nothing OrElse MaxVersion.Minor >= 999) Then
|
||||
ShowRevision = MinVersion.MinorRevision > 0 OrElse MinVersion.MajorRevision > 0
|
||||
Requirement = "至少需要 Java " & MinVersion.Minor & If(ShowRevision, "." & MinVersion.MajorRevision & "." & MinVersion.MinorRevision, "")
|
||||
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 999) Then
|
||||
ShowRevision = MinVersion.MinorRevision > 0 OrElse MinVersion.MajorRevision > 0 OrElse MaxVersion.MinorRevision < 999
|
||||
Dim Left As String = MinVersion.Minor & If(ShowRevision, "." & MinVersion.MajorRevision & "." & MinVersion.MinorRevision, "")
|
||||
Dim Right As String = MaxVersion.Minor & If(ShowRevision, "." & MaxVersion.MajorRevision & "." & MaxVersion.MinorRevision, "")
|
||||
Requirement = "需要 Java " & If(Left = Right, Left, Left & " ~ " & Right)
|
||||
End If
|
||||
Dim JavaCurrent As String = UserJava.VersionCode & If(ShowRevision, "." & UserJava.Version.MajorRevision & "." & UserJava.Version.MinorRevision, "")
|
||||
If Setup.Get("LaunchAdvanceJava") Then
|
||||
'直接跳过弹窗
|
||||
Hint("设置中指定了使用 Java " & JavaCurrent & ",但当前版本" & Requirement & ",这可能会导致游戏崩溃!", HintType.Critical)
|
||||
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
|
||||
Else
|
||||
Select Case MyMsgBox("你在设置中手动指定了使用 Java " & JavaCurrent & ",但当前" & Requirement & "。" & vbCrLf &
|
||||
"如果强制使用该 Java,可能导致游戏崩溃。" & vbCrLf &
|
||||
"你也可以将 游戏 Java 设置修改为 自动选择合适的 Java。" & vbCrLf &
|
||||
vbCrLf &
|
||||
" - 指定的 Java:" & UserJava.ToString,
|
||||
"Java 兼容性警告", "让 PCL 自动选择", "强制使用该 Java", "取消")
|
||||
Case 1 '让 PCL 自动选择
|
||||
Case 2 '强制使用指定的 Java
|
||||
Log("[Java] 已强制使用用户指定的不兼容 Java")
|
||||
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
|
||||
Case 3 '取消启动
|
||||
Throw New Exception(CancelException)
|
||||
End Select
|
||||
End If
|
||||
|
||||
ExitUserJavaCheck:
|
||||
#End Region
|
||||
|
||||
'若依然未找到适合的 Java,直接返回
|
||||
If AllowedJavaList.Count = 0 Then Return Nothing
|
||||
|
||||
'优先使用特定目录下的 Java
|
||||
For Each Java In AllowedJavaList
|
||||
If TargetJavaList.Contains(Java) Then
|
||||
'直接使用指定的 Java
|
||||
AllowedJavaList = New List(Of JavaEntry) From {Java}
|
||||
Log("[Java] 优先使用特定的 Java:" & Java.ToString)
|
||||
GoTo UserPass
|
||||
End If
|
||||
Next
|
||||
UserPass:
|
||||
|
||||
'对适合的 Java 进行排序
|
||||
AllowedJavaList = Sort(AllowedJavaList, AddressOf JavaSorter)
|
||||
|
||||
'检查选定的 Java,若测试失败则尝试进行搜索
|
||||
Dim SelectedJava = AllowedJavaList.First
|
||||
Try
|
||||
SelectedJava.Check()
|
||||
Catch ex As ThreadInterruptedException
|
||||
Throw
|
||||
Catch ex As Exception
|
||||
Log(ex, "找到的 Java 已无法使用,尝试进行搜索")
|
||||
AllowedJavaList = New List(Of JavaEntry)
|
||||
JavaSearchLoader.Start(IsForceRestart:=True)
|
||||
GoTo RetryGet
|
||||
End Try
|
||||
|
||||
'返回
|
||||
Log("[Java] 选定的 Java:" & SelectedJava.ToString)
|
||||
Return SelectedJava
|
||||
|
||||
Catch ex As ThreadInterruptedException
|
||||
Log(ex, "查找符合条件的 Java 时出现加载器中断")
|
||||
Return Nothing
|
||||
Catch ex As Exception
|
||||
If ex.Message = "$$" Then Throw ex
|
||||
Log(ex, "查找符合条件的 Java 失败", LogLevel.Feedback)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 是否强制指定了 64 位 Java。如果没有强制指定,返回是否安装了 64 位 Java。
|
||||
''' </summary>
|
||||
Public Function JavaIs64Bit(Optional RelatedVersion As McVersion = Nothing) As Boolean
|
||||
Try
|
||||
'检查强制指定
|
||||
Dim UserSetup As String = Setup.Get("LaunchArgumentJavaSelect")
|
||||
If RelatedVersion IsNot Nothing Then
|
||||
Dim UserSetupVersion As String = Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)
|
||||
If UserSetupVersion <> "使用全局设置" Then UserSetup = UserSetupVersion
|
||||
End If
|
||||
If UserSetup <> "" Then
|
||||
Dim UserJava As JavaEntry = Nothing
|
||||
Try
|
||||
UserJava = JavaEntry.FromJson(GetJson(UserSetup))
|
||||
Catch ex As Exception
|
||||
Log(ex, "版本指定的 Java 信息已损坏,已重置版本设置中指定的 Java")
|
||||
Setup.Set("VersionArgumentJavaSelect", "使用全局设置", Version:=RelatedVersion)
|
||||
GoTo NoUserJava
|
||||
End Try
|
||||
For Each Java In JavaList
|
||||
If Java.PathFolder = UserJava.PathFolder Then Return UserJava.Is64Bit
|
||||
Next
|
||||
End If
|
||||
NoUserJava:
|
||||
'检查列表
|
||||
For Each Java In JavaList
|
||||
If Java.Is64Bit Then Return True
|
||||
Next
|
||||
Return False
|
||||
Catch ex As Exception
|
||||
Log(ex, "检查 Java 类别时出错", LogLevel.Feedback)
|
||||
Setup.Set("LaunchArgumentJavaSelect", "")
|
||||
Return True
|
||||
End Try
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 将 Java 按照适用性排序。
|
||||
''' </summary>
|
||||
Public Function JavaSorter(Left As JavaEntry, Right As JavaEntry) As Boolean
|
||||
'1. 尽量在当前文件夹或当前 Minecraft 文件夹
|
||||
Dim ProgramPathParent As String, MinecraftPathParent As String = ""
|
||||
ProgramPathParent = If(New DirectoryInfo(Path).Parent, New DirectoryInfo(Path)).FullName
|
||||
If PathMcFolder <> "" Then MinecraftPathParent = If(New DirectoryInfo(PathMcFolder).Parent, New DirectoryInfo(PathMcFolder)).FullName
|
||||
If Left.PathFolder.StartsWith(ProgramPathParent) AndAlso Not Right.PathFolder.StartsWith(ProgramPathParent) Then Return True
|
||||
If Not Left.PathFolder.StartsWith(ProgramPathParent) AndAlso Right.PathFolder.StartsWith(ProgramPathParent) Then Return False
|
||||
If PathMcFolder <> "" Then
|
||||
If Left.PathFolder.StartsWith(MinecraftPathParent) AndAlso Not Right.PathFolder.StartsWith(MinecraftPathParent) Then Return True
|
||||
If Not Left.PathFolder.StartsWith(MinecraftPathParent) AndAlso Right.PathFolder.StartsWith(MinecraftPathParent) Then Return False
|
||||
End If
|
||||
'2. 尽量使用 64 位
|
||||
If Left.Is64Bit AndAlso Not Right.Is64Bit Then Return True
|
||||
If Not Left.Is64Bit AndAlso Right.Is64Bit Then Return False
|
||||
'3. 尽量不使用 JDK
|
||||
If Left.IsJre AndAlso Not Right.IsJre Then Return True
|
||||
If Not Left.IsJre AndAlso Right.IsJre Then Return False
|
||||
'4. Java 大版本
|
||||
If Left.VersionCode <> Right.VersionCode Then
|
||||
' Java 7 8 9 10 11 12 13 14 15 16 17 18 19 20...
|
||||
Dim Weight = {0, 1, 2, 3, 4, 5, 6, 14, 29, 10, 11, 12, 13, 9, 8, 7, 15, 31, 30, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}
|
||||
Return Weight.ElementAtOrDefault(Left.VersionCode) >= Weight.ElementAtOrDefault(Right.VersionCode)
|
||||
End If
|
||||
'5. 最次级版本号更接近 51
|
||||
Return Math.Abs(Left.Version.Revision - 51) <= Math.Abs(Right.Version.Revision - 51)
|
||||
End Function
|
||||
|
||||
#Region "搜索"
|
||||
|
||||
''' <summary>
|
||||
''' 模糊搜索并获取所有可用的 Java,并在结束后更新设置页面显示。输出将直接写入 JavaList。
|
||||
''' </summary>
|
||||
Public JavaSearchLoader As New LoaderTask(Of Integer, Integer)("查找 Java", AddressOf JavaSearchLoaderSub) With {.ProgressWeight = 2}
|
||||
Private Sub JavaSearchLoaderSub(Loader As LoaderTask(Of Integer, Integer))
|
||||
If FrmSetupLaunch IsNot Nothing Then
|
||||
RunInUiWait(Sub()
|
||||
FrmSetupLaunch.ComboArgumentJava.Items.Clear()
|
||||
FrmSetupLaunch.ComboArgumentJava.Items.Add(New ComboBoxItem With {.Content = "加载中……", .IsSelected = True})
|
||||
End Sub)
|
||||
End If
|
||||
If FrmVersionSetup IsNot Nothing Then
|
||||
RunInUiWait(Sub()
|
||||
FrmVersionSetup.ComboArgumentJava.Items.Clear()
|
||||
FrmVersionSetup.ComboArgumentJava.Items.Add(New ComboBoxItem With {.Content = "加载中……", .IsSelected = True})
|
||||
End Sub)
|
||||
End If
|
||||
|
||||
Try
|
||||
|
||||
'可能包含 Java 的文件夹列表,以 “\” 结尾,且仅包含 “\”
|
||||
'Key:文件夹地址
|
||||
'Value: 是否为玩家手动导入
|
||||
Dim JavaPreList As New Dictionary(Of String, Boolean)
|
||||
|
||||
#Region "模糊查找可能可用的 Java"
|
||||
|
||||
'查找环境变量中的 Java
|
||||
For Each PathInEnv As String In Split((PathEnv & ";" & PathJavaHome).Replace("\\", "\").Replace("/", "\"), ";")
|
||||
PathInEnv = PathInEnv.Trim(" """.ToCharArray())
|
||||
If PathInEnv = "" Then Continue For
|
||||
If Not PathInEnv.EndsWith("\") Then PathInEnv += "\"
|
||||
'粗略检查有效性
|
||||
If File.Exists(PathInEnv & "javaw.exe") Then JavaPreList(PathInEnv) = False
|
||||
Next
|
||||
'查找磁盘中的 Java
|
||||
For Each Disk As DriveInfo In DriveInfo.GetDrives()
|
||||
JavaSearchFolder(Disk.Name, JavaPreList, False)
|
||||
Next
|
||||
'查找 APPDATA 文件夹中的 Java
|
||||
JavaSearchFolder(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\", JavaPreList, False)
|
||||
JavaSearchFolder(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) & "\", JavaPreList, False)
|
||||
'查找启动器目录中的 Java
|
||||
JavaSearchFolder(Path, JavaPreList, False, IsFullSearch:=True)
|
||||
'查找所选 Minecraft 文件夹中的 Java
|
||||
If Not String.IsNullOrWhiteSpace(PathMcFolder) AndAlso Path <> PathMcFolder Then
|
||||
JavaSearchFolder(PathMcFolder, JavaPreList, False, IsFullSearch:=True)
|
||||
End If
|
||||
|
||||
'若不全为符号链接,则清除符号链接的地址
|
||||
Dim JavaWithoutReparse As New Dictionary(Of String, Boolean)
|
||||
For Each Pair In JavaPreList
|
||||
Dim Folder As String = Pair.Key.Replace("\\", "\").Replace("/", "\")
|
||||
Dim Info As FileSystemInfo = New FileInfo(Folder & "javaw.exe")
|
||||
Do
|
||||
If Info.Attributes.HasFlag(FileAttributes.ReparsePoint) Then
|
||||
Log("[Java] 位于 " & Folder & " 的 Java 包含符号链接")
|
||||
Continue For
|
||||
End If
|
||||
Info = If(TypeOf Info Is FileInfo, CType(Info, FileInfo).Directory, CType(Info, DirectoryInfo).Parent)
|
||||
Loop While Info IsNot Nothing
|
||||
Log("[Java] 位于 " & Folder & " 的 Java 不含符号链接")
|
||||
JavaWithoutReparse.Add(Pair.Key, Pair.Value)
|
||||
Next
|
||||
If JavaWithoutReparse.Count > 0 Then JavaPreList = JavaWithoutReparse
|
||||
|
||||
'若不全为特殊引用,则清除特殊引用的地址
|
||||
Dim JavaWithoutInherit As New Dictionary(Of String, Boolean)
|
||||
For Each Pair In JavaPreList
|
||||
If Pair.Key.Contains("javapath_target_") OrElse Pair.Key.Contains("javatmp") Then
|
||||
Log("[Java] 位于 " & Pair.Key & " 的 Java 包含特殊引用")
|
||||
Continue For
|
||||
End If
|
||||
Log("[Java] 位于 " & Pair.Key & " 的 Java 不含特殊引用")
|
||||
JavaWithoutInherit.Add(Pair.Key, Pair.Value)
|
||||
Next
|
||||
If JavaWithoutInherit.Count > 0 Then JavaPreList = JavaWithoutInherit
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "添加玩家手动导入的 Java"
|
||||
|
||||
Dim ImportedJava As String = Setup.Get("LaunchArgumentJavaAll")
|
||||
Try
|
||||
For Each JavaJsonObject In GetJson(ImportedJava)
|
||||
Dim Entry = JavaEntry.FromJson(JavaJsonObject)
|
||||
If Entry.IsUserImport Then JavaPreList(Entry.PathFolder) = True
|
||||
Next
|
||||
Catch ex As Exception
|
||||
Log(ex, "Java 列表已损坏", LogLevel.Feedback)
|
||||
Setup.Set("LaunchArgumentJavaAll", "[]")
|
||||
End Try
|
||||
|
||||
#End Region
|
||||
|
||||
'确保可用并获取详细信息,转入正式列表
|
||||
Dim NewJavaList As New List(Of JavaEntry)
|
||||
For Each Entry In Distinct(JavaPreList.ToList, Function(a, b) a.Key.ToLower = b.Key.ToLower) '#794
|
||||
NewJavaList.Add(New JavaEntry(Entry.Key, Entry.Value))
|
||||
Next
|
||||
NewJavaList = Sort(JavaCheckList(NewJavaList), AddressOf JavaSorter)
|
||||
|
||||
'修改设置项
|
||||
Dim AllList As New JArray
|
||||
For Each Java In NewJavaList
|
||||
AllList.Add(Java.ToJson)
|
||||
Next
|
||||
Setup.Set("LaunchArgumentJavaAll", AllList.ToString(Newtonsoft.Json.Formatting.None))
|
||||
JavaList = NewJavaList
|
||||
|
||||
Catch ex As Exception
|
||||
Log(ex, "搜索 Java 时出错", LogLevel.Feedback)
|
||||
JavaList = New List(Of JavaEntry)
|
||||
End Try
|
||||
|
||||
Log("[Java] Java 搜索完成,发现 " & JavaList.Count & " 个 Java")
|
||||
If FrmSetupLaunch IsNot Nothing Then RunInUi(Sub() FrmSetupLaunch.RefreshJavaComboBox())
|
||||
If FrmVersionSetup IsNot Nothing Then RunInUi(Sub() FrmVersionSetup.RefreshJavaComboBox())
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 多线程检查列表中的所有 Java 项。
|
||||
''' </summary>
|
||||
Private Function JavaCheckList(JavaEntries As List(Of JavaEntry)) As List(Of JavaEntry)
|
||||
Log("[Java] 开始确认列表 Java 状态,共 " & JavaEntries.Count & " 项")
|
||||
JavaCheckList = New List(Of JavaEntry)
|
||||
Dim ListLock As New Object
|
||||
|
||||
'启动检查线程
|
||||
Dim CheckThreads As New List(Of Thread)
|
||||
For Each Entry In JavaEntries
|
||||
Dim CheckThread As New Thread(Sub()
|
||||
Try
|
||||
Entry.Check()
|
||||
Log("[Java] " & Entry.ToString)
|
||||
SyncLock ListLock
|
||||
JavaCheckList.Add(Entry)
|
||||
End SyncLock
|
||||
Catch ex As Exception
|
||||
If Entry.IsUserImport Then
|
||||
Log(ex, "位于 " & Entry.PathFolder & " 的 Java 存在异常,将被自动移除", LogLevel.Hint)
|
||||
Else
|
||||
Log(ex, "位于 " & Entry.PathFolder & " 的 Java 存在异常")
|
||||
End If
|
||||
End Try
|
||||
End Sub)
|
||||
CheckThreads.Add(CheckThread)
|
||||
CheckThread.Start()
|
||||
Next
|
||||
|
||||
'等待构造线程完成
|
||||
Wait:
|
||||
Thread.Sleep(10)
|
||||
For Each CheckThread In CheckThreads
|
||||
If CheckThread.IsAlive Then GoTo Wait
|
||||
Next
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 模糊搜索指定文件夹下的 Java,并只进行粗略的检查。这不会搜索全部路径。
|
||||
''' </summary>
|
||||
''' <param name="OriginalPath">开始搜索的起始路径,不限制结尾。</param>
|
||||
''' <param name="IsFullSearch">搜索当前文件夹下的全部文件夹(此参数不会传递到子文件夹)。</param>
|
||||
Private Sub JavaSearchFolder(OriginalPath As String, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
|
||||
Try
|
||||
Log("[Java] 开始" & If(IsFullSearch, "完全", "部分") & "遍历查找:" & OriginalPath)
|
||||
JavaSearchFolder(New DirectoryInfo(OriginalPath), Results, Source, IsFullSearch)
|
||||
Catch ex As UnauthorizedAccessException
|
||||
Log("[Java] 遍历查找 Java 时遭遇无权限的文件夹:" & OriginalPath)
|
||||
Catch ex As Exception
|
||||
Log(ex, "遍历查找 Java 时出错(" & OriginalPath & ")")
|
||||
End Try
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 模糊搜索指定文件夹下的 Java,并只进行粗略的检查。这不会搜索全部路径。
|
||||
''' </summary>
|
||||
''' <param name="OriginalPath">开始搜索的起始路径,不限制结尾。</param>
|
||||
''' <param name="IsFullSearch">搜索当前文件夹下的全部文件夹(此参数不会传递到子文件夹)。</param>
|
||||
Private Sub JavaSearchFolder(OriginalPath As DirectoryInfo, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
|
||||
Try
|
||||
'确认目录存在
|
||||
If Not OriginalPath.Exists Then Exit Sub
|
||||
Dim Path As String = OriginalPath.FullName.Replace("\\", "\")
|
||||
If Not Path.EndsWith("\") Then Path += "\"
|
||||
'若该目录有 Java,则加入结果
|
||||
If File.Exists(Path & "javaw.exe") Then Results(Path) = Source
|
||||
'查找其下的所有文件夹
|
||||
For Each FolderInfo As DirectoryInfo In OriginalPath.EnumerateDirectories
|
||||
If FolderInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) Then Continue For '跳过符号链接
|
||||
Dim SearchEntry = GetFolderNameFromPath(FolderInfo.Name).ToLower '用于搜索的字符串
|
||||
If IsFullSearch OrElse
|
||||
FolderInfo.Parent.Name.ToLower = "users" OrElse
|
||||
SearchEntry.Contains("java") OrElse SearchEntry.Contains("jdk") OrElse SearchEntry.Contains("env") OrElse
|
||||
SearchEntry.Contains("环境") OrElse SearchEntry.Contains("run") OrElse SearchEntry.Contains("软件") OrElse
|
||||
SearchEntry.Contains("jre") OrElse SearchEntry = "bin" OrElse SearchEntry.Contains("mc") OrElse
|
||||
SearchEntry.Contains("software") OrElse SearchEntry.Contains("cache") OrElse SearchEntry.Contains("temp") OrElse
|
||||
SearchEntry.Contains("corretto") OrElse SearchEntry.Contains("roaming") OrElse SearchEntry.Contains("users") OrElse
|
||||
SearchEntry.Contains("craft") OrElse SearchEntry.Contains("program") OrElse SearchEntry.Contains("世界") OrElse
|
||||
SearchEntry.Contains("net") OrElse SearchEntry.Contains("游戏") OrElse SearchEntry.Contains("oracle") OrElse
|
||||
SearchEntry.Contains("game") OrElse SearchEntry.Contains("file") OrElse SearchEntry.Contains("data") OrElse
|
||||
SearchEntry.Contains("jvm") OrElse SearchEntry.Contains("服务") OrElse SearchEntry.Contains("server") OrElse
|
||||
SearchEntry.Contains("客户") OrElse SearchEntry.Contains("client") OrElse SearchEntry.Contains("整合") OrElse
|
||||
SearchEntry.Contains("应用") OrElse SearchEntry.Contains("运行") OrElse SearchEntry.Contains("前置") OrElse
|
||||
SearchEntry.Contains("mojang") OrElse SearchEntry.Contains("官启") OrElse SearchEntry.Contains("新建文件夹") OrElse
|
||||
SearchEntry.Contains("eclipse") OrElse SearchEntry.Contains("microsoft") OrElse SearchEntry.Contains("hotspot") OrElse
|
||||
SearchEntry.Contains("runtime") OrElse SearchEntry.Contains("x86") OrElse SearchEntry.Contains("x64") OrElse
|
||||
SearchEntry.Contains("forge") OrElse SearchEntry.Contains("原版") OrElse SearchEntry.Contains("optifine") OrElse
|
||||
SearchEntry.Contains("官方") OrElse SearchEntry.Contains("启动") OrElse SearchEntry.Contains("hmcl") OrElse
|
||||
SearchEntry.Contains("mod") OrElse SearchEntry.Contains("高清") OrElse SearchEntry.Contains("download") OrElse
|
||||
SearchEntry.Contains("launch") OrElse SearchEntry.Contains("程序") OrElse SearchEntry.Contains("path") OrElse
|
||||
SearchEntry.Contains("version") OrElse SearchEntry.Contains("baka") OrElse SearchEntry.Contains("pcl") OrElse
|
||||
SearchEntry.Contains("local") OrElse SearchEntry.Contains("packages") OrElse SearchEntry.Contains("4297127D64EC6") OrElse '官启文件夹
|
||||
SearchEntry.Contains("国服") OrElse SearchEntry.Contains("网易") OrElse SearchEntry.Contains("ext") OrElse '网易 Java 文件夹名
|
||||
SearchEntry.Contains("netease") OrElse SearchEntry.Contains("1.") OrElse SearchEntry.Contains("启动") Then
|
||||
JavaSearchFolder(FolderInfo, Results, Source)
|
||||
End If
|
||||
Next
|
||||
Catch ex As UnauthorizedAccessException
|
||||
Log("[Java] 遍历查找 Java 时遭遇无权限的文件夹:" & OriginalPath.FullName)
|
||||
Catch ex As Exception
|
||||
Log(ex, "遍历查找 Java 时出错(" & OriginalPath.FullName & ")")
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "下载"
|
||||
|
||||
''' <summary>
|
||||
''' 提示 Java 缺失,并弹窗确认是否自动下载。返回玩家选择是否下载。
|
||||
''' 支持下载 Java 8、14、17,输入其他 VersionCode 会要求玩家自行下载。
|
||||
''' </summary>
|
||||
Public Function JavaDownloadConfirm(VersionCode As String) As Boolean
|
||||
If VersionCode = 8 OrElse VersionCode = 14 OrElse VersionCode = 17 Then
|
||||
Return MyMsgBox($"PCL 未找到 Java {VersionCode},是否需要 PCL 自动下载?" & vbCrLf &
|
||||
$"如果你已经安装了 Java {VersionCode},请在 设置 → 启动选项 → 游戏 Java 中手动导入。",
|
||||
"未找到 Java", "自动下载", "取消") = 1
|
||||
Else
|
||||
MyMsgBox($"PCL 未找到 Java {VersionCode}。" & vbCrLf &
|
||||
$"请自行搜索并安装 Java {VersionCode},安装后在 设置 → 启动选项 → 游戏 Java 中重新搜索或导入。",
|
||||
"未找到 Java")
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 获取下载 Java 8/14/17 的加载器。需要开启 IsForceRestart 以正常刷新 Java 列表。
|
||||
''' </summary>
|
||||
Public Function JavaFixLoaders(Version As Integer) As LoaderCombo(Of Integer)
|
||||
Return New LoaderCombo(Of Integer)($"下载 Java {Version}", {
|
||||
New LoaderTask(Of Integer, List(Of NetFile))("获取 Java 下载信息", AddressOf JavaFileList) With {.ProgressWeight = 2},
|
||||
New LoaderDownload("下载 Java 文件", New List(Of NetFile)) With {.ProgressWeight = 10},
|
||||
JavaSearchLoader
|
||||
})
|
||||
End Function
|
||||
Private Sub JavaFileList(Loader As LoaderTask(Of Integer, List(Of NetFile)))
|
||||
Log("[Java] 开始获取 Java 下载信息")
|
||||
Dim IndexFileStr As String = NetGetCodeByDownload(
|
||||
{"https://download.mcbbs.net/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
||||
"https://bmclapi2.bangbang93.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json",
|
||||
"https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"},
|
||||
IsJson:=True)
|
||||
'获取下载地址
|
||||
Dim MainEntry As JObject = CType(GetJson(IndexFileStr), JObject)($"windows-x{If(Is32BitSystem, "86", "64")}")
|
||||
Dim Entries = MainEntry.Children.Reverse. '选择最靠后的一项(最新)
|
||||
SelectMany(Function(e As JProperty) CType(e.Value, JArray).Select(Function(v) New KeyValuePair(Of String, JObject)(e.Name, v)))
|
||||
Dim TargetEntry = Entries.First(Function(t) t.Value("version")("name").ToString.StartsWith(Loader.Input))
|
||||
Dim Address As String = TargetEntry.Value("manifest")("url")
|
||||
Log($"[Java] 准备下载 Java {TargetEntry.Value("version")("name")}({TargetEntry.Key}):{Address}")
|
||||
'获取文件列表
|
||||
Dim ListFileStr As String = NetGetCodeByDownload(
|
||||
{Address.Replace("piston-meta.mojang.com", "download.mcbbs.net"),
|
||||
Address.Replace("piston-meta.mojang.com", "bmclapi2.bangbang93.com"),
|
||||
Address},
|
||||
IsJson:=True)
|
||||
Dim BaseDir As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\.minecraft\runtime\" & TargetEntry.Key & "\"
|
||||
Dim Results As New List(Of NetFile)
|
||||
For Each File As JProperty In CType(GetJson(ListFileStr), JObject)("files")
|
||||
If CType(File.Value, JObject)("downloads")?("raw") Is Nothing Then Continue For
|
||||
Dim Info As JObject = CType(File.Value, JObject)("downloads")("raw")
|
||||
Dim Checker As New FileChecker(ActualSize:=Info("size"), Hash:=Info("sha1"))
|
||||
If Checker.Check(BaseDir & File.Name) Is Nothing Then Continue For '跳过已存在的文件
|
||||
Dim Url As String = Info("url")
|
||||
Results.Add(New NetFile(
|
||||
{Url.Replace("piston-data.mojang.com", "download.mcbbs.net"),
|
||||
Url.Replace("piston-data.mojang.com", "bmclapi2.bangbang93.com"),
|
||||
Url},
|
||||
BaseDir & File.Name, Checker))
|
||||
Next
|
||||
Loader.Output = Results
|
||||
Log($"[Java] 需要下载 {Results.Count} 个文件,目标文件夹:{BaseDir}")
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
End Module
|
||||
@@ -102,9 +102,7 @@ Public Module ModLaunch
|
||||
Try
|
||||
'构造主加载器
|
||||
Dim LaunchLoader As New LoaderCombo(Of Object)("Minecraft 启动", {
|
||||
New LoaderCombo(Of Integer)("Java 处理", {
|
||||
New LoaderTask(Of Integer, List(Of NetFile))("Java 验证", AddressOf McLaunchJavaValidate) With {.ProgressWeight = 2}
|
||||
}) With {.ProgressWeight = 2, .Show = False, .Block = False},
|
||||
New LoaderTask(Of Integer, Integer)("获取 Java", AddressOf McLaunchJava) With {.ProgressWeight = 4, .Block = False, .Show = False},
|
||||
McLoginLoader,
|
||||
New LoaderCombo(Of String)("补全文件", DlClientFix(McVersionCurrent, False, AssetsIndexExistsBehaviour.DownloadInBackground, True)) With {.ProgressWeight = 15, .Show = False, .Block = True},
|
||||
New LoaderTask(Of String, List(Of McLibToken))("获取启动参数", AddressOf McLaunchArgumentMain) With {.ProgressWeight = 2},
|
||||
@@ -1131,7 +1129,7 @@ SystemBrowser:
|
||||
#Region "Java 处理"
|
||||
|
||||
Private McLaunchJavaSelected As JavaEntry = Nothing
|
||||
Private Sub McLaunchJavaValidate(Task As LoaderTask(Of Integer, List(Of NetFile)))
|
||||
Private Sub McLaunchJava(Task As LoaderTask(Of Integer, Integer))
|
||||
Dim MinVer As New Version(0, 0, 0, 0), MaxVer As New Version(999, 999, 999, 999)
|
||||
|
||||
'MC 大版本检测
|
||||
@@ -1188,11 +1186,11 @@ SystemBrowser:
|
||||
'Fabric 检测
|
||||
If McVersionCurrent.Version.HasFabric Then
|
||||
If McVersionCurrent.Version.McCodeMain >= 15 AndAlso McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain <> -1 Then
|
||||
'1.15 - 1.16:Java 8 - 19
|
||||
MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 19, 999, 999)
|
||||
'1.15 - 1.16:Java 8+
|
||||
MinVer = New Version(1, 8, 0, 0)
|
||||
ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 Then
|
||||
'1.18+:Java 17 - 19
|
||||
MinVer = New Version(1, 17, 0, 0) : MaxVer = New Version(1, 19, 999, 999)
|
||||
'1.18+:Java 17+
|
||||
MinVer = New Version(1, 17, 0, 0)
|
||||
End If
|
||||
End If
|
||||
|
||||
@@ -1213,21 +1211,37 @@ SystemBrowser:
|
||||
|
||||
'无合适的 Java
|
||||
If Task.IsAborted Then Exit Sub '中断加载会导致 JavaSelect 异常地返回空值,误判找不到 Java
|
||||
McLaunchLog("无合适的 Java,取消启动")
|
||||
If MinVer >= New Version(1, 17, 0, 0) Then
|
||||
'缺少 Java 17
|
||||
JavaMissing(17)
|
||||
ElseIf MinVer >= New Version(1, 16, 0, 0) Then
|
||||
'缺少 Java 16
|
||||
JavaMissing(16)
|
||||
McLaunchLog("无合适的 Java,需要确认是否自动下载")
|
||||
Dim JavaCode As String
|
||||
If MinVer >= New Version(1, 16, 0, 0) Then
|
||||
JavaCode = 17
|
||||
ElseIf MaxVer < New Version(1, 8, 0, 0) Then
|
||||
'缺少 Java 7
|
||||
JavaMissing(7)
|
||||
JavaCode = 7
|
||||
ElseIf MinVer > New Version(1, 8, 0, 52) Then
|
||||
'缺少 Java 8 较新版(统一通行证)
|
||||
JavaCode = "8u101"
|
||||
Else
|
||||
'缺少 Java 8 较新版
|
||||
JavaMissing(8)
|
||||
JavaCode = 8
|
||||
End If
|
||||
If Not JavaDownloadConfirm(JavaCode) Then Throw New Exception("$$")
|
||||
|
||||
'开始自动下载
|
||||
Dim JavaLoader = JavaFixLoaders(JavaCode)
|
||||
JavaLoader.Start(JavaCode, IsForceRestart:=True)
|
||||
Do While JavaLoader.State = LoadState.Loading AndAlso Not Task.IsAborted
|
||||
Task.Progress = JavaLoader.Progress
|
||||
Thread.Sleep(10)
|
||||
Loop
|
||||
|
||||
'检查下载结果
|
||||
McLaunchJavaSelected = JavaSelect("$$", MinVer, MaxVer, McVersionCurrent)
|
||||
If Task.IsAborted Then Exit Sub
|
||||
If McLaunchJavaSelected IsNot Nothing Then
|
||||
McLaunchLog("选择的 Java:" & McLaunchJavaSelected.ToString)
|
||||
Else
|
||||
Hint("没有可用的 Java,已取消启动!", HintType.Critical)
|
||||
Throw New Exception("$$")
|
||||
End If
|
||||
Throw New Exception("$$")
|
||||
|
||||
End Sub
|
||||
|
||||
@@ -1304,16 +1318,21 @@ SystemBrowser:
|
||||
'进服
|
||||
Dim Server As String = If(String.IsNullOrEmpty(McLaunchLoader.Input.ServerIp), Setup.Get("VersionServerEnter", McVersionCurrent), McLaunchLoader.Input.ServerIp)
|
||||
If Server.Length > 0 Then
|
||||
If Server.Contains(":") Then
|
||||
'包含端口号
|
||||
Arguments += " --server " & Server.Split(":")(0) & " --port " & Server.Split(":")(1)
|
||||
If McVersionCurrent.ReleaseTime > New Date(2023, 4, 4) Then
|
||||
'QuickPlay
|
||||
Arguments += $" --quickPlayMultiplayer ""{Server}"""
|
||||
Else
|
||||
'不包含端口号
|
||||
Arguments += " --server " & Server & " --port 25565"
|
||||
End If
|
||||
'OptiFine 警告
|
||||
If McVersionCurrent.Version.HasOptiFine Then
|
||||
Hint("OptiFine 与自动进入服务器可能不兼容,有概率导致材质丢失甚至游戏崩溃!", HintType.Critical)
|
||||
'老版本
|
||||
If Server.Contains(":") Then
|
||||
'包含端口号
|
||||
Arguments += " --server " & Server.Split(":")(0) & " --port " & Server.Split(":")(1)
|
||||
Else
|
||||
'不包含端口号
|
||||
Arguments += " --server " & Server & " --port 25565"
|
||||
End If
|
||||
If McVersionCurrent.Version.HasOptiFine Then 'OptiFine 警告
|
||||
Hint("OptiFine 与自动进入服务器可能不兼容,有概率导致材质丢失甚至游戏崩溃!", HintType.Critical)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
'自定义
|
||||
|
||||
@@ -2,718 +2,6 @@
|
||||
|
||||
Public Module ModMinecraft
|
||||
|
||||
#Region "Java"
|
||||
|
||||
'列表初始化
|
||||
|
||||
Public JavaListCacheVersion As Integer = 3
|
||||
''' <summary>
|
||||
''' 目前所有可用的 Java。
|
||||
''' </summary>
|
||||
Public JavaList As New List(Of JavaEntry)
|
||||
''' <summary>
|
||||
''' 初始化 Java 列表,但除非没有 Java,否则不进行检查。
|
||||
''' </summary>
|
||||
Public Sub JavaListInit()
|
||||
JavaList = New List(Of JavaEntry)
|
||||
Try
|
||||
If Setup.Get("CacheJavaListVersion") < JavaListCacheVersion Then
|
||||
'不使用缓存
|
||||
Log("[Java] 要求 Java 列表缓存更新")
|
||||
Setup.Set("CacheJavaListVersion", JavaListCacheVersion)
|
||||
Else
|
||||
'使用缓存
|
||||
For Each JsonEntry In GetJson(Setup.Get("LaunchArgumentJavaAll"))
|
||||
JavaList.Add(JavaEntry.FromJson(JsonEntry))
|
||||
Next
|
||||
End If
|
||||
If JavaList.Count = 0 Then
|
||||
Log("[Java] 初始化未找到可用的 Java,将自动触发搜索", LogLevel.Developer)
|
||||
JavaSearchLoader.Start(0)
|
||||
Else
|
||||
Log("[Java] 缓存中有 " & JavaList.Count & " 个可用的 Java")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Log(ex, "初始化 Java 列表失败", LogLevel.Feedback)
|
||||
Setup.Set("LaunchArgumentJavaAll", "[]")
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'基础环境
|
||||
|
||||
''' <summary>
|
||||
''' Path 环境变量。
|
||||
''' </summary>
|
||||
Private ReadOnly Property PathEnv As String
|
||||
Get
|
||||
If _PathEnv Is Nothing Then _PathEnv = If(Environment.GetEnvironmentVariable("Path"), "")
|
||||
Return _PathEnv
|
||||
End Get
|
||||
End Property
|
||||
Private _PathEnv As String = Nothing
|
||||
|
||||
''' <summary>
|
||||
''' JAVA_HOME 环境变量。
|
||||
''' </summary>
|
||||
Private ReadOnly Property PathJavaHome As String
|
||||
Get
|
||||
If _PathJavaHome Is Nothing Then _PathJavaHome = If(Environment.GetEnvironmentVariable("JAVA_HOME"), "")
|
||||
Return _PathJavaHome
|
||||
End Get
|
||||
End Property
|
||||
Private _PathJavaHome As String = Nothing
|
||||
|
||||
Public Class JavaEntry
|
||||
|
||||
'路径
|
||||
''' <summary>
|
||||
''' Java.exe 文件的完整路径。
|
||||
''' </summary>
|
||||
Public ReadOnly Property PathJava As String
|
||||
Get
|
||||
Return PathFolder & "java.exe"
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' Javaw.exe 文件的完整路径。
|
||||
''' </summary>
|
||||
Public ReadOnly Property PathJavaw As String
|
||||
Get
|
||||
Return PathFolder & "javaw.exe"
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' Javaw.exe 文件所在文件夹的路径,以 \ 结尾。
|
||||
''' </summary>
|
||||
Public PathFolder As String
|
||||
''' <summary>
|
||||
''' 是否为用户手动导入的 Java。
|
||||
''' </summary>
|
||||
Public IsUserImport As Boolean
|
||||
|
||||
'版本信息
|
||||
''' <summary>
|
||||
''' Java 的详细版本。若不足 4 位会在前方补 1,例如 1.16.0.1。
|
||||
''' 其大版本号为 Minor。
|
||||
''' </summary>
|
||||
Public Version As Version
|
||||
''' <summary>
|
||||
''' Java 的大版本号。
|
||||
''' </summary>
|
||||
Public ReadOnly Property VersionCode As Integer
|
||||
Get
|
||||
Return Version.Minor
|
||||
End Get
|
||||
End Property
|
||||
''' <summary>
|
||||
''' 是否为 Java Runtime Environment。
|
||||
''' </summary>
|
||||
Public IsJre As Boolean
|
||||
''' <summary>
|
||||
''' 是否为 64 位 Java。
|
||||
''' </summary>
|
||||
Public Is64Bit As Boolean
|
||||
''' <summary>
|
||||
''' 是否已设置环境变量。
|
||||
''' </summary>
|
||||
Public ReadOnly Property HasEnvironment As Boolean
|
||||
Get
|
||||
If PathFolder Is Nothing OrElse PathEnv Is Nothing Then Return False
|
||||
Return PathEnv.Replace("\", "").Replace("/", "").ToLower.Contains(PathFolder.Replace("\", "").ToLower)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'序列化
|
||||
Public Function ToJson() As JObject
|
||||
Return New JObject({New JProperty("Path", PathFolder), New JProperty("VersionString", Version.ToString), New JProperty("IsJre", IsJre), New JProperty("Is64Bit", Is64Bit), New JProperty("IsUserImport", IsUserImport)})
|
||||
End Function
|
||||
Public Shared Function FromJson(Data As JObject) As JavaEntry
|
||||
Return New JavaEntry(Data("Path"), Data("IsUserImport")) With {.Version = New Version(Data("VersionString")), .IsJre = Data("IsJre"), .Is64Bit = Data("Is64Bit")}
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 转化为用户友好的字符串输出。
|
||||
''' </summary>
|
||||
Public Overrides Function ToString() As String
|
||||
Dim VersionString = Version.ToString
|
||||
If VersionString.StartsWith("1.") Then VersionString = Mid(VersionString, 3)
|
||||
Return If(IsJre, "JRE ", "JDK ") & VersionCode & " (" & VersionString & ")," & If(Is64Bit, "64", "32") & " 位" & If(IsUserImport, ",手动导入", "") & ":" & PathFolder
|
||||
End Function
|
||||
|
||||
'构造
|
||||
''' <summary>
|
||||
''' 输入 javaw.exe 文件所在文件夹的路径,不限制结尾。
|
||||
''' </summary>
|
||||
Public Sub New(Folder As String, IsUserImport As Boolean)
|
||||
If Not Folder.EndsWith("\") Then Folder += "\"
|
||||
PathFolder = Folder.Replace("/", "\")
|
||||
Me.IsUserImport = IsUserImport
|
||||
End Sub
|
||||
|
||||
'方法
|
||||
Private IsChecked As Boolean = False
|
||||
''' <summary>
|
||||
''' 检查并获取 Java 详细信息。在 Java 存在异常时抛出错误。
|
||||
''' </summary>
|
||||
Public Sub Check()
|
||||
If IsChecked Then Exit Sub
|
||||
Dim Output As String = Nothing
|
||||
Try
|
||||
'确定文件存在
|
||||
If Not File.Exists(PathJavaw) Then
|
||||
Throw New FileNotFoundException("未找到 javaw.exe 文件", PathJavaw)
|
||||
End If
|
||||
If Not File.Exists(PathFolder & "java.exe") Then
|
||||
Throw New FileNotFoundException("未找到 java.exe 文件", PathFolder & "java.exe")
|
||||
End If
|
||||
IsJre = Not File.Exists(PathFolder & "javac.exe")
|
||||
'运行 -version
|
||||
Output = ShellAndGetOutput(PathFolder & "java.exe", "-version", 15000).ToLower
|
||||
If Output = "" Then Throw New Exception("尝试运行该 Java 失败")
|
||||
If ModeDebug Then Log("[Java] Java 检查输出:" & PathFolder & "java.exe" & vbCrLf & Output)
|
||||
'获取详细信息
|
||||
Dim VersionString = If(RegexSeek(Output, "(?<=version "")[^""]+"), If(RegexSeek(Output, "(?<=openjdk )[0-9]+"), "")).Replace("_", ".").Split("-").First
|
||||
Do While VersionString.Split(".").Count < 4
|
||||
If VersionString.StartsWith("1.") Then
|
||||
VersionString = VersionString & ".0"
|
||||
Else
|
||||
VersionString = "1." & VersionString
|
||||
End If
|
||||
Loop
|
||||
Version = New Version(VersionString)
|
||||
If Version.Minor = 0 Then
|
||||
Log("[Java] 疑似 X.0.X.X 格式版本号:" & Version.ToString)
|
||||
Version = New Version(1, Version.Major, Version.Build, Version.Revision)
|
||||
End If
|
||||
Is64Bit = Output.Contains("64-bit")
|
||||
If Version.Minor <= 4 OrElse Version.Minor >= 25 Then Throw New Exception("分析详细信息失败,获取的版本为 " & Version.ToString)
|
||||
'无论如何不允许使用 JRE 16,它完全是炸的,安 OptiFine、Forge 和启动 MC 都会炸
|
||||
If IsJre AndAlso VersionCode = 16 Then Throw New Exception("由于 JRE 16 对 Minecraft 的兼容性很差,因此不再允许使用")
|
||||
Catch ex As Exception
|
||||
Log("[Java] 检查失败的 Java 输出:" & PathFolder & "java.exe" & vbCrLf & If(Output, "无程序输出"))
|
||||
Throw New Exception("检查 Java 失败(" & If(PathJavaw, "Nothing") & ")", ex)
|
||||
End Try
|
||||
IsChecked = True
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
'搜索
|
||||
|
||||
''' <summary>
|
||||
''' 模糊搜索并获取所有可用的 Java,并在结束后更新设置页面显示。输出将直接写入 JavaList。
|
||||
''' </summary>
|
||||
Public JavaSearchLoader As New LoaderTask(Of Integer, Integer)("Java Search Loader", AddressOf JavaSearchLoaderSub)
|
||||
Private Sub JavaSearchLoaderSub(Loader As LoaderTask(Of Integer, Integer))
|
||||
If FrmSetupLaunch IsNot Nothing Then
|
||||
RunInUiWait(Sub()
|
||||
FrmSetupLaunch.ComboArgumentJava.Items.Clear()
|
||||
FrmSetupLaunch.ComboArgumentJava.Items.Add(New ComboBoxItem With {.Content = "加载中……", .IsSelected = True})
|
||||
End Sub)
|
||||
End If
|
||||
If FrmVersionSetup IsNot Nothing Then
|
||||
RunInUiWait(Sub()
|
||||
FrmVersionSetup.ComboArgumentJava.Items.Clear()
|
||||
FrmVersionSetup.ComboArgumentJava.Items.Add(New ComboBoxItem With {.Content = "加载中……", .IsSelected = True})
|
||||
End Sub)
|
||||
End If
|
||||
|
||||
Try
|
||||
|
||||
'可能包含 Java 的文件夹列表,以 “\” 结尾,且仅包含 “\”
|
||||
'Key:文件夹地址
|
||||
'Value: 是否为玩家手动导入
|
||||
Dim JavaPreList As New Dictionary(Of String, Boolean)
|
||||
|
||||
#Region "模糊查找可能可用的 Java"
|
||||
|
||||
'查找环境变量中的 Java
|
||||
For Each PathInEnv As String In Split((PathEnv & ";" & PathJavaHome).Replace("\\", "\").Replace("/", "\"), ";")
|
||||
PathInEnv = PathInEnv.Trim(" """.ToCharArray())
|
||||
If PathInEnv = "" Then Continue For
|
||||
If Not PathInEnv.EndsWith("\") Then PathInEnv += "\"
|
||||
'粗略检查有效性
|
||||
If File.Exists(PathInEnv & "javaw.exe") Then JavaPreList(PathInEnv) = False
|
||||
Next
|
||||
'查找磁盘中的 Java
|
||||
For Each Disk As DriveInfo In DriveInfo.GetDrives()
|
||||
JavaSearchFolder(Disk.Name, JavaPreList, False)
|
||||
Next
|
||||
'查找 APPDATA 文件夹中的 Java
|
||||
JavaSearchFolder(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\", JavaPreList, False)
|
||||
'查找启动器目录中的 Java
|
||||
JavaSearchFolder(Path, JavaPreList, False, IsFullSearch:=True)
|
||||
'查找所选 Minecraft 文件夹中的 Java
|
||||
If Not String.IsNullOrWhiteSpace(PathMcFolder) AndAlso Path <> PathMcFolder Then
|
||||
JavaSearchFolder(PathMcFolder, JavaPreList, False, IsFullSearch:=True)
|
||||
End If
|
||||
|
||||
'若不全为符号链接,则清除符号链接的地址
|
||||
Dim JavaWithoutReparse As New Dictionary(Of String, Boolean)
|
||||
For Each Pair In JavaPreList
|
||||
Dim Folder As String = Pair.Key.Replace("\\", "\").Replace("/", "\")
|
||||
Dim Info As FileSystemInfo = New FileInfo(Folder & "javaw.exe")
|
||||
Do
|
||||
If Info.Attributes.HasFlag(FileAttributes.ReparsePoint) Then
|
||||
Log("[Java] 位于 " & Folder & " 的 Java 包含符号链接")
|
||||
Continue For
|
||||
End If
|
||||
Info = If(TypeOf Info Is FileInfo, CType(Info, FileInfo).Directory, CType(Info, DirectoryInfo).Parent)
|
||||
Loop While Info IsNot Nothing
|
||||
Log("[Java] 位于 " & Folder & " 的 Java 不含符号链接")
|
||||
JavaWithoutReparse.Add(Pair.Key, Pair.Value)
|
||||
Next
|
||||
If JavaWithoutReparse.Count > 0 Then JavaPreList = JavaWithoutReparse
|
||||
|
||||
'若不全为特殊引用,则清除特殊引用的地址
|
||||
Dim JavaWithoutInherit As New Dictionary(Of String, Boolean)
|
||||
For Each Pair In JavaPreList
|
||||
If Pair.Key.Contains("javapath_target_") OrElse Pair.Key.Contains("javatmp") Then
|
||||
Log("[Java] 位于 " & Pair.Key & " 的 Java 包含特殊引用")
|
||||
Continue For
|
||||
End If
|
||||
Log("[Java] 位于 " & Pair.Key & " 的 Java 不含特殊引用")
|
||||
JavaWithoutInherit.Add(Pair.Key, Pair.Value)
|
||||
Next
|
||||
If JavaWithoutInherit.Count > 0 Then JavaPreList = JavaWithoutInherit
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "添加玩家手动导入的 Java"
|
||||
|
||||
Dim ImportedJava As String = Setup.Get("LaunchArgumentJavaAll")
|
||||
Try
|
||||
For Each JavaJsonObject In GetJson(ImportedJava)
|
||||
Dim Entry = JavaEntry.FromJson(JavaJsonObject)
|
||||
If Entry.IsUserImport Then JavaPreList(Entry.PathFolder) = True
|
||||
Next
|
||||
Catch ex As Exception
|
||||
Log(ex, "Java 列表已损坏", LogLevel.Feedback)
|
||||
Setup.Set("LaunchArgumentJavaAll", "[]")
|
||||
End Try
|
||||
|
||||
#End Region
|
||||
|
||||
'确保可用并获取详细信息,转入正式列表
|
||||
Dim NewJavaList As New List(Of JavaEntry)
|
||||
For Each Entry In Distinct(JavaPreList.ToList, Function(a, b) a.Key.ToLower = b.Key.ToLower) '#794
|
||||
NewJavaList.Add(New JavaEntry(Entry.Key, Entry.Value))
|
||||
Next
|
||||
NewJavaList = Sort(JavaCheckList(NewJavaList), AddressOf JavaSorter)
|
||||
|
||||
'修改设置项
|
||||
Dim AllList As New JArray
|
||||
For Each Java In NewJavaList
|
||||
AllList.Add(Java.ToJson)
|
||||
Next
|
||||
Setup.Set("LaunchArgumentJavaAll", AllList.ToString(Newtonsoft.Json.Formatting.None))
|
||||
JavaList = NewJavaList
|
||||
|
||||
Catch ex As Exception
|
||||
Log(ex, "搜索 Java 时出错", LogLevel.Feedback)
|
||||
JavaList = New List(Of JavaEntry)
|
||||
End Try
|
||||
|
||||
Log("[Java] Java 搜索完成,发现 " & JavaList.Count & " 个 Java")
|
||||
If FrmSetupLaunch IsNot Nothing Then RunInUi(Sub() FrmSetupLaunch.RefreshJavaComboBox())
|
||||
If FrmVersionSetup IsNot Nothing Then RunInUi(Sub() FrmVersionSetup.RefreshJavaComboBox())
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 多线程检查列表中的所有 Java 项。
|
||||
''' </summary>
|
||||
Private Function JavaCheckList(JavaEntries As List(Of JavaEntry)) As List(Of JavaEntry)
|
||||
Log("[Java] 开始确认列表 Java 状态,共 " & JavaEntries.Count & " 项")
|
||||
JavaCheckList = New List(Of JavaEntry)
|
||||
Dim ListLock As New Object
|
||||
|
||||
'启动检查线程
|
||||
Dim CheckThreads As New List(Of Thread)
|
||||
For Each Entry In JavaEntries
|
||||
Dim CheckThread As New Thread(Sub()
|
||||
Try
|
||||
Entry.Check()
|
||||
Log("[Java] " & Entry.ToString)
|
||||
SyncLock ListLock
|
||||
JavaCheckList.Add(Entry)
|
||||
End SyncLock
|
||||
Catch ex As Exception
|
||||
If Entry.IsUserImport Then
|
||||
Log(ex, "位于 " & Entry.PathFolder & " 的 Java 存在异常,将被自动移除", LogLevel.Hint)
|
||||
Else
|
||||
Log(ex, "位于 " & Entry.PathFolder & " 的 Java 存在异常")
|
||||
End If
|
||||
End Try
|
||||
End Sub)
|
||||
CheckThreads.Add(CheckThread)
|
||||
CheckThread.Start()
|
||||
Next
|
||||
|
||||
'等待构造线程完成
|
||||
Wait:
|
||||
Thread.Sleep(10)
|
||||
For Each CheckThread In CheckThreads
|
||||
If CheckThread.IsAlive Then GoTo Wait
|
||||
Next
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 模糊搜索指定文件夹下的 Java,并只进行粗略的检查。这不会搜索全部路径。
|
||||
''' </summary>
|
||||
''' <param name="OriginalPath">开始搜索的起始路径,不限制结尾。</param>
|
||||
''' <param name="IsFullSearch">搜索当前文件夹下的全部文件夹(此参数不会传递到子文件夹)。</param>
|
||||
Private Sub JavaSearchFolder(OriginalPath As String, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
|
||||
Try
|
||||
Log("[Java] 开始" & If(IsFullSearch, "完全", "部分") & "遍历查找:" & OriginalPath)
|
||||
JavaSearchFolder(New DirectoryInfo(OriginalPath), Results, Source, IsFullSearch)
|
||||
Catch ex As UnauthorizedAccessException
|
||||
Log("[Java] 遍历查找 Java 时遭遇无权限的文件夹:" & OriginalPath)
|
||||
Catch ex As Exception
|
||||
Log(ex, "遍历查找 Java 时出错(" & OriginalPath & ")")
|
||||
End Try
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' 模糊搜索指定文件夹下的 Java,并只进行粗略的检查。这不会搜索全部路径。
|
||||
''' </summary>
|
||||
''' <param name="OriginalPath">开始搜索的起始路径,不限制结尾。</param>
|
||||
''' <param name="IsFullSearch">搜索当前文件夹下的全部文件夹(此参数不会传递到子文件夹)。</param>
|
||||
Private Sub JavaSearchFolder(OriginalPath As DirectoryInfo, ByRef Results As Dictionary(Of String, Boolean), Source As Boolean, Optional IsFullSearch As Boolean = False)
|
||||
Try
|
||||
'确认目录存在
|
||||
If Not OriginalPath.Exists Then Exit Sub
|
||||
Dim Path As String = OriginalPath.FullName.Replace("\\", "\")
|
||||
If Not Path.EndsWith("\") Then Path += "\"
|
||||
'若该目录有 Java,则加入结果
|
||||
If File.Exists(Path & "javaw.exe") Then Results(Path) = Source
|
||||
'查找其下的所有文件夹
|
||||
For Each FolderInfo As DirectoryInfo In OriginalPath.EnumerateDirectories
|
||||
If FolderInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) Then Continue For '跳过符号链接
|
||||
Dim SearchEntry = GetFolderNameFromPath(FolderInfo.Name).ToLower '用于搜索的字符串
|
||||
If IsFullSearch OrElse
|
||||
FolderInfo.Parent.Name.ToLower = "users" OrElse
|
||||
SearchEntry.Contains("java") OrElse SearchEntry.Contains("jdk") OrElse SearchEntry.Contains("env") OrElse
|
||||
SearchEntry.Contains("环境") OrElse SearchEntry.Contains("run") OrElse SearchEntry.Contains("软件") OrElse
|
||||
SearchEntry.Contains("jre") OrElse SearchEntry = "bin" OrElse SearchEntry.Contains("mc") OrElse
|
||||
SearchEntry.Contains("software") OrElse SearchEntry.Contains("cache") OrElse SearchEntry.Contains("temp") OrElse
|
||||
SearchEntry.Contains("corretto") OrElse SearchEntry.Contains("roaming") OrElse SearchEntry.Contains("users") OrElse
|
||||
SearchEntry.Contains("craft") OrElse SearchEntry.Contains("program") OrElse SearchEntry.Contains("世界") OrElse
|
||||
SearchEntry.Contains("net") OrElse SearchEntry.Contains("游戏") OrElse SearchEntry.Contains("oracle") OrElse
|
||||
SearchEntry.Contains("game") OrElse SearchEntry.Contains("file") OrElse SearchEntry.Contains("data") OrElse
|
||||
SearchEntry.Contains("jvm") OrElse SearchEntry.Contains("服务") OrElse SearchEntry.Contains("server") OrElse
|
||||
SearchEntry.Contains("客户") OrElse SearchEntry.Contains("client") OrElse SearchEntry.Contains("整合") OrElse
|
||||
SearchEntry.Contains("应用") OrElse SearchEntry.Contains("运行") OrElse SearchEntry.Contains("前置") OrElse
|
||||
SearchEntry.Contains("mojang") OrElse SearchEntry.Contains("官启") OrElse SearchEntry.Contains("新建文件夹") OrElse
|
||||
SearchEntry.Contains("eclipse") OrElse SearchEntry.Contains("microsoft") OrElse SearchEntry.Contains("hotspot") OrElse
|
||||
SearchEntry.Contains("runtime") OrElse SearchEntry.Contains("x86") OrElse SearchEntry.Contains("x64") OrElse
|
||||
SearchEntry.Contains("forge") OrElse SearchEntry.Contains("原版") OrElse SearchEntry.Contains("optifine") OrElse
|
||||
SearchEntry.Contains("官方") OrElse SearchEntry.Contains("启动") OrElse SearchEntry.Contains("hmcl") OrElse
|
||||
SearchEntry.Contains("mod") OrElse SearchEntry.Contains("高清") OrElse SearchEntry.Contains("download") OrElse
|
||||
SearchEntry.Contains("launch") OrElse SearchEntry.Contains("程序") OrElse SearchEntry.Contains("path") OrElse
|
||||
SearchEntry.Contains("国服") OrElse SearchEntry.Contains("网易") OrElse SearchEntry.Contains("ext") OrElse '网易 Java 文件夹名
|
||||
SearchEntry.Contains("netease") OrElse SearchEntry.Contains("1.") OrElse SearchEntry.Contains("启动") Then
|
||||
JavaSearchFolder(FolderInfo, Results, Source)
|
||||
End If
|
||||
Next
|
||||
Catch ex As UnauthorizedAccessException
|
||||
Log("[Java] 遍历查找 Java 时遭遇无权限的文件夹:" & OriginalPath.FullName)
|
||||
Catch ex As Exception
|
||||
Log(ex, "遍历查找 Java 时出错(" & OriginalPath.FullName & ")")
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'获取
|
||||
|
||||
''' <summary>
|
||||
''' 根据要求返回最适合的 Java,若找不到则返回 Nothing。
|
||||
''' 最小与最大版本在与输入相同时也会通过。
|
||||
''' 必须在工作线程调用。
|
||||
''' </summary>
|
||||
Public Function JavaSelect(CancelException As String, Optional MinVersion As Version = Nothing, Optional MaxVersion As Version = Nothing,
|
||||
Optional RelatedVersion As McVersion = Nothing) As JavaEntry
|
||||
Try
|
||||
Dim AllowedJavaList As New List(Of JavaEntry)
|
||||
|
||||
'添加特定的 Java
|
||||
Dim JavaPreList As New Dictionary(Of String, Boolean)
|
||||
If PathMcFolder.Split("\").Count > 3 Then JavaSearchFolder(GetPathFromFullPath(PathMcFolder), JavaPreList, False, True) 'Minecraft 文件夹的父文件夹(如果不是根目录的话)
|
||||
JavaSearchFolder(PathMcFolder, JavaPreList, False, True) 'Minecraft 文件夹
|
||||
If RelatedVersion IsNot Nothing Then JavaSearchFolder(RelatedVersion.Path, JavaPreList, False, True) '所选版本文件夹
|
||||
Dim TargetJavaList As New List(Of JavaEntry)
|
||||
For Each Entry In JavaPreList
|
||||
TargetJavaList.Add(New JavaEntry(Entry.Key, Entry.Value))
|
||||
Next
|
||||
|
||||
#Region "添加用户指定的 Java,储存到 UserJava 中"
|
||||
|
||||
Dim UserJava As JavaEntry = Nothing
|
||||
|
||||
'获取版本独立设置中指定的 Java
|
||||
If RelatedVersion IsNot Nothing AndAlso Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion).ToString.StartsWith("{") Then
|
||||
Try
|
||||
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)))
|
||||
'确保版本独立设置中指定的 Java 在 Java 列表中(#978)
|
||||
If Not JavaList.Any(Function(j) j.PathFolder = UserJava.PathFolder) Then
|
||||
UserJava = Nothing
|
||||
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
|
||||
Log("版本独立设置中指定的 Java 不在主 Java 列表中,此设置已重置", LogLevel.Debug)
|
||||
Exit Try
|
||||
End If
|
||||
Catch ex As Exception
|
||||
UserJava = Nothing
|
||||
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
|
||||
Log(ex, "版本独立设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
|
||||
End Try
|
||||
End If
|
||||
|
||||
'获取全局设置中指定的 Java
|
||||
If UserJava Is Nothing AndAlso Setup.Get("LaunchArgumentJavaSelect") <> "" Then
|
||||
Try
|
||||
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("LaunchArgumentJavaSelect")))
|
||||
Catch ex As Exception
|
||||
UserJava = Nothing
|
||||
Setup.Reset("LaunchArgumentJavaSelect")
|
||||
Log(ex, "设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
|
||||
End Try
|
||||
End If
|
||||
|
||||
'添加到特定 Java 列表
|
||||
If UserJava IsNot Nothing Then
|
||||
Log($"[Java] 用户指定的 Java:{UserJava}")
|
||||
TargetJavaList.Add(UserJava)
|
||||
End If
|
||||
|
||||
#End Region
|
||||
|
||||
'检查特定的 Java
|
||||
If TargetJavaList.Count > 0 Then
|
||||
TargetJavaList = JavaCheckList(TargetJavaList)
|
||||
Log("[Java] 检查后找到 " & TargetJavaList.Count & " 个特定的 Java")
|
||||
End If
|
||||
|
||||
RetryGet:
|
||||
'等待进行中的搜索结束
|
||||
If JavaSearchLoader.State <> LoadState.Finished AndAlso JavaSearchLoader.State <> LoadState.Waiting Then JavaSearchLoader.WaitForExit()
|
||||
Select Case JavaSearchLoader.State
|
||||
Case LoadState.Failed
|
||||
Throw JavaSearchLoader.Error
|
||||
Case LoadState.Aborted
|
||||
Throw New ThreadInterruptedException("Java 搜索加载器已中断")
|
||||
End Select
|
||||
|
||||
'生成完整的 Java 列表
|
||||
Dim AllJavaList As New List(Of JavaEntry)
|
||||
AllJavaList.AddRange(TargetJavaList)
|
||||
AllJavaList.AddRange(JavaList)
|
||||
|
||||
'根据选定条件进行过滤
|
||||
For Each Java In AllJavaList
|
||||
If MinVersion IsNot Nothing AndAlso Java.Version < MinVersion Then Continue For
|
||||
If MaxVersion IsNot Nothing AndAlso Java.Version > MaxVersion Then Continue For
|
||||
If Java.Is64Bit AndAlso Is32BitSystem Then Continue For
|
||||
AllowedJavaList.Add(Java)
|
||||
Next
|
||||
|
||||
'若未找到适合的 Java,尝试触发搜索
|
||||
If AllowedJavaList.Count = 0 AndAlso JavaSearchLoader.State = LoadState.Waiting Then
|
||||
Log("[Java] 未找到满足条件的 Java,尝试进行搜索")
|
||||
JavaSearchLoader.Start()
|
||||
GoTo RetryGet
|
||||
End If
|
||||
|
||||
#Region "检查用户指定的 Java 是否可用"
|
||||
|
||||
'确保指定的 Java 可用
|
||||
If UserJava Is Nothing Then GoTo ExitUserJavaCheck
|
||||
If AllowedJavaList.Any(Function(j) j.PathFolder = UserJava.PathFolder) Then
|
||||
Log("[Java] 使用用户指定的 Java:" & UserJava.PathFolder)
|
||||
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
|
||||
GoTo UserPass
|
||||
End If
|
||||
|
||||
'指定的 Java 不可用,弹窗要求选择
|
||||
Log("[Java] 发现用户指定的不兼容 Java:" & UserJava.ToString)
|
||||
For Each Java In AllowedJavaList
|
||||
Log($"[Java] 实际可用的 Java:{Java.ToString}")
|
||||
Next
|
||||
Dim Requirement As String = ""
|
||||
Dim ShowRevision As Boolean = False
|
||||
If (MinVersion Is Nothing OrElse MinVersion.Minor = 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 999) Then
|
||||
ShowRevision = MaxVersion.MinorRevision < 999
|
||||
Requirement = "最高兼容到 Java " & MaxVersion.Minor & If(ShowRevision, "." & MaxVersion.MajorRevision & "." & MaxVersion.MinorRevision, "")
|
||||
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion Is Nothing OrElse MaxVersion.Minor >= 999) Then
|
||||
ShowRevision = MinVersion.MinorRevision > 0 OrElse MinVersion.MajorRevision > 0
|
||||
Requirement = "至少需要 Java " & MinVersion.Minor & If(ShowRevision, "." & MinVersion.MajorRevision & "." & MinVersion.MinorRevision, "")
|
||||
ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 999) Then
|
||||
ShowRevision = MinVersion.MinorRevision > 0 OrElse MinVersion.MajorRevision > 0 OrElse MaxVersion.MinorRevision < 999
|
||||
Dim Left As String = MinVersion.Minor & If(ShowRevision, "." & MinVersion.MajorRevision & "." & MinVersion.MinorRevision, "")
|
||||
Dim Right As String = MaxVersion.Minor & If(ShowRevision, "." & MaxVersion.MajorRevision & "." & MaxVersion.MinorRevision, "")
|
||||
Requirement = "需要 Java " & If(Left = Right, Left, Left & " ~ " & Right)
|
||||
End If
|
||||
Dim JavaCurrent As String = UserJava.VersionCode & If(ShowRevision, "." & UserJava.Version.MajorRevision & "." & UserJava.Version.MinorRevision, "")
|
||||
If Setup.Get("LaunchAdvanceJava") Then
|
||||
'直接跳过弹窗
|
||||
Hint("设置中指定了使用 Java " & JavaCurrent & ",但当前版本" & Requirement & ",这可能会导致游戏崩溃!", HintType.Critical)
|
||||
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
|
||||
Else
|
||||
Select Case MyMsgBox("你在设置中手动指定了使用 Java " & JavaCurrent & ",但当前" & Requirement & "。" & vbCrLf &
|
||||
"如果强制使用该 Java,可能导致游戏崩溃。" & vbCrLf &
|
||||
"你也可以将 游戏 Java 设置修改为 自动选择合适的 Java。" & vbCrLf &
|
||||
vbCrLf &
|
||||
" - 指定的 Java:" & UserJava.ToString,
|
||||
"Java 兼容性警告", "让 PCL 自动选择", "强制使用该 Java", "取消")
|
||||
Case 1 '让 PCL 自动选择
|
||||
Case 2 '强制使用指定的 Java
|
||||
Log("[Java] 已强制使用用户指定的不兼容 Java")
|
||||
AllowedJavaList = New List(Of JavaEntry) From {UserJava}
|
||||
Case 3 '取消启动
|
||||
Throw New Exception(CancelException)
|
||||
End Select
|
||||
End If
|
||||
|
||||
ExitUserJavaCheck:
|
||||
#End Region
|
||||
|
||||
'若依然未找到适合的 Java,直接返回
|
||||
If AllowedJavaList.Count = 0 Then Return Nothing
|
||||
|
||||
'优先使用特定目录下的 Java
|
||||
For Each Java In AllowedJavaList
|
||||
If TargetJavaList.Contains(Java) Then
|
||||
'直接使用指定的 Java
|
||||
AllowedJavaList = New List(Of JavaEntry) From {Java}
|
||||
Log("[Java] 优先使用特定的 Java:" & Java.ToString)
|
||||
GoTo UserPass
|
||||
End If
|
||||
Next
|
||||
UserPass:
|
||||
|
||||
'对适合的 Java 进行排序
|
||||
AllowedJavaList = Sort(AllowedJavaList, AddressOf JavaSorter)
|
||||
|
||||
'检查选定的 Java,若测试失败则尝试进行搜索
|
||||
Dim SelectedJava = AllowedJavaList.First
|
||||
Try
|
||||
SelectedJava.Check()
|
||||
Catch ex As ThreadInterruptedException
|
||||
Throw
|
||||
Catch ex As Exception
|
||||
Log(ex, "找到的 Java 已无法使用,尝试进行搜索")
|
||||
AllowedJavaList = New List(Of JavaEntry)
|
||||
JavaSearchLoader.Start(IsForceRestart:=True)
|
||||
GoTo RetryGet
|
||||
End Try
|
||||
|
||||
'返回
|
||||
Log("[Java] 选定的 Java:" & SelectedJava.ToString)
|
||||
Return SelectedJava
|
||||
|
||||
Catch ex As ThreadInterruptedException
|
||||
Log(ex, "查找符合条件的 Java 时出现加载器中断")
|
||||
Return Nothing
|
||||
Catch ex As Exception
|
||||
If ex.Message = "$$" Then Throw ex
|
||||
Log(ex, "查找符合条件的 Java 失败", LogLevel.Feedback)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 返回是否安装了 64 位 Java,或在强制指定的时候是否指定 64 位 Java。
|
||||
''' </summary>
|
||||
Public Function JavaUse64Bit(Optional RelatedVersion As McVersion = Nothing) As Boolean
|
||||
Try
|
||||
'检查强制指定
|
||||
Dim UserSetup As String = Setup.Get("LaunchArgumentJavaSelect")
|
||||
If RelatedVersion IsNot Nothing Then
|
||||
Dim UserSetupVersion As String = Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)
|
||||
If UserSetupVersion <> "使用全局设置" Then UserSetup = UserSetupVersion
|
||||
End If
|
||||
If UserSetup <> "" Then
|
||||
Dim UserJava As JavaEntry = Nothing
|
||||
Try
|
||||
UserJava = JavaEntry.FromJson(GetJson(UserSetup))
|
||||
Catch ex As Exception
|
||||
Log(ex, "版本指定的 Java 信息已损坏,已重置版本设置中指定的 Java")
|
||||
Setup.Set("VersionArgumentJavaSelect", "使用全局设置", Version:=RelatedVersion)
|
||||
GoTo NoUserJava
|
||||
End Try
|
||||
For Each Java In JavaList
|
||||
If Java.PathFolder = UserJava.PathFolder Then Return UserJava.Is64Bit
|
||||
Next
|
||||
End If
|
||||
NoUserJava:
|
||||
'检查列表
|
||||
For Each Java In JavaList
|
||||
If Java.Is64Bit Then Return True
|
||||
Next
|
||||
Return False
|
||||
Catch ex As Exception
|
||||
Log(ex, "检查 Java 类别时出错", LogLevel.Feedback)
|
||||
Setup.Set("LaunchArgumentJavaSelect", "")
|
||||
Return True
|
||||
End Try
|
||||
End Function
|
||||
''' <summary>
|
||||
''' 用于 Java 排序的函数。
|
||||
''' </summary>
|
||||
Public Function JavaSorter(Left As JavaEntry, Right As JavaEntry) As Boolean
|
||||
'1. 尽量在当前文件夹或当前 Minecraft 文件夹
|
||||
Dim ProgramPathParent As String, MinecraftPathParent As String = ""
|
||||
ProgramPathParent = If(New DirectoryInfo(Path).Parent, New DirectoryInfo(Path)).FullName
|
||||
If PathMcFolder <> "" Then MinecraftPathParent = If(New DirectoryInfo(PathMcFolder).Parent, New DirectoryInfo(PathMcFolder)).FullName
|
||||
If Left.PathFolder.StartsWith(ProgramPathParent) AndAlso Not Right.PathFolder.StartsWith(ProgramPathParent) Then Return True
|
||||
If Not Left.PathFolder.StartsWith(ProgramPathParent) AndAlso Right.PathFolder.StartsWith(ProgramPathParent) Then Return False
|
||||
If PathMcFolder <> "" Then
|
||||
If Left.PathFolder.StartsWith(MinecraftPathParent) AndAlso Not Right.PathFolder.StartsWith(MinecraftPathParent) Then Return True
|
||||
If Not Left.PathFolder.StartsWith(MinecraftPathParent) AndAlso Right.PathFolder.StartsWith(MinecraftPathParent) Then Return False
|
||||
End If
|
||||
'2. 尽量使用 64 位
|
||||
If Left.Is64Bit AndAlso Not Right.Is64Bit Then Return True
|
||||
If Not Left.Is64Bit AndAlso Right.Is64Bit Then Return False
|
||||
'3. 尽量不使用 JDK
|
||||
If Left.IsJre AndAlso Not Right.IsJre Then Return True
|
||||
If Not Left.IsJre AndAlso Right.IsJre Then Return False
|
||||
'4. Java 大版本
|
||||
If Left.VersionCode <> Right.VersionCode Then
|
||||
' Java 7 8 9 10 11 12 13 14 15 16 17 18 19 20...
|
||||
Dim Weight = {0, 1, 2, 3, 4, 5, 6, 14, 29, 10, 11, 12, 13, 9, 8, 7, 15, 31, 30, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}
|
||||
Return Weight.ElementAtOrDefault(Left.VersionCode) >= Weight.ElementAtOrDefault(Right.VersionCode)
|
||||
End If
|
||||
'5. 最次级版本号更接近 51
|
||||
Return Math.Abs(Left.Version.Revision - 51) <= Math.Abs(Right.Version.Revision - 51)
|
||||
End Function
|
||||
|
||||
'缺失
|
||||
''' <summary>
|
||||
''' 提示 Java 缺失并跳转下载。支持 Java 7、8、16、17。
|
||||
''' </summary>
|
||||
Public Sub JavaMissing(VersionCode As Integer)
|
||||
Select Case VersionCode
|
||||
Case 7
|
||||
MyMsgBox("PCL 未找到 Java 7。" & vbCrLf &
|
||||
"请自行百度安装 Java 7,安装后在 PCL 的 设置 → 启动设置 → 游戏 Java 中通过搜索或导入,确保安装的 Java 已列入 Java 列表。",
|
||||
"未找到 Java")
|
||||
Case 8 '291
|
||||
If Is32BitSystem Then
|
||||
OpenWebsite("https://wwa.lanzoui.com/i7RyXq0jbub")
|
||||
Else
|
||||
OpenWebsite("https://wwa.lanzoui.com/i2UyMq0jaqb")
|
||||
End If
|
||||
MyMsgBox("PCL 未找到版本适宜的 Java 8。" & vbCrLf &
|
||||
"请在打开的网页中下载安装包并安装,安装后在 PCL 的 设置 → 启动设置 → 游戏 Java 中通过搜索或导入,确保安装的 Java 已列入 Java 列表。",
|
||||
"未找到 Java")
|
||||
Case 16, 17
|
||||
If Is32BitSystem Then
|
||||
MyMsgBox("该版本的 MC 已不支持 32 位操作系统。你必须增加内存并重装为 64 位系统才能继续。", "系统兼容性提示")
|
||||
Else
|
||||
OpenWebsite("https://www.oracle.com/java/technologies/downloads/#java17")
|
||||
MyMsgBox("PCL 未找到 Java 17。" & vbCrLf &
|
||||
"请在打开的网页中选择 x64 Installer,下载并安装。" & vbCrLf &
|
||||
"安装后在 PCL 的 设置 → 启动设置 → 游戏 Java 中通过搜索或导入,确保安装的 Java 已列入 Java 列表。",
|
||||
"未找到 Java")
|
||||
End If
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "文件夹"
|
||||
|
||||
''' <summary>
|
||||
@@ -1701,6 +989,8 @@ ExitDataLoad:
|
||||
Return "我们从地下室的废墟里找到了这个开发于 1994 年的杰作!"
|
||||
ElseIf Name = "22w13oneblockatatime" Then
|
||||
Return "一次一个方块更新!迎接全新的挖掘、合成与骑乘玩法吧!"
|
||||
ElseIf Name = "23w13a_or_b" Then
|
||||
Return "研究表明玩家喜欢作出选择——越多越好!"
|
||||
Else
|
||||
Return ""
|
||||
End If
|
||||
@@ -2265,6 +1555,19 @@ NextVersion:
|
||||
Dim c = Integer.Parse(Uuid(23), Globalization.NumberStyles.AllowHexSpecifier)
|
||||
Dim d = Integer.Parse(Uuid(31), Globalization.NumberStyles.AllowHexSpecifier)
|
||||
Return If((a Xor b Xor c Xor d) Mod 2, "Alex", "Steve")
|
||||
'Math.floorMod(uuid.hashCode(), 18)
|
||||
|
||||
'Public Function hashCode(ByVal str As String) As Integer
|
||||
'Dim hash As Integer = 0
|
||||
'Dim n As Integer = str.Length
|
||||
'If n = 0 Then
|
||||
' Return hash
|
||||
'End If
|
||||
'For i As Integer = 0 To n - 1
|
||||
' hash = hash + Asc(str(i)) * (1 << (n - i - 1))
|
||||
'Next
|
||||
'Return hash
|
||||
'End Function
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
@@ -2366,7 +1669,10 @@ NextVersion:
|
||||
End If
|
||||
End If
|
||||
If Not IsNothing(Rule("features")) Then '标签
|
||||
IsRightRule = IsRightRule AndAlso IsNothing(Rule("features")("is_demo_user")) '只反选是否为 Demo 用户
|
||||
IsRightRule = IsRightRule AndAlso IsNothing(Rule("features")("is_demo_user")) '反选是否为 Demo 用户
|
||||
If CType(Rule("features"), JObject).Children.Any(Function(j As JProperty) j.Name.StartsWith("is_quick_play")) Then
|
||||
IsRightRule = False '不开 Quick Play,让玩家自己加去
|
||||
End If
|
||||
End If
|
||||
|
||||
'反选确认
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
TimerLog()
|
||||
'设置窗口标题
|
||||
For i = 1 To 3
|
||||
If IsWindowFinished AndAlso WindowTitle <> "" AndAlso State = MinecraftState.Running AndAlso Not GameProcess.HasExited Then
|
||||
If IsWindowFinished AndAlso IsWindowAppeared AndAlso WindowTitle <> "" AndAlso State = MinecraftState.Running AndAlso Not GameProcess.HasExited Then
|
||||
Dim RealTitle As String = WindowTitle.Replace("{time}", Date.Now.ToShortTimeString)
|
||||
SetWindowText(WindowHandle, RealTitle.ToCharArray)
|
||||
End If
|
||||
@@ -248,6 +248,9 @@
|
||||
|
||||
'窗口检查
|
||||
Private IsWindowAppeared As Boolean = False
|
||||
''' <summary>
|
||||
''' 窗口检查是否已经完成。这不一定代表着找到了窗口(如果没有找到,IsWindowAppeared 仍为 False)。
|
||||
''' </summary>
|
||||
Private IsWindowFinished As Boolean = False
|
||||
Private WindowHandle As IntPtr
|
||||
Private Sub TimerWindow()
|
||||
@@ -255,7 +258,14 @@
|
||||
If GameProcess.HasExited Then Exit Sub
|
||||
If IsWindowFinished Then Exit Sub
|
||||
'获取全部窗口,检查是否有新增的
|
||||
Dim MinecraftWindow = TryGetMinecraftWindow()
|
||||
Dim MinecraftWindow As KeyValuePair(Of IntPtr, String)? = Nothing
|
||||
Try
|
||||
MinecraftWindow = TryGetMinecraftWindow()
|
||||
Catch ex As ComponentModel.Win32Exception
|
||||
'拒绝访问(#1062)
|
||||
Log(ex, "由于反作弊或安全软件拦截,PCL 无法操作游戏窗口", LogLevel.Hint)
|
||||
IsWindowFinished = True
|
||||
End Try
|
||||
If MinecraftWindow Is Nothing Then Exit Sub
|
||||
Dim MinecraftWindowName = MinecraftWindow.Value.Value, MinecraftWindowHandle = MinecraftWindow.Value.Key
|
||||
'已找到窗口
|
||||
|
||||
@@ -49,17 +49,17 @@
|
||||
<Grid Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" VerticalAlignment="Bottom"
|
||||
IsHitTestVisible="False" SnapsToDevicePixels="False" UseLayoutRounding="False">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="CompItemVersion" />
|
||||
<ColumnDefinition Width="0.7*" x:Name="ColumnVersionMargin" />
|
||||
<ColumnDefinition x:Name="ColumnVersion1" Width="Auto" />
|
||||
<ColumnDefinition x:Name="ColumnVersion2" Width="Auto" SharedSizeGroup="CompItemVersion" />
|
||||
<ColumnDefinition x:Name="ColumnVersion3" Width="0.7*" />
|
||||
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="55" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" MinWidth="57" SharedSizeGroup="CompItemTime" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition x:Name="ColumnTime1" Width="Auto" />
|
||||
<ColumnDefinition x:Name="ColumnTime2" Width="Auto" MinWidth="57" SharedSizeGroup="CompItemTime" />
|
||||
<ColumnDefinition x:Name="ColumnTime3" Width="1*" />
|
||||
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="CompItemSource" />
|
||||
|
||||
@@ -259,7 +259,10 @@
|
||||
PreviousVolume = Setup.Get("UiMusicVolume")
|
||||
CurrentWave.Volume = PreviousVolume / 1000
|
||||
End If
|
||||
Thread.Sleep(50)
|
||||
'更新进度条
|
||||
Dim Percent = Reader.CurrentTime.TotalMilliseconds / Reader.TotalTime.TotalMilliseconds
|
||||
RunInUi(Sub() FrmMain.BtnExtraMusic.Progress = Percent)
|
||||
Thread.Sleep(100)
|
||||
End While
|
||||
'当前音乐已播放结束,继续下一曲
|
||||
If CurrentWave.PlaybackState = NAudio.Wave.PlaybackState.Stopped AndAlso MusicAllList.Count > 0 Then MusicStartPlay(DequeueNextMusicAddress)
|
||||
|
||||
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
|
||||
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
' 方法是按如下所示使用“*”
|
||||
|
||||
<Assembly: AssemblyVersion("2.5.2.0")>
|
||||
<Assembly: AssemblyFileVersion("2.5.2.0")>
|
||||
<Assembly: AssemblyVersion("2.5.3.0")>
|
||||
<Assembly: AssemblyFileVersion("2.5.3.0")>
|
||||
<Assembly: NeutralResourcesLanguage("")>
|
||||
|
||||
@@ -382,8 +382,17 @@ Public Module ModDownloadLib
|
||||
'选择 Java
|
||||
Dim Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
|
||||
If Java Is Nothing Then
|
||||
JavaMissing(17)
|
||||
Throw New Exception("未找到用于安装 OptiFine 的 Java")
|
||||
If Not JavaDownloadConfirm(17) Then Throw New Exception("由于未找到 Java,已取消安装。")
|
||||
'开始自动下载
|
||||
Dim JavaLoader = JavaFixLoaders(17)
|
||||
JavaLoader.Start(17, IsForceRestart:=True)
|
||||
Do While JavaLoader.State = LoadState.Loading AndAlso Not Task.IsAborted
|
||||
Thread.Sleep(10)
|
||||
Loop
|
||||
'检查下载结果
|
||||
Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
|
||||
If Task.IsAborted Then Exit Sub
|
||||
If Java Is Nothing Then Throw New Exception("由于未找到 Java,已取消安装。")
|
||||
End If
|
||||
'添加 Java Wrapper 作为主 Jar
|
||||
Dim Arguments = "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """ -Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & ExtractJavaWrapper() & """ optifine.Installer"
|
||||
@@ -1099,8 +1108,17 @@ Public Module ModDownloadLib
|
||||
'选择 Java
|
||||
Dim Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
|
||||
If Java Is Nothing Then
|
||||
JavaMissing(17)
|
||||
Throw New Exception("未找到用于安装 Forge 的 Java")
|
||||
If Not JavaDownloadConfirm(17) Then Throw New Exception("由于未找到 Java,已取消安装。")
|
||||
'开始自动下载
|
||||
Dim JavaLoader = JavaFixLoaders(17)
|
||||
JavaLoader.Start(17, IsForceRestart:=True)
|
||||
Do While JavaLoader.State = LoadState.Loading AndAlso Not Task.IsAborted
|
||||
Thread.Sleep(10)
|
||||
Loop
|
||||
'检查下载结果
|
||||
Java = JavaSelect("已取消安装。", New Version(1, 8, 0, 0))
|
||||
If Task.IsAborted Then Exit Sub
|
||||
If Java Is Nothing Then Throw New Exception("由于未找到 Java,已取消安装。")
|
||||
End If
|
||||
'添加 Java Wrapper 作为主 Jar
|
||||
Dim Arguments = "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """ -cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & ExtractJavaWrapper() & """ com.bangbang93.ForgeInstaller """ & McFolder
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
Version("id") = "20w14∞"
|
||||
Version("type") = "special"
|
||||
Version.Add("lore", GetMcFoolName(Version("id")))
|
||||
Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime"
|
||||
Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime", "23w13a_or_b"
|
||||
Type = "愚人节版"
|
||||
Version("type") = "special"
|
||||
Version.Add("lore", GetMcFoolName(Version("id")))
|
||||
|
||||
@@ -100,9 +100,7 @@
|
||||
</Grid>
|
||||
</local:MyCard>
|
||||
<local:MyCard Title="Fabric" Height="40" Margin="0,15,0,0" x:Name="CardFabric" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
|
||||
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top">
|
||||
<StackPanel Name="PanFabric" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanFabric" />
|
||||
<Grid x:Name="PanFabricInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
|
||||
<Grid.RenderTransform>
|
||||
<TranslateTransform />
|
||||
|
||||
@@ -522,7 +522,7 @@
|
||||
Version("id") = "20w14∞"
|
||||
Version("type") = "special"
|
||||
Version.Add("lore", GetMcFoolName(Version("id")))
|
||||
Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime"
|
||||
Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime", "23w13a_or_b"
|
||||
Type = "愚人节版"
|
||||
Version("type") = "special"
|
||||
Version.Add("lore", GetMcFoolName(Version("id")))
|
||||
@@ -859,16 +859,16 @@
|
||||
If Versions.Count = 0 Then Exit Sub
|
||||
'可视化
|
||||
PanFabric.Children.Clear()
|
||||
For Each Version In Versions
|
||||
PanFabric.Children.Add(FabricDownloadListItem(Version, AddressOf Fabric_Selected))
|
||||
Next
|
||||
PanFabric.Tag = Versions
|
||||
CardFabric.SwapControl = PanFabric
|
||||
CardFabric.SwapType = 12
|
||||
Catch ex As Exception
|
||||
Log(ex, "可视化 Fabric 安装版本列表出错", LogLevel.Feedback)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'选择与清除
|
||||
Private Sub Fabric_Selected(sender As MyListItem, e As EventArgs)
|
||||
Public Sub Fabric_Selected(sender As MyListItem, e As EventArgs)
|
||||
SelectedFabric = sender.Tag("version").ToString
|
||||
FabricApi_Loaded()
|
||||
OptiFabric_Loaded()
|
||||
|
||||
@@ -10,22 +10,55 @@
|
||||
<StackPanel Margin="25,40,25,15">
|
||||
<Grid Margin="0,0,0,11" HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="70" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="1.3*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="9" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="名称" Margin="0,0,25,0" />
|
||||
<local:MyTextBox x:Name="TextSearchName" Grid.Column="1" Grid.ColumnSpan="10" />
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="类型" Margin="0,0,25,0" />
|
||||
<local:MyComboBox x:Name="ComboSearchTag" Grid.Column="1" Grid.Row="2" MaxDropDownHeight="320">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="名称" Margin="0,0,18,0" />
|
||||
<local:MyTextBox x:Name="TextSearchName" Grid.Column="1" Grid.ColumnSpan="2" />
|
||||
<TextBlock VerticalAlignment="Center" Grid.Column="4" HorizontalAlignment="Left" Text="来源" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="ComboSearchSource" Grid.Column="5">
|
||||
<local:MyComboBoxItem Content="全部" Tag="3" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="CurseForge" Tag="1" />
|
||||
<local:MyComboBoxItem Content="Modrinth" Tag="2" />
|
||||
</local:MyComboBox>
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" IsEditable="True" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.19.4" />
|
||||
<local:MyComboBoxItem Content="1.19.3" />
|
||||
<local:MyComboBoxItem Content="1.19.2" />
|
||||
<local:MyComboBoxItem Content="1.19.1" />
|
||||
<local:MyComboBoxItem Content="1.19" />
|
||||
<local:MyComboBoxItem Content="1.18.2" />
|
||||
<local:MyComboBoxItem Content="1.17.1" />
|
||||
<local:MyComboBoxItem Content="1.16.5" />
|
||||
<local:MyComboBoxItem Content="1.15.2" />
|
||||
<local:MyComboBoxItem Content="1.14.4" />
|
||||
<local:MyComboBoxItem Content="1.13.2" />
|
||||
<local:MyComboBoxItem Content="1.12.2" />
|
||||
<local:MyComboBoxItem Content="1.11.2" />
|
||||
<local:MyComboBoxItem Content="1.10.2" />
|
||||
<local:MyComboBoxItem Content="1.9.4" />
|
||||
<local:MyComboBoxItem Content="1.8.9" />
|
||||
<local:MyComboBoxItem Content="1.7.10" />
|
||||
</local:MyComboBox>
|
||||
<local:MyComboBox x:Name="ComboSearchLoader" Visibility="Collapsed" Grid.Row="2" Grid.Column="2" MaxDropDownHeight="320" Margin="10,0,0,0">
|
||||
<local:MyComboBoxItem Content="任意 Mod 加载器" IsSelected="True" Tag="0" />
|
||||
<local:MyComboBoxItem Content="Forge" Tag="1" />
|
||||
<local:MyComboBoxItem Content="Fabric" Tag="4" />
|
||||
<local:MyComboBoxItem Content="Quilt" Tag="5" />
|
||||
</local:MyComboBox>
|
||||
<TextBlock VerticalAlignment="Center" Grid.Column="4" Grid.Row="2" HorizontalAlignment="Left" Text="类型" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="ComboSearchTag" Grid.Column="5" Grid.Row="2" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Content="全部" Tag="" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="世界元素" Tag="406/worldgen" />
|
||||
<local:MyComboBoxItem Content="生物群系" Tag="407/" Margin="15,0,0,0" />
|
||||
@@ -53,33 +86,6 @@
|
||||
<local:MyComboBoxItem Content="改良" Tag="5191/utility" />
|
||||
<local:MyComboBoxItem Content="支持库" Tag="421/library" />
|
||||
</local:MyComboBox>
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="版本" Margin="0,0,25,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="4" Grid.ColumnSpan="2" IsEditable="True" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.19.4" />
|
||||
<local:MyComboBoxItem Content="1.19.3" />
|
||||
<local:MyComboBoxItem Content="1.19.2" />
|
||||
<local:MyComboBoxItem Content="1.19.1" />
|
||||
<local:MyComboBoxItem Content="1.19" />
|
||||
<local:MyComboBoxItem Content="1.18.2" />
|
||||
<local:MyComboBoxItem Content="1.17.1" />
|
||||
<local:MyComboBoxItem Content="1.16.5" />
|
||||
<local:MyComboBoxItem Content="1.15.2" />
|
||||
<local:MyComboBoxItem Content="1.14.4" />
|
||||
<local:MyComboBoxItem Content="1.13.2" />
|
||||
<local:MyComboBoxItem Content="1.12.2" />
|
||||
<local:MyComboBoxItem Content="1.11.2" />
|
||||
<local:MyComboBoxItem Content="1.10.2" />
|
||||
<local:MyComboBoxItem Content="1.9.4" />
|
||||
<local:MyComboBoxItem Content="1.8.9" />
|
||||
<local:MyComboBoxItem Content="1.7.10" />
|
||||
</local:MyComboBox>
|
||||
<local:MyComboBox x:Name="ComboSearchLoader" Visibility="Collapsed" Grid.Row="2" Grid.Column="5" MaxDropDownHeight="320" Margin="10,0,0,0">
|
||||
<local:MyComboBoxItem Content="任意 Mod 加载器" IsSelected="True" Tag="0" />
|
||||
<local:MyComboBoxItem Content="Forge" Tag="1" />
|
||||
<local:MyComboBoxItem Content="Fabric" Tag="4" />
|
||||
<local:MyComboBoxItem Content="Quilt" Tag="5" />
|
||||
</local:MyComboBox>
|
||||
</Grid>
|
||||
<Grid Margin="0,4,0,6" Height="35">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
End Sub
|
||||
Private Shared Function LoaderInput() As CompProjectRequest
|
||||
Dim Request As New CompProjectRequest(CompType.Mod, Storage, (Page + 1) * PageSize)
|
||||
If FrmDownloadMod IsNot Nothing AndAlso FrmDownloadMod.IsLoaded Then
|
||||
If FrmDownloadMod IsNot Nothing Then
|
||||
With Request
|
||||
.SearchText = FrmDownloadMod.TextSearchName.Text
|
||||
.GameVersion = If(FrmDownloadMod.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
|
||||
If(FrmDownloadMod.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadMod.TextSearchVersion.Text.Contains("w"), FrmDownloadMod.TextSearchVersion.Text, Nothing))
|
||||
.Tag = FrmDownloadMod.ComboSearchTag.SelectedItem.Tag
|
||||
.ModLoader = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag)
|
||||
.Source = CType(Val(FrmDownloadMod.ComboSearchSource.SelectedItem.Tag), CompSourceType)
|
||||
End With
|
||||
End If
|
||||
Return Request
|
||||
|
||||
@@ -10,21 +10,48 @@
|
||||
<StackPanel Margin="25,40,25,15">
|
||||
<Grid Margin="0,0,0,11" HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="70" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="2.5*" />
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="9" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="名称" Margin="0,0,25,0" />
|
||||
<local:MyTextBox x:Name="TextSearchName" Grid.Column="1" Grid.ColumnSpan="10" HintText="仅支持使用英文搜索" />
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="类型" Margin="0,0,25,0" />
|
||||
<local:MyComboBox x:Name="ComboSearchTag" Grid.Column="1" Grid.Row="2" MaxDropDownHeight="320">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="名称" Margin="0,0,18,0" />
|
||||
<local:MyTextBox x:Name="TextSearchName" Grid.Column="1" />
|
||||
<TextBlock VerticalAlignment="Center" Grid.Column="3" HorizontalAlignment="Left" Text="来源" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="ComboSearchSource" Grid.Column="4">
|
||||
<local:MyComboBoxItem Content="全部" Tag="3" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="CurseForge" Tag="1" />
|
||||
<local:MyComboBoxItem Content="Modrinth" Tag="2" />
|
||||
</local:MyComboBox>
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="1" IsEditable="True" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.19.4" />
|
||||
<local:MyComboBoxItem Content="1.19.3" />
|
||||
<local:MyComboBoxItem Content="1.19.2" />
|
||||
<local:MyComboBoxItem Content="1.19.1" />
|
||||
<local:MyComboBoxItem Content="1.19" />
|
||||
<local:MyComboBoxItem Content="1.18.2" />
|
||||
<local:MyComboBoxItem Content="1.17.1" />
|
||||
<local:MyComboBoxItem Content="1.16.5" />
|
||||
<local:MyComboBoxItem Content="1.15.2" />
|
||||
<local:MyComboBoxItem Content="1.14.4" />
|
||||
<local:MyComboBoxItem Content="1.13.2" />
|
||||
<local:MyComboBoxItem Content="1.12.2" />
|
||||
<local:MyComboBoxItem Content="1.11.2" />
|
||||
<local:MyComboBoxItem Content="1.10.2" />
|
||||
<local:MyComboBoxItem Content="1.9.4" />
|
||||
<local:MyComboBoxItem Content="1.8.9" />
|
||||
<local:MyComboBoxItem Content="1.7.10" />
|
||||
</local:MyComboBox>
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="类型" Margin="0,0,18,0" />
|
||||
<local:MyComboBox x:Name="ComboSearchTag" Grid.Column="4" Grid.Row="2" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Tag="" Content="全部" IsSelected="True" />
|
||||
<local:MyComboBoxItem Tag="4484/" Content="多人" />
|
||||
<local:MyComboBoxItem Tag="/optimization" Content="性能优化" />
|
||||
@@ -45,27 +72,6 @@
|
||||
<local:MyComboBoxItem Tag="4481/lightweight" Content="轻量整合" />
|
||||
<local:MyComboBoxItem Tag="4482/" Content="大型整合" />
|
||||
</local:MyComboBox>
|
||||
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="版本" Margin="0,0,25,0" />
|
||||
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="4" IsEditable="True" MaxDropDownHeight="320">
|
||||
<local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" />
|
||||
<local:MyComboBoxItem Content="1.19.4" />
|
||||
<local:MyComboBoxItem Content="1.19.3" />
|
||||
<local:MyComboBoxItem Content="1.19.2" />
|
||||
<local:MyComboBoxItem Content="1.19.1" />
|
||||
<local:MyComboBoxItem Content="1.19" />
|
||||
<local:MyComboBoxItem Content="1.18.2" />
|
||||
<local:MyComboBoxItem Content="1.17.1" />
|
||||
<local:MyComboBoxItem Content="1.16.5" />
|
||||
<local:MyComboBoxItem Content="1.15.2" />
|
||||
<local:MyComboBoxItem Content="1.14.4" />
|
||||
<local:MyComboBoxItem Content="1.13.2" />
|
||||
<local:MyComboBoxItem Content="1.12.2" />
|
||||
<local:MyComboBoxItem Content="1.11.2" />
|
||||
<local:MyComboBoxItem Content="1.10.2" />
|
||||
<local:MyComboBoxItem Content="1.9.4" />
|
||||
<local:MyComboBoxItem Content="1.8.9" />
|
||||
<local:MyComboBoxItem Content="1.7.10" />
|
||||
</local:MyComboBox>
|
||||
</Grid>
|
||||
<Grid Margin="0,4,0,6" Height="35">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
@@ -6,18 +6,19 @@
|
||||
Public Shared Loader As New LoaderTask(Of CompProjectRequest, Integer)("CompProject ModPack", AddressOf CompProjectsGet, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000}
|
||||
Public Shared Storage As New CompProjectStorage
|
||||
Public Shared Page As Integer = 0
|
||||
Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
|
||||
Private Sub PageDownloadPack_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
|
||||
PageLoaderInit(Load, PanLoad, PanContent, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
|
||||
McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1)))
|
||||
End Sub
|
||||
Private Shared Function LoaderInput() As CompProjectRequest
|
||||
Dim Request As New CompProjectRequest(CompType.ModPack, Storage, (Page + 1) * PageSize)
|
||||
If FrmDownloadPack IsNot Nothing AndAlso FrmDownloadPack.IsLoaded Then
|
||||
If FrmDownloadPack IsNot Nothing Then
|
||||
With Request
|
||||
.SearchText = FrmDownloadPack.TextSearchName.Text
|
||||
.GameVersion = If(FrmDownloadPack.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
|
||||
If(FrmDownloadPack.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadPack.TextSearchVersion.Text.Contains("w"), FrmDownloadPack.TextSearchVersion.Text, Nothing))
|
||||
.Tag = FrmDownloadPack.ComboSearchTag.SelectedItem.Tag
|
||||
.Source = CType(Val(FrmDownloadPack.ComboSearchSource.SelectedItem.Tag), CompSourceType)
|
||||
End With
|
||||
End If
|
||||
Return Request
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
If(RamGame <> RamGameActual, " (可用 " & If(RamGameActual = Math.Floor(RamGameActual), RamGameActual & ".0", RamGameActual) & " GB)", "")
|
||||
LabRamUsed.Text = If(RamUsed = Math.Floor(RamUsed), RamUsed & ".0", RamUsed) & " GB"
|
||||
LabRamTotal.Text = " / " & If(RamTotal = Math.Floor(RamTotal), RamTotal & ".0", RamTotal) & " GB"
|
||||
LabRamWarn.Visibility = If(RamGame = 1 AndAlso Not JavaUse64Bit() AndAlso Not Is32BitSystem, Visibility.Visible, Visibility.Collapsed)
|
||||
LabRamWarn.Visibility = If(RamGame = 1 AndAlso Not JavaIs64Bit() AndAlso Not Is32BitSystem, Visibility.Visible, Visibility.Collapsed)
|
||||
If ShowAnim Then
|
||||
'宽度动画
|
||||
AniStart({
|
||||
@@ -413,7 +413,7 @@ PreFin:
|
||||
End If
|
||||
End If
|
||||
'若使用 32 位 Java,则限制为 1G
|
||||
If Not JavaUse64Bit(If(UseVersionJavaSetup, Version, Nothing)) Then RamGive = Math.Min(1, RamGive)
|
||||
If Not JavaIs64Bit(If(UseVersionJavaSetup, Version, Nothing)) Then RamGive = Math.Min(1, RamGive)
|
||||
Return RamGive
|
||||
End Function
|
||||
|
||||
@@ -487,18 +487,14 @@ PreFin:
|
||||
Exit Sub
|
||||
End If
|
||||
'选择 Java
|
||||
Dim JavaSelected As String = SelectFile("javaw.exe|javaw.exe", "选择 javaw.exe 文件")
|
||||
Dim JavaSelected As String = SelectFile("javaw.exe|javaw.exe", "选择 bin 文件夹中的 javaw.exe 文件")
|
||||
If JavaSelected = "" Then Exit Sub
|
||||
If Not JavaSelected.ToLower.EndsWith("javaw.exe") Then
|
||||
Hint("请选择 bin 文件夹中的 javaw.exe 文件!", HintType.Critical)
|
||||
Exit Sub
|
||||
End If
|
||||
JavaSelected = GetPathFromFullPath(JavaSelected)
|
||||
Try
|
||||
'验证 Java 可用
|
||||
Dim NewEntry As New JavaEntry(JavaSelected, True)
|
||||
NewEntry.Check()
|
||||
'加入列表并改变选择
|
||||
'加入列表
|
||||
Dim JavaNewList As New JArray From {NewEntry.ToJson}
|
||||
For Each JsonEntry In GetJson(Setup.Get("LaunchArgumentJavaAll"))
|
||||
Dim Entry = JavaEntry.FromJson(JsonEntry)
|
||||
@@ -506,9 +502,9 @@ PreFin:
|
||||
JavaNewList.Add(JsonEntry)
|
||||
Next
|
||||
Setup.Set("LaunchArgumentJavaAll", JavaNewList.ToString(Newtonsoft.Json.Formatting.None))
|
||||
Setup.Set("LaunchArgumentJavaSelect", NewEntry.ToJson.ToString(Newtonsoft.Json.Formatting.None)) '加载器会优先选择设置中的 Java
|
||||
'重新加载列表
|
||||
JavaSearchLoader.Start(IsForceRestart:=True)
|
||||
Hint("已将该 Java 加入 Java 列表!", HintType.Finish)
|
||||
Catch ex As Exception
|
||||
Log(ex, "该 Java 存在异常,无法使用", LogLevel.Msgbox, "异常的 Java")
|
||||
Exit Sub
|
||||
@@ -522,7 +518,7 @@ PreFin:
|
||||
End If
|
||||
RunInThread(Sub()
|
||||
Hint("正在搜索 Java!")
|
||||
JavaSearchLoader.WaitForExit(GetUuid)
|
||||
JavaSearchLoader.WaitForExit(IsForceRestart:=True)
|
||||
If JavaList.Count = 0 Then
|
||||
Hint("未找到可用的 Java!", HintType.Critical)
|
||||
Else
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
If(RamGame <> RamGameActual, " (可用 " & If(RamGameActual = Math.Floor(RamGameActual), RamGameActual & ".0", RamGameActual) & " GB)", "")
|
||||
LabRamUsed.Text = If(RamUsed = Math.Floor(RamUsed), RamUsed & ".0", RamUsed) & " GB"
|
||||
LabRamTotal.Text = " / " & If(RamTotal = Math.Floor(RamTotal), RamTotal & ".0", RamTotal) & " GB"
|
||||
LabRamWarn.Visibility = If(RamGame = 1 AndAlso Not JavaUse64Bit(PageVersionLeft.Version) AndAlso Not Is32BitSystem, Visibility.Visible, Visibility.Collapsed)
|
||||
LabRamWarn.Visibility = If(RamGame = 1 AndAlso Not JavaIs64Bit(PageVersionLeft.Version) AndAlso Not Is32BitSystem, Visibility.Visible, Visibility.Collapsed)
|
||||
If ShowAnim Then
|
||||
'宽度动画
|
||||
AniStart({
|
||||
@@ -349,7 +349,7 @@ PreFin:
|
||||
End If
|
||||
End If
|
||||
'若使用 32 位 Java,则限制为 1G
|
||||
If Not JavaUse64Bit(PageVersionLeft.Version) Then RamGive = Math.Min(1, RamGive)
|
||||
If Not JavaIs64Bit(PageVersionLeft.Version) Then RamGive = Math.Min(1, RamGive)
|
||||
Return RamGive
|
||||
End Function
|
||||
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
<Compile Include="Controls\MyPageRight.vb" />
|
||||
<Compile Include="Controls\MyPageLeft.vb" />
|
||||
<Compile Include="Modules\Minecraft\ModComp.vb" />
|
||||
<Compile Include="Modules\Minecraft\ModJava.vb" />
|
||||
<Compile Include="Modules\Minecraft\ModModpack.vb" />
|
||||
<Compile Include="Modules\ModEvent.vb" />
|
||||
<Compile Include="Controls\MyExtraButton.xaml.vb">
|
||||
|
||||
@@ -280,7 +280,6 @@ local:MyCard(卡片):
|
||||
local:MyHint(提示条):
|
||||
- Text:设置显示的文本(
 代表换行)
|
||||
- IsWarn:设置为 True 代表警告样式,False 代表提示样式
|
||||
- Foreground:调整前景颜色(十六进制字符串,例如 #FF010203 代表 ARGB 中的 255,1,2,3。前两位代表不透明度,FF 为全不透明,00 为全透明)
|
||||
- HorizontalAlignment:设置对齐方式(Left、Center、Right)
|
||||
|
||||
local:MyButton(按钮):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user