Merge branch 'main' into resourcepacks

This commit is contained in:
Pigeon0v0
2024-07-11 20:38:14 +08:00
committed by GitHub
57 changed files with 1832 additions and 1060 deletions
+2 -1
View File
@@ -9,6 +9,7 @@ on:
paths: paths:
- 'Plain Craft Launcher 2/**' - 'Plain Craft Launcher 2/**'
- '.github/workflows/**' - '.github/workflows/**'
workflow_dispatch:
jobs: jobs:
@@ -29,7 +30,7 @@ jobs:
- name: Set Describe - name: Set Describe
shell: bash shell: bash
run: | run: |
Describe=`git describe --tags` Describe=`git describe --tags --always`
echo "Describe=$Describe" >> $GITHUB_ENV echo "Describe=$Describe" >> $GITHUB_ENV
- name: Setup MSBuild.exe - name: Setup MSBuild.exe
+5 -9
View File
@@ -3,7 +3,7 @@
一、承诺与声明。 一、承诺与声明。
  开发者承诺,在您遵守本指南的情况下,不会追究您的法律责任,但最终裁量权仍由开发者保留。   开发者承诺,在您遵守本指南的情况下,不会追究您的法律责任,但最终裁量权仍由开发者保留。
  开发者仍保留所有权利(All Rights Reserved),且可能随时修改本指南,本指南并不是永久性保证。   法律上,开发者仍保留所有权利(All Rights Reserved),且可能随时修改本指南,本指南并不是永久性保证。
二、少量使用情形。 二、少量使用情形。
@@ -16,9 +16,9 @@
  如果您基于该存储库进行衍生创作,或合理使用了本存储库中的较大量内容,您必须:   如果您基于该存储库进行衍生创作,或合理使用了本存储库中的较大量内容,您必须:
  (一)给出适当的署名,且提供指向本存储库的链接。   (一)给出适当的署名,且提供指向本存储库的链接。
  (二)不得以任何方式暗示开发者为您或您的使用作担保。   (二)不得以任何方式暗示开发者为您或您的使用作担保。
  (三)给出适当的说明,表示这是第三方内容。   (三)给出适当的说明,表示这是第三方内容。在 GitHub 上直接进行 Fork 是允许的。
  (四)使用本指南文件作为协议,不得附加额外条款。   (四)使用本指南文件作为协议,不得附加额外条款。
  (五)不得分发编译后的可执行文件。   (五)不得分发编译后的可执行文件。唯一的例外是,你可以在明确禁止再次分发的前提下,在小于 100 人的 QQ 群内分发编译后的可执行文件。
———————————— ————————————
@@ -27,9 +27,5 @@
因为没有法律专业人士检查,所以这不敢作为正式的法律协议,如果有专业人士愿意帮忙改一改我也很乐意…… 因为没有法律专业人士检查,所以这不敢作为正式的法律协议,如果有专业人士愿意帮忙改一改我也很乐意……
这些规则主要是为了阻止恶意的使用和 “山寨版” 的出现,常规、善意的使用都没啥问题的,放心吧! 这些规则主要是为了阻止恶意的使用和 “山寨版” 的出现,常规、善意的使用都没啥问题的,放心吧!
如果你只是想参考一下,或者用了一小部分代码: 如果你只是想参考一下,或者用了一小部分代码,署个名就行啦。
  署名就行啦。 如果你整了个魔改版,或者用了一大堆代码,请仔细参考上面的第三条。
如果你整了个魔改版,或者用了一大堆代码:
  你不能把编译后的文件发给其他人,但可以私下使用。
如果你修改了代码,并且打算公开:
  请仔细参考上面的第三条。
+8 -15
View File
@@ -98,21 +98,13 @@
'排序 '排序
Select Case Type Select Case Type
Case 3 Case 3
Stack.Tag = Sort(CType(Stack.Tag, List(Of DlOptiFineListEntry)), Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean Stack.Tag = Sort(CType(Stack.Tag, List(Of DlOptiFineListEntry)), Function(a, b) VersionSortBoolean(a.NameDisplay, b.NameDisplay))
Return VersionSortBoolean(Left.NameDisplay, Right.NameDisplay)
End Function)
Case 4, 10 Case 4, 10
Stack.Tag = Sort(CType(Stack.Tag, List(Of DlLiteLoaderListEntry)), Function(Left As DlLiteLoaderListEntry, Right As DlLiteLoaderListEntry) As Boolean Stack.Tag = Sort(CType(Stack.Tag, List(Of DlLiteLoaderListEntry)), Function(a, b) VersionSortBoolean(a.Inherit, b.Inherit))
Return VersionSortBoolean(Left.Inherit, Right.Inherit)
End Function)
Case 6 Case 6
Stack.Tag = Sort(CType(Stack.Tag, List(Of DlForgeVersionEntry)), Function(Left As DlForgeVersionEntry, Right As DlForgeVersionEntry) As Boolean Stack.Tag = Sort(CType(Stack.Tag, List(Of DlForgeVersionEntry)), Function(a, b) a.Version > b.Version)
Return VersionSortBoolean(Left.Version, Right.Version)
End Function)
Case 8, 9 Case 8, 9
Stack.Tag = Sort(CType(Stack.Tag, List(Of CompFile)), Function(Left As CompFile, Right As CompFile) As Boolean Stack.Tag = Sort(CType(Stack.Tag, List(Of CompFile)), Function(a, b) a.ReleaseDate > b.ReleaseDate)
Return Left.ReleaseDate > Right.ReleaseDate
End Function)
End Select End Select
'控件转换 '控件转换
Select Case Type Select Case Type
@@ -144,9 +136,8 @@
Case 6 Case 6
Stack.Children.Add(ForgeDownloadListItem(Data, AddressOf ForgeSave_Click, True)) Stack.Children.Add(ForgeDownloadListItem(Data, AddressOf ForgeSave_Click, True))
Case 7 Case 7
Stack.Children.Add(McDownloadListItem(Data, Sub(sender, e) '不能使用 AddressOf,这导致了 #535,原因完全不明,疑似是编译器 Bug '不能使用 AddressOf,这导致了 #535,原因完全不明,疑似是编译器 Bug
FrmDownloadInstall.MinecraftSelected(sender, e) Stack.Children.Add(McDownloadListItem(Data, Sub(sender, e) FrmDownloadInstall.MinecraftSelected(sender, e), False))
End Sub, False))
Case 8 Case 8
If CType(Stack.Tag, List(Of CompFile)).Distinct(Function(a, b) a.DisplayName = b.DisplayName).Count <> If CType(Stack.Tag, List(Of CompFile)).Distinct(Function(a, b) a.DisplayName = b.DisplayName).Count <>
CType(Stack.Tag, List(Of CompFile)).Count Then CType(Stack.Tag, List(Of CompFile)).Count Then
@@ -171,6 +162,8 @@
Stack.Children.Add(CType(Data, HelpEntry).ToListItem) Stack.Children.Add(CType(Data, HelpEntry).ToListItem)
Case 12 Case 12
Stack.Children.Add(FabricDownloadListItem(CType(Data, JObject), AddressOf FrmDownloadInstall.Fabric_Selected)) Stack.Children.Add(FabricDownloadListItem(CType(Data, JObject), AddressOf FrmDownloadInstall.Fabric_Selected))
Case 13
Stack.Children.Add(NeoForgeDownloadListItem(Data, AddressOf NeoForgeSave_Click, True))
Case Else Case Else
Log("未知的虚拟化种类:" & Type, LogLevel.Feedback) Log("未知的虚拟化种类:" & Type, LogLevel.Feedback)
End Select End Select
@@ -74,13 +74,13 @@
'添加结束 Invoke '添加结束 Invoke
If FinishedInvoke IsNot Nothing Then If FinishedInvoke IsNot Nothing Then
AddHandler RealLoader.PreviewFinish, AddHandler RealLoader.PreviewFinish,
Sub() Sub()
Do While PageState = MyPageRight.PageStates.PageExit OrElse PageState = MyPageRight.PageStates.ContentExit Do While PageState = MyPageRight.PageStates.PageExit OrElse PageState = MyPageRight.PageStates.ContentExit
Thread.Sleep(10) '不在退出动画时执行 UI 线程操作,避免退出动画被重置 Thread.Sleep(10) '不在退出动画时执行 UI 线程操作,避免退出动画被重置
Loop Loop
RunInUiWait(Sub() FinishedInvoke(RealLoader)) RunInUiWait(Sub() FinishedInvoke(RealLoader))
Thread.Sleep(20) '由于大量初始化控件会导致掉帧,延迟触发 State 改变事件 Thread.Sleep(20) '由于大量初始化控件会导致掉帧,延迟触发 State 改变事件
End Sub End Sub
End If End If
AddHandler RealLoader.OnStateChangedUi, Sub(Loader As LoaderBase, NewState As LoadState, OldState As LoadState) RunInUi(Sub() PageLoaderState(Loader, NewState, OldState)) AddHandler RealLoader.OnStateChangedUi, Sub(Loader As LoaderBase, NewState As LoadState, OldState As LoadState) RunInUi(Sub() PageLoaderState(Loader, NewState, OldState))
'隐藏 UI '隐藏 UI
+38 -5
View File
@@ -10,6 +10,19 @@ Public Class FormMain
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String)) Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
'统计更新日志条目 '统计更新日志条目
#If BETA Then #If BETA Then
If LastVersion < 330 Then 'Release 2.8.2
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "NeoForge 兼容与自动安装"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持编译、运行 PCL 开源代码"))
FeatureCount += 15
BugCount += 22
End If
If LastVersion < 326 Then 'Release 2.7.4
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "会自动隐藏明显不可用的自动安装选项"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化正版登录流程和 MC 性能"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复正版登录时弹出脚本错误提示的 Bug"))
FeatureCount += 17
BugCount += 19
End If
If LastVersion < 323 Then 'Release 2.7.3 If LastVersion < 323 Then 'Release 2.7.3
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 启动游戏前进行内存优化 设置")) FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 启动游戏前进行内存优化 设置"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 MC 性能")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 MC 性能"))
@@ -108,6 +121,25 @@ Public Class FormMain
'3:BUG+ IMP* FEAT- '3:BUG+ IMP* FEAT-
'2:BUG* IMP- '2:BUG* IMP-
'1:BUG- '1:BUG-
If LastVersion < 329 Then 'Snapshot 2.8.2
If LastVersion >= 327 Then
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Beta 版 NeoForge 的整合包的 Bug"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复自动安装无法选择部分 OptiFine 的 Bug"))
End If
FeatureCount += 4
BugCount += 8
End If
If LastVersion < 328 Then 'Snapshot 2.8.1
If LastVersion = 327 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.12.2- 的 Bug"))
If LastVersion = 327 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法输入解锁码的 Bug"))
If LastVersion = 327 Then BugCount += 1
End If
If LastVersion < 327 Then 'Snapshot 2.8.0
FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "NeoForge 兼容与自动安装"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持编译、运行 PCL 开源代码"))
FeatureCount += 11
BugCount += 14
End If
If LastVersion < 325 Then 'Snapshot 2.7.4 If LastVersion < 325 Then 'Snapshot 2.7.4
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "会自动隐藏明显不可用的自动安装选项")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "会自动隐藏明显不可用的自动安装选项"))
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化正版登录流程和 MC 性能")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化正版登录流程和 MC 性能"))
@@ -1019,11 +1051,12 @@ Install:
DownloadClient = 4 DownloadClient = 4
DownloadOptiFine = 5 DownloadOptiFine = 5
DownloadForge = 6 DownloadForge = 6
DownloadFabric = 7 DownloadNeoForge = 7
DownloadLiteLoader = 8 DownloadFabric = 8
DownloadMod = 10 DownloadLiteLoader = 9
DownloadPack = 11 DownloadMod = 11
DownloadResourcePack = 12 DownloadPack = 12
DownloadResourcePack = 13
SetupLaunch = 0 SetupLaunch = 0
SetupUI = 1 SetupUI = 1
SetupSystem = 2 SetupSystem = 2
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

+94 -71
View File
@@ -11,12 +11,12 @@ Public Module ModBase
#Region "声明" #Region "声明"
'下列版本信息由更新器自动修改 '下列版本信息由更新器自动修改
Public Const VersionBaseName As String = "2.7.4" '不含分支前缀的显示用版本名 Public Const VersionBaseName As String = "2.8.2" '不含分支前缀的显示用版本名
Public Const VersionStandardCode As String = "2.7.4." & VersionBranchCode '标准格式的四段式版本号 Public Const VersionStandardCode As String = "2.8.2." & VersionBranchCode '标准格式的四段式版本号
#If BETA Then #If BETA Then
Public Const VersionCode As Integer = 323 'Release Public Const VersionCode As Integer = 330 'Release
#Else #Else
Public Const VersionCode As Integer = 325 'Snapshot Public Const VersionCode As Integer = 329 'Snapshot
#End If #End If
'自动生成的版本信息 '自动生成的版本信息
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -86,7 +86,7 @@ Public Module ModBase
''' <summary> ''' <summary>
''' 系统盘盘符,以 \ 结尾。例如 “C:\”。 ''' 系统盘盘符,以 \ 结尾。例如 “C:\”。
''' </summary> ''' </summary>
Public OsDrive As String = Environment.GetLogicalDrives().First.ToUpper.First & ":\" Public OsDrive As String = Environment.GetLogicalDrives().Where(Function(p) Directory.Exists(p)).First.ToUpper.First & ":\" '#3799
''' <summary> ''' <summary>
''' 程序的缓存文件夹路径,以 \ 结尾。 ''' 程序的缓存文件夹路径,以 \ 结尾。
''' </summary> ''' </summary>
@@ -1257,12 +1257,19 @@ Re:
Dim DeletedCount As Integer = 0 Dim DeletedCount As Integer = 0
Dim Temp As String() Dim Temp As String()
Temp = Directory.GetFiles(Path) Temp = Directory.GetFiles(Path)
For Each str As String In Temp For Each FilePath As String In Temp
Dim RetriedFile As Boolean = False
RetryFile:
Try Try
File.Delete(str) File.Delete(FilePath)
DeletedCount += 1 DeletedCount += 1
Catch ex As Exception Catch ex As Exception
If IgnoreIssue Then If Not RetriedFile Then
RetriedFile = True
Log(ex, $"删除文件失败,将在 0.3s 后重试({FilePath})")
Thread.Sleep(300)
GoTo RetryFile
ElseIf IgnoreIssue Then
Log(ex, "删除单个文件可忽略地失败") Log(ex, "删除单个文件可忽略地失败")
Else Else
Throw Throw
@@ -1273,10 +1280,17 @@ Re:
For Each str As String In Temp For Each str As String In Temp
DeleteDirectory(str, IgnoreIssue) DeleteDirectory(str, IgnoreIssue)
Next Next
Dim RetriedDir As Boolean = False
RetryDir:
Try Try
Directory.Delete(Path, True) Directory.Delete(Path, True)
Catch ex As Exception Catch ex As Exception
If IgnoreIssue Then If Not RetriedDir Then
RetriedDir = True
Log(ex, $"删除文件夹失败,将在 0.3s 后重试({Path})")
Thread.Sleep(300)
GoTo RetryDir
ElseIf IgnoreIssue Then
Log(ex, "删除单个文件夹可忽略地失败") Log(ex, "删除单个文件夹可忽略地失败")
Else Else
Throw Throw
@@ -1652,7 +1666,10 @@ Re:
''' 为字符串进行 XML 转义。 ''' 为字符串进行 XML 转义。
''' </summary> ''' </summary>
Public Function EscapeXML(Str As String) As String Public Function EscapeXML(Str As String) As String
Return Str.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("'", "&apos;").Replace("""", "&quot;").Replace(vbCrLf, "&#xa;") If Str.StartsWithF("{") Then Str = "{}" & Str '#4187
Return Str.
Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("'", "&apos;").
Replace("""", "&quot;").Replace(vbCrLf, "&#xa;")
End Function End Function
'正则 '正则
@@ -2065,15 +2082,16 @@ NextElement:
''' 在新的工作线程中执行代码。 ''' 在新的工作线程中执行代码。
''' </summary> ''' </summary>
Public Function RunInNewThread(Action As Action, Name As String, Optional Priority As ThreadPriority = ThreadPriority.Normal) As Thread Public Function RunInNewThread(Action As Action, Name As String, Optional Priority As ThreadPriority = ThreadPriority.Normal) As Thread
Dim th As New Thread(Sub() Dim th As New Thread(
Try Sub()
Action() Try
Catch ex As ThreadInterruptedException Action()
Log(Name & ":线程已中止") Catch ex As ThreadInterruptedException
Catch ex As Exception Log(Name & ":线程已中止")
Log(ex, Name & ":线程执行失败", LogLevel.Feedback) Catch ex As Exception
End Try Log(ex, Name & ":线程执行失败", LogLevel.Feedback)
End Sub) With {.Name = Name, .Priority = Priority} End Try
End Sub) With {.Name = Name, .Priority = Priority}
th.Start() th.Start()
Return th Return th
End Function End Function
@@ -2186,7 +2204,9 @@ NextElement:
''' </summary> ''' </summary>
Public Sub OpenWebsite(Url As String) Public Sub OpenWebsite(Url As String)
Try Try
If Not Url.StartsWithF("http", True) Then Throw New Exception(Url & " 不是一个有效的网址,它必须以 http 开头!") If Not Url.StartsWithF("http", True) AndAlso Not Url.StartsWithF("minecraft://", True) Then
Throw New Exception(Url & " 不是一个有效的网址,它必须以 http 开头!")
End If
Log("[System] 正在打开网页:" & Url) Log("[System] 正在打开网页:" & Url)
Process.Start(Url) Process.Start(Url)
Catch ex As Exception Catch ex As Exception
@@ -2211,25 +2231,27 @@ NextElement:
''' 设置剪贴板。将在另一线程运行,且不会抛出异常。 ''' 设置剪贴板。将在另一线程运行,且不会抛出异常。
''' </summary> ''' </summary>
Public Sub ClipboardSet(Text As String, Optional ShowSuccessHint As Boolean = True) Public Sub ClipboardSet(Text As String, Optional ShowSuccessHint As Boolean = True)
RunInThread(Sub() RunInThread(
Dim RetryCount As Integer = 0 Sub()
Dim RetryCount As Integer = 0
Retry: Retry:
Try Try
RunInUi(Sub() RunInUi(
My.Computer.Clipboard.Clear() Sub()
My.Computer.Clipboard.SetText(Text) My.Computer.Clipboard.Clear()
End Sub) My.Computer.Clipboard.SetText(Text)
Catch ex As Exception End Sub)
RetryCount += 1 Catch ex As Exception
If RetryCount <= 5 Then RetryCount += 1
Thread.Sleep(20) If RetryCount <= 5 Then
GoTo Retry Thread.Sleep(20)
Else GoTo Retry
Log(ex, "可能由于剪贴板被其他程序占用,文本复制失败", LogLevel.Hint) Else
End If Log(ex, "可能由于剪贴板被其他程序占用,文本复制失败", LogLevel.Hint)
End Try End If
If ShowSuccessHint Then Hint("已成功复制!", HintType.Finish) End Try
End Sub) If ShowSuccessHint Then Hint("已成功复制!", HintType.Finish)
End Sub)
End Sub End Sub
''' <summary> ''' <summary>
@@ -2448,39 +2470,40 @@ Retry:
Private LogList As New StringBuilder Private LogList As New StringBuilder
Private LogWritter As StreamWriter Private LogWritter As StreamWriter
Public Sub LogStart() Public Sub LogStart()
RunInNewThread(Sub() RunInNewThread(
Dim IsInitSuccess As Boolean = True Sub()
Try Dim IsInitSuccess As Boolean = True
For i = 4 To 1 Step -1 Try
If File.Exists(Path & "PCL\Log" & i & ".txt") Then For i = 4 To 1 Step -1
If File.Exists(Path & "PCL\Log" & (i + 1) & ".txt") Then File.Delete(Path & "PCL\Log" & (i + 1) & ".txt") If File.Exists(Path & "PCL\Log" & i & ".txt") Then
CopyFile(Path & "PCL\Log" & i & ".txt", Path & "PCL\Log" & (i + 1) & ".txt") If File.Exists(Path & "PCL\Log" & (i + 1) & ".txt") Then File.Delete(Path & "PCL\Log" & (i + 1) & ".txt")
End If CopyFile(Path & "PCL\Log" & i & ".txt", Path & "PCL\Log" & (i + 1) & ".txt")
Next End If
File.Create(Path & "PCL\Log1.txt").Dispose() Next
Catch ex As IOException File.Create(Path & "PCL\Log1.txt").Dispose()
IsInitSuccess = False Catch ex As IOException
Hint("可能同时开启了多个 PCL,程序可能会出现未知问题!", HintType.Critical) IsInitSuccess = False
Log(ex, "日志初始化失败(疑似文件占用问题)") Hint("可能同时开启了多个 PCL,程序可能会出现未知问题!", HintType.Critical)
Catch ex As Exception Log(ex, "日志初始化失败(疑似文件占用问题)")
IsInitSuccess = False Catch ex As Exception
Log(ex, "日志初始化失败", LogLevel.Hint) IsInitSuccess = False
End Try Log(ex, "日志初始化失败", LogLevel.Hint)
Try End Try
LogWritter = New StreamWriter(Path & "PCL\Log1.txt", True) With {.AutoFlush = True} Try
Catch ex As Exception LogWritter = New StreamWriter(Path & "PCL\Log1.txt", True) With {.AutoFlush = True}
LogWritter = Nothing Catch ex As Exception
Log(ex, "日志写入失败", LogLevel.Hint) LogWritter = Nothing
End Try Log(ex, "日志写入失败", LogLevel.Hint)
While True End Try
If IsInitSuccess Then While True
LogFlush() If IsInitSuccess Then
Else LogFlush()
LogList = New StringBuilder '清空 LogList 避免内存爆炸 Else
End If LogList = New StringBuilder '清空 LogList 避免内存爆炸
Thread.Sleep(50) End If
End While Thread.Sleep(50)
End Sub, "Log Writer", ThreadPriority.Lowest) End While
End Sub, "Log Writer", ThreadPriority.Lowest)
End Sub End Sub
Private ReadOnly LogFlushLock As New Object '防止外部调用 LogFlush 时同时输出多次日志 Private ReadOnly LogFlushLock As New Object '防止外部调用 LogFlush 时同时输出多次日志
Public Sub LogFlush() Public Sub LogFlush()
+11 -15
View File
@@ -341,14 +341,15 @@ Retry:
Dim RequestEx As Exception = Nothing Dim RequestEx As Exception = Nothing
Dim FailCount As Integer = 0 Dim FailCount As Integer = 0
For i = 1 To RequestCount For i = 1 To RequestCount
Dim th As New Thread(Sub() Dim th As New Thread(
Try Sub()
RequestResult = NetRequestOnce(Url, Method, Data, ContentType, 30000, Headers) Try
Catch ex As Exception RequestResult = NetRequestOnce(Url, Method, Data, ContentType, 30000, Headers)
FailCount += 1 Catch ex As Exception
RequestEx = ex FailCount += 1
End Try RequestEx = ex
End Sub) End Try
End Sub)
th.Start() th.Start()
Threads.Add(th) Threads.Add(th)
Thread.Sleep(i * 250) Thread.Sleep(i * 250)
@@ -382,7 +383,7 @@ RequestFinished:
Dim Resp As WebResponse = Nothing Dim Resp As WebResponse = Nothing
Dim Req As HttpWebRequest Dim Req As HttpWebRequest
Try Try
Req = WebRequest.Create(New Uri(Url)) Req = WebRequest.Create(Url)
Req.Method = Method Req.Method = Method
Dim SendData As Byte() Dim SendData As Byte()
If TypeOf Data Is Byte() Then If TypeOf Data Is Byte() Then
@@ -1859,15 +1860,10 @@ Retry:
Try Try
While True While True
Thread.Sleep(20) Thread.Sleep(20)
'若已完成,则清空
If Id = 0 AndAlso FileRemain = 0 AndAlso Files.Any() Then
SyncLock LockFiles
Files.Clear()
End SyncLock
End If
'获取文件列表 '获取文件列表
Dim AllFiles As List(Of NetFile) Dim AllFiles As List(Of NetFile)
SyncLock LockFiles SyncLock LockFiles
If Id = 0 AndAlso FileRemain = 0 AndAlso Files.Any() Then Files.Clear() '若已完成,则清空
AllFiles = Files.Values.ToList() AllFiles = Files.Values.ToList()
End SyncLock End SyncLock
Dim WaitingFiles As New List(Of NetFile) Dim WaitingFiles As New List(Of NetFile)
@@ -372,12 +372,12 @@
ModLoaders = New List(Of CompModLoaderType) ModLoaders = New List(Of CompModLoaderType)
For Each Category In Data("categories").Select(Function(t) t.ToString) For Each Category In Data("categories").Select(Function(t) t.ToString)
Select Case Category Select Case Category
'加载器 '加载器
Case "forge" : ModLoaders.Add(CompModLoaderType.Forge) Case "forge" : ModLoaders.Add(CompModLoaderType.Forge)
Case "fabric" : ModLoaders.Add(CompModLoaderType.Fabric) Case "fabric" : ModLoaders.Add(CompModLoaderType.Fabric)
Case "quilt" : ModLoaders.Add(CompModLoaderType.Quilt) Case "quilt" : ModLoaders.Add(CompModLoaderType.Quilt)
Case "neoforge" : ModLoaders.Add(CompModLoaderType.NeoForge) Case "neoforge" : ModLoaders.Add(CompModLoaderType.NeoForge)
'Mod 'Mod
Case "worldgen" : Tags.Add("世界元素") Case "worldgen" : Tags.Add("世界元素")
Case "technology" : Tags.Add("科技") Case "technology" : Tags.Add("科技")
Case "food" : Tags.Add("食物/烹饪") Case "food" : Tags.Add("食物/烹饪")
@@ -393,7 +393,7 @@
Case "social" : Tags.Add("服务器") Case "social" : Tags.Add("服务器")
Case "utility" : Tags.Add("改良") Case "utility" : Tags.Add("改良")
Case "library" : Tags.Add("支持库") Case "library" : Tags.Add("支持库")
'整合包 '整合包
Case "multiplayer" : Tags.Add("多人") Case "multiplayer" : Tags.Add("多人")
Case "optimization" : Tags.Add("性能优化") Case "optimization" : Tags.Add("性能优化")
Case "challenging" : Tags.Add("硬核") Case "challenging" : Tags.Add("硬核")
@@ -404,7 +404,7 @@
Case "adventure" : Tags.Add("冒险") Case "adventure" : Tags.Add("冒险")
Case "kitchen-sink" : Tags.Add("烹饪") Case "kitchen-sink" : Tags.Add("烹饪")
Case "lightweight" : Tags.Add("轻量") Case "lightweight" : Tags.Add("轻量")
'资源包 '资源包
Case "8x-" : Tags.Add("8x-") Case "8x-" : Tags.Add("8x-")
Case "16x" : Tags.Add("16x") Case "16x" : Tags.Add("16x")
Case "32x" : Tags.Add("32x") Case "32x" : Tags.Add("32x")
@@ -676,19 +676,19 @@ NoSubtitle:
If Id = Project.Id Then Return True '相同实例 If Id = Project.Id Then Return True '相同实例
'提取字符串中的字母和数字 '提取字符串中的字母和数字
Dim GetRaw = Dim GetRaw =
Function(Data As String) As String Function(Data As String) As String
Dim Result As New StringBuilder() Dim Result As New StringBuilder()
For Each r As Char In Data.Where(Function(c) Char.IsLetterOrDigit(c)) For Each r As Char In Data.Where(Function(c) Char.IsLetterOrDigit(c))
Result.Append(r) Result.Append(r)
Next Next
Return Result.ToString.ToLower Return Result.ToString.ToLower
End Function End Function
'来自不同的网站 '来自不同的网站
If FromCurseForge = Project.FromCurseForge Then Return False If FromCurseForge = Project.FromCurseForge Then Return False
'Mod 加载器一致 'Mod 加载器一致
If ModLoaders.Count <> Project.ModLoaders.Count OrElse ModLoaders.Except(Project.ModLoaders).Count > 0 Then Return False If ModLoaders.Count <> Project.ModLoaders.Count OrElse ModLoaders.Except(Project.ModLoaders).Any() Then Return False
'MC 版本一致 'MC 版本一致
If GameVersions.Count <> Project.GameVersions.Count OrElse GameVersions.Except(Project.GameVersions).Count > 0 Then Return False If GameVersions.Count <> Project.GameVersions.Count OrElse GameVersions.Except(Project.GameVersions).Any() Then Return False
'MCMOD 翻译名 / 原名 / 描述文本 / Slug 的英文部分相同 'MCMOD 翻译名 / 原名 / 描述文本 / Slug 的英文部分相同
If TranslatedName = Project.TranslatedName OrElse If TranslatedName = Project.TranslatedName OrElse
RawName = Project.RawName OrElse Description = Project.Description OrElse RawName = Project.RawName OrElse Description = Project.Description OrElse
@@ -1367,6 +1367,7 @@ Retry:
Dim RawLoaders As List(Of String) = Data("loaders").Select(Function(v) v.ToString).ToList Dim RawLoaders As List(Of String) = Data("loaders").Select(Function(v) v.ToString).ToList
ModLoaders = New List(Of CompModLoaderType) ModLoaders = New List(Of CompModLoaderType)
If RawLoaders.Contains("forge") Then ModLoaders.Add(CompModLoaderType.Forge) If RawLoaders.Contains("forge") Then ModLoaders.Add(CompModLoaderType.Forge)
If RawLoaders.Contains("neoforge") Then ModLoaders.Add(CompModLoaderType.NeoForge)
If RawLoaders.Contains("fabric") Then ModLoaders.Add(CompModLoaderType.Fabric) If RawLoaders.Contains("fabric") Then ModLoaders.Add(CompModLoaderType.Fabric)
If RawLoaders.Contains("quilt") Then ModLoaders.Add(CompModLoaderType.Quilt) If RawLoaders.Contains("quilt") Then ModLoaders.Add(CompModLoaderType.Quilt)
#End Region #End Region
@@ -697,8 +697,8 @@ NextStack:
"forge", "setup", "block", "model", "mixin", "event", "unimi", "netty", "world", "forge", "setup", "block", "model", "mixin", "event", "unimi", "netty", "world",
"gitlab", "common", "server", "config", "loader", "launch", "entity", "assist", "client", "plugin", "modapi", "mojang", "shader", "events", "github", "recipe", "render", "packet", "events", "gitlab", "common", "server", "config", "loader", "launch", "entity", "assist", "client", "plugin", "modapi", "mojang", "shader", "events", "github", "recipe", "render", "packet", "events",
"preinit", "preload", "machine", "reflect", "channel", "general", "handler", "content", "systems", "modules", "service", "preinit", "preload", "machine", "reflect", "channel", "general", "handler", "content", "systems", "modules", "service",
"fastutil", "optifine", "internal", "platform", "override", "fabricmc", "fastutil", "optifine", "internal", "platform", "override", "fabricmc", "neoforge",
"injection", "listeners", "scheduler", "minecraft", "transformer", "transformers", "universal", "multipart", "minecraftforge", "blockentity", "spongepowered", "electronwill" "injection", "listeners", "scheduler", "minecraft", "transformer", "transformers", "neoforged", "universal", "multipart", "minecraftforge", "blockentity", "spongepowered", "electronwill"
}.Contains(Word.ToLower) Then Continue For }.Contains(Word.ToLower) Then Continue For
PossibleWords.Add(Word.Trim) PossibleWords.Add(Word.Trim)
Next Next
@@ -8,9 +8,13 @@
''' </summary> ''' </summary>
Public Function DlClientJarGet(Version As McVersion, ReturnNothingOnFileUseable As Boolean) As NetFile Public Function DlClientJarGet(Version As McVersion, ReturnNothingOnFileUseable As Boolean) As NetFile
'获取底层继承版本 '获取底层继承版本
Do While Not String.IsNullOrEmpty(Version.InheritVersion) Try
Version = New McVersion(Version.InheritVersion) Do While Not String.IsNullOrEmpty(Version.InheritVersion)
Loop Version = New McVersion(Version.InheritVersion)
Loop
Catch ex As Exception
Log(ex, "获取底层继承版本失败")
End Try
'检查 Json 是否标准 '检查 Json 是否标准
If Version.JsonObject("downloads") Is Nothing OrElse Version.JsonObject("downloads")("client") Is Nothing OrElse Version.JsonObject("downloads")("client")("url") Is Nothing Then If Version.JsonObject("downloads") Is Nothing OrElse Version.JsonObject("downloads")("client") Is Nothing OrElse Version.JsonObject("downloads")("client")("url") Is Nothing Then
Throw New Exception("底层版本 " & Version.Name & " 中无 jar 文件下载信息") Throw New Exception("底层版本 " & Version.Name & " 中无 jar 文件下载信息")
@@ -220,7 +224,7 @@
End If End If
Setup.Set("ToolUpdateSnapshotLast", If(Version, "Nothing")) Setup.Set("ToolUpdateSnapshotLast", If(Version, "Nothing"))
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败", ex) Throw New Exception("Minecraft 官方源版本列表解析失败", ex)
End Try End Try
End Sub End Sub
''' <summary> ''' <summary>
@@ -237,7 +241,7 @@
'返回 '返回
Loader.Output = New DlClientListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Json} Loader.Output = New DlClientListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Json}
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败(" & Json.ToString & ")", ex) Throw New Exception("Minecraft BMCLAPI 版本列表解析失败(" & Json.ToString & ")", ex)
End Try End Try
End Sub End Sub
@@ -288,6 +292,7 @@
''' </summary> ''' </summary>
Public Value As List(Of DlOptiFineListEntry) Public Value As List(Of DlOptiFineListEntry)
End Structure End Structure
Public Class DlOptiFineListEntry Public Class DlOptiFineListEntry
''' <summary> ''' <summary>
''' 显示名称,已去除 HD_U 字样,如“1.12.2 C8”。 ''' 显示名称,已去除 HD_U 字样,如“1.12.2 C8”。
@@ -359,29 +364,33 @@
Private Sub DlOptiFineListOfficialMain(Loader As LoaderTask(Of Integer, DlOptiFineListResult)) Private Sub DlOptiFineListOfficialMain(Loader As LoaderTask(Of Integer, DlOptiFineListResult))
Dim Result As String = NetGetCodeByClient("https://optifine.net/downloads", Encoding.Default) Dim Result As String = NetGetCodeByClient("https://optifine.net/downloads", Encoding.Default)
If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")") If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")")
'获取所有版本信息 Try
Dim Forge As List(Of String) = RegexSearch(Result, "(?<=colForge'>)[^<]*") '获取所有版本信息
Dim ReleaseTime As List(Of String) = RegexSearch(Result, "(?<=colDate'>)[^<]+") Dim Forge As List(Of String) = RegexSearch(Result, "(?<=colForge'>)[^<]*")
Dim Name As List(Of String) = RegexSearch(Result, "(?<=OptiFine_)[0-9A-Za-z_.]+(?=.jar"")") Dim ReleaseTime As List(Of String) = RegexSearch(Result, "(?<=colDate'>)[^<]+")
If Not ReleaseTime.Count = Name.Count Then Throw New Exception("版本与发布时间数据无法对应") Dim Name As List(Of String) = RegexSearch(Result, "(?<=OptiFine_)[0-9A-Za-z_.]+(?=.jar"")")
If Not Forge.Count = Name.Count Then Throw New Exception("版本与 Forge 兼容数据无法对应") If Not ReleaseTime.Count = Name.Count Then Throw New Exception("版本与发布时间数据无法对应")
If ReleaseTime.Count < 10 Then Throw New Exception("获取到的版本数量不足(" & Result & ")") If Not Forge.Count = Name.Count Then Throw New Exception("版本与 Forge 兼容数据无法对应")
'转化为列表输出 If ReleaseTime.Count < 10 Then Throw New Exception("获取到的版本数量不足(" & Result & ")")
Dim Versions As New List(Of DlOptiFineListEntry) '转化为列表输出
For i = 0 To ReleaseTime.Count - 1 Dim Versions As New List(Of DlOptiFineListEntry)
Name(i) = Name(i).Replace("_", " ") For i = 0 To ReleaseTime.Count - 1
Dim Entry As New DlOptiFineListEntry With { Name(i) = Name(i).Replace("_", " ")
.NameDisplay = Name(i).Replace("HD U ", "").Replace(".0 ", " "), Dim Entry As New DlOptiFineListEntry With {
.ReleaseTime = Join({ReleaseTime(i).Split(".")(2), ReleaseTime(i).Split(".")(1), ReleaseTime(i).Split(".")(0)}, "/"), .NameDisplay = Name(i).Replace("HD U ", "").Replace(".0 ", " "),
.IsPreview = Name(i).ContainsF("pre", True), .ReleaseTime = Join({ReleaseTime(i).Split(".")(2), ReleaseTime(i).Split(".")(1), ReleaseTime(i).Split(".")(0)}, "/"),
.Inherit = Name(i).ToString.Split(" ")(0), .IsPreview = Name(i).ContainsF("pre", True),
.NameFile = If(Name(i).ContainsF("pre", True), "preview_", "") & "OptiFine_" & Name(i).Replace(" ", "_") & ".jar", .Inherit = Name(i).ToString.Split(" ")(0),
.RequiredForgeVersion = Forge(i).Replace("Forge ", "").Replace("#", "")} .NameFile = If(Name(i).ContainsF("pre", True), "preview_", "") & "OptiFine_" & Name(i).Replace(" ", "_") & ".jar",
If Entry.RequiredForgeVersion.Contains("N/A") Then Entry.RequiredForgeVersion = Nothing .RequiredForgeVersion = Forge(i).Replace("Forge ", "").Replace("#", "")}
Entry.NameVersion = Entry.Inherit & "-OptiFine_" & Name(i).ToString.Replace(" ", "_").Replace(Entry.Inherit & "_", "") If Entry.RequiredForgeVersion.Contains("N/A") Then Entry.RequiredForgeVersion = Nothing
Versions.Add(Entry) Entry.NameVersion = Entry.Inherit & "-OptiFine_" & Name(i).ToString.Replace(" ", "_").Replace(Entry.Inherit & "_", "")
Next Versions.Add(Entry)
Loader.Output = New DlOptiFineListResult With {.IsOfficial = True, .SourceName = "OptiFine 官方源", .Value = Versions} Next
Loader.Output = New DlOptiFineListResult With {.IsOfficial = True, .SourceName = "OptiFine 官方源", .Value = Versions}
Catch ex As Exception
Throw New Exception("OptiFine 官方源版本列表解析失败(" & Result & ")", ex)
End Try
End Sub End Sub
''' <summary> ''' <summary>
@@ -407,7 +416,7 @@
Next Next
Loader.Output = New DlOptiFineListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Versions} Loader.Output = New DlOptiFineListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Versions}
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败(" & Json.ToString & ")", ex) Throw New Exception("OptiFine BMCLAPI 版本列表解析失败(" & Json.ToString & ")", ex)
End Try End Try
End Sub End Sub
@@ -485,15 +494,61 @@
#Region "DlForgeVersion | Forge 版本列表" #Region "DlForgeVersion | Forge 版本列表"
Public Class DlForgeVersionEntry Public MustInherit Class DlForgelikeEntry
Public IsNeoForge As Boolean
''' <summary> ''' <summary>
''' 完整的版本名,如 “14.22.1.2478”。 ''' 加载器名称。Forge 或 NeoForge。
''' </summary> ''' </summary>
Public Version As String Public ReadOnly Property LoaderName As String
Get
Return If(IsNeoForge, "NeoForge", "Forge")
End Get
End Property
''' <summary>
''' 文件扩展名。不以小数点开头。
''' </summary>
Public ReadOnly Property FileExtension As String
Get
If IsNeoForge Then
Return "jar"
Else
Return If(CType(Me, DlForgeVersionEntry).Category = "installer", "jar", "zip")
End If
End Get
End Property
''' <summary>
''' Forge:MC 版本是否小于 1.13。
''' NeoForge:MC 版本是否为 1.20.1。
''' </summary>
Public ReadOnly Property IsLegacy As Boolean
Get
'虽然很抽象,但确实可以这样判断
'Forge:1.13+ 的版本号首位都大于 20
'NeoForge:1.20.1 的版本号首位人为规定为 19 开头
Return Version.Major < 20
End Get
End Property
''' <summary>
''' 标准化后的版本号,仅可用于比较与排序。
''' 格式:Major.Minor.Build.Revision
''' Forge:如 “50.1.9.0”(最后一位固定为 0)、“14.22.1.2478”(Legacy)。
''' NeoForge:如 “20.4.30.0”(最后一位固定为 0)、“19.47.1.99”(Legacy:第一位固定为 19)。
''' </summary>
Public Version As Version
''' <summary>
''' 可对玩家显示的非格式化版本名。
''' Forge:如 “50.1.9”、“14.22.1.2478”(Legacy)。
''' NeoForge:如 “20.4.30-beta”、“47.1.99”(Legacy)。
''' </summary>
Public VersionName As String
''' <summary> ''' <summary>
''' 对应的 Minecraft 版本,如“1.12.2”。 ''' 对应的 Minecraft 版本,如“1.12.2”。
''' </summary> ''' </summary>
Public Inherit As String Public Inherit As String
End Class
Public Class DlForgeVersionEntry
Inherits DlForgelikeEntry
''' <summary> ''' <summary>
''' 发布时间,格式为“yyyy/MM/dd HH:mm”。 ''' 发布时间,格式为“yyyy/MM/dd HH:mm”。
''' </summary> ''' </summary>
@@ -511,58 +566,21 @@
''' </summary> ''' </summary>
Public Category As String Public Category As String
''' <summary> ''' <summary>
''' 版本分支。若无分支则为 Nothing。
''' </summary>
Public Branch As String = Nothing
''' <summary>
''' 是否为新版 Forge。(即为 Minecraft 1.13+)
''' </summary>
Public ReadOnly Property IsNewType As Boolean
Get
Return Version.Split(".")(0) >= 20
End Get
End Property
''' <summary>
''' 构建数。
''' </summary>
Public ReadOnly Property Build As Integer
Get
Dim Version = Me.Version.Split(".")
If Version(0) < 15 Then
Return Version(Version.Count - 1)
Else
Return Version(Version.Count - 1) + 10000
End If
End Get
End Property
''' <summary>
''' 用于下载的文件版本名。可能在 Version 的基础上添加了分支。 ''' 用于下载的文件版本名。可能在 Version 的基础上添加了分支。
''' </summary> ''' </summary>
Public ReadOnly Property FileVersion As String Public FileVersion As String
Get
Return Version & If(Branch Is Nothing, "", "-" & Branch) Public Sub New(Version As String, Branch As String, Inherit As String)
End Get '司马版本的特殊处理
End Property If Version = "11.15.1.2318" OrElse Version = "11.15.1.1902" OrElse Version = "11.15.1.1890" Then Branch = "1.8.9"
''' <summary> If Branch Is Nothing AndAlso Inherit = "1.7.10" AndAlso Version.Split(".")(3) >= 1300 Then Branch = "1.7.10"
''' 即将下载的文件全名。 '为 DlForgelikeEntry 提供所有信息
''' </summary> IsNeoForge = False
Public ReadOnly Property FileName As String VersionName = Version
Get Me.Version = New Version(Version)
Return "forge-" & Inherit & "-" & FileVersion & "-" & Category & "." & FileSuffix Me.Inherit = Inherit
End Get FileVersion = Version & If(Branch Is Nothing, "", "-" & Branch)
End Property End Sub
''' <summary>
''' 文件扩展名。
''' </summary>
Public ReadOnly Property FileSuffix As String
Get
If Category = "installer" Then
Return "jar"
Else
Return "zip"
End If
End Get
End Property
End Class End Class
''' <summary> ''' <summary>
@@ -596,7 +614,9 @@
Public Sub DlForgeVersionOfficialMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry))) Public Sub DlForgeVersionOfficialMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
Dim Result As String Dim Result As String
Try Try
Result = NetGetCodeByDownload("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" & Loader.Input & ".html", UseBrowserUserAgent:=True) Result = NetGetCodeByDownload("https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_" &
Loader.Input.Replace("-", "_") & '兼容 Forge 1.7.10-pre4,#4057
".html", UseBrowserUserAgent:=True)
Catch ex As Exception Catch ex As Exception
If GetExceptionSummary(ex).Contains("(404)") Then If GetExceptionSummary(ex).Contains("(404)") Then
Throw New Exception("没有可用版本") Throw New Exception("没有可用版本")
@@ -620,8 +640,6 @@
'分支获取 '分支获取
Dim Branch As String = RegexSeek(VersionCode, $"(?<=-{Name}-)[^-""]+(?=-[a-z]+.[a-z]{{3}})") Dim Branch As String = RegexSeek(VersionCode, $"(?<=-{Name}-)[^-""]+(?=-[a-z]+.[a-z]{{3}})")
If String.IsNullOrWhiteSpace(Branch) Then Branch = Nothing If String.IsNullOrWhiteSpace(Branch) Then Branch = Nothing
If Name = "11.15.1.2318" OrElse Name = "11.15.1.1902" OrElse Name = "11.15.1.1890" Then Branch = "1.8.9"
If Branch Is Nothing AndAlso Inherit = "1.7.10" AndAlso Name.Split(".")(3) >= 1300 Then Branch = "1.7.10"
'发布时间获取 '发布时间获取
Dim ReleaseTimeOriginal = RegexSeek(VersionCode, "(?<=""download-time"" title="")[^""]+") Dim ReleaseTimeOriginal = RegexSeek(VersionCode, "(?<=""download-time"" title="")[^""]+")
Dim ReleaseTimeSplit = ReleaseTimeOriginal.Split(" -:".ToCharArray) '原格式:"2021-02-15 03:24:02" Dim ReleaseTimeSplit = ReleaseTimeOriginal.Split(" -:".ToCharArray) '原格式:"2021-02-15 03:24:02"
@@ -651,13 +669,13 @@
Continue For Continue For
End If End If
'添加进列表 '添加进列表
Versions.Add(New DlForgeVersionEntry With {.Category = Category, .Version = Name, .IsRecommended = IsRecommended, .Hash = MD5.Trim(vbCr, vbLf), .Inherit = Inherit, .ReleaseTime = ReleaseTime, .Branch = Branch}) Versions.Add(New DlForgeVersionEntry(Name, Branch, Inherit) With {.Category = Category, .IsRecommended = IsRecommended, .Hash = MD5.Trim(vbCr, vbLf), .ReleaseTime = ReleaseTime})
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本信息提取失败(" & VersionCode & ")", ex) Throw New Exception("Forge 官方源版本信息提取失败(" & VersionCode & ")", ex)
End Try End Try
Next Next
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败(" & Result & ")", ex) Throw New Exception("Forge 官方源版本列表解析失败(" & Result & ")", ex)
End Try End Try
If Not Versions.Any() Then Throw New Exception("没有可用版本") If Not Versions.Any() Then Throw New Exception("没有可用版本")
Loader.Output = Versions Loader.Output = Versions
@@ -667,7 +685,9 @@
''' Forge 版本列表,BMCLAPI。 ''' Forge 版本列表,BMCLAPI。
''' </summary> ''' </summary>
Public Sub DlForgeVersionBmclapiMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry))) Public Sub DlForgeVersionBmclapiMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)))
Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" & Loader.Input, IsJson:=True) Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" &
Loader.Input.Replace("-", "_"), '兼容 Forge 1.7.10-pre4,#4057
IsJson:=True)
Dim Versions As New List(Of DlForgeVersionEntry) Dim Versions As New List(Of DlForgeVersionEntry)
Try Try
Dim Recommended As String = McDownloadForgeRecommendedGet(Loader.Input) Dim Recommended As String = McDownloadForgeRecommendedGet(Loader.Input)
@@ -700,20 +720,17 @@
End Select End Select
Next Next
'获取 Entry '获取 Entry
Dim Inherit As String = Loader.Input
Dim Branch As String = Token("branch") Dim Branch As String = Token("branch")
Dim Name As String = Token("version") Dim Name As String = Token("version")
If Name = "11.15.1.2318" OrElse Name = "11.15.1.1902" OrElse Name = "11.15.1.1890" Then Branch = "1.8.9"
If Branch Is Nothing AndAlso Inherit = "1.7.10" AndAlso Name.Split(".")(3) >= 1300 Then Branch = "1.7.10"
'基础信息获取 '基础信息获取
Dim Entry = New DlForgeVersionEntry With {.Hash = Hash, .Category = Category, .Version = Name, .Branch = Branch, .Inherit = Inherit, .IsRecommended = Recommended = Name} Dim Entry = New DlForgeVersionEntry(Name, Branch, Loader.Input) With {.Hash = Hash, .Category = Category, .IsRecommended = Recommended = Name}
Dim TimeSplit = Token("modified").ToString.Split("-"c, "T"c, ":"c, "."c, " "c, "/"c) Dim TimeSplit = Token("modified").ToString.Split("-"c, "T"c, ":"c, "."c, " "c, "/"c)
Entry.ReleaseTime = Token("modified").ToObject(Of Date).ToLocalTime.ToString("yyyy'/'MM'/'dd HH':'mm") Entry.ReleaseTime = Token("modified").ToObject(Of Date).ToLocalTime.ToString("yyyy'/'MM'/'dd HH':'mm")
'添加项 '添加项
Versions.Add(Entry) Versions.Add(Entry)
Next Next
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败(" & Json.ToString & ")", ex) Throw New Exception("Forge BMCLAPI 版本列表解析失败(" & Json.ToString & ")", ex)
End Try End Try
If Not Versions.Any() Then Throw New Exception("没有可用版本") If Not Versions.Any() Then Throw New Exception("没有可用版本")
Loader.Output = Versions Loader.Output = Versions
@@ -721,6 +738,132 @@
#End Region #End Region
#Region "DlNeoForgeList | NeoForge 版本列表"
Public Structure DlNeoForgeListResult
''' <summary>
''' 数据来源名称,如“Official”,“BMCLAPI”。
''' </summary>
Public SourceName As String
''' <summary>
''' 是否为官方的实时数据。
''' </summary>
Public IsOfficial As Boolean
''' <summary>
''' 所有版本的列表。已经按从新到老排序。
''' </summary>
Public Value As List(Of DlNeoForgeListEntry)
End Structure
Public Class DlNeoForgeListEntry
Inherits DlForgelikeEntry
''' <summary>
''' 是否是 Beta 版。
''' </summary>
Public IsBeta As Boolean
''' <summary>
''' API 使用的原始版本字符串,如 “20.4.30-beta”、“1.20.1-47.1.99”(Legacy)。
''' </summary>
Public ApiName As String
''' <summary>
''' 文件在官网的基础地址,不包含后缀。
''' </summary>
Public ReadOnly Property UrlBase As String
Get
Dim PackageName As String = If(IsLegacy, "forge", "neoforge")
Return $"https://maven.neoforged.net/releases/net/neoforged/{PackageName}/{ApiName}/{PackageName}-{ApiName}"
End Get
End Property
Public Sub New(ApiName As String)
IsNeoForge = True
Me.ApiName = ApiName
IsBeta = ApiName.Contains("beta")
If ApiName.Contains("1.20.1") Then '1.20.1-47.1.99
VersionName = ApiName.Replace("1.20.1-", "")
Version = New Version("19." & VersionName)
Inherit = "1.20.1"
Else '20.4.30-beta
VersionName = ApiName
Version = New Version(ApiName.Before("-"))
Inherit = $"1.{Version.Major}" & If(Version.Minor = 0, "", "." & Version.Minor)
End If
End Sub
End Class
''' <summary>
''' NeoForge 版本列表,主加载器。
''' </summary>
Public DlNeoForgeListLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Main", AddressOf DlNeoForgeListMain)
Private Sub DlNeoForgeListMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
Select Case Setup.Get("ToolDownloadVersion")
Case 0
DlSourceLoader(Loader, New List(Of KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)) From {
New KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)(DlNeoForgeListBmclapiLoader, 30),
New KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)(DlNeoForgeListOfficialLoader, 60)
}, Loader.IsForceRestarting)
Case 1
DlSourceLoader(Loader, New List(Of KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)) From {
New KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)(DlNeoForgeListOfficialLoader, 5),
New KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)(DlNeoForgeListBmclapiLoader, 35)
}, Loader.IsForceRestarting)
Case Else
DlSourceLoader(Loader, New List(Of KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)) From {
New KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)(DlNeoForgeListOfficialLoader, 60),
New KeyValuePair(Of LoaderTask(Of Integer, DlNeoForgeListResult), Integer)(DlNeoForgeListBmclapiLoader, 60)
}, Loader.IsForceRestarting)
End Select
End Sub
''' <summary>
''' NeoForge 版本列表,官方源。
''' </summary>
Public DlNeoForgeListOfficialLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Official", AddressOf DlNeoForgeListOfficialMain)
Private Sub DlNeoForgeListOfficialMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
'获取版本列表 JSON
Dim ResultLatest As String = NetGetCodeByDownload("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge", UseBrowserUserAgent:=True, IsJson:=True)
Dim ResultLegacy As String = NetGetCodeByDownload("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/forge", UseBrowserUserAgent:=True, IsJson:=True)
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
'解析
Try
Loader.Output = New DlNeoForgeListResult With {.IsOfficial = True, .SourceName = "NeoForge 官方源",
.Value = GetNeoForgeEntries(ResultLatest, ResultLegacy)}
Catch ex As Exception
Throw New Exception("NeoForge 官方源版本列表解析失败(" & ResultLatest & vbCrLf & vbCrLf & ResultLegacy & ")", ex)
End Try
End Sub
''' <summary>
''' NeoForge 版本列表,BMCLAPI。
''' </summary>
Public DlNeoForgeListBmclapiLoader As New LoaderTask(Of Integer, DlNeoForgeListResult)("DlNeoForgeList Bmclapi", AddressOf DlNeoForgeListOfficialMain)
Public Sub DlNeoForgeVersionBmclapiMain(Loader As LoaderTask(Of Integer, DlNeoForgeListResult))
'获取版本列表 JSON
Dim ResultLatest As String = NetGetCodeByDownload("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/neoforge", UseBrowserUserAgent:=True, IsJson:=True)
Dim ResultLegacy As String = NetGetCodeByDownload("https://bmclapi2.bangbang93.com/neoforge/meta/api/maven/details/releases/net/neoforged/forge", UseBrowserUserAgent:=True, IsJson:=True)
If ResultLatest.Length < 100 OrElse ResultLegacy.Length < 100 Then Throw New Exception("获取到的版本列表长度不足(" & ResultLatest & ")")
'解析
Try
Loader.Output = New DlNeoForgeListResult With {.IsOfficial = True, .SourceName = "BMCLAPI",
.Value = GetNeoForgeEntries(ResultLatest, ResultLegacy)}
Catch ex As Exception
Throw New Exception("NeoForge BMCLAPI 版本列表解析失败(" & ResultLatest & vbCrLf & vbCrLf & ResultLegacy & ")", ex)
End Try
End Sub
Private Function GetNeoForgeEntries(LatestJson As String, LatestLegacyJson As String) As List(Of DlNeoForgeListEntry)
Dim VersionNames = RegexSearch(LatestLegacyJson & LatestJson,
"(?<="")(1\.20\.1-)?\d+\.\d+\.\d+(-beta)?(?="")") '我寻思直接正则就行.jpg
Dim Versions = VersionNames.
Where(Function(name) name <> "47.1.82"). '这个版本虽然在版本列表中,但不能下载
Select(Function(name) New DlNeoForgeListEntry(name)).ToList
If Not Versions.Any() Then Throw New Exception("没有可用版本")
Versions = Versions.OrderByDescending(Function(a) a.Version).ToList
Return Versions
End Function
#End Region
#Region "DlLiteLoaderList | LiteLoader 版本列表" #Region "DlLiteLoaderList | LiteLoader 版本列表"
Public Structure DlLiteLoaderListResult Public Structure DlLiteLoaderListResult
@@ -741,6 +884,7 @@
''' </summary> ''' </summary>
Public OfficialError As Exception Public OfficialError As Exception
End Structure End Structure
Public Class DlLiteLoaderListEntry Public Class DlLiteLoaderListEntry
''' <summary> ''' <summary>
''' 实际的文件名,如“liteloader-installer-1.12-00-SNAPSHOT.jar”。 ''' 实际的文件名,如“liteloader-installer-1.12-00-SNAPSHOT.jar”。
@@ -820,7 +964,7 @@
Next Next
Loader.Output = New DlLiteLoaderListResult With {.IsOfficial = True, .SourceName = "LiteLoader 官方源", .Value = Versions} Loader.Output = New DlLiteLoaderListResult With {.IsOfficial = True, .SourceName = "LiteLoader 官方源", .Value = Versions}
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败(" & Result.ToString & ")", ex) Throw New Exception("LiteLoader 官方源版本列表解析失败(" & Result.ToString & ")", ex)
End Try End Try
End Sub End Sub
@@ -848,7 +992,7 @@
Next Next
Loader.Output = New DlLiteLoaderListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Versions} Loader.Output = New DlLiteLoaderListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Versions}
Catch ex As Exception Catch ex As Exception
Throw New Exception("版本列表解析失败(" & Result.ToString & ")", ex) Throw New Exception("LiteLoader BMCLAPI 版本列表解析失败(" & Result.ToString & ")", ex)
End Try End Try
End Sub End Sub
@@ -906,7 +1050,7 @@
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项") If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
Loader.Output = Output Loader.Output = Output
Catch ex As Exception Catch ex As Exception
Throw New Exception("列表解析失败(" & Result.ToString & ")", ex) Throw New Exception("Fabric 官方源版本列表解析失败(" & Result.ToString & ")", ex)
End Try End Try
End Sub End Sub
@@ -921,7 +1065,7 @@
If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项") If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项")
Loader.Output = Output Loader.Output = Output
Catch ex As Exception Catch ex As Exception
Throw New Exception("列表解析失败(" & Result.ToString & ")", ex) Throw New Exception("Fabric BMCLAPI 版本列表解析失败(" & Result.ToString & ")", ex)
End Try End Try
End Sub End Sub
@@ -944,25 +1088,25 @@
Public Function DlSourceResourceGet(MojangBase As String) As String() Public Function DlSourceResourceGet(MojangBase As String) As String()
MojangBase = MojangBase.Replace("http://resources.download.minecraft.net", "https://resources.download.minecraft.net") MojangBase = MojangBase.Replace("http://resources.download.minecraft.net", "https://resources.download.minecraft.net")
Return { Return {
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://resources.download.minecraft.net", "https://bmclapi2.bangbang93.com/assets"), MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/assets").Replace("https://resources.download.minecraft.net", "https://bmclapi2.bangbang93.com/assets"),
MojangBase MojangBase
} }
End Function End Function
Public Function DlSourceLibraryGet(MojangBase As String) As String() Public Function DlSourceLibraryGet(MojangBase As String) As String()
Return { Return {
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/maven").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/maven").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/maven"), MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/maven").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/maven").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/maven"),
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/libraries"), MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com/libraries").Replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/libraries"),
MojangBase MojangBase
} }
End Function End Function
Public Function DlSourceLauncherOrMetaGet(MojangBase As String) As String() Public Function DlSourceLauncherOrMetaGet(MojangBase As String) As String()
If MojangBase Is Nothing Then Throw New Exception("无对应的 json 下载地址") If MojangBase Is Nothing Then Throw New Exception("无对应的 json 下载地址")
Return { Return {
MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launcher.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "https://bmclapi2.bangbang93.com"), MojangBase.Replace("https://piston-data.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://piston-meta.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launcher.mojang.com", "https://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "https://bmclapi2.bangbang93.com"),
MojangBase MojangBase
} }
End Function End Function
Private Sub DlSourceLoader(Of InputType, OutputType)(MainLoader As LoaderTask(Of InputType, OutputType), Private Sub DlSourceLoader(Of InputType, OutputType)(MainLoader As LoaderTask(Of InputType, OutputType),
@@ -240,21 +240,25 @@
Dim UserJava As JavaEntry = Nothing Dim UserJava As JavaEntry = Nothing
'获取版本独立设置中指定的 Java '获取版本独立设置中指定的 Java
If RelatedVersion IsNot Nothing AndAlso Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion).ToString.StartsWithF("{") Then Dim VersionSelect As String = ""
Try If RelatedVersion IsNot Nothing Then
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion))) VersionSelect = Setup.Get("VersionArgumentJavaSelect", Version:=RelatedVersion)
UserJava.Check() If VersionSelect.StartsWithF("{") Then
Catch ex As ThreadInterruptedException Try
Throw UserJava = JavaEntry.FromJson(GetJson(VersionSelect))
Catch ex As Exception UserJava.Check()
UserJava = Nothing Catch ex As ThreadInterruptedException
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion) Throw
Log(ex, "版本独立设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint) Catch ex As Exception
End Try UserJava = Nothing
Setup.Reset("VersionArgumentJavaSelect", Version:=RelatedVersion)
Log(ex, "版本独立设置中指定的 Java 已无法使用,此设置已重置", LogLevel.Hint)
End Try
End If
End If End If
'获取全局设置中指定的 Java '获取全局设置中指定的 Java
If UserJava Is Nothing AndAlso Setup.Get("LaunchArgumentJavaSelect") <> "" Then If UserJava Is Nothing AndAlso VersionSelect <> "" AndAlso Setup.Get("LaunchArgumentJavaSelect") <> "" Then
Try Try
UserJava = JavaEntry.FromJson(GetJson(Setup.Get("LaunchArgumentJavaSelect"))) UserJava = JavaEntry.FromJson(GetJson(Setup.Get("LaunchArgumentJavaSelect")))
UserJava.Check() UserJava.Check()
@@ -665,34 +669,18 @@ Wait:
'若该目录有 Java,则加入结果 '若该目录有 Java,则加入结果
If File.Exists(Path & "javaw.exe") Then Results(Path) = Source If File.Exists(Path & "javaw.exe") Then Results(Path) = Source
'查找其下的所有文件夹 '查找其下的所有文件夹
Dim Keywords = {"java", "jdk", "env", "环境", "run", "软件", "jre", "mc", "dragon",
"soft", "cache", "temp", "corretto", "roaming", "users", "craft", "program", "世界", "net",
"游戏", "oracle", "game", "file", "data", "jvm", "服务", "server", "客户", "client", "整合",
"应用", "运行", "前置", "mojang", "官启", "新建文件夹", "eclipse", "microsoft", "hotspot",
"runtime", "x86", "x64", "forge", "原版", "optifine", "官方", "启动", "hmcl", "mod", "高清",
"download", "launch", "程序", "path", "version", "baka", "pcl", "zulu", "local", "packages",
"4297127d64ec6", "国服", "网易", "ext", "netease", "1.", "启动"}
For Each FolderInfo As DirectoryInfo In OriginalPath.EnumerateDirectories For Each FolderInfo As DirectoryInfo In OriginalPath.EnumerateDirectories
If FolderInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) Then Continue For '跳过符号链接 If FolderInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) Then Continue For '跳过符号链接
Dim SearchEntry = GetFolderNameFromPath(FolderInfo.Name).ToLower '用于搜索的字符串 Dim SearchEntry = GetFolderNameFromPath(FolderInfo.Name).ToLower '用于搜索的字符串
If IsFullSearch OrElse If IsFullSearch OrElse FolderInfo.Parent.Name.ToLower = "users" OrElse
FolderInfo.Parent.Name.ToLower = "users" OrElse Keywords.Any(Function(w) SearchEntry.Contains(w)) OrElse SearchEntry = "bin" Then
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("soft") 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("zulu") 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) JavaSearchFolder(FolderInfo, Results, Source)
End If End If
Next Next
@@ -113,10 +113,18 @@ Public Module ModLaunch
New LoaderTask(Of Process, Integer)("等待游戏窗口出现", AddressOf McLaunchWait) With {.ProgressWeight = 1}, New LoaderTask(Of Process, Integer)("等待游戏窗口出现", AddressOf McLaunchWait) With {.ProgressWeight = 1},
New LoaderTask(Of Integer, Integer)("结束处理", AddressOf McLaunchEnd) With {.ProgressWeight = 1} New LoaderTask(Of Integer, Integer)("结束处理", AddressOf McLaunchEnd) With {.ProgressWeight = 1}
} }
If Setup.Get("LaunchArgumentRam") Then '内存优化
CType(Loaders(2), LoaderCombo(Of String)).Block = False Select Case Setup.Get("VersionRamOptimize", Version:=McVersionCurrent)
Loaders.Insert(3, New LoaderTask(Of Integer, Integer)("内存优化", AddressOf McLaunchMemoryOptimize) With {.ProgressWeight = 30}) Case 0 '全局
End If If Setup.Get("LaunchArgumentRam") Then '使用全局设置
CType(Loaders(2), LoaderCombo(Of String)).Block = False
Loaders.Insert(3, New LoaderTask(Of Integer, Integer)("内存优化", AddressOf McLaunchMemoryOptimize) With {.ProgressWeight = 30})
End If
Case 1 '开启
CType(Loaders(2), LoaderCombo(Of String)).Block = False
Loaders.Insert(3, New LoaderTask(Of Integer, Integer)("内存优化", AddressOf McLaunchMemoryOptimize) With {.ProgressWeight = 30})
Case 2 '关闭
End Select
Dim LaunchLoader As New LoaderCombo(Of Object)("Minecraft 启动", Loaders) With {.Show = False} Dim LaunchLoader As New LoaderCombo(Of Object)("Minecraft 启动", Loaders) With {.Show = False}
If McLoginLoader.State = LoadState.Finished Then McLoginLoader.State = LoadState.Waiting '要求重启登录主加载器,它会自行决定是否启动副加载器 If McLoginLoader.State = LoadState.Finished Then McLoginLoader.State = LoadState.Waiting '要求重启登录主加载器,它会自行决定是否启动副加载器
'等待加载器执行并更新 UI '等待加载器执行并更新 UI
@@ -1072,8 +1080,8 @@ SystemBrowser:
Case 4 Case 4
'自定义 '自定义
Do Until McSkinSex(Uuid) = If(Setup.Get("LaunchSkinSlim"), "Alex", "Steve") Do Until McSkinSex(Uuid) = If(Setup.Get("LaunchSkinSlim"), "Alex", "Steve")
If Uuid.EndsWithF("FFFFF") Then Uuid = Mid(Uuid, 1, 32 - 5) & "00000" If Uuid.EndsWithF("FFFFF") Then Uuid = Uuid.Substring(0, 27) & "00000"
Uuid = Mid(Uuid, 1, 32 - 5) & (Long.Parse(Right(Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X").PadLeft(5, "0") Uuid = Uuid.Substring(0, 27) & (Long.Parse(Uuid.Substring(27), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X").PadLeft(5, "0")
Loop Loop
End Select End Select
Return Uuid Return Uuid
@@ -1270,7 +1278,9 @@ SystemBrowser:
Public Function ExtractJavaWrapper() As String Public Function ExtractJavaWrapper() As String
Dim WrapperPath As String = GetJavaWrapperDir() & "\JavaWrapper.jar" Dim WrapperPath As String = GetJavaWrapperDir() & "\JavaWrapper.jar"
SyncLock ExtractJavaWrapperLock '避免 OptiFine 和 Forge 安装时同时释放 Java Wrapper 导致冲突 SyncLock ExtractJavaWrapperLock '避免 OptiFine 和 Forge 安装时同时释放 Java Wrapper 导致冲突
WriteFile(WrapperPath, GetResources("JavaWrapper")) If Not WriteFile(WrapperPath, GetResources("JavaWrapper")) Then
Throw New FileNotFoundException("释放 Java Wrapper 失败")
End If
End SyncLock End SyncLock
Log("[Java] 已释放 Java Wrapper:" & WrapperPath) Log("[Java] 已释放 Java Wrapper:" & WrapperPath)
Return WrapperPath Return WrapperPath
@@ -151,7 +151,7 @@ Public Module ModMinecraft
#Region "版本处理" #Region "版本处理"
Public Const McVersionCacheVersion As Integer = 29 Public Const McVersionCacheVersion As Integer = 30
Private _McVersionCurrent As McVersion Private _McVersionCurrent As McVersion
Private _McVersionLast = 0 '为 0 以保证与 Nothing 不相同,使得 UI 显示可以正常初始化 Private _McVersionLast = 0 '为 0 以保证与 Nothing 不相同,使得 UI 显示可以正常初始化
@@ -290,7 +290,7 @@ Public Module ModMinecraft
Public ReadOnly Property Modable As Boolean Public ReadOnly Property Modable As Boolean
Get Get
If Not IsLoaded Then Load() If Not IsLoaded Then Load()
Return Version.HasFabric OrElse Version.HasForge OrElse Version.HasLiteLoader OrElse Return Version.HasFabric OrElse Version.HasForge OrElse Version.HasLiteLoader OrElse Version.HasNeoForge OrElse
DisplayType = McVersionCardType.API '#223 DisplayType = McVersionCardType.API '#223
End Get End Get
End Property End Property
@@ -345,7 +345,7 @@ Public Module ModMinecraft
End If End If
Next Next
End If End If
'从 Forge Arguments 中获取版本号 '从 Forge / NeoForge Arguments 中获取版本号
If JsonObject("arguments") IsNot Nothing AndAlso JsonObject("arguments")("game") IsNot Nothing Then If JsonObject("arguments") IsNot Nothing AndAlso JsonObject("arguments")("game") IsNot Nothing Then
Dim Mark As Boolean = False Dim Mark As Boolean = False
For Each Argument In JsonObject("arguments")("game") For Each Argument In JsonObject("arguments")("game")
@@ -715,8 +715,8 @@ Recheck:
'OptiFine 'OptiFine
If RealJson.Contains("optifine") Then If RealJson.Contains("optifine") Then
State = McVersionState.OptiFine State = McVersionState.OptiFine
Version.OptiFineVersion = If(RegexSeek(RealJson, "(?<=HD_U_)[^"":/]+"), "未知版本")
Version.HasOptiFine = True Version.HasOptiFine = True
Version.OptiFineVersion = If(RegexSeek(RealJson, "(?<=HD_U_)[^"":/]+"), "未知版本")
End If End If
'LiteLoader 'LiteLoader
If RealJson.Contains("liteloader") Then If RealJson.Contains("liteloader") Then
@@ -727,14 +727,20 @@ Recheck:
'FUTURE: [Quilt 支持] 确认这里的玩意儿对不对 'FUTURE: [Quilt 支持] 确认这里的玩意儿对不对
If RealJson.Contains("net.fabricmc:fabric-loader") OrElse RealJson.Contains("org.quiltmc:quilt-loader") Then If RealJson.Contains("net.fabricmc:fabric-loader") OrElse RealJson.Contains("org.quiltmc:quilt-loader") Then
State = McVersionState.Fabric State = McVersionState.Fabric
Version.FabricVersion = If(RegexSeek(RealJson, "(?<=(net.fabricmc:fabric-loader:)|(org.quiltmc:quilt-loader:))[0-9\.]+(\+build.[0-9]+)?"), "未知版本").Replace("+build", "")
Version.HasFabric = True Version.HasFabric = True
ElseIf RealJson.Contains("minecraftforge") Then Version.FabricVersion = If(RegexSeek(RealJson, "(?<=(net.fabricmc:fabric-loader:)|(org.quiltmc:quilt-loader:))[0-9\.]+(\+build.[0-9]+)?"), "未知版本").Replace("+build", "")
ElseIf RealJson.Contains("minecraftforge") AndAlso Not RealJson.Contains("net.neoforge") Then
State = McVersionState.Forge State = McVersionState.Forge
Version.HasForge = True
Version.ForgeVersion = RegexSeek(RealJson, "(?<=forge:[0-9\.]+(_pre[0-9]*)?\-)[0-9\.]+") Version.ForgeVersion = RegexSeek(RealJson, "(?<=forge:[0-9\.]+(_pre[0-9]*)?\-)[0-9\.]+")
If Version.ForgeVersion Is Nothing Then Version.ForgeVersion = RegexSeek(RealJson, "(?<=net\.minecraftforge:minecraftforge:)[0-9\.]+") If Version.ForgeVersion Is Nothing Then Version.ForgeVersion = RegexSeek(RealJson, "(?<=net\.minecraftforge:minecraftforge:)[0-9\.]+")
If Version.ForgeVersion Is Nothing Then Version.ForgeVersion = If(RegexSeek(RealJson, "(?<=net\.minecraftforge:fmlloader:[0-9\.]+-)[0-9\.]+"), "未知版本") If Version.ForgeVersion Is Nothing Then Version.ForgeVersion = If(RegexSeek(RealJson, "(?<=net\.minecraftforge:fmlloader:[0-9\.]+-)[0-9\.]+"), "未知版本")
Version.HasForge = True ElseIf RealJson.Contains("net.neoforge") Then
'1.20.1 JSON 范例:"--fml.forgeVersion", "47.1.99"
'1.20.2+ JSON 范例:"--fml.neoForgeVersion", "20.6.119-beta"
State = McVersionState.NeoForge
Version.HasNeoForge = True
Version.NeoForgeVersion = If(RegexSeek(RealJson, "(?<=orgeVersion"",[^""]*?"")[^""]+(?="",)"), "未知版本")
End If End If
Version.IsApiLoaded = True Version.IsApiLoaded = True
End Select End Select
@@ -752,6 +758,8 @@ ExitDataLoad:
Logo = PathImage & "Blocks/CobbleStone.png" Logo = PathImage & "Blocks/CobbleStone.png"
Case McVersionState.Forge Case McVersionState.Forge
Logo = PathImage & "Blocks/Anvil.png" Logo = PathImage & "Blocks/Anvil.png"
Case McVersionState.NeoForge
Logo = PathImage & "Blocks/NeoForge.png"
Case McVersionState.Fabric Case McVersionState.Fabric
Logo = PathImage & "Blocks/Fabric.png" Logo = PathImage & "Blocks/Fabric.png"
Case McVersionState.OptiFine Case McVersionState.OptiFine
@@ -780,7 +788,7 @@ ExitDataLoad:
End If End If
Case McVersionState.Old Case McVersionState.Old
Info = "远古版本" Info = "远古版本"
Case McVersionState.Original, McVersionState.Forge, McVersionState.Fabric, McVersionState.OptiFine, McVersionState.LiteLoader Case McVersionState.Original, McVersionState.Forge, McVersionState.NeoForge, McVersionState.Fabric, McVersionState.OptiFine, McVersionState.LiteLoader
Info = Version.ToString Info = Version.ToString
Case McVersionState.Fool Case McVersionState.Fool
Info = GetMcFoolName(Version.McName) Info = GetMcFoolName(Version.McName)
@@ -813,6 +821,7 @@ ExitDataLoad:
WriteIni(Path & "PCL\Setup.ini", "VersionOptiFine", Version.OptiFineVersion) WriteIni(Path & "PCL\Setup.ini", "VersionOptiFine", Version.OptiFineVersion)
WriteIni(Path & "PCL\Setup.ini", "VersionLiteLoader", Version.HasLiteLoader) WriteIni(Path & "PCL\Setup.ini", "VersionLiteLoader", Version.HasLiteLoader)
WriteIni(Path & "PCL\Setup.ini", "VersionForge", Version.ForgeVersion) WriteIni(Path & "PCL\Setup.ini", "VersionForge", Version.ForgeVersion)
WriteIni(Path & "PCL\Setup.ini", "VersionNeoForge", Version.NeoForgeVersion)
WriteIni(Path & "PCL\Setup.ini", "VersionApiCode", Version.SortCode) WriteIni(Path & "PCL\Setup.ini", "VersionApiCode", Version.SortCode)
WriteIni(Path & "PCL\Setup.ini", "VersionOriginal", Version.McName) WriteIni(Path & "PCL\Setup.ini", "VersionOriginal", Version.McName)
WriteIni(Path & "PCL\Setup.ini", "VersionOriginalMain", Version.McCodeMain) WriteIni(Path & "PCL\Setup.ini", "VersionOriginalMain", Version.McCodeMain)
@@ -852,6 +861,7 @@ ExitDataLoad:
OptiFine OptiFine
Old Old
Forge Forge
NeoForge
LiteLoader LiteLoader
Fabric Fabric
End Enum End Enum
@@ -903,6 +913,17 @@ ExitDataLoad:
''' </summary> ''' </summary>
Public ForgeVersion As String = "" Public ForgeVersion As String = ""
'NeoForge
''' <summary>
''' 该版本是否安装了 NeoForge。
''' </summary>
Public HasNeoForge As Boolean = False
''' <summary>
''' NeoForge 版本号,如 21.0.2-beta、47.1.79。
''' </summary>
Public NeoForgeVersion As String = ""
'Fabric 'Fabric
''' <summary> ''' <summary>
@@ -929,6 +950,7 @@ ExitDataLoad:
Public Overrides Function ToString() As String Public Overrides Function ToString() As String
ToString = "" ToString = ""
If HasForge Then ToString += ", Forge" & If(ForgeVersion = "未知版本", "", " " & ForgeVersion) If HasForge Then ToString += ", Forge" & If(ForgeVersion = "未知版本", "", " " & ForgeVersion)
If HasNeoForge Then ToString += ", NeoForge" & If(NeoForgeVersion = "未知版本", "", " " & NeoForgeVersion)
If HasFabric Then ToString += ", Fabric" & If(FabricVersion = "未知版本", "", " " & FabricVersion) If HasFabric Then ToString += ", Fabric" & If(FabricVersion = "未知版本", "", " " & FabricVersion)
If HasOptiFine Then ToString += ", OptiFine" & If(OptiFineVersion = "未知版本", "", " " & OptiFineVersion) If HasOptiFine Then ToString += ", OptiFine" & If(OptiFineVersion = "未知版本", "", " " & OptiFineVersion)
If HasLiteLoader Then ToString += ", LiteLoader" If HasLiteLoader Then ToString += ", LiteLoader"
@@ -955,15 +977,15 @@ ExitDataLoad:
Else Else
Throw New Exception("无效的 Fabric 版本:" & ForgeVersion) Throw New Exception("无效的 Fabric 版本:" & ForgeVersion)
End If End If
ElseIf HasForge Then ElseIf HasForge OrElse HasNeoForge Then
If ForgeVersion = "未知版本" Then Return 0 If ForgeVersion = "未知版本" AndAlso NeoForgeVersion = "未知版本" Then Return 0
Dim SubVersions = ForgeVersion.Split(".") Dim SubVersions = If(HasForge, ForgeVersion.Split("."), NeoForgeVersion.Split("."))
If SubVersions.Length = 4 Then If SubVersions.Length = 4 Then
_SortCode = Val(SubVersions(0)) * 1000000 + Val(SubVersions(1)) * 10000 + Val(SubVersions(3)) _SortCode = Val(SubVersions(0)) * 1000000 + Val(SubVersions(1)) * 10000 + Val(SubVersions(3))
ElseIf SubVersions.Length = 3 Then ElseIf SubVersions.Length = 3 Then
_SortCode = Val(SubVersions(0)) * 1000000 + Val(SubVersions(1)) * 10000 + Val(SubVersions(2)) _SortCode = Val(SubVersions(0)) * 1000000 + Val(SubVersions(1)) * 10000 + Val(SubVersions(2))
Else Else
Throw New Exception("无效的 Forge 版本:" & ForgeVersion) Throw New Exception("无效的 Neo/Forge 版本:" & ForgeVersion)
End If End If
ElseIf HasOptiFine Then ElseIf HasOptiFine Then
If OptiFineVersion = "未知版本" Then Return 0 If OptiFineVersion = "未知版本" Then Return 0
@@ -1175,6 +1197,7 @@ OnLoaded:
Dim VersionInfo As New McVersionInfo With { Dim VersionInfo As New McVersionInfo With {
.FabricVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionFabric", ""), .FabricVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionFabric", ""),
.ForgeVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionForge", ""), .ForgeVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionForge", ""),
.NeoForgeVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionNeoForge", ""),
.OptiFineVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionOptiFine", ""), .OptiFineVersion = ReadIni(Version.Path & "PCL\Setup.ini", "VersionOptiFine", ""),
.HasLiteLoader = ReadIni(Version.Path & "PCL\Setup.ini", "VersionLiteLoader", False), .HasLiteLoader = ReadIni(Version.Path & "PCL\Setup.ini", "VersionLiteLoader", False),
.SortCode = ReadIni(Version.Path & "PCL\Setup.ini", "VersionApiCode", -1), .SortCode = ReadIni(Version.Path & "PCL\Setup.ini", "VersionApiCode", -1),
@@ -1183,9 +1206,10 @@ OnLoaded:
.McCodeSub = ReadIni(Version.Path & "PCL\Setup.ini", "VersionOriginalSub", -1), .McCodeSub = ReadIni(Version.Path & "PCL\Setup.ini", "VersionOriginalSub", -1),
.IsApiLoaded = True .IsApiLoaded = True
} }
VersionInfo.HasFabric = VersionInfo.FabricVersion.Count > 1 VersionInfo.HasFabric = VersionInfo.FabricVersion.Any()
VersionInfo.HasForge = VersionInfo.ForgeVersion.Count > 1 VersionInfo.HasForge = VersionInfo.ForgeVersion.Any()
VersionInfo.HasOptiFine = VersionInfo.OptiFineVersion.Count > 1 VersionInfo.HasNeoForge = VersionInfo.NeoForgeVersion.Any()
VersionInfo.HasOptiFine = VersionInfo.OptiFineVersion.Any()
Version.Version = VersionInfo Version.Version = VersionInfo
End If End If
@@ -1273,7 +1297,7 @@ OnLoaded:
McVersionFilter(VersionList, VersionListOriginal, {McVersionState.Fool}, McVersionCardType.Fool) McVersionFilter(VersionList, VersionListOriginal, {McVersionState.Fool}, McVersionCardType.Fool)
'筛选 API 版本 '筛选 API 版本
McVersionFilter(VersionList, VersionListOriginal, {McVersionState.Forge, McVersionState.LiteLoader, McVersionState.Fabric}, McVersionCardType.API) McVersionFilter(VersionList, VersionListOriginal, {McVersionState.Forge, McVersionState.NeoForge, McVersionState.LiteLoader, McVersionState.Fabric}, McVersionCardType.API)
'将老版本预先分类入不常用,只剩余原版、快照、OptiFine '将老版本预先分类入不常用,只剩余原版、快照、OptiFine
Dim VersionUseful As New List(Of McVersion) Dim VersionUseful As New List(Of McVersion)
@@ -1407,7 +1431,7 @@ OnLoaded:
End Function) End Function)
End If End If
'API 版本:优先按版本排序,此后【先放 Fabric,再放 Forge(按版本号从高到低排序),最后放 LiteLoader(按名称排序)】 'API 版本:优先按版本排序,此后【先放 Fabric,再放 Neo/Forge(按版本号从高到低排序),最后放 LiteLoader(按名称排序)】
If ResultVersionList.ContainsKey(McVersionCardType.API) Then If ResultVersionList.ContainsKey(McVersionCardType.API) Then
ResultVersionList(McVersionCardType.API) = Sort(ResultVersionList(McVersionCardType.API), ResultVersionList(McVersionCardType.API) = Sort(ResultVersionList(McVersionCardType.API),
Function(Left As McVersion, Right As McVersion) Function(Left As McVersion, Right As McVersion)
@@ -1417,6 +1441,8 @@ OnLoaded:
Else Else
If Left.Version.HasFabric Xor Right.Version.HasFabric Then If Left.Version.HasFabric Xor Right.Version.HasFabric Then
Return Left.Version.HasFabric Return Left.Version.HasFabric
ElseIf Left.Version.HasNeoForge Xor Right.Version.HasNeoForge Then
Return Left.Version.HasNeoForge
ElseIf Left.Version.HasForge Xor Right.Version.HasForge Then ElseIf Left.Version.HasForge Xor Right.Version.HasForge Then
Return Left.Version.HasForge Return Left.Version.HasForge
ElseIf Not Left.Version.SortCode <> Right.Version.SortCode Then ElseIf Not Left.Version.SortCode <> Right.Version.SortCode Then
@@ -1649,7 +1675,7 @@ OnLoaded:
Return _Url Return _Url
End Get End Get
Set(value As String) Set(value As String)
'孤儿 Forge 作者喜欢把没有的 URL 写个空字符串 '孤儿 Forge 作者喜欢把没有 URL 的写个空字符串
_Url = If(String.IsNullOrWhiteSpace(value), Nothing, value) _Url = If(String.IsNullOrWhiteSpace(value), Nothing, value)
End Set End Set
End Property End Property
@@ -1666,15 +1692,6 @@ OnLoaded:
End Get End Get
End Property End Property
''' <summary> ''' <summary>
''' 原 Json 中 Name 项最后一部分的版本号。
''' </summary>
Public ReadOnly Property Version As String
Get
Dim Splited = OriginalName.Split(":")
Return Splited(Splited.Count - 1)
End Get
End Property
''' <summary>
''' 原 Json 中的 Name 项。 ''' 原 Json 中的 Name 项。
''' </summary> ''' </summary>
Public OriginalName As String Public OriginalName As String
@@ -1755,7 +1772,7 @@ OnLoaded:
'根据 Inherit 获取最深层版本 '根据 Inherit 获取最深层版本
Dim OriginalVersion As McVersion = Version Dim OriginalVersion As McVersion = Version
'1.17+ 的 Forge 不寻找 Inherit '1.17+ 的 Forge 不寻找 Inherit
If Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17) Then If Not ((Version.Version.HasForge OrElse Version.Version.HasNeoForge) AndAlso Version.Version.McCodeMain >= 17) Then
Do Until OriginalVersion.InheritVersion = "" Do Until OriginalVersion.InheritVersion = ""
If OriginalVersion.InheritVersion = OriginalVersion.Name Then Exit Do If OriginalVersion.InheritVersion = OriginalVersion.Name Then Exit Do
OriginalVersion = New McVersion(PathMcFolder & "versions\" & OriginalVersion.InheritVersion & "\") OriginalVersion = New McVersion(PathMcFolder & "versions\" & OriginalVersion.InheritVersion & "\")
@@ -1840,13 +1857,14 @@ OnLoaded:
Try Try
If Library("downloads") IsNot Nothing AndAlso Library("downloads")("artifact") IsNot Nothing Then If Library("downloads") IsNot Nothing AndAlso Library("downloads")("artifact") IsNot Nothing Then
BasicArray.Add(New McLibToken With { BasicArray.Add(New McLibToken With {
.IsJumpLoader = IsJumpLoader, .IsJumpLoader = IsJumpLoader,
.OriginalName = Library("name"), .OriginalName = Library("name"),
.Url = If(RootUrl, Library("downloads")("artifact")("url")), .Url = If(RootUrl, Library("downloads")("artifact")("url")),
.LocalPath = If(Library("downloads")("artifact")("path") Is Nothing, McLibGet(Library("name"), CustomMcFolder:=CustomMcFolder), CustomMcFolder & "libraries\" & Library("downloads")("artifact")("path").ToString.Replace("/", "\")), .LocalPath = If(Library("downloads")("artifact")("path") Is Nothing, McLibGet(Library("name"),
.Size = Val(Library("downloads")("artifact")("size").ToString), CustomMcFolder:=CustomMcFolder), CustomMcFolder & "libraries\" & Library("downloads")("artifact")("path").ToString.Replace("/", "\")),
.IsNatives = False, .Size = Val(Library("downloads")("artifact")("size").ToString),
.SHA1 = Library("downloads")("artifact")("sha1")?.ToString}) .IsNatives = False,
.SHA1 = Library("downloads")("artifact")("sha1")?.ToString})
Else Else
BasicArray.Add(New McLibToken With {.IsJumpLoader = IsJumpLoader, .OriginalName = Library("name"), .Url = RootUrl, .LocalPath = LocalPath, .Size = 0, .IsNatives = False, .SHA1 = Nothing}) BasicArray.Add(New McLibToken With {.IsJumpLoader = IsJumpLoader, .OriginalName = Library("name"), .Url = RootUrl, .LocalPath = LocalPath, .Size = 0, .IsNatives = False, .SHA1 = Nothing})
End If End If
@@ -1880,15 +1898,25 @@ OnLoaded:
'去重 '去重
Dim ResultArray As New Dictionary(Of String, McLibToken) Dim ResultArray As New Dictionary(Of String, McLibToken)
Dim GetVersion =
Function(Token As McLibToken) As String
'测试例:
'D:\Minecraft\test\libraries\net\neoforged\mergetool\2.0.0\mergetool-2.0.0-api.jar
'D:\Minecraft\test\libraries\org\apache\commons\commons-collections4\4.2\commons-collections4-4.2.jar
'D:\Minecraft\test\libraries\com\google\guava\guava\31.1-jre\guava-31.1-jre.jar
Return GetFolderNameFromPath(GetPathFromFullPath(Token.LocalPath))
End Function
For i = 0 To BasicArray.Count - 1 For i = 0 To BasicArray.Count - 1
Dim Key As String = BasicArray(i).Name & BasicArray(i).IsNatives.ToString & BasicArray(i).IsJumpLoader.ToString Dim Key As String = BasicArray(i).Name & BasicArray(i).IsNatives.ToString & BasicArray(i).IsJumpLoader.ToString
If ResultArray.ContainsKey(Key) Then If ResultArray.ContainsKey(Key) Then
If BasicArray(i).Version <> ResultArray(Key).Version AndAlso KeepSameNameDifferentVersionResult Then Dim BasicArrayVersion As String = GetVersion(BasicArray(i))
Log($"[Minecraft] 发现疑似重复的支持库:{BasicArray(i)} 与 {ResultArray(Key)}") Dim ResultArrayVersion As String = GetVersion(ResultArray(Key))
If BasicArrayVersion <> ResultArrayVersion AndAlso KeepSameNameDifferentVersionResult Then
Log($"[Minecraft] 发现疑似重复的支持库:{BasicArray(i)} ({BasicArrayVersion}) 与 {ResultArray(Key)} ({ResultArrayVersion})")
ResultArray.Add(Key & GetUuid(), BasicArray(i)) ResultArray.Add(Key & GetUuid(), BasicArray(i))
Else Else
Log($"[Minecraft] 发现重复的支持库:{BasicArray(i)} 与 {ResultArray(Key)},已忽略其中之一") Log($"[Minecraft] 发现重复的支持库:{BasicArray(i)} ({BasicArrayVersion}) 与 {ResultArray(Key)} ({ResultArrayVersion}),已忽略其中之一")
If VersionSortBoolean(BasicArray(i).Version, ResultArray(Key).Version) Then If VersionSortBoolean(BasicArrayVersion, ResultArrayVersion) Then
ResultArray(Key) = BasicArray(i) ResultArray(Key) = BasicArray(i)
End If End If
End If End If
@@ -1948,6 +1976,7 @@ OnLoaded:
End If End If
End If End If
End If End If
'Authlib-Injector 文件 'Authlib-Injector 文件
If Setup.Get("VersionServerLogin", Version:=Version) = 4 OrElse If Setup.Get("VersionServerLogin", Version:=Version) = 4 OrElse
(PageLinkHiper.HiperState = LoadState.Finished AndAlso Setup.Get("LoginType") = McLoginType.Legacy) Then 'HiPer 登录转接 (PageLinkHiper.HiperState = LoadState.Finished AndAlso Setup.Get("LoginType") = McLoginType.Legacy) Then 'HiPer 登录转接
@@ -1997,8 +2026,13 @@ OnLoaded:
If Token.Url IsNot Nothing Then If Token.Url IsNot Nothing Then
'获取 Url 的真实地址 '获取 Url 的真实地址
Urls.Add(Token.Url) Urls.Add(Token.Url)
If Token.Url.Contains("launcher.mojang.com/v1/objects") Then Urls = DlSourceLauncherOrMetaGet(Token.Url).ToList() 'Mappings If Token.Url.Contains("launcher.mojang.com/v1/objects") Then
If Token.Url.Contains("maven") Then Urls.Insert(0, Token.Url.Replace(Mid(Token.Url, 1, Token.Url.IndexOfF("maven")), "https://bmclapi2.bangbang93.com/").Replace("maven.fabricmc.net", "maven").Replace("maven.minecraftforge.net", "maven")) Urls = DlSourceLauncherOrMetaGet(Token.Url).ToList() 'Mappings
End If
If Token.Url.Contains("maven") Then
Urls.Insert(0, Token.Url.Replace(Mid(Token.Url, 1, Token.Url.IndexOfF("maven")), "https://bmclapi2.bangbang93.com/").
Replace("maven.fabricmc.net", "maven").Replace("maven.minecraftforge.net", "maven").Replace("maven.neoforged.net/releases", "maven"))
End If
End If End If
If Token.LocalPath.Contains("transformer-discovery-service") Then If Token.LocalPath.Contains("transformer-discovery-service") Then
'Transformer 文件释放 'Transformer 文件释放
@@ -887,7 +887,7 @@ Finished:
ModList.Add(ModEntry) ModList.Add(ModEntry)
'读取 Comp 缓存 '读取 Comp 缓存
If ModEntry.State = McMod.McModState.Unavaliable Then Continue For If ModEntry.State = McMod.McModState.Unavaliable Then Continue For
Dim CacheKey = ModEntry.ModrinthHash & PageVersionLeft.Version.Version.McName Dim CacheKey = ModEntry.ModrinthHash & PageVersionLeft.Version.Version.McName & GetTargetModLoaders().Join("")
If Cache.ContainsKey(CacheKey) Then If Cache.ContainsKey(CacheKey) Then
ModEntry.FromJson(Cache(CacheKey)) ModEntry.FromJson(Cache(CacheKey))
'如果缓存中的信息在 6 小时以内更新过,则无需重新获取 '如果缓存中的信息在 6 小时以内更新过,则无需重新获取
@@ -923,20 +923,15 @@ Finished:
Throw Throw
End Try End Try
End Sub End Sub
'联网加载 Mod 详情 '联网加载 Mod 详情
Private Const LocalModCacheVersion As Integer = 4 Private Const LocalModCacheVersion As Integer = 5
Public McModDetailLoader As New LoaderTask(Of KeyValuePair(Of List(Of McMod), JObject), Integer)("Mod List Detail Loader", AddressOf McModDetailLoad) Public McModDetailLoader As New LoaderTask(Of KeyValuePair(Of List(Of McMod), JObject), Integer)("Mod List Detail Loader", AddressOf McModDetailLoad)
Private Sub McModDetailLoad(Loader As LoaderTask(Of KeyValuePair(Of List(Of McMod), JObject), Integer)) Private Sub McModDetailLoad(Loader As LoaderTask(Of KeyValuePair(Of List(Of McMod), JObject), Integer))
Dim Mods As List(Of McMod) = Loader.Input.Key Dim Mods As List(Of McMod) = Loader.Input.Key
Dim Cache As JObject = Loader.Input.Value Dim Cache As JObject = Loader.Input.Value
'获取作为检查目标的加载器和版本 '获取作为检查目标的加载器和版本
Dim TargetMcVersion As McVersionInfo = PageVersionLeft.Version.Version Dim TargetMcVersion As McVersionInfo = PageVersionLeft.Version.Version
Dim ModLoaders As New List(Of CompModLoaderType) Dim ModLoaders = GetTargetModLoaders()
If TargetMcVersion.HasForge Then ModLoaders.Add(CompModLoaderType.Forge)
If TargetMcVersion.HasFabric Then ModLoaders.Add(CompModLoaderType.Fabric)
If TargetMcVersion.HasLiteLoader Then ModLoaders.Add(CompModLoaderType.LiteLoader)
If Not ModLoaders.Any() Then ModLoaders.AddRange({CompModLoaderType.Forge, CompModLoaderType.Fabric, CompModLoaderType.LiteLoader, CompModLoaderType.Quilt})
Dim McVersion = TargetMcVersion.McName Dim McVersion = TargetMcVersion.McName
'暂不向下扩展检查的 MC 小版本 '暂不向下扩展检查的 MC 小版本
'例如:Mod 在更新 1.16.5 后,对早期的 1.16.2 版本发布了修补补丁,这会导致 PCL 将 1.16.5 版本的 Mod 降级到 1.16.2 '例如:Mod 在更新 1.16.5 后,对早期的 1.16.2 版本发布了修补补丁,这会导致 PCL 将 1.16.5 版本的 Mod 降级到 1.16.2
@@ -1136,10 +1131,19 @@ Finished:
If Not Mods.Any() Then Exit Sub If Not Mods.Any() Then Exit Sub
For Each Entry In Mods 'TODO: Bookshelf 的 Logo 会在两个网站间横跳 For Each Entry In Mods 'TODO: Bookshelf 的 Logo 会在两个网站间横跳
Entry.CompLoaded = SucceedThreadCount = 2 Entry.CompLoaded = SucceedThreadCount = 2
Cache(Entry.ModrinthHash & McVersion) = Entry.ToJson() Cache(Entry.ModrinthHash & McVersion & ModLoaders.Join("")) = Entry.ToJson()
Next Next
WriteFile(PathTemp & "Cache\LocalMod.json", Cache.ToString(If(ModeDebug, Newtonsoft.Json.Formatting.Indented, Newtonsoft.Json.Formatting.None))) WriteFile(PathTemp & "Cache\LocalMod.json", Cache.ToString(If(ModeDebug, Newtonsoft.Json.Formatting.Indented, Newtonsoft.Json.Formatting.None)))
End Sub End Sub
Private Function GetTargetModLoaders() As List(Of CompModLoaderType)
Dim ModLoaders As New List(Of CompModLoaderType)
If PageVersionLeft.Version.Version.HasForge Then ModLoaders.Add(CompModLoaderType.Forge)
If PageVersionLeft.Version.Version.HasNeoForge Then ModLoaders.Add(CompModLoaderType.NeoForge)
If PageVersionLeft.Version.Version.HasFabric Then ModLoaders.Add(CompModLoaderType.Fabric)
If PageVersionLeft.Version.Version.HasLiteLoader Then ModLoaders.Add(CompModLoaderType.LiteLoader)
If Not ModLoaders.Any() Then ModLoaders.AddRange({CompModLoaderType.Forge, CompModLoaderType.NeoForge, CompModLoaderType.Fabric, CompModLoaderType.LiteLoader, CompModLoaderType.Quilt})
Return ModLoaders
End Function
#If DEBUG Then #If DEBUG Then
''' <summary> ''' <summary>
@@ -25,6 +25,7 @@ Public Module ModModpack
Archive = New ZipArchive(New FileStream(File, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) Archive = New ZipArchive(New FileStream(File, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
'从根目录判断整合包类型 '从根目录判断整合包类型
If Archive.GetEntry("mcbbs.packmeta") IsNot Nothing Then PackType = 3 : Exit Try 'MCBBS 整合包(优先于 manifest.json 判断) If Archive.GetEntry("mcbbs.packmeta") IsNot Nothing Then PackType = 3 : Exit Try 'MCBBS 整合包(优先于 manifest.json 判断)
If Archive.GetEntry("mmc-pack.json") IsNot Nothing Then PackType = 2 : Exit Try 'MMC 整合包(优先于 manifest.json 判断,#4194)
If Archive.GetEntry("modrinth.index.json") IsNot Nothing Then PackType = 4 : Exit Try 'Modrinth 整合包 If Archive.GetEntry("modrinth.index.json") IsNot Nothing Then PackType = 4 : Exit Try 'Modrinth 整合包
If Archive.GetEntry("manifest.json") IsNot Nothing Then If Archive.GetEntry("manifest.json") IsNot Nothing Then
Dim Json As JObject = GetJson(ReadFile(Archive.GetEntry("manifest.json").Open, Encoding.UTF8)) Dim Json As JObject = GetJson(ReadFile(Archive.GetEntry("manifest.json").Open, Encoding.UTF8))
@@ -35,7 +36,6 @@ Public Module ModModpack
End If End If
End If End If
If Archive.GetEntry("modpack.json") IsNot Nothing Then PackType = 1 : Exit Try 'HMCL 整合包 If Archive.GetEntry("modpack.json") IsNot Nothing Then PackType = 1 : Exit Try 'HMCL 整合包
If Archive.GetEntry("mmc-pack.json") IsNot Nothing Then PackType = 2 : Exit Try 'MMC 整合包
'从一级目录判断整合包类型 '从一级目录判断整合包类型
For Each Entry In Archive.Entries For Each Entry In Archive.Entries
Dim FullNames As String() = Entry.FullName.Split("/") Dim FullNames As String() = Entry.FullName.Split("/")
@@ -183,6 +183,7 @@ Retry:
'获取 Mod API 版本信息 '获取 Mod API 版本信息
Dim ForgeVersion As String = Nothing Dim ForgeVersion As String = Nothing
Dim NeoForgeVersion As String = Nothing
Dim FabricVersion As String = Nothing Dim FabricVersion As String = Nothing
For Each Entry In If(Json("minecraft")("modLoaders"), {}) For Each Entry In If(Json("minecraft")("modLoaders"), {})
Dim Id As String = If(Entry("id"), "").ToString.ToLower Dim Id As String = If(Entry("id"), "").ToString.ToLower
@@ -194,16 +195,25 @@ Retry:
End If End If
Try Try
Log("[ModPack] 整合包 Forge 版本:" & Id) Log("[ModPack] 整合包 Forge 版本:" & Id)
ForgeVersion = Id.Split("-")(1) ForgeVersion = Id.Replace("forge-", "")
Exit For Exit For
Catch ex As Exception Catch ex As Exception
Log(ex, "读取整合包 Forge 版本失败:" & Id) Log(ex, "读取整合包 Forge 版本失败:" & Id)
End Try End Try
ElseIf Id.StartsWithF("neoforge-") Then
'NeoForge 指定
Try
Log("[ModPack] 整合包 NeoForge 版本:" & Id)
NeoForgeVersion = Id.Replace("neoforge-", "")
Exit For
Catch ex As Exception
Log(ex, "读取整合包 NeoForge 版本失败:" & Id)
End Try
ElseIf Id.StartsWithF("fabric-") Then ElseIf Id.StartsWithF("fabric-") Then
'Fabric 指定 'Fabric 指定
Try Try
Log("[ModPack] 整合包 Fabric 版本:" & Id) Log("[ModPack] 整合包 Fabric 版本:" & Id)
FabricVersion = Id.Split("-")(1) FabricVersion = Id.Replace("fabric-", "")
Exit For Exit For
Catch ex As Exception Catch ex As Exception
Log(ex, "读取整合包 Fabric 版本失败:" & Id) Log(ex, "读取整合包 Fabric 版本失败:" & Id)
@@ -271,19 +281,23 @@ Retry:
'建立 CompFile '建立 CompFile
Dim File As New CompFile(ModJson, CompType.Mod) Dim File As New CompFile(ModJson, CompType.Mod)
If Not File.Available Then Continue For If Not File.Available Then Continue For
'根据 modules 和文件名后缀判断是资源包还是 Mod '根据 modules 和文件名后缀判断资源类型
Dim IsResourcePack As Boolean Dim TargetFolder As String
If ModJson("modules").Any Then 'modules 可能返回 null(#1006) If ModJson("modules").Any Then 'modules 可能返回 null(#1006)
Dim ModuleNames = CType(ModJson("modules"), JArray).Select(Function(l) l("name").ToString).ToList Dim ModuleNames = CType(ModJson("modules"), JArray).Select(Function(l) l("name").ToString).ToList
IsResourcePack = If ModuleNames.Contains("META-INF") OrElse ModuleNames.Contains("mcmod.info") OrElse
(Not ModuleNames.Contains("META-INF")) AndAlso (Not ModuleNames.Contains("mcmod.info")) AndAlso '不包含 META-INF 或 mcmod.info File.FileName.EndsWithF(".jar", True) Then
ModuleNames.Contains("pack.mcmeta") AndAlso '包含 pack.mcmeta TargetFolder = "mods"
(Not File.FileName.EndsWithF(".jar", True)) '文件后缀不是 .jar ElseIf ModuleNames.Contains("pack.mcmeta") Then
TargetFolder = "resourcepacks"
Else
TargetFolder = "shaderpacks"
End If
Else Else
IsResourcePack = False TargetFolder = "mods"
End If End If
'实际的添加 '实际的添加
FileList.Add(Id, File.ToNetFile($"{PathMcFolder}versions\{VersionName}\{If(IsResourcePack, "resourcepacks", "mods")}\")) FileList.Add(Id, File.ToNetFile($"{PathMcFolder}versions\{VersionName}\{TargetFolder}\"))
Task.Progress += 1 / (1 + ModList.Count) Task.Progress += 1 / (1 + ModList.Count)
Next Next
Task.Output = FileList.Values.ToList Task.Output = FileList.Values.ToList
@@ -301,6 +315,7 @@ Retry:
.TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\", .TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\",
.MinecraftName = Json("minecraft")("version").ToString, .MinecraftName = Json("minecraft")("version").ToString,
.ForgeVersion = ForgeVersion, .ForgeVersion = ForgeVersion,
.NeoForgeVersion = NeoForgeVersion,
.FabricVersion = FabricVersion .FabricVersion = FabricVersion
} }
Dim MergeLoaders As List(Of LoaderBase) = McInstallLoader(Request, True) Dim MergeLoaders As List(Of LoaderBase) = McInstallLoader(Request, True)
@@ -368,6 +383,7 @@ Retry:
'获取 Mod API 版本信息 '获取 Mod API 版本信息
Dim MinecraftVersion As String = Nothing Dim MinecraftVersion As String = Nothing
Dim ForgeVersion As String = Nothing Dim ForgeVersion As String = Nothing
Dim NeoForgeVersion As String = Nothing
Dim FabricVersion As String = Nothing Dim FabricVersion As String = Nothing
For Each Entry As JProperty In If(Json("dependencies"), {}) For Each Entry As JProperty In If(Json("dependencies"), {})
Select Case Entry.Name.ToLower Select Case Entry.Name.ToLower
@@ -376,6 +392,9 @@ Retry:
Case "forge" 'eg. 14.23.5.2859 / 1.19-41.1.0 Case "forge" 'eg. 14.23.5.2859 / 1.19-41.1.0
ForgeVersion = Entry.Value.ToString ForgeVersion = Entry.Value.ToString
Log("[ModPack] 整合包 Forge 版本:" & ForgeVersion) Log("[ModPack] 整合包 Forge 版本:" & ForgeVersion)
Case "neoforge", "neo-forge" 'eg. 20.6.98-beta
NeoForgeVersion = Entry.Value.ToString
Log("[ModPack] 整合包 NeoForge 版本:" & NeoForgeVersion)
Case "fabric-loader" 'eg. 0.14.14 Case "fabric-loader" 'eg. 0.14.14
FabricVersion = Entry.Value.ToString FabricVersion = Entry.Value.ToString
Log("[ModPack] 整合包 Fabric 版本:" & FabricVersion) Log("[ModPack] 整合包 Fabric 版本:" & FabricVersion)
@@ -447,6 +466,7 @@ Retry:
.TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\", .TargetVersionFolder = $"{PathMcFolder}versions\{VersionName}\",
.MinecraftName = MinecraftVersion, .MinecraftName = MinecraftVersion,
.ForgeVersion = ForgeVersion, .ForgeVersion = ForgeVersion,
.NeoForgeVersion = NeoForgeVersion,
.FabricVersion = FabricVersion .FabricVersion = FabricVersion
} }
Dim MergeLoaders As List(Of LoaderBase) = McInstallLoader(Request, True) Dim MergeLoaders As List(Of LoaderBase) = McInstallLoader(Request, True)
@@ -676,6 +696,8 @@ Retry:
Request.MinecraftName = Component("version") Request.MinecraftName = Component("version")
Case "net.minecraftforge" Case "net.minecraftforge"
Request.ForgeVersion = Component("version") Request.ForgeVersion = Component("version")
Case "net.neoforged"
Request.NeoForgeVersion = Component("version")
Case "net.fabricmc.fabric-loader" Case "net.fabricmc.fabric-loader"
Request.FabricVersion = Component("version") Request.FabricVersion = Component("version")
Case "org.quiltmc.quilt-loader" 'eg. 1.0.0 Case "org.quiltmc.quilt-loader" 'eg. 1.0.0
@@ -772,6 +794,7 @@ Retry:
.MinecraftName = Addons("game"), .MinecraftName = Addons("game"),
.OptiFineVersion = If(Addons.ContainsKey("optifine"), Addons("optifine"), Nothing), .OptiFineVersion = If(Addons.ContainsKey("optifine"), Addons("optifine"), Nothing),
.ForgeVersion = If(Addons.ContainsKey("forge"), Addons("forge"), Nothing), .ForgeVersion = If(Addons.ContainsKey("forge"), Addons("forge"), Nothing),
.NeoForgeVersion = If(Addons.ContainsKey("neoforge"), Addons("neoforge"), Nothing),
.FabricVersion = If(Addons.ContainsKey("fabric"), Addons("fabric"), Nothing) .FabricVersion = If(Addons.ContainsKey("fabric"), Addons("fabric"), Nothing)
} }
Dim MergeLoaders As List(Of LoaderBase) = McInstallLoader(Request, True) Dim MergeLoaders As List(Of LoaderBase) = McInstallLoader(Request, True)
+30 -20
View File
@@ -21,28 +21,38 @@
OpenWebsite(Data(0)) OpenWebsite(Data(0))
Case "打开文件", "打开帮助" Case "打开文件", "打开帮助"
RunInThread(Sub() RunInThread(
Try Sub()
'确认实际路径 Try
Dim ActualPaths = GetEventAbsoluteUrls(Data(0), Type) '确认实际路径
Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1) Dim ActualPaths = GetEventAbsoluteUrls(Data(0), Type)
'执行 Dim Location = ActualPaths(0), WorkingDir = ActualPaths(1)
If Type = "打开文件" Then Log($"[Control] 打开类自定义事件实际路径:{Location},工作目录:{WorkingDir}")
Dim Info As New ProcessStartInfo With { '执行
.Arguments = If(Data.Length >= 2, Data(1), ""), If Type = "打开文件" Then
.FileName = Location, Dim Info As New ProcessStartInfo With {
.WorkingDirectory = WorkingDir .Arguments = If(Data.Length >= 2, Data(1), ""),
} .FileName = Location,
Process.Start(Info) .WorkingDirectory = WorkingDir
Else '打开帮助 }
PageOtherHelp.EnterHelpPage(Location) Process.Start(Info)
End If Else '打开帮助
Catch ex As Exception PageOtherHelp.EnterHelpPage(Location)
Log(ex, "执行打开类自定义事件失败", LogLevel.Msgbox) End If
End Try Catch ex As Exception
End Sub) Log(ex, "执行打开类自定义事件失败", LogLevel.Msgbox)
End Try
End Sub)
Case "启动游戏" Case "启动游戏"
If Data(0) = "\current" Then
If McVersionCurrent Is Nothing Then
Hint("请先选择一个 Minecraft 版本!", HintType.Critical)
Exit Sub
Else
Data(0) = McVersionCurrent.Name
End If
End If
If McLaunchStart(New McLaunchOptions With If McLaunchStart(New McLaunchOptions With
{.ServerIp = If(Data.Length >= 2, Data(1), Nothing), .Version = New McVersion(Data(0))}) Then {.ServerIp = If(Data.Length >= 2, Data(1), Nothing), .Version = New McVersion(Data(0))}) Then
Hint("正在启动 " & Data(0) & "……") Hint("正在启动 " & Data(0) & "……")
@@ -394,6 +394,7 @@ EndHint:
Public FrmDownloadOptiFine As PageDownloadOptiFine Public FrmDownloadOptiFine As PageDownloadOptiFine
Public FrmDownloadLiteLoader As PageDownloadLiteLoader Public FrmDownloadLiteLoader As PageDownloadLiteLoader
Public FrmDownloadForge As PageDownloadForge Public FrmDownloadForge As PageDownloadForge
Public FrmDownloadNeoForge As PageDownloadNeoForge
Public FrmDownloadFabric As PageDownloadFabric Public FrmDownloadFabric As PageDownloadFabric
Public FrmDownloadMod As PageDownloadMod Public FrmDownloadMod As PageDownloadMod
Public FrmDownloadPack As PageDownloadPack Public FrmDownloadPack As PageDownloadPack
+16 -6
View File
@@ -69,16 +69,25 @@
Else Else
'有背景音乐 '有背景音乐
FrmMain.BtnExtraMusic.Show = True FrmMain.BtnExtraMusic.Show = True
Dim ToolTipText As String
Dim ToolTipText As String = "正在播放:" & GetFileNameWithoutExtentionFromPath(MusicCurrent)
If MusicState = MusicStates.Pause Then If MusicState = MusicStates.Pause Then
FrmMain.BtnExtraMusic.Logo = Logo.IconPlay FrmMain.BtnExtraMusic.Logo = Logo.IconPlay
FrmMain.BtnExtraMusic.LogoScale = 0.8 FrmMain.BtnExtraMusic.LogoScale = 0.8
If MusicAllList.Count > 1 Then ToolTipText += vbCrLf & "左键播放,右键播放下一曲。" ToolTipText = "已暂停:" & GetFileNameWithoutExtentionFromPath(MusicCurrent)
If MusicAllList.Count > 1 Then
ToolTipText += vbCrLf & "左键恢复播放,右键播放下一曲。"
Else
ToolTipText += vbCrLf & "左键恢复播放,右键重新从头播放。"
End If
Else Else
FrmMain.BtnExtraMusic.Logo = Logo.IconMusic FrmMain.BtnExtraMusic.Logo = Logo.IconMusic
FrmMain.BtnExtraMusic.LogoScale = 1 FrmMain.BtnExtraMusic.LogoScale = 1
If MusicAllList.Count > 1 Then ToolTipText += vbCrLf & "左键暂停,右键播放下一曲。" ToolTipText = "正在播放:" & GetFileNameWithoutExtentionFromPath(MusicCurrent)
If MusicAllList.Count > 1 Then
ToolTipText += vbCrLf & "左键暂停,右键播放下一曲。"
Else
ToolTipText += vbCrLf & "左键暂停,右键重新从头播放。"
End If
End If End If
FrmMain.BtnExtraMusic.ToolTip = ToolTipText FrmMain.BtnExtraMusic.ToolTip = ToolTipText
ToolTipService.SetVerticalOffset(FrmMain.BtnExtraMusic, If(ToolTipText.Contains(vbLf), 10, 16)) ToolTipService.SetVerticalOffset(FrmMain.BtnExtraMusic, If(ToolTipText.Contains(vbLf), 10, 16))
@@ -115,13 +124,14 @@
''' </summary> ''' </summary>
Public Sub MusicControlNext() Public Sub MusicControlNext()
If MusicAllList.Count = 1 Then If MusicAllList.Count = 1 Then
Hint("播放列表中仅有一首歌曲!") MusicStartPlay(MusicCurrent)
Hint("重新播放:" & GetFileNameFromPath(MusicCurrent), HintType.Finish)
Else Else
Dim Address As String = DequeueNextMusicAddress() Dim Address As String = DequeueNextMusicAddress()
MusicStartPlay(Address) MusicStartPlay(Address)
Hint("正在播放:" & GetFileNameFromPath(Address), HintType.Finish) Hint("正在播放:" & GetFileNameFromPath(Address), HintType.Finish)
MusicRefreshUI()
End If End If
MusicRefreshUI()
End Sub End Sub
#End Region #End Region
@@ -252,6 +252,7 @@ Friend Module ModSecret
Return False Return False
End Function End Function
Public Function DonateCodeInput() As Boolean? Public Function DonateCodeInput() As Boolean?
Return Nothing
End Function End Function
#End Region #End Region
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
' 方法是按如下所示使用“*” ' 方法是按如下所示使用“*”
<Assembly: AssemblyVersion("2.7.4.0")> <Assembly: AssemblyVersion("2.8.2.0")>
<Assembly: AssemblyFileVersion("2.7.4.0")> <Assembly: AssemblyFileVersion("2.8.2.0")>
<Assembly: NeutralResourcesLanguage("")> <Assembly: NeutralResourcesLanguage("")>
@@ -316,46 +316,6 @@ Public Module ModDownloadLib
#Region "OptiFine 下载" #Region "OptiFine 下载"
Public Sub McDownloadOptiFine(DownloadInfo As DlOptiFineListEntry)
Try
Dim Id As String = DownloadInfo.NameVersion
Dim VersionFolder As String = PathMcFolder & "versions\" & Id & "\"
Dim IsNewVersion As Boolean = Val(DownloadInfo.Inherit.Split(".")(1)) >= 14
Dim Target As String = If(IsNewVersion,
PathTemp & "Cache\Code\" & DownloadInfo.NameVersion & "_" & GetUuid(),
PathMcFolder & "libraries\optifine\OptiFine\" & DownloadInfo.NameFile.Replace("OptiFine_", "").Replace(".jar", "").Replace("preview_", "") & "\" & DownloadInfo.NameFile.Replace("OptiFine_", "OptiFine-").Replace("preview_", ""))
'重复任务检查
SyncLock LoaderTaskbarLock
For i = 0 To LoaderTaskbar.Count - 1
If LoaderTaskbar(i).Name = "OptiFine " & DownloadInfo.NameDisplay & " 下载" Then
Hint("该版本正在下载中!", HintType.Critical)
Exit Sub
End If
Next
End SyncLock
'已有版本检查
If File.Exists(VersionFolder & Id & ".json") Then
If MyMsgBox("版本 " & Id & " 已存在,是否重新下载?" & vbCrLf & "这会覆盖版本的 json 和 jar 文件,但不会影响版本隔离的文件。", "版本已存在", "继续", "取消") = 1 Then
File.Delete(VersionFolder & Id & ".jar")
File.Delete(VersionFolder & Id & ".json")
Else
Exit Sub
End If
End If
'启动
Dim Loader As New LoaderCombo(Of String)("OptiFine " & DownloadInfo.NameDisplay & " 下载", McDownloadOptiFineLoader(DownloadInfo)) With {.OnStateChanged = AddressOf McInstallState}
Loader.Start(VersionFolder)
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "开始 OptiFine 下载失败", LogLevel.Feedback)
End Try
End Sub
Private Sub McDownloadOptiFineSave(DownloadInfo As DlOptiFineListEntry) Private Sub McDownloadOptiFineSave(DownloadInfo As DlOptiFineListEntry)
Try Try
Dim Id As String = DownloadInfo.NameVersion Dim Id As String = DownloadInfo.NameVersion
@@ -1005,74 +965,13 @@ Retry:
#End Region #End Region
#Region "Forge 下载" #Region "Forgelike 下载"
Public Sub McDownloadForge(DownloadInfo As DlForgeVersionEntry) Public Sub McDownloadForgelikeSave(Info As DlForgelikeEntry)
'老版本提示
If DownloadInfo.Category = "client" Then
If MyMsgBox("该 Forge 版本过于古老,PCL 暂不支持该版本的自动安装。" & vbCrLf &
"若你仍然希望继续,PCL 将把安装程序下载到你指定的位置,但不会进行安装。",
"版本过老", "继续", "取消") = 1 Then
McDownloadForgeSave(DownloadInfo)
End If
Exit Sub
End If
If DownloadInfo.Category = "universal" OrElse DownloadInfo.Inherit.StartsWithF("1.5") Then '对该版本自动安装的支持将在之后加入
If MyMsgBox("该 Forge 版本过于古老,PCL 暂不支持该版本的自动安装。" & vbCrLf &
"若你仍然希望继续,PCL 将把安装程序下载到你指定的位置,但不会进行安装。",
"版本过老", "继续", "取消") = 1 Then
McDownloadForgeSave(DownloadInfo)
End If
Exit Sub
End If
'初始化参数
Dim Id As String = DownloadInfo.Inherit & "-forge-" & DownloadInfo.Version
Dim Target As String = PathTemp & "Cache\Code\ForgeInstall-" & DownloadInfo.Version & "_" & GetUuid() & "." & DownloadInfo.FileSuffix
Dim VersionFolder As String = PathMcFolder & "versions\" & Id & "\"
Dim DisplayName As String = "Forge " & DownloadInfo.Inherit & " - " & DownloadInfo.Version
Try Try
Dim Target As String = SelectAs("选择保存位置", $"{Info.LoaderName}-{Info.Inherit}-{Info.VersionName}.{Info.FileExtension}",
'重复任务检查 $"{Info.LoaderName} 安装器 (*.{Info.FileExtension})|*.{Info.FileExtension}")
SyncLock LoaderTaskbarLock Dim DisplayName As String = $"{Info.LoaderName} {Info.Inherit} - {Info.VersionName}"
For i = 0 To LoaderTaskbar.Count - 1
If LoaderTaskbar(i).Name = DisplayName & " 下载" Then
Hint("该版本正在下载中!", HintType.Critical)
Exit Sub
End If
Next
End SyncLock
'已有版本检查
If File.Exists(VersionFolder & Id & ".json") Then
If MyMsgBox("版本 " & Id & " 已存在,是否重新下载?" & vbCrLf & "这会覆盖版本的 json 和 jar 文件,但不会影响版本隔离的文件。", "版本已存在", "继续", "取消") = 1 Then
File.Delete(VersionFolder & Id & ".jar")
File.Delete(VersionFolder & Id & ".json")
Else
Exit Sub
End If
End If
'启动
Dim Loader As New LoaderCombo(Of String)(DisplayName & " 下载", McDownloadForgeLoader(DownloadInfo.Version, DownloadInfo.Inherit, DownloadInfo)) With {.OnStateChanged = AddressOf McInstallState}
Loader.Start(VersionFolder)
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "开始 Forge 下载失败", LogLevel.Feedback)
Finally
'删除安装包
Try
If File.Exists(Target) Then File.Delete(Target)
Catch
End Try
End Try
End Sub
Public Sub McDownloadForgeSave(DownloadInfo As DlForgeVersionEntry)
Try
Dim Target As String = SelectAs("选择保存位置", DownloadInfo.FileName, "Forge 文件 (*." & DownloadInfo.FileSuffix & ")|*." & DownloadInfo.FileSuffix)
Dim DisplayName As String = "Forge " & DownloadInfo.Inherit & " - " & DownloadInfo.Version
If Not Target.Contains("\") Then Exit Sub If Not Target.Contains("\") Then Exit Sub
'重复任务检查 '重复任务检查
@@ -1085,34 +984,41 @@ Retry:
Next Next
End SyncLock End SyncLock
'构造步骤加载器
Dim Loaders As New List(Of LoaderBase)
'获取下载地址 '获取下载地址
Loaders.Add(New LoaderTask(Of DlForgeVersionEntry, List(Of NetFile))("获取下载地址", Dim Files As New List(Of NetFile)
Sub(Task As LoaderTask(Of DlForgeVersionEntry, List(Of NetFile))) If Info.IsNeoForge Then
Dim Files As New List(Of NetFile) 'NeoForge
Dim Neo As DlNeoForgeListEntry = Info
Dim Url As String = Neo.UrlBase & "-installer.jar"
Files.Add(New NetFile({ Files.Add(New NetFile({
"https://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/" & DownloadInfo.Inherit & "-" & DownloadInfo.FileVersion & "/" & DownloadInfo.FileName, Url.Replace("maven.neoforged.net/releases", "bmclapi2.bangbang93.com/maven"), Url
"https://files.minecraftforge.net/maven/net/minecraftforge/forge/" & DownloadInfo.Inherit & "-" & DownloadInfo.FileVersion & "/" & DownloadInfo.FileName }, Target, New FileChecker(MinSize:=64 * 1024)))
}, Target, New FileChecker(MinSize:=64 * 1024, Hash:=DownloadInfo.Hash))) Else
Task.Output = Files 'Forge
End Sub) With {.ProgressWeight = 0.1, .Show = False}) Dim Forge As DlForgeVersionEntry = Info
'下载 Files.Add(New NetFile({
Loaders.Add(New LoaderDownload("下载主文件", New List(Of NetFile)) With {.ProgressWeight = 6}) $"https://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/{Forge.Inherit}-{Forge.FileVersion}/forge-{Forge.Inherit}-{Forge.FileVersion}-{Forge.Category}.{Forge.FileExtension}",
$"https://files.minecraftforge.net/maven/net/minecraftforge/forge/{Forge.Inherit}-{Forge.FileVersion}/forge-{Forge.Inherit}-{Forge.FileVersion}-{Forge.Category}.{Forge.FileExtension}"
}, Target, New FileChecker(MinSize:=64 * 1024, Hash:=Forge.Hash)))
End If
'构造加载器
Dim Loaders As New List(Of LoaderBase)
Loaders.Add(New LoaderDownload("下载主文件", Files) With {.ProgressWeight = 6})
'启动 '启动
Dim Loader As New LoaderCombo(Of DlForgeVersionEntry)(DisplayName & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} Dim Loader = New LoaderCombo(Of DlForgelikeEntry)(DisplayName & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
Loader.Start(DownloadInfo) Loader.Start(Info)
LoaderTaskbarAdd(Loader) LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh() FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble() FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception Catch ex As Exception
Log(ex, "开始 Forge 下载失败", LogLevel.Feedback) Log(ex, $"开始 {Info.LoaderName} 安装器下载失败", LogLevel.Feedback)
End Try End Try
End Sub End Sub
Private Sub ForgeInjector(Target As String, Task As LoaderTask(Of Boolean, Boolean), McFolder As String, UseJavaWrapper As Boolean) Private Sub ForgelikeInjector(Target As String, Task As LoaderTask(Of Boolean, Boolean), McFolder As String, UseJavaWrapper As Boolean, IsNeoForge As Boolean)
'选择 Java '选择 Java
Dim Java As JavaEntry Dim Java As JavaEntry
SyncLock JavaLock SyncLock JavaLock
@@ -1153,7 +1059,8 @@ Retry:
.RedirectStandardError = True, .RedirectStandardError = True,
.RedirectStandardOutput = True .RedirectStandardOutput = True
} }
Log("[Download] 开始安装 Forge:" & Arguments) Dim LoaderName As String = If(IsNeoForge, "NeoForge", "Forge")
Log($"[Download] 开始安装 {LoaderName}:" & Arguments)
Dim process As New Process With {.StartInfo = Info} Dim process As New Process With {.StartInfo = Info}
Dim LastResults As New Queue(Of String) Dim LastResults As New Queue(Of String)
Using outputWaitHandle As New AutoResetEvent(False) Using outputWaitHandle As New AutoResetEvent(False)
@@ -1166,15 +1073,15 @@ Retry:
Else Else
LastResults.Enqueue(e.Data) LastResults.Enqueue(e.Data)
If LastResults.Count > 100 Then LastResults.Dequeue() If LastResults.Count > 100 Then LastResults.Dequeue()
ForgeInjectorLine(e.Data, Task) ForgelikeInjectorLine(e.Data, Task)
End If End If
Catch ex As ObjectDisposedException Catch ex As ObjectDisposedException
Catch ex As Exception Catch ex As Exception
Log(ex, "读取 Forge 安装器信息失败") Log(ex, $"读取 {LoaderName} 安装器信息失败")
End Try End Try
Try Try
If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then
Log("[Installer] 由于任务取消,已中止 Forge 安装") Log($"[Installer] 由于任务取消,已中止 {LoaderName} 安装")
process.Kill() process.Kill()
End If End If
Catch Catch
@@ -1189,15 +1096,15 @@ Retry:
Else Else
LastResults.Enqueue(e.Data) LastResults.Enqueue(e.Data)
If LastResults.Count > 100 Then LastResults.Dequeue() If LastResults.Count > 100 Then LastResults.Dequeue()
ForgeInjectorLine(e.Data, Task) ForgelikeInjectorLine(e.Data, Task)
End If End If
Catch ex As ObjectDisposedException Catch ex As ObjectDisposedException
Catch ex As Exception Catch ex As Exception
Log(ex, "读取 Forge 安装器错误信息失败") Log(ex, $"读取 {LoaderName} 安装器错误信息失败")
End Try End Try
Try Try
If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then If Task.State = LoadState.Aborted AndAlso Not process.HasExited Then
Log("[Installer] 由于任务取消,已中止 Forge 安装") Log($"[Installer] 由于任务取消,已中止 {LoaderName} 安装")
process.Kill() process.Kill()
End If End If
Catch Catch
@@ -1222,116 +1129,135 @@ Retry:
For i As Integer = Math.Max(0, LastResults.Count - 5) To LastResults.Count - 1 '最后 5 行 For i As Integer = Math.Max(0, LastResults.Count - 5) To LastResults.Count - 1 '最后 5 行
LastLines &= vbCrLf & LastResults(i) LastLines &= vbCrLf & LastResults(i)
Next Next
Throw New Exception("Forge 安装器出错,日志结束部分为:" & LastLines) Throw New Exception($"{LoaderName} 安装器出错,日志结束部分为:" & LastLines)
End Using End Using
End Using End Using
End SyncLock End SyncLock
End Sub End Sub
Private Sub ForgeInjectorLine(Content As String, Task As LoaderTask(Of Boolean, Boolean)) Private Sub ForgelikeInjectorLine(Content As String, Task As LoaderTask(Of Boolean, Boolean))
If Content.StartsWithF(" Data") OrElse Content.StartsWithF(" Slim") Then Select Case Content
If ModeDebug Then Log("[Installer] " & Content) Case "Extracting json"
ElseIf Content.StartsWithF(" Reading patch ") Then Log("[Installer] " & Content)
If ModeDebug Then Log("[Installer] " & Content) Task.Progress = 0.07
Task.Progress = 0.86 Case "Downloading libraries"
Else Log("[Installer] " & Content)
Select Case Content Task.Progress = 0.08
Case "Extracting json" Case " File exists: Checksum validated."
Log("[Installer] " & Content) If ModeDebug Then Log("[Installer] " & Content)
Task.Progress = 0.07 Task.Progress += 0.003
Case "Downloading libraries" Case "Building Processors"
Log("[Installer] " & Content) Task.Progress = 0.18
Task.Progress = 0.08 Case "Task: DOWNLOAD_MOJMAPS" 'B
Case " File exists: Checksum validated." Task.Progress = 0.2
If ModeDebug Then Log("[Installer] " & Content) Case "Task: MERGE_MAPPING" 'B
Task.Progress += 0.003 Task.Progress = 0.3
Case "Building Processors" Case "Splitting: "
Task.Progress = 0.38 Task.Progress = 0.35
Case "Task: DOWNLOAD_MOJMAPS" 'B Case "Parameter Annotations" 'B
Task.Progress = 0.4 Task.Progress = 0.4
Case "Task: MERGE_MAPPING" 'B Case "Processing Complete" 'B
Task.Progress = 0.6 Task.Progress = 0.5
Case "Splitting: " Case "log: null" 'new
Task.Progress = 0.62 Task.Progress = 0.5
Case "Parameter Annotations" 'B Case "Sorting" 'new
Task.Progress = 0.66 Task.Progress = 0.65
Case "Processing Complete" 'B Case "Remapping final jar" 'A
Task.Progress = 0.7 Task.Progress = 0.72
Case "Remapping final jar" 'A Case "Remapping jar... 50%" 'A
Task.Progress = 0.72 Task.Progress = 0.76
Case "Remapping jar... 50%" 'A Case "Remapping jar... 100%" 'A
Task.Progress = 0.76 Task.Progress = 0.81
Case "Remapping jar... 100%" 'A Case "Injecting profile"
Task.Progress = 0.81 Task.Progress = 0.91
Case "Injecting profile" Case Else
Task.Progress = 0.91 If ModeDebug Then Log("[Installer] " & Content)
Case Else Exit Sub
If ModeDebug Then Log("[Installer] " & Content) End Select
Exit Sub Log("[Installer] " & Content)
End Select
Log("[Installer] " & Content)
End If
End Sub End Sub
''' <summary> ''' <summary>
''' 获取下载某个 Forge 版本的加载器列表。 ''' 获取下载某个 Forgelike 版本的加载器列表。
''' </summary> ''' </summary>
Private Function McDownloadForgeLoader(Version As String, Inherit As String, Optional DownloadInfo As DlForgeVersionEntry = Nothing, Optional McFolder As String = Nothing, Optional ClientDownloadLoader As LoaderCombo(Of String) = Nothing, Optional ClientFolder As String = Nothing, Optional FixLibrary As Boolean = True) As List(Of LoaderBase) Private Function McDownloadForgelikeLoader(IsNeoForge As Boolean, LoaderVersion As String, TargetVersion As String, Inherit As String, Optional Info As DlForgelikeEntry = Nothing, Optional McFolder As String = Nothing, Optional ClientDownloadLoader As LoaderCombo(Of String) = Nothing, Optional ClientFolder As String = Nothing) As List(Of LoaderBase)
'参数初始化 '参数初始化
McFolder = If(McFolder, PathMcFolder) McFolder = If(McFolder, PathMcFolder)
If Version.StartsWithF("1.") AndAlso Version.Contains("-") Then If IsNeoForge AndAlso Info Is Nothing Then
'类似 1.19.3-41.2.8 格式,优先使用 Version 中要求的版本而非 Inherit(例如 1.19.3 却使用了 1.19 的 Forge) '需要传入 API Name,但整合包版本可能不以 1.20.1- 开头,所以需要进行特别处理
Inherit = Version.Before("-") If Inherit = "1.20.1" AndAlso Not LoaderVersion.StartsWithF("1.20.1-") Then
Version = Version.After("-") Info = New DlNeoForgeListEntry("1.20.1-" & LoaderVersion)
Else
Info = New DlNeoForgeListEntry(LoaderVersion)
End If
End If End If
If Not IsNeoForge AndAlso LoaderVersion.StartsWithF("1.") AndAlso LoaderVersion.Contains("-") Then
'类似 1.19.3-41.2.8 格式,优先使用 Version 中要求的版本而非 Inherit(例如 1.19.3 却使用了 1.19 的 Forge)
Inherit = LoaderVersion.Before("-")
LoaderVersion = LoaderVersion.After("-")
End If
Dim LoaderName As String = If(IsNeoForge, "NeoForge", "Forge")
Dim IsCustomFolder As Boolean = McFolder <> PathMcFolder Dim IsCustomFolder As Boolean = McFolder <> PathMcFolder
Dim Id As String = Inherit & "-forge-" & Version Dim InstallerAddress As String = $"{PathTemp}Cache\Code\{LoaderName}Install-{LoaderVersion}_{RandomInteger(0, 100000)}"
Dim InstallerAddress As String = PathTemp & "Cache\Code\ForgeInstall-" & Version & "_" & RandomInteger(0, 100000) Dim VersionFolder As String = $"{McFolder}versions\{TargetVersion}\"
Dim VersionFolder As String = McFolder & "versions\" & Id & "\" Dim DisplayName As String = $"{LoaderName} {Inherit} - {LoaderVersion}"
Dim DisplayName As String = "Forge " & Inherit & " - " & Version
Dim Loaders As New List(Of LoaderBase) Dim Loaders As New List(Of LoaderBase)
Dim LibVersionFolder As String = PathMcFolder & "versions\" & Id & "\" '作为 Lib 文件目标的版本文件夹 Dim LibVersionFolder As String = $"{PathMcFolder}versions\{TargetVersion}\" '作为 Lib 文件目标的版本文件夹
'获取下载信息 '获取 Forge 下载信息
If DownloadInfo Is Nothing Then If Info Is Nothing Then
Loaders.Add(New LoaderTask(Of String, String)("获取 Mod 加载器详细信息", Loaders.Add(New LoaderTask(Of String, String)($"获取 {LoaderName} 详细信息",
Sub(Task As LoaderTask(Of String, String)) Sub(Task As LoaderTask(Of String, String))
'获取 Forge 版本列表 '获取 Forge 对应 MC 版本列表
Dim ForgeLoader = New LoaderTask(Of String, List(Of DlForgeVersionEntry))("McDownloadForgeLoader " & Inherit, AddressOf DlForgeVersionMain) Dim ForgeLoader = New LoaderTask(Of String, List(Of DlForgeVersionEntry))("McDownloadForgeLoader " & Inherit, AddressOf DlForgeVersionMain)
ForgeLoader.WaitForExit(Inherit) ForgeLoader.WaitForExit(Inherit)
Task.Progress = 0.8 Task.Progress = 0.8
'查找对应版本 '查找对应版本
For Each ForgeVersion In ForgeLoader.Output For Each ForgeVersion In ForgeLoader.Output
If ForgeVersion.Version = Version Then If VersionSortInteger(ForgeVersion.Version.ToString, LoaderVersion) = 0 Then
DownloadInfo = ForgeVersion Info = ForgeVersion
Exit Sub Exit Sub
End If End If
Next Next
Throw New Exception("未能找到 Forge " & Inherit & "-" & Version & " 的详细信息!") Throw New Exception($"未能找到 {LoaderName} " & Inherit & "-" & LoaderVersion & " 的详细信息!")
End Sub) With {.ProgressWeight = 3}) End Sub) With {.ProgressWeight = 3})
End If End If
'下载 Forge 主文件 '下载 Forgelike 主文件
Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("准备 Mod 加载器下载", Loaders.Add(New LoaderTask(Of String, List(Of NetFile))($"准备下载 {LoaderName}",
Sub(Task As LoaderTask(Of String, List(Of NetFile))) Sub(Task As LoaderTask(Of String, List(Of NetFile)))
'启动依赖版本的下载 '启动依赖版本的下载
If ClientDownloadLoader Is Nothing Then If ClientDownloadLoader Is Nothing Then
If IsCustomFolder Then Throw New Exception("如果没有指定原版下载器,则不能指定 MC 安装文件夹") If IsCustomFolder Then Throw New Exception("如果没有指定原版下载器,则不能指定 MC 安装文件夹")
ClientDownloadLoader = McDownloadClient(NetPreDownloadBehaviour.ExitWhileExistsOrDownloading, Inherit) ClientDownloadLoader = McDownloadClient(NetPreDownloadBehaviour.ExitWhileExistsOrDownloading, Inherit)
End If End If
'添加主文件 '添加主文件下载
Dim Files As New List(Of NetFile) From {New NetFile({ Dim Files As New List(Of NetFile)
"https://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/" & Inherit & "-" & DownloadInfo.FileVersion & "/" & DownloadInfo.FileName, If Info.IsNeoForge Then
"https://files.minecraftforge.net/maven/net/minecraftforge/forge/" & Inherit & "-" & DownloadInfo.FileVersion & "/" & DownloadInfo.FileName 'NeoForge
}, InstallerAddress, New FileChecker(MinSize:=64 * 1024, Hash:=DownloadInfo.Hash))} Dim Neo As DlNeoForgeListEntry = Info
Task.Output = Files Dim Url As String = Neo.UrlBase & "-installer.jar"
End Sub) With {.ProgressWeight = 0.5, .Show = False}) Files.Add(New NetFile({
Loaders.Add(New LoaderDownload("下载 Mod 加载器主文件", New List(Of NetFile)) With {.ProgressWeight = 9}) Url.Replace("maven.neoforged.net/releases", "bmclapi2.bangbang93.com/maven"), Url
}, InstallerAddress, New FileChecker(MinSize:=64 * 1024)))
Else
'Forge
Dim Forge As DlForgeVersionEntry = Info
Dim FileName As String =
$"{Forge.Inherit.Replace("-", "_")}-{Forge.FileVersion}/forge-{Forge.Inherit.Replace("-", "_")}-{Forge.FileVersion}-{Forge.Category}.{Forge.FileExtension}"
Files.Add(New NetFile({
$"https://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/{FileName}",
$"https://files.minecraftforge.net/maven/net/minecraftforge/forge/{FileName}"
}, InstallerAddress, New FileChecker(MinSize:=64 * 1024, Hash:=Forge.Hash)))
End If
Task.Output = Files
End Sub) With {.ProgressWeight = 0.5, .Show = False})
Loaders.Add(New LoaderDownload($"下载 {LoaderName} 主文件", New List(Of NetFile)) With {.ProgressWeight = 9})
'安装(仅在新版安装时需要原版 Jar) '安装(仅在新版安装时需要原版 Jar)
If Version.Before(".") >= 20 Then If IsNeoForge OrElse LoaderVersion.Before(".") >= 20 Then
Log("[Download] 检测为新版 Forge:" & Version) Log($"[Download] 检测为{If(IsNeoForge, " Neo", "新版 ")}Forge:" & LoaderVersion)
Dim Libs As List(Of McLibToken) = Nothing Dim Libs As List(Of McLibToken) = Nothing
Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析 Mod 加载器支持库文件", Loaders.Add(New LoaderTask(Of String, List(Of NetFile))($"分析 {LoaderName} 支持库文件",
Sub(Task As LoaderTask(Of String, List(Of NetFile))) Sub(Task As LoaderTask(Of String, List(Of NetFile)))
Task.Output = New List(Of NetFile) Task.Output = New List(Of NetFile)
Dim Installer As ZipArchive = Nothing Dim Installer As ZipArchive = Nothing
@@ -1357,27 +1283,27 @@ Retry:
Log("[Download] 需要下载 Mappings:" & Address) Log("[Download] 需要下载 Mappings:" & Address)
End If End If
Task.Progress = 0.8 Task.Progress = 0.8
'去除其中的原始 Forge 项 '去除其中的原始 Forgelike 项
For i = 0 To Libs.Count - 1 For i = 0 To Libs.Count - 1
If Libs(i).LocalPath.EndsWithF("forge-" & Inherit & "-" & Version & ".jar") OrElse If Libs(i).LocalPath.EndsWithF($"{LoaderName.ToLower}-{Inherit}-{LoaderVersion}.jar") OrElse
Libs(i).LocalPath.EndsWithF("forge-" & Inherit & "-" & Version & "-client.jar") Then Libs(i).LocalPath.EndsWithF($"{LoaderName.ToLower}-{Inherit}-{LoaderVersion}-client.jar") Then
Log("[Download] 已从待下载 Forge 支持库中移除:" & Libs(i).LocalPath, LogLevel.Debug) Log($"[Download] 已从待下载 {LoaderName} 支持库中移除:" & Libs(i).LocalPath, LogLevel.Debug)
Libs.RemoveAt(i) Libs.RemoveAt(i)
Exit For Exit For
End If End If
Next Next
Task.Output = McLibFixFromLibToken(Libs, PathMcFolder) Task.Output = McLibFixFromLibToken(Libs, PathMcFolder)
Catch ex As Exception Catch ex As Exception
Throw New Exception("获取新版 Forge 支持库列表失败", ex) Throw New Exception($"获取{If(IsNeoForge, " Neo", "新版 ")}Forge 支持库列表失败", ex)
Finally Finally
'释放文件 '释放文件
If Installer IsNot Nothing Then Installer.Dispose() If Installer IsNot Nothing Then Installer.Dispose()
End Try End Try
End Sub) With {.ProgressWeight = 2}) End Sub) With {.ProgressWeight = 2})
Loaders.Add(New LoaderDownload("下载 Mod 加载器支持库文件", New List(Of NetFile)) With {.ProgressWeight = 12}) Loaders.Add(New LoaderDownload($"下载 {LoaderName} 支持库文件", New List(Of NetFile)) With {.ProgressWeight = 12})
Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("获取 Mod 下载器支持库文件", Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)($"获取 {LoaderName} 支持库文件",
Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
#Region "Forge 文件" #Region "Forgelike 文件"
If IsCustomFolder Then If IsCustomFolder Then
For Each LibFile As McLibToken In Libs For Each LibFile As McLibToken In Libs
Dim RealPath As String = LibFile.LocalPath.Replace(PathMcFolder, McFolder) Dim RealPath As String = LibFile.LocalPath.Replace(PathMcFolder, McFolder)
@@ -1385,7 +1311,7 @@ Retry:
Directory.CreateDirectory(IO.Path.GetDirectoryName(RealPath)) Directory.CreateDirectory(IO.Path.GetDirectoryName(RealPath))
CopyFile(LibFile.LocalPath, RealPath) CopyFile(LibFile.LocalPath, RealPath)
End If End If
If ModeDebug Then Log("[Download] 复制的 Forge 支持库文件:" & LibFile.LocalPath) If ModeDebug Then Log($"[Download] 复制的 {LoaderName} 支持库文件:" & LibFile.LocalPath)
Next Next
End If End If
#End Region #End Region
@@ -1393,9 +1319,9 @@ Retry:
'等待原版文件下载完成 '等待原版文件下载完成
If ClientDownloadLoader Is Nothing Then Exit Sub If ClientDownloadLoader Is Nothing Then Exit Sub
Dim TargetLoaders As List(Of LoaderBase) = Dim TargetLoaders As List(Of LoaderBase) =
ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName). ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName).
Where(Function(l) l.State <> LoadState.Finished).ToList Where(Function(l) l.State <> LoadState.Finished).ToList()
If TargetLoaders.Any Then Log("[Download] Forge 安装正在等待原版文件下载完成") If TargetLoaders.Any Then Log($"[Download] {LoaderName} 安装正在等待原版文件下载完成")
Do While TargetLoaders.Any AndAlso Not Task.IsAborted Do While TargetLoaders.Any AndAlso Not Task.IsAborted
TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList
Thread.Sleep(50) Thread.Sleep(50)
@@ -1415,14 +1341,13 @@ Retry:
End SyncLock End SyncLock
#End Region #End Region
End Sub) With {.ProgressWeight = 0.1, .Show = False}) End Sub) With {.ProgressWeight = 0.1, .Show = False})
Loaders.Add(New LoaderTask(Of Boolean, Boolean)("安装 Mod 加载器(方式 A)", Loaders.Add(New LoaderTask(Of Boolean, Boolean)(If(IsNeoForge, "安装 NeoForge", "安装 Forge(方式 A)"),
Sub(Task As LoaderTask(Of Boolean, Boolean)) Sub(Task As LoaderTask(Of Boolean, Boolean))
Dim Installer As ZipArchive = Nothing Dim Installer As ZipArchive = Nothing
Try Try
Log("[Download] 开始进行新版方式 Forge 安装:" & InstallerAddress) Log($"[Download] 开始进行 Forgelike 安装:" & InstallerAddress)
'记录当前文件夹列表(在新建目标文件夹之前) '记录当前文件夹列表(在新建目标文件夹之前)
Dim OldList = New DirectoryInfo(McFolder & "versions\").EnumerateDirectories. Dim OldList = New DirectoryInfo(McFolder & "versions\").EnumerateDirectories.Select(Function(i) i.FullName).ToList()
Select(Function(i) i.FullName).ToList()
'解压并获取信息 '解压并获取信息
Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open)) Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open))
Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open)) Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open))
@@ -1440,15 +1365,15 @@ Retry:
WriteFile(PathTemp & "Cache\forge_installer.jar", GetResources("ForgeInstaller")) WriteFile(PathTemp & "Cache\forge_installer.jar", GetResources("ForgeInstaller"))
Task.Progress = 0.06 Task.Progress = 0.06
'运行注入器 '运行注入器
ForgeInjector(InstallerAddress, Task, McFolder, UseJavaWrapper) ForgelikeInjector(InstallerAddress, Task, McFolder, UseJavaWrapper, IsNeoForge)
Task.Progress = 0.97 Task.Progress = 0.97
Catch ex As Exception Catch ex As Exception
If UseJavaWrapper Then If UseJavaWrapper Then
Log(ex, "使用 JavaWrapper 安装 Forge 失败,将不使用 JavaWrapper 并重试") Log(ex, $"使用 JavaWrapper 安装 {LoaderName} 失败,将不使用 JavaWrapper 并重试")
UseJavaWrapper = False UseJavaWrapper = False
GoTo Retry GoTo Retry
Else Else
Throw New Exception("运行 Forge 安装器失败", ex) Throw New Exception($"运行 {LoaderName} 安装器失败", ex)
End If End If
End Try End Try
'拷贝新增的版本 Json '拷贝新增的版本 Json
@@ -1457,29 +1382,38 @@ Retry:
If DeltaList.Count > 1 Then If DeltaList.Count > 1 Then
'它可能和 OptiFine 安装同时运行,导致增加的文件不止一个(这导致了 #151) '它可能和 OptiFine 安装同时运行,导致增加的文件不止一个(这导致了 #151)
'也可能是因为 Forge 安装器的 Bug,生成了一个名字错误的文件夹,所以需要检查文件夹是否为空 '也可能是因为 Forge 安装器的 Bug,生成了一个名字错误的文件夹,所以需要检查文件夹是否为空
DeltaList = DeltaList.Where(Function(l) l.Name.Contains("forge") AndAlso l.EnumerateFiles.Any).ToList DeltaList = DeltaList.Where(Function(l) l.Name.ContainsF("forge", True) AndAlso l.EnumerateFiles.Any).ToList
End If End If
If DeltaList.Count = 1 Then '如果没有新增文件夹,那么预测的文件夹名就是正确的 If DeltaList.Count = 1 Then
'如果没有新增文件夹,那么预测的文件夹名就是正确的
'如果只新增 1 个文件夹,那么拷贝 json 文件
Dim JsonFile As FileInfo = DeltaList(0).EnumerateFiles.First() Dim JsonFile As FileInfo = DeltaList(0).EnumerateFiles.First()
WriteFile(VersionFolder & Id & ".json", ReadFile(JsonFile.FullName)) WriteFile(VersionFolder & TargetVersion & ".json", ReadFile(JsonFile.FullName))
Log($"[Download] 已拷贝新增的版本 JSON 文件:{JsonFile.FullName} -> {VersionFolder}{TargetVersion}.json")
ElseIf DeltaList.Count > 1 Then
'新增了多个文件夹
Log($"[Download] 有多个疑似的新增版本,无法确定:{DeltaList.Select(Function(d) d.Name).Join(";")}")
Else
'没有新增文件夹
Log("[Download] 未找到新增的版本文件夹")
End If End If
'新建 mods 文件夹 '新建 mods 文件夹
Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\") Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\")
Catch ex As Exception Catch ex As Exception
Throw New Exception("安装新 Forge 版本失败", ex) Throw New Exception($"安装新 {LoaderName} 版本失败", ex)
Finally Finally
'清理文件 '清理文件
Try Try
If Installer IsNot Nothing Then Installer.Dispose() If Installer IsNot Nothing Then Installer.Dispose()
If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress) If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress)
Catch ex As Exception Catch ex As Exception
Log(ex, "安装 Forge 清理文件时出错") Log(ex, $"安装 {LoaderName} 清理文件时出错")
End Try End Try
End Try End Try
End Sub) With {.ProgressWeight = 10}) End Sub) With {.ProgressWeight = 10})
Else Else
Log("[Download] 检测为非新版 Forge:" & Version) Log("[Download] 检测为非新版 Forge:" & LoaderVersion)
Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("安装 Mod 加载器(方式 B)", Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)($"安装 {LoaderName}(方式 B)",
Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) Sub(Task As LoaderTask(Of List(Of NetFile), Boolean))
Dim Installer As ZipArchive = Nothing Dim Installer As ZipArchive = Nothing
Try Try
@@ -1492,12 +1426,12 @@ Retry:
Directory.CreateDirectory(VersionFolder) Directory.CreateDirectory(VersionFolder)
Task.Progress = 0.5 Task.Progress = 0.5
If Json("install") Is Nothing Then If Json("install") Is Nothing Then
'中版格式 '中版:Legacy 方式 1
Log("[Download] 进行中版方式安装:" & InstallerAddress) Log("[Download] 开始进行 Forge 安装,Legacy 方式 1:" & InstallerAddress)
'建立 Json 文件 '建立 Json 文件
Dim JsonVersion As JObject = GetJson(ReadFile(Installer.GetEntry(Json("json").ToString.TrimStart("/")).Open)) Dim JsonVersion As JObject = GetJson(ReadFile(Installer.GetEntry(Json("json").ToString.TrimStart("/")).Open))
JsonVersion("id") = Id JsonVersion("id") = TargetVersion
WriteFile(VersionFolder & Id & ".json", JsonVersion.ToString) WriteFile(VersionFolder & TargetVersion & ".json", JsonVersion.ToString)
Task.Progress = 0.6 Task.Progress = 0.6
'解压支持库文件 '解压支持库文件
Installer.Dispose() Installer.Dispose()
@@ -1505,17 +1439,17 @@ Retry:
CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\") CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\")
DeleteDirectory(InstallerAddress & "_unrar\") DeleteDirectory(InstallerAddress & "_unrar\")
Else Else
'旧版格式 '旧版:Legacy 方式 2
Log("[Download] 进行旧版方式安装:" & InstallerAddress) Log("[Download] 开始进行 Forge 安装,Legacy 方式 2:" & InstallerAddress)
'解压 Jar 文件 '解压 Jar 文件
Dim JarAddress As String = McLibGet(Json("install")("path"), CustomMcFolder:=McFolder) Dim JarAddress As String = McLibGet(Json("install")("path"), CustomMcFolder:=McFolder)
If File.Exists(JarAddress) Then File.Delete(JarAddress) If File.Exists(JarAddress) Then File.Delete(JarAddress)
WriteFile(JarAddress, Installer.GetEntry(Json("install")("filePath")).Open) WriteFile(JarAddress, Installer.GetEntry(Json("install")("filePath")).Open)
Task.Progress = 0.9 Task.Progress = 0.9
'建立 Json 文件 '建立 Json 文件
Json("versionInfo")("id") = Id Json("versionInfo")("id") = TargetVersion
If Json("versionInfo")("inheritsFrom") Is Nothing Then CType(Json("versionInfo"), JObject).Add("inheritsFrom", Inherit) If Json("versionInfo")("inheritsFrom") Is Nothing Then CType(Json("versionInfo"), JObject).Add("inheritsFrom", Inherit)
WriteFile(VersionFolder & Id & ".json", Json("versionInfo").ToString) WriteFile(VersionFolder & TargetVersion & ".json", Json("versionInfo").ToString)
End If End If
'新建 mods 文件夹 '新建 mods 文件夹
Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\") Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\")
@@ -1532,11 +1466,6 @@ Retry:
End Try End Try
End Try End Try
End Sub) With {.ProgressWeight = 1}) End Sub) With {.ProgressWeight = 1})
If FixLibrary Then
If IsCustomFolder Then Throw New Exception("若需要补全支持库,就不能自定义 MC 文件夹")
Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析 Mod 加载器支持库文件", Sub(Task As LoaderTask(Of String, List(Of NetFile))) Task.Output = McLibFix(New McVersion(VersionFolder))) With {.ProgressWeight = 1, .Show = False})
Loaders.Add(New LoaderDownload("下载 Mod 加载器支持库文件", New List(Of NetFile)) With {.ProgressWeight = 11})
End If
End If End If
Return Loaders Return Loaders
@@ -1546,16 +1475,16 @@ Retry:
#Region "Forge 下载菜单" #Region "Forge 下载菜单"
Public Sub ForgeDownloadListItemPreload(Stack As StackPanel, Entrys As List(Of DlForgeVersionEntry), OnClick As MyListItem.ClickEventHandler, IsSaveOnly As Boolean) Public Sub ForgeDownloadListItemPreload(Stack As StackPanel, Entries As List(Of DlForgeVersionEntry), OnClick As MyListItem.ClickEventHandler, IsSaveOnly As Boolean)
'获取推荐版本与最新版本 '获取推荐版本与最新版本
Dim FreshVersion As DlForgeVersionEntry = Nothing Dim FreshVersion As DlForgeVersionEntry = Nothing
If Entrys.Any Then If Entries.Any Then
FreshVersion = Entrys(0) FreshVersion = Entries(0)
Else Else
Log("[System] 未找到可用的 Forge 版本", LogLevel.Debug) Log("[System] 未找到可用的 Forge 版本", LogLevel.Debug)
End If End If
Dim RecommendedVersion As DlForgeVersionEntry = Nothing Dim RecommendedVersion As DlForgeVersionEntry = Nothing
For Each Entry In Entrys For Each Entry In Entries
If Entry.IsRecommended Then RecommendedVersion = Entry If Entry.IsRecommended Then RecommendedVersion = Entry
Next Next
'若推荐版本与最新版本为同一版本,则仅显示推荐版本 '若推荐版本与最新版本为同一版本,则仅显示推荐版本
@@ -1572,15 +1501,14 @@ Retry:
Stack.Children.Add(Fresh) Stack.Children.Add(Fresh)
End If End If
'添加间隔 '添加间隔
Stack.Children.Add(New TextBlock With {.Text = "全部版本 (" & Entrys.Count & ")", .HorizontalAlignment = HorizontalAlignment.Left, .Margin = New Thickness(6, 13, 0, 4)}) Stack.Children.Add(New TextBlock With {.Text = "全部版本 (" & Entries.Count & ")", .HorizontalAlignment = HorizontalAlignment.Left, .Margin = New Thickness(6, 13, 0, 4)})
End Sub End Sub
Public Function ForgeDownloadListItem(Entry As DlForgeVersionEntry, OnClick As MyListItem.ClickEventHandler, IsSaveOnly As Boolean) As MyListItem Public Function ForgeDownloadListItem(Entry As DlForgeVersionEntry, OnClick As MyListItem.ClickEventHandler, IsSaveOnly As Boolean) As MyListItem
'建立控件 '建立控件
Dim NewItem As New MyListItem With { Dim NewItem As New MyListItem With {
.Title = Entry.Version, .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .Title = Entry.VersionName, .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry,
.Info = If(Entry.ReleaseTime = "", .Info = {If(Entry.ReleaseTime = "", "", "发布于 " & Entry.ReleaseTime), If(ModeDebug, "种类:" & Entry.Category, "")}.
If(ModeDebug, "种类:" & Entry.Category & If(Entry.Branch Is Nothing, "", ",开发分支:" & Entry.Branch), ""), Where(Function(d) d <> "").Join(","),
"发布于 " & Entry.ReleaseTime & If(ModeDebug, ",种类:" & Entry.Category & If(Entry.Branch Is Nothing, "", ",开发分支:" & Entry.Branch), "")),
.Logo = PathImage & "Blocks/Anvil.png" .Logo = PathImage & "Blocks/Anvil.png"
} }
AddHandler NewItem.Click, OnClick AddHandler NewItem.Click, OnClick
@@ -1623,7 +1551,7 @@ Retry:
Else Else
Version = sender.Parent.Parent.Tag Version = sender.Parent.Parent.Tag
End If End If
OpenWebsite("https://files.minecraftforge.net/maven/net/minecraftforge/forge/" & Version.Inherit & "-" & Version.Version & "/forge-" & Version.Inherit & "-" & Version.Version & "-changelog.txt") OpenWebsite($"https://files.minecraftforge.net/maven/net/minecraftforge/forge/{Version.Inherit}-{Version.VersionName}/forge-{Version.Inherit}-{Version.VersionName}-changelog.txt")
End Sub End Sub
Public Sub ForgeSave_Click(sender As Object, e As RoutedEventArgs) Public Sub ForgeSave_Click(sender As Object, e As RoutedEventArgs)
Dim Version As DlForgeVersionEntry Dim Version As DlForgeVersionEntry
@@ -1634,7 +1562,7 @@ Retry:
Else Else
Version = sender.Parent.Parent.Tag Version = sender.Parent.Parent.Tag
End If End If
McDownloadForgeSave(Version) McDownloadForgelikeSave(Version)
End Sub End Sub
#End Region #End Region
@@ -1696,6 +1624,101 @@ Retry:
#End Region #End Region
#Region "NeoForge 下载菜单"
Public Sub NeoForgeDownloadListItemPreload(Stack As StackPanel, Entries As List(Of DlNeoForgeListEntry), OnClick As MyListItem.ClickEventHandler, IsSaveOnly As Boolean)
'获取最新稳定版和测试版
Dim FreshStableVersion As DlNeoForgeListEntry = Nothing
Dim FreshBetaVersion As DlNeoForgeListEntry = Nothing
If Entries.Any() Then
For Each Entry In Entries.ToList()
If Entry.IsBeta Then
If FreshBetaVersion Is Nothing Then FreshBetaVersion = Entry
Else
FreshStableVersion = Entry
Exit For
End If
Next
Else
Log("[System] 未找到可用的 NeoForge 版本", LogLevel.Debug)
End If
'显示各个版本
If FreshStableVersion IsNot Nothing Then
Dim Fresh = NeoForgeDownloadListItem(FreshStableVersion, OnClick, IsSaveOnly)
Fresh.Info = If(Fresh.Info = "", "最新稳定版", "最新" & Fresh.Info)
Stack.Children.Add(Fresh)
End If
If FreshBetaVersion IsNot Nothing Then
Dim Fresh = NeoForgeDownloadListItem(FreshBetaVersion, OnClick, IsSaveOnly)
Fresh.Info = If(Fresh.Info = "", "最新测试版", "最新" & Fresh.Info)
Stack.Children.Add(Fresh)
End If
'添加间隔
Stack.Children.Add(New TextBlock With {.Text = "全部版本 (" & Entries.Count & ")", .HorizontalAlignment = HorizontalAlignment.Left, .Margin = New Thickness(6, 13, 0, 4)})
End Sub
Public Function NeoForgeDownloadListItem(Info As DlNeoForgeListEntry, OnClick As MyListItem.ClickEventHandler, IsSaveOnly As Boolean) As MyListItem
'建立控件
Dim NewItem As New MyListItem With {
.Title = Info.VersionName, .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Info,
.Info = If(Info.IsBeta, "测试版", "稳定版"),
.Logo = PathImage & "Blocks/NeoForge.png"
}
AddHandler NewItem.Click, OnClick
'建立菜单
If IsSaveOnly Then
NewItem.ContentHandler = AddressOf NeoForgeSaveContMenuBuild
Else
NewItem.ContentHandler = AddressOf NeoForgeContMenuBuild
End If
'结束
Return NewItem
End Function
Private Sub NeoForgeContMenuBuild(sender As MyListItem, e As EventArgs)
Dim BtnSave As New MyIconButton With {.Logo = Logo.IconButtonSave, .ToolTip = "另存为"}
ToolTipService.SetPlacement(BtnSave, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnSave, 30)
ToolTipService.SetHorizontalOffset(BtnSave, 2)
AddHandler BtnSave.Click, AddressOf NeoForgeSave_Click
Dim BtnInfo As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonInfo, .ToolTip = "更新日志"}
ToolTipService.SetPlacement(BtnInfo, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnInfo, 30)
ToolTipService.SetHorizontalOffset(BtnInfo, 2)
AddHandler BtnInfo.Click, AddressOf NeoForgeLog_Click
sender.Buttons = {BtnSave, BtnInfo}
End Sub
Private Sub NeoForgeSaveContMenuBuild(sender As MyListItem, e As EventArgs)
Dim BtnInfo As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonInfo, .ToolTip = "更新日志"}
ToolTipService.SetPlacement(BtnInfo, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnInfo, 30)
ToolTipService.SetHorizontalOffset(BtnInfo, 2)
AddHandler BtnInfo.Click, AddressOf NeoForgeLog_Click
sender.Buttons = {BtnInfo}
End Sub
Private Sub NeoForgeLog_Click(sender As Object, e As RoutedEventArgs)
Dim Info As DlNeoForgeListEntry
If sender.Tag IsNot Nothing Then
Info = sender.Tag
ElseIf sender.Parent.Tag IsNot Nothing Then
Info = sender.Parent.Tag
Else
Info = sender.Parent.Parent.Tag
End If
OpenWebsite(Info.UrlBase & "-changelog.txt")
End Sub
Public Sub NeoForgeSave_Click(sender As Object, e As RoutedEventArgs)
Dim Info As DlNeoForgeListEntry
If sender.Tag IsNot Nothing Then
Info = sender.Tag
ElseIf sender.Parent.Tag IsNot Nothing Then
Info = sender.Parent.Tag
Else
Info = sender.Parent.Parent.Tag
End If
McDownloadForgelikeSave(Info)
End Sub
#End Region
#Region "Fabric 下载" #Region "Fabric 下载"
Public Sub McDownloadFabricLoaderSave(DownloadInfo As JObject) Public Sub McDownloadFabricLoaderSave(DownloadInfo As JObject)
@@ -1861,6 +1884,16 @@ Retry:
''' </summary> ''' </summary>
Public ForgeEntry As DlForgeVersionEntry = Nothing Public ForgeEntry As DlForgeVersionEntry = Nothing
'若要下载 NeoForge,则需要在下面两项中完成至少一项
''' <summary>
''' 欲下载的 NeoForge 版本名。
''' </summary>
Public NeoForgeVersion As String = Nothing
''' <summary>
''' 欲下载的 NeoForge。
''' </summary>
Public NeoForgeEntry As DlNeoForgeListEntry = Nothing
''' <summary> ''' <summary>
''' 欲下载的 Fabric Loader 版本名。 ''' 欲下载的 Fabric Loader 版本名。
''' </summary> ''' </summary>
@@ -1961,7 +1994,7 @@ Retry:
Public Function McInstallLoader(Request As McInstallRequest, Optional DontFixLibraries As Boolean = False) As List(Of LoaderBase) Public Function McInstallLoader(Request As McInstallRequest, Optional DontFixLibraries As Boolean = False) As List(Of LoaderBase)
'获取缓存目录 '获取缓存目录
Dim PathInstallTemp As String Dim PathInstallTemp As String
If PathTemp.Contains(" ") AndAlso Request.ForgeEntry IsNot Nothing Then If PathTemp.Contains(" ") AndAlso (Request.OptiFineEntry IsNot Nothing OrElse Request.ForgeEntry IsNot Nothing OrElse Request.NeoForgeEntry IsNot Nothing) Then
PathInstallTemp = OsDrive & "ProgramData\PCL\Install\" PathInstallTemp = OsDrive & "ProgramData\PCL\Install\"
Else Else
PathInstallTemp = PathTemp & "Install\" PathInstallTemp = PathTemp & "Install\"
@@ -1996,8 +2029,11 @@ Retry:
End If End If
If Request.OptiFineEntry IsNot Nothing Then OptiFineFolder = TempMcFolder & "versions\" & Request.OptiFineEntry.NameVersion If Request.OptiFineEntry IsNot Nothing Then OptiFineFolder = TempMcFolder & "versions\" & Request.OptiFineEntry.NameVersion
Dim ForgeFolder As String = Nothing Dim ForgeFolder As String = Nothing
If Request.ForgeEntry IsNot Nothing Then Request.ForgeVersion = If(Request.ForgeVersion, Request.ForgeEntry.Version) If Request.ForgeEntry IsNot Nothing Then Request.ForgeVersion = If(Request.ForgeVersion, Request.ForgeEntry.VersionName)
If Request.ForgeVersion IsNot Nothing Then ForgeFolder = TempMcFolder & "versions\" & Request.MinecraftName & "-forge-" & Request.ForgeVersion If Request.ForgeVersion IsNot Nothing Then ForgeFolder = TempMcFolder & "versions\forge-" & Request.ForgeVersion
Dim NeoForgeFolder As String = Nothing
If Request.NeoForgeEntry IsNot Nothing Then Request.NeoForgeVersion = If(Request.NeoForgeVersion, Request.NeoForgeEntry.VersionName)
If Request.NeoForgeVersion IsNot Nothing Then NeoForgeFolder = TempMcFolder & "versions\neoforge-" & Request.NeoForgeVersion
Dim FabricFolder As String = Nothing Dim FabricFolder As String = Nothing
If Request.FabricVersion IsNot Nothing Then FabricFolder = TempMcFolder & "versions\fabric-loader-" & Request.FabricVersion & "-" & Request.MinecraftName If Request.FabricVersion IsNot Nothing Then FabricFolder = TempMcFolder & "versions\fabric-loader-" & Request.FabricVersion & "-" & Request.MinecraftName
Dim LiteLoaderFolder As String = Nothing Dim LiteLoaderFolder As String = Nothing
@@ -2014,6 +2050,7 @@ Retry:
'记录日志 '记录日志
If OptiFineFolder IsNot Nothing Then Log("[Download] OptiFine 缓存:" & OptiFineFolder) If OptiFineFolder IsNot Nothing Then Log("[Download] OptiFine 缓存:" & OptiFineFolder)
If ForgeFolder IsNot Nothing Then Log("[Download] Forge 缓存:" & ForgeFolder) If ForgeFolder IsNot Nothing Then Log("[Download] Forge 缓存:" & ForgeFolder)
If NeoForgeFolder IsNot Nothing Then Log("[Download] NeoForge 缓存:" & NeoForgeFolder)
If FabricFolder IsNot Nothing Then Log("[Download] Fabric 缓存:" & FabricFolder) If FabricFolder IsNot Nothing Then Log("[Download] Fabric 缓存:" & FabricFolder)
If LiteLoaderFolder IsNot Nothing Then Log("[Download] LiteLoader 缓存:" & LiteLoaderFolder) If LiteLoaderFolder IsNot Nothing Then Log("[Download] LiteLoader 缓存:" & LiteLoaderFolder)
Log("[Download] 对应的原版版本:" & Request.MinecraftName) Log("[Download] 对应的原版版本:" & Request.MinecraftName)
@@ -2048,7 +2085,11 @@ Retry:
End If End If
'Forge 'Forge
If Request.ForgeVersion IsNot Nothing Then If Request.ForgeVersion IsNot Nothing Then
LoaderList.Add(New LoaderCombo(Of String)("下载 Forge " & Request.ForgeVersion, McDownloadForgeLoader(Request.ForgeVersion, Request.MinecraftName, Request.ForgeEntry, TempMcFolder, ClientLoader, Request.TargetVersionFolder, False)) With {.Show = False, .ProgressWeight = 25, .Block = Request.FabricVersion Is Nothing AndAlso Request.LiteLoaderEntry Is Nothing}) LoaderList.Add(New LoaderCombo(Of String)("下载 Forge " & Request.ForgeVersion, McDownloadForgelikeLoader(False, Request.ForgeVersion, "forge-" & Request.ForgeVersion, Request.MinecraftName, Request.ForgeEntry, TempMcFolder, ClientLoader, Request.TargetVersionFolder)) With {.Show = False, .ProgressWeight = 25, .Block = Request.FabricVersion Is Nothing AndAlso Request.LiteLoaderEntry Is Nothing AndAlso Request.NeoForgeEntry Is Nothing})
End If
'NeoForge
If Request.NeoForgeVersion IsNot Nothing Then
LoaderList.Add(New LoaderCombo(Of String)("下载 NeoForge " & Request.NeoForgeVersion, McDownloadForgelikeLoader(True, Request.NeoForgeVersion, "neoforge-" & Request.NeoForgeVersion, Request.MinecraftName, Request.NeoForgeEntry, TempMcFolder, ClientLoader, Request.TargetVersionFolder)) With {.Show = False, .ProgressWeight = 25, .Block = Request.ForgeEntry Is Nothing AndAlso Request.FabricVersion Is Nothing AndAlso Request.LiteLoaderEntry Is Nothing})
End If End If
'LiteLoader 'LiteLoader
If Request.LiteLoaderEntry IsNot Nothing Then If Request.LiteLoaderEntry IsNot Nothing Then
@@ -2061,14 +2102,14 @@ Retry:
'合并安装 '合并安装
LoaderList.Add(New LoaderTask(Of String, String)("安装游戏", LoaderList.Add(New LoaderTask(Of String, String)("安装游戏",
Sub(Task As LoaderTask(Of String, String)) Sub(Task As LoaderTask(Of String, String))
InstallMerge(OutputFolder, OutputFolder, OptiFineFolder, OptiFineAsMod, ForgeFolder, Request.ForgeVersion, FabricFolder, LiteLoaderFolder) InstallMerge(OutputFolder, OutputFolder, OptiFineFolder, OptiFineAsMod, ForgeFolder, Request.ForgeVersion, NeoForgeFolder, Request.NeoForgeVersion, FabricFolder, LiteLoaderFolder)
Task.Progress = 0.3 Task.Progress = 0.3
If Directory.Exists(TempMcFolder & "libraries") Then CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries") If Directory.Exists(TempMcFolder & "libraries") Then CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries")
If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", PathMcFolder & "mods") If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", PathMcFolder & "mods")
End Sub) With {.ProgressWeight = 2, .Block = True}) End Sub) With {.ProgressWeight = 2, .Block = True})
'补全文件 '补全文件
If Not DontFixLibraries AndAlso If Not DontFixLibraries AndAlso
(Request.OptiFineEntry IsNot Nothing OrElse (Request.ForgeVersion IsNot Nothing AndAlso Request.ForgeVersion.Before(".") >= 20) OrElse Request.FabricVersion IsNot Nothing OrElse Request.LiteLoaderEntry IsNot Nothing) Then (Request.OptiFineEntry IsNot Nothing OrElse (Request.ForgeVersion IsNot Nothing AndAlso Request.ForgeVersion.Before(".") >= 20) OrElse Request.NeoForgeVersion IsNot Nothing OrElse Request.FabricVersion IsNot Nothing OrElse Request.LiteLoaderEntry IsNot Nothing) Then
Dim LoadersLib As New List(Of LoaderBase) Dim LoadersLib As New List(Of LoaderBase)
LoadersLib.Add(New LoaderTask(Of String, List(Of NetFile))("分析游戏支持库文件(副加载器)", Sub(Task As LoaderTask(Of String, List(Of NetFile))) Task.Output = McLibFix(New McVersion(OutputFolder))) With {.ProgressWeight = 1, .Show = False}) LoadersLib.Add(New LoaderTask(Of String, List(Of NetFile))("分析游戏支持库文件(副加载器)", Sub(Task As LoaderTask(Of String, List(Of NetFile))) Task.Output = McLibFix(New McVersion(OutputFolder))) With {.ProgressWeight = 1, .Show = False})
LoadersLib.Add(New LoaderDownload("下载游戏支持库文件(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 7, .Show = False}) LoadersLib.Add(New LoaderDownload("下载游戏支持库文件(副加载器)", New List(Of NetFile)) With {.ProgressWeight = 7, .Show = False})
@@ -2084,17 +2125,18 @@ Retry:
''' <summary> ''' <summary>
''' 将多个版本 Json 进行合并,如果目标已存在则直接覆盖。失败会抛出异常。 ''' 将多个版本 Json 进行合并,如果目标已存在则直接覆盖。失败会抛出异常。
''' </summary> ''' </summary>
Private Sub InstallMerge(OutputFolder As String, MinecraftFolder As String, Optional OptiFineFolder As String = Nothing, Optional OptiFineAsMod As Boolean = False, Optional ForgeFolder As String = Nothing, Optional ForgeVersion As String = Nothing, Optional FabricFolder As String = Nothing, Optional LiteLoaderFolder As String = Nothing) Private Sub InstallMerge(OutputFolder As String, MinecraftFolder As String, Optional OptiFineFolder As String = Nothing, Optional OptiFineAsMod As Boolean = False, Optional ForgeFolder As String = Nothing, Optional ForgeVersion As String = Nothing, Optional NeoForgeFolder As String = Nothing, Optional NeoForgeVersion As String = Nothing, Optional FabricFolder As String = Nothing, Optional LiteLoaderFolder As String = Nothing)
Log("[Download] 开始进行版本合并,输出:" & OutputFolder & ",Minecraft:" & MinecraftFolder & Log("[Download] 开始进行版本合并,输出:" & OutputFolder & ",Minecraft:" & MinecraftFolder &
If(OptiFineFolder IsNot Nothing, ",OptiFine:" & OptiFineFolder, "") & If(OptiFineFolder IsNot Nothing, ",OptiFine:" & OptiFineFolder, "") &
If(ForgeFolder IsNot Nothing, ",Forge:" & ForgeFolder, "") & If(ForgeFolder IsNot Nothing, ",Forge:" & ForgeFolder, "") &
If(NeoForgeFolder IsNot Nothing, ",NeoForge:" & NeoForgeFolder, "") &
If(LiteLoaderFolder IsNot Nothing, ",LiteLoader:" & LiteLoaderFolder, "") & If(LiteLoaderFolder IsNot Nothing, ",LiteLoader:" & LiteLoaderFolder, "") &
If(FabricFolder IsNot Nothing, ",Fabric:" & FabricFolder, "")) If(FabricFolder IsNot Nothing, ",Fabric:" & FabricFolder, ""))
Directory.CreateDirectory(OutputFolder) Directory.CreateDirectory(OutputFolder)
Dim HasOptiFine As Boolean = OptiFineFolder IsNot Nothing AndAlso Not OptiFineAsMod, HasForge As Boolean = ForgeFolder IsNot Nothing, HasLiteLoader As Boolean = LiteLoaderFolder IsNot Nothing, HasFabric As Boolean = FabricFolder IsNot Nothing Dim HasOptiFine As Boolean = OptiFineFolder IsNot Nothing AndAlso Not OptiFineAsMod, HasForge As Boolean = ForgeFolder IsNot Nothing, HasNeoForge As Boolean = NeoForgeFolder IsNot Nothing, HasLiteLoader As Boolean = LiteLoaderFolder IsNot Nothing, HasFabric As Boolean = FabricFolder IsNot Nothing
Dim OutputName As String, MinecraftName As String, OptiFineName As String, ForgeName As String, LiteLoaderName As String, FabricName As String Dim OutputName As String, MinecraftName As String, OptiFineName As String, ForgeName As String, NeoForgeName As String, LiteLoaderName As String, FabricName As String
Dim OutputJsonPath As String, MinecraftJsonPath As String, OptiFineJsonPath As String = Nothing, ForgeJsonPath As String = Nothing, LiteLoaderJsonPath As String = Nothing, FabricJsonPath As String = Nothing Dim OutputJsonPath As String, MinecraftJsonPath As String, OptiFineJsonPath As String = Nothing, ForgeJsonPath As String = Nothing, NeoForgeJsonPath As String = Nothing, LiteLoaderJsonPath As String = Nothing, FabricJsonPath As String = Nothing
Dim OutputJar As String, MinecraftJar As String Dim OutputJar As String, MinecraftJar As String
#Region "初始化路径信息" #Region "初始化路径信息"
If Not OutputFolder.EndsWithF("\") Then OutputFolder += "\" If Not OutputFolder.EndsWithF("\") Then OutputFolder += "\"
@@ -2119,6 +2161,12 @@ Retry:
ForgeJsonPath = ForgeFolder & ForgeName & ".json" ForgeJsonPath = ForgeFolder & ForgeName & ".json"
End If End If
If HasNeoForge Then
If Not NeoForgeFolder.EndsWithF("\") Then NeoForgeFolder += "\"
NeoForgeName = GetFolderNameFromPath(NeoForgeFolder)
NeoForgeJsonPath = NeoForgeFolder & NeoForgeName & ".json"
End If
If HasLiteLoader Then If HasLiteLoader Then
If Not LiteLoaderFolder.EndsWithF("\") Then LiteLoaderFolder += "\" If Not LiteLoaderFolder.EndsWithF("\") Then LiteLoaderFolder += "\"
LiteLoaderName = GetFolderNameFromPath(LiteLoaderFolder) LiteLoaderName = GetFolderNameFromPath(LiteLoaderFolder)
@@ -2132,7 +2180,7 @@ Retry:
End If End If
#End Region #End Region
Dim OutputJson As JObject, MinecraftJson As JObject, OptiFineJson As JObject = Nothing, ForgeJson As JObject = Nothing, LiteLoaderJson As JObject = Nothing, FabricJson As JObject = Nothing Dim OutputJson As JObject, MinecraftJson As JObject, OptiFineJson As JObject = Nothing, ForgeJson As JObject = Nothing, NeoForgeJson As JObject = Nothing, LiteLoaderJson As JObject = Nothing, FabricJson As JObject = Nothing
#Region "读取文件并检查文件是否合规" #Region "读取文件并检查文件是否合规"
Dim MinecraftJsonText As String = ReadFile(MinecraftJsonPath) Dim MinecraftJsonText As String = ReadFile(MinecraftJsonPath)
If Not MinecraftJsonText.StartsWithF("{") Then Throw New Exception("Minecraft json 有误,地址:" & MinecraftJsonPath & ",前段内容:" & MinecraftJsonText.Substring(0, Math.Min(MinecraftJsonText.Length, 1000))) If Not MinecraftJsonText.StartsWithF("{") Then Throw New Exception("Minecraft json 有误,地址:" & MinecraftJsonPath & ",前段内容:" & MinecraftJsonText.Substring(0, Math.Min(MinecraftJsonText.Length, 1000)))
@@ -2150,6 +2198,12 @@ Retry:
ForgeJson = GetJson(ForgeJsonText) ForgeJson = GetJson(ForgeJsonText)
End If End If
If HasNeoForge Then
Dim NeoForgeJsonText As String = ReadFile(NeoForgeJsonPath)
If Not NeoForgeJsonText.StartsWithF("{") Then Throw New Exception("NeoForge json 有误,地址:" & NeoForgeJsonPath & ",前段内容:" & NeoForgeJsonText.Substring(0, Math.Min(NeoForgeJsonText.Length, 1000)))
NeoForgeJson = GetJson(NeoForgeJsonText)
End If
If HasLiteLoader Then If HasLiteLoader Then
Dim LiteLoaderJsonText As String = ReadFile(LiteLoaderJsonPath) Dim LiteLoaderJsonText As String = ReadFile(LiteLoaderJsonPath)
If Not LiteLoaderJsonText.StartsWithF("{") Then Throw New Exception("LiteLoader json 有误,地址:" & LiteLoaderJsonPath & ",前段内容:" & LiteLoaderJsonText.Substring(0, Math.Min(LiteLoaderJsonText.Length, 1000))) If Not LiteLoaderJsonText.StartsWithF("{") Then Throw New Exception("LiteLoader json 有误,地址:" & LiteLoaderJsonPath & ",前段内容:" & LiteLoaderJsonText.Substring(0, Math.Min(LiteLoaderJsonText.Length, 1000)))
@@ -2163,12 +2217,13 @@ Retry:
End If End If
#End Region #End Region
#Region "处理 Json 文件" #Region "处理 JSON 文件"
'获取 minecraftArguments '获取 minecraftArguments
Dim AllArguments As String = Dim AllArguments As String =
If(MinecraftJson("minecraftArguments"), " ").ToString & " " & If(MinecraftJson("minecraftArguments"), " ").ToString & " " &
If(OptiFineJson IsNot Nothing, If(OptiFineJson("minecraftArguments"), " ").ToString, " ") & " " & If(OptiFineJson IsNot Nothing, If(OptiFineJson("minecraftArguments"), " ").ToString, " ") & " " &
If(ForgeJson IsNot Nothing, If(ForgeJson("minecraftArguments"), " ").ToString, " ") & " " & If(ForgeJson IsNot Nothing, If(ForgeJson("minecraftArguments"), " ").ToString, " ") & " " &
If(NeoForgeJson IsNot Nothing, If(NeoForgeJson("minecraftArguments"), " ").ToString, " ") & " " &
If(LiteLoaderJson IsNot Nothing, If(LiteLoaderJson("minecraftArguments"), " ").ToString, " ") If(LiteLoaderJson IsNot Nothing, If(LiteLoaderJson("minecraftArguments"), " ").ToString, " ")
'分割参数字符串 '分割参数字符串
Dim RawArguments As List(Of String) = AllArguments.Split(" ").Where(Function(l) l <> "").Select(Function(l) l.Trim).ToList Dim RawArguments As List(Of String) = AllArguments.Split(" ").Where(Function(l) l <> "").Select(Function(l) l.Trim).ToList
@@ -2198,6 +2253,12 @@ Retry:
ForgeJson.Remove("time") ForgeJson.Remove("time")
OutputJson.Merge(ForgeJson) OutputJson.Merge(ForgeJson)
End If End If
If HasNeoForge Then
'合并 NeoForge
NeoForgeJson.Remove("releaseTime")
NeoForgeJson.Remove("time")
OutputJson.Merge(NeoForgeJson)
End If
If HasLiteLoader Then If HasLiteLoader Then
'合并 LiteLoader '合并 LiteLoader
LiteLoaderJson.Remove("releaseTime") LiteLoaderJson.Remove("releaseTime")
@@ -87,7 +87,7 @@
PanMain.Children.Add(NewCard) PanMain.Children.Add(NewCard)
Next Next
Catch ex As Exception Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback) Log(ex, "可视化 MC 版本列表出错", LogLevel.Feedback)
End Try End Try
End Sub End Sub
@@ -177,17 +177,18 @@
End Sub) With {.ProgressWeight = 0.1}) End Sub) With {.ProgressWeight = 0.1})
'启动 '启动
Dim Loader As New LoaderCombo(Of String)(LoaderName, Loaders) With {.OnStateChanged = Sub(MyLoader) Dim Loader As New LoaderCombo(Of String)(LoaderName, Loaders) With {.OnStateChanged =
Select Case MyLoader.State Sub(MyLoader)
Case LoadState.Failed Select Case MyLoader.State
Hint(MyLoader.Name & "失败:" & GetExceptionSummary(MyLoader.Error), HintType.Critical) Case LoadState.Failed
Case LoadState.Aborted Hint(MyLoader.Name & "失败:" & GetExceptionSummary(MyLoader.Error), HintType.Critical)
Hint(MyLoader.Name & "已取消!", HintType.Info) Case LoadState.Aborted
Case LoadState.Loading Hint(MyLoader.Name & "已取消!", HintType.Info)
Exit Sub '不重新加载版本列表 Case LoadState.Loading
End Select Exit Sub '不重新加载版本列表
McInstallFailedClearFolder(MyLoader) End Select
End Sub} McInstallFailedClearFolder(MyLoader)
End Sub}
Loader.Start(PathMcFolder & "versions\" & VersionName & "\") Loader.Start(PathMcFolder & "versions\" & VersionName & "\")
LoaderTaskbarAdd(Loader) LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh() FrmMain.BtnExtraDownload.ShowRefresh()
@@ -197,7 +198,7 @@
Log(ex, "下载资源整合包失败", LogLevel.Feedback) Log(ex, "下载资源整合包失败", LogLevel.Feedback)
End Try End Try
End Sub End Sub
'Mod 下载;整合包另存为 'Mod、资源包下载;整合包另存为
Public Shared CachedFolder As String = Nothing '仅在本次缓存的下载文件夹 Public Shared CachedFolder As String = Nothing '仅在本次缓存的下载文件夹
Public Sub Save_Click(sender As Object, e As EventArgs) Public Sub Save_Click(sender As Object, e As EventArgs)
Dim File As CompFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag Dim File As CompFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag
@@ -211,10 +212,10 @@
'获取 Mod 所需的加载器种类 '获取 Mod 所需的加载器种类
Dim AllowForge As Boolean? = Nothing, AllowFabric As Boolean? = Nothing Dim AllowForge As Boolean? = Nothing, AllowFabric As Boolean? = Nothing
If File.ModLoaders.Any Then '从文件中获取 If File.ModLoaders.Any Then '从文件中获取
AllowForge = File.ModLoaders.Contains(CompModLoaderType.Forge) AllowForge = File.ModLoaders.Contains(CompModLoaderType.Forge) OrElse File.ModLoaders.Contains(CompModLoaderType.NeoForge)
AllowFabric = File.ModLoaders.Contains(CompModLoaderType.Fabric) AllowFabric = File.ModLoaders.Contains(CompModLoaderType.Fabric)
ElseIf Project.ModLoaders.Any Then '从工程中获取 ElseIf Project.ModLoaders.Any Then '从工程中获取
AllowForge = Project.ModLoaders.Contains(CompModLoaderType.Forge) AllowForge = Project.ModLoaders.Contains(CompModLoaderType.Forge) OrElse File.ModLoaders.Contains(CompModLoaderType.NeoForge)
AllowFabric = Project.ModLoaders.Contains(CompModLoaderType.Fabric) AllowFabric = Project.ModLoaders.Contains(CompModLoaderType.Fabric)
End If End If
If AllowForge IsNot Nothing AndAlso Not AllowForge AndAlso If AllowForge IsNot Nothing AndAlso Not AllowForge AndAlso
@@ -230,7 +231,7 @@
If File.GameVersions.Any(Function(v) v.Contains(".")) AndAlso If File.GameVersions.Any(Function(v) v.Contains(".")) AndAlso
Not File.GameVersions.Any(Function(v) v.Contains(".") AndAlso v.Split(".")(1) = Version.Version.McCodeMain.ToString) Then Return False Not File.GameVersions.Any(Function(v) v.Contains(".") AndAlso v.Split(".")(1) = Version.Version.McCodeMain.ToString) Then Return False
If AllowForge Is Nothing OrElse AllowFabric Is Nothing Then Return True If AllowForge Is Nothing OrElse AllowFabric Is Nothing Then Return True
If AllowForge AndAlso Version.Version.HasForge Then Return True If AllowForge AndAlso (Version.Version.HasForge OrElse Version.Version.HasNeoForge) Then Return True
If AllowFabric AndAlso Version.Version.HasFabric Then Return True If AllowFabric AndAlso Version.Version.HasFabric Then Return True
Return False Return False
End Function End Function
@@ -260,10 +261,11 @@
Log("[Comp] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置") Log("[Comp] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置")
End If End If
Else '选择 Mod 数量最多的版本 Else '选择 Mod 数量最多的版本
Dim SelectedVersion = SuitableVersions.OrderBy(Function(v) Dim SelectedVersion = SuitableVersions.OrderBy(
Dim Info As New DirectoryInfo(v.PathIndie & "mods\") Function(v)
Return If(Info.Exists, Info.GetFiles().Length, -1) Dim Info As New DirectoryInfo(v.PathIndie & "mods\")
End Function).LastOrDefault() Return If(Info.Exists, Info.GetFiles().Length, -1)
End Function).LastOrDefault()
DefaultFolder = SelectedVersion.PathIndie & "mods\" DefaultFolder = SelectedVersion.PathIndie & "mods\"
Directory.CreateDirectory(DefaultFolder) Directory.CreateDirectory(DefaultFolder)
Log("[Comp] 使用适合的游戏版本作为默认下载位置(" & SelectedVersion.Name & ")") Log("[Comp] 使用适合的游戏版本作为默认下载位置(" & SelectedVersion.Name & ")")
@@ -33,7 +33,7 @@
' PanMain.Children.Insert(0, CardWarn) ' PanMain.Children.Insert(0, CardWarn)
'End If 'End If
Catch ex As Exception Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback) Log(ex, "可视化 Forge 版本列表出错", LogLevel.Feedback)
End Try End Try
End Sub End Sub
@@ -55,10 +55,6 @@
Card.StackInstall() Card.StackInstall()
End Sub End Sub
Public Sub DownloadStart(sender As MyListItem, e As Object)
McDownloadForge(sender.Tag)
End Sub
'介绍栏 '介绍栏
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
OpenWebsite("https://files.minecraftforge.net") OpenWebsite("https://files.minecraftforge.net")
@@ -20,6 +20,7 @@
<StackPanel Margin="25,37,25,15"> <StackPanel Margin="25,37,25,15">
<local:MyHint Text="你尚未选择安装 Fabric API,这会导致大多数 Mod 无法使用!" Margin="0,1,0,7" x:Name="HintFabricAPI" IsWarn="True" /> <local:MyHint Text="你尚未选择安装 Fabric API,这会导致大多数 Mod 无法使用!" Margin="0,1,0,7" x:Name="HintFabricAPI" IsWarn="True" />
<local:MyHint Text="你尚未选择安装 OptiFabric,这会导致 OptiFine 无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabric" IsWarn="True" /> <local:MyHint Text="你尚未选择安装 OptiFabric,这会导致 OptiFine 无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabric" IsWarn="True" />
<local:MyHint Text="安装结束后,请在 Mod 下载中搜索 OptiFabric Origins 并下载,否则 OptiFine 会无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabricOld" IsWarn="False" />
<local:MyHint Text="OptiFine 与一部分 Mod 的兼容性不佳,请谨慎安装。" Margin="0,1,0,7" x:Name="HintModOptiFine" IsWarn="False" /> <local:MyHint Text="OptiFine 与一部分 Mod 的兼容性不佳,请谨慎安装。" Margin="0,1,0,7" x:Name="HintModOptiFine" IsWarn="False" />
<Grid Margin="0,0,0,11"> <Grid Margin="0,0,0,11">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -79,6 +80,24 @@
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" /> Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid> </Grid>
</local:MyCard> </local:MyCard>
<local:MyCard Title="NeoForge" Height="40" Margin="0,15,0,0" x:Name="CardNeoForge" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanNeoForge" />
<Grid x:Name="PanNeoForgeInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgNeoForge" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="Linear" Source="pack://application:,,,/images/Blocks/NeoForge.png" />
<TextBlock x:Name="LabNeoForge" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnNeoForgeClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnNeoForgeClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
<local:MyCard Title="Fabric" Height="40" Margin="0,15,0,0" x:Name="CardFabric" IsSwaped="True" CanSwap="True" SwapLogoRight="True"> <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" Name="PanFabric" /> <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 x:Name="PanFabricInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
@@ -178,6 +197,7 @@
<local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="LoadMinecraft" HorizontalAlignment="Center" VerticalAlignment="Center" /> <local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="LoadMinecraft" HorizontalAlignment="Center" VerticalAlignment="Center" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadOptiFine" HasAnimation="False" /> <local:MyLoading Visibility="Collapsed" x:Name="LoadOptiFine" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadForge" HasAnimation="False" /> <local:MyLoading Visibility="Collapsed" x:Name="LoadForge" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadNeoForge" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadLiteLoader" HasAnimation="False" /> <local:MyLoading Visibility="Collapsed" x:Name="LoadLiteLoader" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadFabric" HasAnimation="False" /> <local:MyLoading Visibility="Collapsed" x:Name="LoadFabric" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadFabricApi" HasAnimation="False" /> <local:MyLoading Visibility="Collapsed" x:Name="LoadFabricApi" HasAnimation="False" />
@@ -10,6 +10,7 @@
DlOptiFineListLoader.Start() DlOptiFineListLoader.Start()
DlLiteLoaderListLoader.Start() DlLiteLoaderListLoader.Start()
DlFabricListLoader.Start() DlFabricListLoader.Start()
DlNeoForgeListLoader.Start()
'重载预览 '重载预览
TextSelectName.ValidateRules = New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions")} TextSelectName.ValidateRules = New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions")}
@@ -26,6 +27,7 @@
LoadLiteLoader.State = DlLiteLoaderListLoader LoadLiteLoader.State = DlLiteLoaderListLoader
LoadFabric.State = DlFabricListLoader LoadFabric.State = DlFabricListLoader
LoadFabricApi.State = DlFabricApiLoader LoadFabricApi.State = DlFabricApiLoader
LoadNeoForge.State = DlNeoForgeListLoader
LoadOptiFabric.State = DlOptiFabricLoader LoadOptiFabric.State = DlOptiFabricLoader
End Sub End Sub
@@ -51,6 +53,7 @@
CardOptiFine.IsSwaped = True CardOptiFine.IsSwaped = True
CardLiteLoader.IsSwaped = True CardLiteLoader.IsSwaped = True
CardForge.IsSwaped = True CardForge.IsSwaped = True
CardNeoForge.IsSwaped = True
CardFabric.IsSwaped = True CardFabric.IsSwaped = True
CardFabricApi.IsSwaped = True CardFabricApi.IsSwaped = True
CardOptiFabric.IsSwaped = True CardOptiFabric.IsSwaped = True
@@ -80,32 +83,36 @@
AniStart({ AniStart({
AaOpacity(PanMinecraft, -PanMinecraft.Opacity, 100, 10), AaOpacity(PanMinecraft, -PanMinecraft.Opacity, 100, 10),
AaTranslateX(PanMinecraft, -50 - CType(PanMinecraft.RenderTransform, TranslateTransform).X, 110, 10), AaTranslateX(PanMinecraft, -50 - CType(PanMinecraft.RenderTransform, TranslateTransform).X, 110, 10),
AaCode(Sub() AaCode(
PanBack.ScrollToHome() Sub()
TextSelectName.Validate() PanBack.ScrollToHome()
OptiFine_Loaded() TextSelectName.Validate()
LiteLoader_Loaded() OptiFine_Loaded()
Forge_Loaded() LiteLoader_Loaded()
Fabric_Loaded() Forge_Loaded()
FabricApi_Loaded() NeoForge_Loaded()
OptiFabric_Loaded() Fabric_Loaded()
SelectReload() FabricApi_Loaded()
End Sub, After:=True), OptiFabric_Loaded()
SelectReload()
End Sub, After:=True),
AaOpacity(PanSelect, 1 - PanSelect.Opacity, 250, 150), AaOpacity(PanSelect, 1 - PanSelect.Opacity, 250, 150),
AaTranslateX(PanSelect, -CType(PanSelect.RenderTransform, TranslateTransform).X, 500, 150, Ease:=New AniEaseOutBack(AniEasePower.Weak)), AaTranslateX(PanSelect, -CType(PanSelect.RenderTransform, TranslateTransform).X, 500, 150, Ease:=New AniEaseOutBack(AniEasePower.Weak)),
AaCode(Sub() AaCode(
PanMinecraft.Visibility = Visibility.Collapsed Sub()
PanBack.IsHitTestVisible = True PanMinecraft.Visibility = Visibility.Collapsed
'初始化 Binding PanBack.IsHitTestVisible = True
If IsFirstLoaded Then Exit Sub '初始化 Binding
IsFirstLoaded = True If IsFirstLoaded Then Exit Sub
BtnOptiFineClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFine.MainTextBlock, .Mode = BindingMode.OneWay}) IsFirstLoaded = True
BtnLiteLoaderClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardLiteLoader.MainTextBlock, .Mode = BindingMode.OneWay}) BtnOptiFineClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFine.MainTextBlock, .Mode = BindingMode.OneWay})
BtnForgeClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardForge.MainTextBlock, .Mode = BindingMode.OneWay}) BtnLiteLoaderClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardLiteLoader.MainTextBlock, .Mode = BindingMode.OneWay})
BtnFabricClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardFabric.MainTextBlock, .Mode = BindingMode.OneWay}) BtnForgeClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardForge.MainTextBlock, .Mode = BindingMode.OneWay})
BtnFabricApiClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardFabricApi.MainTextBlock, .Mode = BindingMode.OneWay}) BtnNeoForgeClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardNeoForge.MainTextBlock, .Mode = BindingMode.OneWay})
BtnOptiFabricClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFabric.MainTextBlock, .Mode = BindingMode.OneWay}) BtnFabricClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardFabric.MainTextBlock, .Mode = BindingMode.OneWay})
End Sub,, True) BtnFabricApiClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardFabricApi.MainTextBlock, .Mode = BindingMode.OneWay})
BtnOptiFabricClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFabric.MainTextBlock, .Mode = BindingMode.OneWay})
End Sub,, True)
}, "FrmDownloadInstall SelectPageSwitch", True) }, "FrmDownloadInstall SelectPageSwitch", True)
End Sub End Sub
Public Sub ExitSelectPage() Public Sub ExitSelectPage()
@@ -213,6 +220,26 @@
End If End If
End Sub End Sub
'NeoForge
Private SelectedNeoForge As DlNeoForgeListEntry = Nothing
Private Sub SetNeoForgeInfoShow(IsShow As String)
If PanNeoForgeInfo.Tag = IsShow Then Exit Sub
PanNeoForgeInfo.Tag = IsShow
If IsShow = "True" Then
'显示信息栏
AniStart({
AaTranslateY(PanNeoForgeInfo, -CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
AaOpacity(PanNeoForgeInfo, 1 - PanNeoForgeInfo.Opacity, 100, 90)
}, "SetNeoForgeInfoShow")
Else
'隐藏信息栏
AniStart({
AaTranslateY(PanNeoForgeInfo, 6 - CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 200),
AaOpacity(PanNeoForgeInfo, -PanNeoForgeInfo.Opacity, 100)
}, "SetNeoForgeInfoShow")
End If
End Sub
'Fabric 'Fabric
Private SelectedFabric As String = Nothing Private SelectedFabric As String = Nothing
Private Sub SetFabricInfoShow(IsShow As String) Private Sub SetFabricInfoShow(IsShow As String)
@@ -277,7 +304,7 @@
''' <summary> ''' <summary>
''' 重载已选择的项目的显示。 ''' 重载已选择的项目的显示。
''' </summary> ''' </summary>
Private Sub SelectReload() Handles CardOptiFine.Swap, LoadOptiFine.StateChanged, CardForge.Swap, LoadForge.StateChanged, CardFabric.Swap, LoadFabric.StateChanged, CardFabricApi.Swap, LoadFabricApi.StateChanged, CardOptiFabric.Swap, LoadOptiFabric.StateChanged, CardLiteLoader.Swap, LoadLiteLoader.StateChanged Private Sub SelectReload() Handles CardOptiFine.Swap, LoadOptiFine.StateChanged, CardForge.Swap, LoadForge.StateChanged, CardNeoForge.Swap, LoadNeoForge.StateChanged, CardFabric.Swap, LoadFabric.StateChanged, CardFabricApi.Swap, LoadFabricApi.StateChanged, CardOptiFabric.Swap, LoadOptiFabric.StateChanged, CardLiteLoader.Swap, LoadLiteLoader.StateChanged
If SelectedMinecraftId Is Nothing OrElse IsReloading Then Exit Sub If SelectedMinecraftId Is Nothing OrElse IsReloading Then Exit Sub
IsReloading = True IsReloading = True
'主预览 '主预览
@@ -338,9 +365,30 @@
Else Else
BtnForgeClear.Visibility = Visibility.Visible BtnForgeClear.Visibility = Visibility.Visible
ImgForge.Visibility = Visibility.Visible ImgForge.Visibility = Visibility.Visible
LabForge.Text = SelectedForge.Version LabForge.Text = SelectedForge.VersionName
LabForge.Foreground = ColorGray1 LabForge.Foreground = ColorGray1
End If End If
'NeoForge
If Not SelectedMinecraftId.Contains("1.") OrElse Val(SelectedMinecraftId.Split(".")(1)) <= 19 Then
CardNeoForge.Visibility = Visibility.Collapsed
Else
CardNeoForge.Visibility = Visibility.Visible
Dim NeoForgeError As String = LoadNeoForgeGetError()
CardNeoForge.MainSwap.Visibility = If(NeoForgeError Is Nothing, Visibility.Visible, Visibility.Collapsed)
If NeoForgeError IsNot Nothing Then CardNeoForge.IsSwaped = True
SetNeoForgeInfoShow(CardNeoForge.IsSwaped)
If SelectedNeoForge Is Nothing Then
BtnNeoForgeClear.Visibility = Visibility.Collapsed
ImgNeoForge.Visibility = Visibility.Collapsed
LabNeoForge.Text = If(NeoForgeError, "点击选择")
LabNeoForge.Foreground = ColorGray4
Else
BtnNeoForgeClear.Visibility = Visibility.Visible
ImgNeoForge.Visibility = Visibility.Visible
LabNeoForge.Text = SelectedNeoForge.VersionName
LabNeoForge.Foreground = ColorGray1
End If
End If
'Fabric 'Fabric
If SelectedMinecraftId.Contains("1.") AndAlso Val(SelectedMinecraftId.Split(".")(1)) <= 13 Then If SelectedMinecraftId.Contains("1.") AndAlso Val(SelectedMinecraftId.Split(".")(1)) <= 13 Then
CardFabric.Visibility = Visibility.Collapsed CardFabric.Visibility = Visibility.Collapsed
@@ -411,9 +459,16 @@
HintFabricAPI.Visibility = Visibility.Collapsed HintFabricAPI.Visibility = Visibility.Collapsed
End If End If
If SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso SelectedOptiFabric Is Nothing Then If SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso SelectedOptiFabric Is Nothing Then
HintOptiFabric.Visibility = Visibility.Visible If SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15") Then
HintOptiFabric.Visibility = Visibility.Collapsed
HintOptiFabricOld.Visibility = Visibility.Visible
Else
HintOptiFabric.Visibility = Visibility.Visible
HintOptiFabricOld.Visibility = Visibility.Collapsed
End If
Else Else
HintOptiFabric.Visibility = Visibility.Collapsed HintOptiFabric.Visibility = Visibility.Collapsed
HintOptiFabricOld.Visibility = Visibility.Collapsed
End If End If
If SelectedMinecraftId.Contains("1.") AndAlso Val(SelectedMinecraftId.Split(".")(1)) >= 16 AndAlso SelectedOptiFine IsNot Nothing AndAlso If SelectedMinecraftId.Contains("1.") AndAlso Val(SelectedMinecraftId.Split(".")(1)) >= 16 AndAlso SelectedOptiFine IsNot Nothing AndAlso
(SelectedForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) Then (SelectedForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) Then
@@ -434,6 +489,7 @@
SelectedOptiFine = Nothing SelectedOptiFine = Nothing
SelectedLiteLoader = Nothing SelectedLiteLoader = Nothing
SelectedForge = Nothing SelectedForge = Nothing
SelectedNeoForge = Nothing
SelectedFabric = Nothing SelectedFabric = Nothing
SelectedFabricApi = Nothing SelectedFabricApi = Nothing
SelectedOptiFabric = Nothing SelectedOptiFabric = Nothing
@@ -449,7 +505,10 @@
Name += "-Fabric " & SelectedFabric.Replace("+build", "") Name += "-Fabric " & SelectedFabric.Replace("+build", "")
End If End If
If SelectedForge IsNot Nothing Then If SelectedForge IsNot Nothing Then
Name += "-Forge_" & SelectedForge.Version Name += "-Forge_" & SelectedForge.VersionName
End If
If SelectedNeoForge IsNot Nothing Then
Name += "-NeoForge_" & SelectedNeoForge.VersionName
End If End If
If SelectedLiteLoader IsNot Nothing Then If SelectedLiteLoader IsNot Nothing Then
Name += "-LiteLoader" Name += "-LiteLoader"
@@ -468,7 +527,10 @@
Info += ", Fabric " & SelectedFabric.Replace("+build", "") Info += ", Fabric " & SelectedFabric.Replace("+build", "")
End If End If
If SelectedForge IsNot Nothing Then If SelectedForge IsNot Nothing Then
Info += ", Forge " & SelectedForge.Version Info += ", Forge " & SelectedForge.VersionName
End If
If SelectedNeoForge IsNot Nothing Then
Info += ", NeoForge " & SelectedNeoForge.VersionName
End If End If
If SelectedLiteLoader IsNot Nothing Then If SelectedLiteLoader IsNot Nothing Then
Info += ", LiteLoader" Info += ", LiteLoader"
@@ -487,6 +549,8 @@
Return "pack://application:,,,/images/Blocks/Fabric.png" Return "pack://application:,,,/images/Blocks/Fabric.png"
ElseIf SelectedForge IsNot Nothing Then ElseIf SelectedForge IsNot Nothing Then
Return "pack://application:,,,/images/Blocks/Anvil.png" Return "pack://application:,,,/images/Blocks/Anvil.png"
ElseIf SelectedNeoForge IsNot Nothing Then
Return "pack://application:,,,/images/Blocks/NeoForge.png"
ElseIf SelectedLiteLoader IsNot Nothing Then ElseIf SelectedLiteLoader IsNot Nothing Then
Return "pack://application:,,,/images/Blocks/Egg.png" Return "pack://application:,,,/images/Blocks/Egg.png"
ElseIf SelectedOptiFine IsNot Nothing Then ElseIf SelectedOptiFine IsNot Nothing Then
@@ -624,6 +688,7 @@
''' 获取 OptiFine 的加载异常信息。若正常则返回 Nothing。 ''' 获取 OptiFine 的加载异常信息。若正常则返回 Nothing。
''' </summary> ''' </summary>
Private Function LoadOptiFineGetError() As String Private Function LoadOptiFineGetError() As String
If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
If LoadOptiFine Is Nothing OrElse LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……" If LoadOptiFine Is Nothing OrElse LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
If LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFine.State, Object).Error.Message If LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFine.State, Object).Error.Message
'检查 Forge 1.13 - 1.14.3:全部不兼容 '检查 Forge 1.13 - 1.14.3:全部不兼容
@@ -659,10 +724,12 @@
Private Function IsOptiFineSuitForForge(OptiFine As DlOptiFineListEntry, Forge As DlForgeVersionEntry) Private Function IsOptiFineSuitForForge(OptiFine As DlOptiFineListEntry, Forge As DlForgeVersionEntry)
If Forge.Inherit <> OptiFine.Inherit Then Return False '不是同一个大版本 If Forge.Inherit <> OptiFine.Inherit Then Return False '不是同一个大版本
If OptiFine.RequiredForgeVersion Is Nothing Then Return False '不兼容 Forge If OptiFine.RequiredForgeVersion Is Nothing Then Return False '不兼容 Forge
Return (OptiFine.RequiredForgeVersion.Contains(".") AndAlso 'XX.X.XXX If String.IsNullOrWhiteSpace(OptiFine.RequiredForgeVersion) Then Return True '#4183
VersionSortInteger(Forge.Version, OptiFine.RequiredForgeVersion) >= 0) OrElse If OptiFine.RequiredForgeVersion.Contains(".") Then 'XX.X.XXX
(Not OptiFine.RequiredForgeVersion.Contains(".") AndAlso '#XXXX Return VersionSortInteger(Forge.Version.ToString, OptiFine.RequiredForgeVersion) >= 0
Forge.Version.After(".") >= OptiFine.RequiredForgeVersion) Else 'XXXX
Return Forge.Version.Revision >= OptiFine.RequiredForgeVersion
End If
End Function End Function
'限制展开 '限制展开
@@ -685,11 +752,12 @@
Next Next
If Not Versions.Any() Then Exit Sub If Not Versions.Any() Then Exit Sub
'排序 '排序
Versions = Sort(Versions, Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean Versions = Sort(Versions,
If Not Left.IsPreview AndAlso Right.IsPreview Then Return True Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean
If Left.IsPreview AndAlso Not Right.IsPreview Then Return False If Not Left.IsPreview AndAlso Right.IsPreview Then Return True
Return VersionSortBoolean(Left.NameDisplay, Right.NameDisplay) If Left.IsPreview AndAlso Not Right.IsPreview Then Return False
End Function) Return VersionSortBoolean(Left.NameDisplay, Right.NameDisplay)
End Function)
'可视化 '可视化
PanOptiFine.Children.Clear() PanOptiFine.Children.Clear()
For Each Version In Versions For Each Version In Versions
@@ -706,6 +774,7 @@
If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedForge = Nothing If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedForge = Nothing
OptiFabric_Loaded() OptiFabric_Loaded()
Forge_Loaded() Forge_Loaded()
NeoForge_Loaded()
CardOptiFine.IsSwaped = True CardOptiFine.IsSwaped = True
SelectReload() SelectReload()
End Sub End Sub
@@ -715,6 +784,7 @@
CardOptiFine.IsSwaped = True CardOptiFine.IsSwaped = True
e.Handled = True e.Handled = True
Forge_Loaded() Forge_Loaded()
NeoForge_Loaded()
SelectReload() SelectReload()
End Sub End Sub
@@ -800,6 +870,7 @@
Dim NotSuitForOptiFine As Boolean = False Dim NotSuitForOptiFine As Boolean = False
For Each Version In Loader.Output For Each Version In Loader.Output
If Version.Category = "universal" OrElse Version.Category = "client" Then Continue For '跳过无法自动安装的版本 If Version.Category = "universal" OrElse Version.Category = "client" Then Continue For '跳过无法自动安装的版本
If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容" If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容"
If SelectedOptiFine IsNot Nothing AndAlso If SelectedOptiFine IsNot Nothing AndAlso
VersionSortInteger(SelectedMinecraftId, "1.13") >= 0 AndAlso VersionSortInteger("1.14.3", SelectedMinecraftId) >= 0 Then VersionSortInteger(SelectedMinecraftId, "1.13") >= 0 AndAlso VersionSortInteger("1.14.3", SelectedMinecraftId) >= 0 Then
@@ -829,16 +900,15 @@
If SelectedMinecraftId <> Loader.Input Then Exit Sub If SelectedMinecraftId <> Loader.Input Then Exit Sub
If Loader.State <> LoadState.Finished Then Exit Sub If Loader.State <> LoadState.Finished Then Exit Sub
'获取要显示的版本 '获取要显示的版本
Dim Versions As New List(Of DlForgeVersionEntry) Dim Versions = Loader.Output.ToList '复制数组,以免 Output 在实例化后变空
Versions.AddRange(Loader.Output) '复制数组,以免 Output 在实例化后变空
If Not Loader.Output.Any() Then Exit Sub If Not Loader.Output.Any() Then Exit Sub
PanForge.Children.Clear() PanForge.Children.Clear()
Versions = Sort(Versions, Function(a, b) New Version(a.Version) > New Version(b.Version)). Versions = Sort(Versions, Function(a, b) a.Version > b.Version).Where(
Where(Function(v) Function(v)
If v.Category = "universal" OrElse v.Category = "client" Then Return False '跳过无法自动安装的版本 If v.Category = "universal" OrElse v.Category = "client" Then Return False '跳过无法自动安装的版本
If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, v) Then Return False If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, v) Then Return False
Return True Return True
End Function).ToList End Function).ToList()
ForgeDownloadListItemPreload(PanForge, Versions, AddressOf Forge_Selected, False) ForgeDownloadListItemPreload(PanForge, Versions, AddressOf Forge_Selected, False)
For Each Version In Versions For Each Version In Versions
PanForge.Children.Add(ForgeDownloadListItem(Version, AddressOf Forge_Selected, False)) PanForge.Children.Add(ForgeDownloadListItem(Version, AddressOf Forge_Selected, False))
@@ -866,6 +936,67 @@
#End Region #End Region
#Region "NeoForge 列表"
''' <summary>
''' 获取 NeoForge 的加载异常信息。若正常则返回 Nothing。
''' </summary>
Private Function LoadNeoForgeGetError() As String
If Not SelectedMinecraftId.StartsWith("1.") Then Return "没有可用版本"
If SelectedOptiFine IsNot Nothing Then Return "与 OptiFine 不兼容"
If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容"
If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容"
If LoadNeoForge Is Nothing OrElse LoadNeoForge.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
If LoadNeoForge.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadNeoForge.State, Object).Error.Message
If DlNeoForgeListLoader.Output.Value.Any(Function(v) v.Inherit = SelectedMinecraftId) Then
Return Nothing
Else
Return "没有可用版本"
End If
End Function
'限制展开
Private Sub CardNeoForge_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardNeoForge.PreviewSwap
If LoadNeoForgeGetError() IsNot Nothing Then e.Handled = True
End Sub
''' <summary>
''' 尝试重新可视化 NeoForge 版本列表。
''' </summary>
Private Sub NeoForge_Loaded() Handles LoadNeoForge.StateChanged
Try
'获取版本列表
If DlNeoForgeListLoader.State <> LoadState.Finished Then Exit Sub
Dim Versions = DlNeoForgeListLoader.Output.Value.Where(Function(v) v.Inherit = SelectedMinecraftId).ToList
If Not Versions.Any() Then Exit Sub
'可视化
PanNeoForge.Children.Clear()
NeoForgeDownloadListItemPreload(PanNeoForge, Versions, AddressOf NeoForge_Selected, False)
For Each Version In Versions
PanNeoForge.Children.Add(NeoForgeDownloadListItem(Version, AddressOf NeoForge_Selected, False))
Next
Catch ex As Exception
Log(ex, "可视化 NeoForge 安装版本列表出错", LogLevel.Feedback)
End Try
End Sub
'选择与清除
Private Sub NeoForge_Selected(sender As MyListItem, e As EventArgs)
SelectedNeoForge = sender.Tag
CardNeoForge.IsSwaped = True
OptiFine_Loaded()
SelectReload()
End Sub
Private Sub NeoForge_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnNeoForgeClear.MouseLeftButtonUp
SelectedNeoForge = Nothing
CardNeoForge.IsSwaped = True
e.Handled = True
OptiFine_Loaded()
SelectReload()
End Sub
#End Region
#Region "Fabric 列表" #Region "Fabric 列表"
''' <summary> ''' <summary>
@@ -877,7 +1008,7 @@
For Each Version As JObject In DlFabricListLoader.Output.Value("game") For Each Version As JObject In DlFabricListLoader.Output.Value("game")
If Version("version").ToString = SelectedMinecraftId.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3") Then If Version("version").ToString = SelectedMinecraftId.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3") Then
If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容" If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容"
'If SelectedOptiFine IsNot Nothing Then Return "与 OptiFine 不兼容" If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
Return Nothing Return Nothing
End If End If
Next Next
@@ -1064,6 +1195,7 @@
''' 获取 OptiFabric 的加载异常信息。若正常则返回 Nothing。 ''' 获取 OptiFabric 的加载异常信息。若正常则返回 Nothing。
''' </summary> ''' </summary>
Private Function LoadOptiFabricGetError() As String Private Function LoadOptiFabricGetError() As String
If SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15") Then Return "不兼容老版本 Fabric,请手动下载 OptiFabric Origins"
If LoadOptiFabric Is Nothing OrElse LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……" If LoadOptiFabric Is Nothing OrElse LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
If LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFabric.State, Object).Error.Message If LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFabric.State, Object).Error.Message
If DlOptiFabricLoader.Output Is Nothing Then If DlOptiFabricLoader.Output Is Nothing Then
@@ -1109,7 +1241,8 @@
PanOptiFabric.Children.Add(OptiFabricDownloadListItem(Version, AddressOf OptiFabric_Selected)) PanOptiFabric.Children.Add(OptiFabricDownloadListItem(Version, AddressOf OptiFabric_Selected))
Next Next
'自动选择 OptiFabric '自动选择 OptiFabric
If Not AutoSelectedOptiFabric Then If Not AutoSelectedOptiFabric AndAlso
Not (SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15")) Then '1.14~15 不自动选择
AutoSelectedOptiFabric = True AutoSelectedOptiFabric = True
Log($"[Download] 已自动选择 OptiFabric:{CType(PanOptiFabric.Children(0), MyListItem).Title}") Log($"[Download] 已自动选择 OptiFabric:{CType(PanOptiFabric.Children(0), MyListItem).Title}")
OptiFabric_Selected(PanOptiFabric.Children(0), Nothing) OptiFabric_Selected(PanOptiFabric.Children(0), Nothing)
@@ -1141,7 +1274,7 @@
End Sub End Sub
Private Sub BtnSelectStart_Click() Handles BtnSelectStart.Click Private Sub BtnSelectStart_Click() Handles BtnSelectStart.Click
'确认版本隔离 '确认版本隔离
If (SelectedForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) AndAlso If (SelectedForge IsNot Nothing OrElse SelectedNeoForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) AndAlso
(Setup.Get("LaunchArgumentIndie") = 0 OrElse Setup.Get("LaunchArgumentIndie") = 2) Then (Setup.Get("LaunchArgumentIndie") = 0 OrElse Setup.Get("LaunchArgumentIndie") = 2) Then
If MyMsgBox("你尚未开启版本隔离,这会导致多个 MC 共用同一个 Mod 文件夹。" & vbCrLf & If MyMsgBox("你尚未开启版本隔离,这会导致多个 MC 共用同一个 Mod 文件夹。" & vbCrLf &
"因此在切换 MC 版本时,MC 会因为读取到与当前版本不符的 Mod 而崩溃。" & vbCrLf & "因此在切换 MC 版本时,MC 会因为读取到与当前版本不符的 Mod 而崩溃。" & vbCrLf &
@@ -1157,6 +1290,7 @@
.MinecraftName = SelectedMinecraftId, .MinecraftName = SelectedMinecraftId,
.OptiFineEntry = SelectedOptiFine, .OptiFineEntry = SelectedOptiFine,
.ForgeEntry = SelectedForge, .ForgeEntry = SelectedForge,
.NeoForgeEntry = SelectedNeoForge,
.FabricVersion = SelectedFabric, .FabricVersion = SelectedFabric,
.FabricApi = SelectedFabricApi, .FabricApi = SelectedFabricApi,
.OptiFabric = SelectedOptiFabric, .OptiFabric = SelectedOptiFabric,
@@ -43,47 +43,55 @@
</x:Array> </x:Array>
</local:MyListItem.Buttons> </local:MyListItem.Buttons>
</local:MyListItem> </local:MyListItem>
<local:MyListItem x:Name="ItemFabric" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="7" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Fabric" <local:MyListItem x:Name="ItemNeoForge" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="7" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="NeoForge"
LogoScale="1.02" Logo="M826.453333 170.666667c-100.266667-93.866667-248.96-76.373333-256-75.52a31.786667 31.786667 0 0 0-26.666666 22.613333c-1.066667 3.2-101.546667 330.666667-426.666667 445.013333a29.013333 29.013333 0 0 0-7.893333 4.48l-1.493334 1.066667a29.44 29.44 0 0 0-5.973333 6.613333 31.786667 31.786667 0 0 0-3.626667 7.68 5.333333 5.333333 0 0 1 0 1.493334 30.506667 30.506667 0 0 0 0 8.96c7.466667 116.266667 45.013333 204.586667 112 262.826666a303.36 303.36 0 0 0 194.773334 71.466667h11.52a32.426667 32.426667 0 0 0 27.093333-19.626667 694.186667 694.186667 0 0 1 159.36-234.666666l-7.68 55.466666A31.786667 31.786667 0 0 0 621.44 768h4.48a32.213333 32.213333 0 0 0 31.786667-27.733333l15.573333-112.426667 112.426667 8.32a32 32 0 1 0 4.693333-64l-56.96-4.266667c36.48-25.813333 74.026667-50.56 112-75.52l51.626667-34.133333a31.573333 31.573333 0 0 0 14.08-24.746667c6.186667-115.2-21.76-203.306667-84.693334-262.826666zM620.8 573.013333l-1.706667 1.493334a219.093333 219.093333 0 0 0-87.466666-116.693334 222.933333 222.933333 0 0 0-95.146667-33.28c18.986667-21.333333 36.266667-42.666667 51.626667-64a198.613333 198.613333 0 0 1 202.453333 158.08c-20.053333 14.506667-39.893333 29.44-59.52 45.226667a29.866667 29.866667 0 0 0-10.24 9.173333z m-228.693333 292.266667a238.72 238.72 0 0 1-141.44-55.893333 213.333333 213.333333 0 0 1-34.986667-39.466667 123.946667 123.946667 0 0 0 44.373333 8.106667 168.533333 168.533333 0 0 0 69.12-16.213334 29.44 29.44 0 0 0 7.04-4.266666l106.666667-85.333334a32 32 0 1 0-39.893333-49.92L298.666667 704a78.293333 78.293333 0 0 1-69.546667 1.706667c-32.426667-17.066667-52.693333-61.653333-62.506667-93.44a709.333333 709.333333 0 0 0 202.453334-123.733334 187.52 187.52 0 0 1 128 21.333334 171.946667 171.946667 0 0 1 68.906666 109.653333 756.48 756.48 0 0 0-173.866666 245.76zM810.666667 438.4l-64 42.666667A256 256 0 0 0 529.706667 298.666667a810.666667 810.666667 0 0 0 69.12-140.8c37.973333-1.066667 123.946667 4.053333 183.68 59.946666 45.866667 42.666667 67.84 108.8 65.493333 195.84z"> LogoScale="0.95" Logo="M544.6 921.2l-23.7 32.6c14.1 10.2 33.3 10.2 47.5 0l-23.7-32.6zM114.6 608.5l-23.9 32.5 0.2 0.1 23.6-32.6z m-12.0-38.0l38.3 12.7v-0.2l-38.3-12.4z m49.2-152.6l-38.4-12.4 38.4 12.4zM250.2 114.4l-37.6-14.6a40.2 40.2 0 0 0-0.7 2.1l38.4 12.4z m4.3-6.4l27.0 29.9 0.2-0.2-27.2-29.7z m11.7-4.5V63.0v40.4z m11.7 4.5l28.0-29.0a40.5 40.5 0 0 0-0.8-0.8l-27.2 29.8z m4.4 7.3l-38.6 11.7a40.5 40.5 0 0 0 0.2 0.7l38.3-12.4zM381.0 417.7l-38.4 12.5a40.3 40.3 0 0 0 38.4 27.8v-40.3z m327.0 0v40.3c17.5 0 32.9-11.2 38.4-27.8L708.1 417.7z m98.5-303.3l-37.6-14.6a38.4 38.4 0 0 0-0.7 2.1l38.4 12.4z m4.3-6.4l27.1 29.9 0.1-0.2-27.2-29.7z m11.7-4.5v0z m11.7 4.5l28.0-29.0a38.4 38.4 0 0 0-0.8-0.8l-27.2 29.8z m4.3 7.3l-38.6 11.7a47.5 47.5 0 0 0 0.2 0.7l38.4-12.4z m98.5 303.3l-38.4 12.4 0.1 0.5 38.2-12.9z m51.2 151.9l38.7-11.3a34.5 34.5 0 0 0-0.5-1.6l-38.1 12.9z m-37.8 5.2l-430.0 312.6 47.5 65.3 429.9-312.6-47.5-65.3z m-382.5 312.6L138.3 575.8l-47.5 65.3L520.9 953.9l47.3-65.3zM138.5 576a6.4 6.4 0 0 1 2.3 3.2l-76.9 24.5c4.7 14.9 14.1 28.0 26.7 37.3l47.8-65.0z m2.3 3.2a6.4 6.4 0 0 1 0 4.0L64.1 557.9a74.3 74.3 0 0 0-0.2 45.8l76.9-24.5z m0 3.7l49.2-152.6-76.8-24.8L64.0 558.2l76.8 24.8z m49.2-152.5l98.5-303.3-76.8-25.0L113.3 405.3l76.8 25.0z m97.7-301.3a23.4 23.4 0 0 1-6.1 8.9L227.6 78.0a57.3 57.3 0 0 0-15.0 21.8l75.3 29.1z m-5.9 8.7a23.0 23.0 0 0 1-15.5 6.0V63.0a57.7 57.7 0 0 0-38.9 15.1l54.4 59.6z m-15.5 6.0a23.0 23.0 0 0 1-15.5-6.0l54.4-59.6A57.7 57.7 0 0 0 266.4 63.0v80.8z m-16.3-6.8a23.4 23.4 0 0 1-6.1-10.0l77.3-23.4a57.3 57.3 0 0 0-15.0-24.5l-56.1 58.0z m-5.8-9.2l98.4 302.5 76.8-25.0-98.5-302.5-76.8 25.0z m136.8 330.4H708.1V377.5H381.2v80.7z m365.4-27.8l98.5-303.3-76.8-25.0L669.6 405.3l76.8 25.0z m97.7-301.3a23.4 23.4 0 0 1-6.1 8.9l-54.1-59.9a57.3 57.3 0 0 0-15.0 21.8l75.3 29.1z m-5.9 8.7a23.0 23.0 0 0 1-15.5 6.0V63.0a57.7 57.7 0 0 0-38.9 15.1l54.4 59.6z m-15.5 6.0a23.0 23.0 0 0 1-15.5-6.0l54.4-59.6a57.7 57.7 0 0 0-38.9-15.1v80.8z m-16.3-6.8a23.4 23.4 0 0 1-6.1-10.0l77.3-23.4a57.4 57.4 0 0 0-14.9-24.5l-56.1 58.0z m-5.8-9.2l98.5 303.3 76.8-25.0-98.5-303.3-76.8 25.0z m98.6 303.8l51.2 151.9 76.5-25.8-51.2-151.9-76.5 25.8z m50.7 150.2a6.5 6.5 0 0 1 0.1-4.0l75.6 28.1c5.5-14.9 6.2-31.3 1.6-46.7l-77.5 22.6z m0.1-4.0a6.4 6.4 0 0 1 2.4-3.2l43.8 67.8c13.4-8.7 23.6-21.5 29.2-36.4l-75.6-28.1z">
<local:MyListItem.Buttons> <local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}"> <x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="7" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" /> <local:MyIconButton Tag="7" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array> </x:Array>
</local:MyListItem.Buttons> </local:MyListItem.Buttons>
</local:MyListItem> </local:MyListItem>
<local:MyListItem x:Name="ItemLiteLoader" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="8" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="LiteLoader" <local:MyListItem x:Name="ItemFabric" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="8" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Fabric"
LogoScale="1.06" Logo="M517.41 186.99l22.45 83.78h-55.04l-18.76-70.02c-2.85-10.63-13.78-16.95-24.42-14.1-10.63 2.85-16.95 13.78-14.1 24.42l16 59.71H388.5l-12.31-45.95c-10.45-38.99 12.69-79.08 51.69-89.52s79.08 12.68 89.53 51.68z M538.58 98c40.37 0 73.1 32.73 73.1 73.1v79.74h-53.16V171.1c0-11.01-8.93-19.94-19.94-19.94-11.01 0-19.94 8.93-19.94 19.94v79.74h-53.16V171.1c0-40.37 32.73-73.1 73.1-73.1z M512 224.26c191.58 0 346.88 155.3 346.88 346.88v61.8c0 28.85 3.33 59.94 9.98 93.27l1.29 6.28c12.43 59.1-21.15 118.2-78.28 137.78C691.18 904.75 597.9 922 512 922c-83.94 0-174.95-16.47-273.01-49.41l-6.85-2.32c-56.4-19.32-89.85-77.16-78.74-135.5l0.46-2.27c7.51-35.71 11.27-68.89 11.27-99.55v-61.8c0-189.66 152.21-343.77 341.14-346.83l5.73-0.06z m-4.64 66.49c-151.21 2.45-273.32 124.58-275.75 275.8l-0.04 4.59v61.8l-0.04 5.93c-0.45 33.74-4.7 69.49-12.65 107.3-5.53 26.27 9.4 52.53 34.79 61.23 94.08 32.23 180.19 48.15 258.32 48.15s164.25-15.92 258.32-48.15c25.39-8.7 40.32-34.97 34.79-61.23-7.95-37.81-12.2-73.56-12.65-107.3l-0.04-5.93v-61.8c0-153.33-123.05-277.91-275.79-280.39l-4.64-0.04-4.62 0.04z M500.66 717.38l-53.28-87.19c-3.83-6.26-1.85-14.44 4.41-18.27 0.76-0.46 1.56-0.85 2.39-1.15L512 589.74l57.82 21.03c6.9 2.51 10.46 10.13 7.95 17.03-0.3 0.83-0.69 1.63-1.15 2.39l-53.28 87.19c-3.83 6.26-12.01 8.24-18.27 4.41-1.8-1.1-3.31-2.61-4.41-4.41z M684.77 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z M339.23 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z"> LogoScale="1.02" Logo="M826.453333 170.666667c-100.266667-93.866667-248.96-76.373333-256-75.52a31.786667 31.786667 0 0 0-26.666666 22.613333c-1.066667 3.2-101.546667 330.666667-426.666667 445.013333a29.013333 29.013333 0 0 0-7.893333 4.48l-1.493334 1.066667a29.44 29.44 0 0 0-5.973333 6.613333 31.786667 31.786667 0 0 0-3.626667 7.68 5.333333 5.333333 0 0 1 0 1.493334 30.506667 30.506667 0 0 0 0 8.96c7.466667 116.266667 45.013333 204.586667 112 262.826666a303.36 303.36 0 0 0 194.773334 71.466667h11.52a32.426667 32.426667 0 0 0 27.093333-19.626667 694.186667 694.186667 0 0 1 159.36-234.666666l-7.68 55.466666A31.786667 31.786667 0 0 0 621.44 768h4.48a32.213333 32.213333 0 0 0 31.786667-27.733333l15.573333-112.426667 112.426667 8.32a32 32 0 1 0 4.693333-64l-56.96-4.266667c36.48-25.813333 74.026667-50.56 112-75.52l51.626667-34.133333a31.573333 31.573333 0 0 0 14.08-24.746667c6.186667-115.2-21.76-203.306667-84.693334-262.826666zM620.8 573.013333l-1.706667 1.493334a219.093333 219.093333 0 0 0-87.466666-116.693334 222.933333 222.933333 0 0 0-95.146667-33.28c18.986667-21.333333 36.266667-42.666667 51.626667-64a198.613333 198.613333 0 0 1 202.453333 158.08c-20.053333 14.506667-39.893333 29.44-59.52 45.226667a29.866667 29.866667 0 0 0-10.24 9.173333z m-228.693333 292.266667a238.72 238.72 0 0 1-141.44-55.893333 213.333333 213.333333 0 0 1-34.986667-39.466667 123.946667 123.946667 0 0 0 44.373333 8.106667 168.533333 168.533333 0 0 0 69.12-16.213334 29.44 29.44 0 0 0 7.04-4.266666l106.666667-85.333334a32 32 0 1 0-39.893333-49.92L298.666667 704a78.293333 78.293333 0 0 1-69.546667 1.706667c-32.426667-17.066667-52.693333-61.653333-62.506667-93.44a709.333333 709.333333 0 0 0 202.453334-123.733334 187.52 187.52 0 0 1 128 21.333334 171.946667 171.946667 0 0 1 68.906666 109.653333 756.48 756.48 0 0 0-173.866666 245.76zM810.666667 438.4l-64 42.666667A256 256 0 0 0 529.706667 298.666667a810.666667 810.666667 0 0 0 69.12-140.8c37.973333-1.066667 123.946667 4.053333 183.68 59.946666 45.866667 42.666667 67.84 108.8 65.493333 195.84z">
<local:MyListItem.Buttons> <local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}"> <x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="8" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" /> <local:MyIconButton Tag="8" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array> </x:Array>
</local:MyListItem.Buttons> </local:MyListItem.Buttons>
</local:MyListItem> </local:MyListItem>
<TextBlock Text="资源" Margin="13,18,5,4" Opacity="0.6" FontSize="12" /> <local:MyListItem x:Name="ItemLiteLoader" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="9" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="LiteLoader"
<local:MyListItem x:Name="ItemMod" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="10" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod" LogoScale="1.06" Logo="M517.41 186.99l22.45 83.78h-55.04l-18.76-70.02c-2.85-10.63-13.78-16.95-24.42-14.1-10.63 2.85-16.95 13.78-14.1 24.42l16 59.71H388.5l-12.31-45.95c-10.45-38.99 12.69-79.08 51.69-89.52s79.08 12.68 89.53 51.68z M538.58 98c40.37 0 73.1 32.73 73.1 73.1v79.74h-53.16V171.1c0-11.01-8.93-19.94-19.94-19.94-11.01 0-19.94 8.93-19.94 19.94v79.74h-53.16V171.1c0-40.37 32.73-73.1 73.1-73.1z M512 224.26c191.58 0 346.88 155.3 346.88 346.88v61.8c0 28.85 3.33 59.94 9.98 93.27l1.29 6.28c12.43 59.1-21.15 118.2-78.28 137.78C691.18 904.75 597.9 922 512 922c-83.94 0-174.95-16.47-273.01-49.41l-6.85-2.32c-56.4-19.32-89.85-77.16-78.74-135.5l0.46-2.27c7.51-35.71 11.27-68.89 11.27-99.55v-61.8c0-189.66 152.21-343.77 341.14-346.83l5.73-0.06z m-4.64 66.49c-151.21 2.45-273.32 124.58-275.75 275.8l-0.04 4.59v61.8l-0.04 5.93c-0.45 33.74-4.7 69.49-12.65 107.3-5.53 26.27 9.4 52.53 34.79 61.23 94.08 32.23 180.19 48.15 258.32 48.15s164.25-15.92 258.32-48.15c25.39-8.7 40.32-34.97 34.79-61.23-7.95-37.81-12.2-73.56-12.65-107.3l-0.04-5.93v-61.8c0-153.33-123.05-277.91-275.79-280.39l-4.64-0.04-4.62 0.04z M500.66 717.38l-53.28-87.19c-3.83-6.26-1.85-14.44 4.41-18.27 0.76-0.46 1.56-0.85 2.39-1.15L512 589.74l57.82 21.03c6.9 2.51 10.46 10.13 7.95 17.03-0.3 0.83-0.69 1.63-1.15 2.39l-53.28 87.19c-3.83 6.26-12.01 8.24-18.27 4.41-1.8-1.1-3.31-2.61-4.41-4.41z M684.77 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z M339.23 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z">
LogoScale="0.97" Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">
<local:MyListItem.Buttons> <local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}"> <x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="10" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" /> <local:MyIconButton Tag="9" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array> </x:Array>
</local:MyListItem.Buttons> </local:MyListItem.Buttons>
</local:MyListItem> </local:MyListItem>
<local:MyListItem x:Name="ItemPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="11" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="整合包" <TextBlock Text="资源" Margin="13,18,5,4" Opacity="0.6" FontSize="12" />
LogoScale="0.98" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z"> <local:MyListItem x:Name="ItemMod" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="11" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod"
LogoScale="0.97" Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">
<local:MyListItem.Buttons> <local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}"> <x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="11" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" /> <local:MyIconButton Tag="11" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array> </x:Array>
</local:MyListItem.Buttons> </local:MyListItem.Buttons>
</local:MyListItem> </local:MyListItem>
<local:MyListItem x:Name="ItemResourcePack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="12" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="资源包" <local:MyListItem x:Name="ItemPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="12" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="整合包"
LogoScale="0.98" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z"> LogoScale="0.98" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z">
<local:MyListItem.Buttons> <local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}"> <x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="12" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" /> <local:MyIconButton Tag="12" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array> </x:Array>
</local:MyListItem.Buttons> </local:MyListItem.Buttons>
</local:MyListItem> </local:MyListItem>
<local:MyListItem x:Name="ItemResourcePack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="13" MinPaddingRight="35" Height="36" VerticalAlignment="Top" Title="资源包"
LogoScale="0.98" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="13" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.InitialShowDelay="200" ToolTipService.VerticalOffset="-1" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
</StackPanel> </StackPanel>
</local:MyPageLeft> </local:MyPageLeft>
@@ -10,7 +10,7 @@
''' <summary> ''' <summary>
''' 勾选事件改变页面。 ''' 勾选事件改变页面。
''' </summary> ''' </summary>
Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemInstall.Check, ItemClient.Check, ItemOptiFine.Check, ItemForge.Check, ItemLiteLoader.Check, ItemMod.Check, ItemFabric.Check, ItemPack.Check, ItemResourcePack.Check Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemInstall.Check, ItemClient.Check, ItemOptiFine.Check, ItemForge.Check, ItemNeoForge.Check, ItemLiteLoader.Check, ItemMod.Check, ItemFabric.Check, ItemPack.Check, ItemResourcePack.Check
'尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0 '尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False) '若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag)) If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
@@ -31,6 +31,9 @@
Case FormMain.PageSubType.DownloadForge Case FormMain.PageSubType.DownloadForge
If FrmDownloadForge Is Nothing Then FrmDownloadForge = New PageDownloadForge If FrmDownloadForge Is Nothing Then FrmDownloadForge = New PageDownloadForge
Return FrmDownloadForge Return FrmDownloadForge
Case FormMain.PageSubType.DownloadNeoForge
If FrmDownloadNeoForge Is Nothing Then FrmDownloadNeoForge = New PageDownloadNeoForge
Return FrmDownloadNeoForge
Case FormMain.PageSubType.DownloadLiteLoader Case FormMain.PageSubType.DownloadLiteLoader
If FrmDownloadLiteLoader Is Nothing Then FrmDownloadLiteLoader = New PageDownloadLiteLoader If FrmDownloadLiteLoader Is Nothing Then FrmDownloadLiteLoader = New PageDownloadLiteLoader
Return FrmDownloadLiteLoader Return FrmDownloadLiteLoader
@@ -72,17 +75,19 @@
FrmMain.PageRight = Target FrmMain.PageRight = Target
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit() CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit()
AniStart({ AniStart({
AaCode(Sub() AaCode(
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit() Sub()
FrmMain.PanMainRight.Child = FrmMain.PageRight CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit()
FrmMain.PageRight.Opacity = 0 FrmMain.PanMainRight.Child = FrmMain.PageRight
End Sub, 130), FrmMain.PageRight.Opacity = 0
AaCode(Sub() End Sub, 130),
'延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理 AaCode(
FrmMain.PageRight.Opacity = 1 Sub()
FrmMain.PageRight.PageOnEnter() '延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
End Sub, 30, True) FrmMain.PageRight.Opacity = 1
}, "PageLeft PageChange") FrmMain.PageRight.PageOnEnter()
End Sub, 30, True)
}, "PageLeft PageChange")
End Sub End Sub
#End Region #End Region
@@ -94,6 +99,7 @@
DlClientListLoader.Start(IsForceRestart:=True) DlClientListLoader.Start(IsForceRestart:=True)
DlOptiFineListLoader.Start(IsForceRestart:=True) DlOptiFineListLoader.Start(IsForceRestart:=True)
DlForgeListLoader.Start(IsForceRestart:=True) DlForgeListLoader.Start(IsForceRestart:=True)
DlNeoForgeListLoader.Start(IsForceRestart:=True)
DlLiteLoaderListLoader.Start(IsForceRestart:=True) DlLiteLoaderListLoader.Start(IsForceRestart:=True)
DlFabricListLoader.Start(IsForceRestart:=True) DlFabricListLoader.Start(IsForceRestart:=True)
DlFabricApiLoader.Start(IsForceRestart:=True) DlFabricApiLoader.Start(IsForceRestart:=True)
@@ -126,6 +132,9 @@
Case FormMain.PageSubType.DownloadForge Case FormMain.PageSubType.DownloadForge
DlForgeListLoader.Start(IsForceRestart:=True) DlForgeListLoader.Start(IsForceRestart:=True)
ItemForge.Checked = True ItemForge.Checked = True
Case FormMain.PageSubType.DownloadNeoForge
DlNeoForgeListLoader.Start(IsForceRestart:=True)
ItemNeoForge.Checked = True
Case FormMain.PageSubType.DownloadLiteLoader Case FormMain.PageSubType.DownloadLiteLoader
DlLiteLoaderListLoader.Start(IsForceRestart:=True) DlLiteLoaderListLoader.Start(IsForceRestart:=True)
ItemLiteLoader.Checked = True ItemLiteLoader.Checked = True
@@ -163,12 +172,14 @@
ItemOptiFine.Visibility = Visibility.Visible ItemOptiFine.Visibility = Visibility.Visible
ItemFabric.Visibility = Visibility.Visible ItemFabric.Visibility = Visibility.Visible
ItemForge.Visibility = Visibility.Visible ItemForge.Visibility = Visibility.Visible
ItemNeoForge.Visibility = Visibility.Visible
ItemLiteLoader.Visibility = Visibility.Visible ItemLiteLoader.Visibility = Visibility.Visible
RunInThread(Sub() RunInThread(
Thread.Sleep(20) Sub()
RunInUiWait(Sub() ItemClient.SetChecked(True, True, True)) Thread.Sleep(20)
AniControlEnabled -= 1 RunInUiWait(Sub() ItemClient.SetChecked(True, True, True))
End Sub) AniControlEnabled -= 1
End Sub)
End Sub End Sub
'折叠手动安装 '折叠手动安装
Private Sub LabHand_Click(sender As Object, e As MouseButtonEventArgs) Handles LabHand.MouseLeftButtonUp Private Sub LabHand_Click(sender As Object, e As MouseButtonEventArgs) Handles LabHand.MouseLeftButtonUp
@@ -179,14 +190,16 @@
LabHand.Visibility = Visibility.Collapsed LabHand.Visibility = Visibility.Collapsed
ItemClient.Visibility = Visibility.Collapsed ItemClient.Visibility = Visibility.Collapsed
ItemOptiFine.Visibility = Visibility.Collapsed ItemOptiFine.Visibility = Visibility.Collapsed
ItemNeoForge.Visibility = Visibility.Collapsed
ItemFabric.Visibility = Visibility.Collapsed ItemFabric.Visibility = Visibility.Collapsed
ItemForge.Visibility = Visibility.Collapsed ItemForge.Visibility = Visibility.Collapsed
ItemLiteLoader.Visibility = Visibility.Collapsed ItemLiteLoader.Visibility = Visibility.Collapsed
RunInThread(Sub() RunInThread(
Thread.Sleep(20) Sub()
RunInUiWait(Sub() ItemInstall.SetChecked(True, True, True)) Thread.Sleep(20)
AniControlEnabled -= 1 RunInUiWait(Sub() ItemInstall.SetChecked(True, True, True))
End Sub) AniControlEnabled -= 1
End Sub)
End Sub End Sub
End Class End Class
@@ -38,7 +38,7 @@
PanMain.Children.Add(NewCard) PanMain.Children.Add(NewCard)
Next Next
Catch ex As Exception Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback) Log(ex, "可视化 LiteLoader 版本列表出错", LogLevel.Feedback)
End Try End Try
End Sub End Sub
@@ -33,6 +33,7 @@
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本" Margin="0,0,18,0" /> <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: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="全部 (也可自行输入)" IsSelected="True" />
<local:MyComboBoxItem Content="1.21" />
<local:MyComboBoxItem Content="1.20.6" /> <local:MyComboBoxItem Content="1.20.6" />
<local:MyComboBoxItem Content="1.20.4" /> <local:MyComboBoxItem Content="1.20.4" />
<local:MyComboBoxItem Content="1.20.1" /> <local:MyComboBoxItem Content="1.20.1" />
@@ -40,12 +40,14 @@
Visibility.Visible, Visibility.Collapsed) Visibility.Visible, Visibility.Collapsed)
LabPage.Text = Page + 1 LabPage.Text = Page + 1
BtnPageFirst.IsEnabled = Page > 1 BtnPageFirst.IsEnabled = Page > 1
BtnPageFirst.Opacity = If(BtnPageFirst.IsEnabled, 1, 0.2) BtnPageFirst.Opacity = If(Page > 1, 1, 0.2)
BtnPageLeft.IsEnabled = Page > 0 BtnPageLeft.IsEnabled = Page > 0
BtnPageLeft.Opacity = If(BtnPageLeft.IsEnabled, 1, 0.2) BtnPageLeft.Opacity = If(Page > 0, 1, 0.2)
BtnPageRight.IsEnabled = Storage.Results.Count > PageSize * (Page + 1) OrElse Dim IsRightEnabled As Boolean = '由于 WPF 的未知 bug,读取到的 IsEnabled 可能是错误的值(#3319)
Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal Storage.Results.Count > PageSize * (Page + 1) OrElse
BtnPageRight.Opacity = If(BtnPageRight.IsEnabled, 1, 0.2) Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal
BtnPageRight.IsEnabled = IsRightEnabled
BtnPageRight.Opacity = If(IsRightEnabled, 1, 0.2)
'错误信息 '错误信息
If Storage.ErrorMessage Is Nothing Then If Storage.ErrorMessage Is Nothing Then
HintError.Visibility = Visibility.Collapsed HintError.Visibility = Visibility.Collapsed
@@ -89,11 +91,12 @@
Page = NewPage Page = NewPage
FrmMain.BackToTop() FrmMain.BackToTop()
Log($"[Download] Mod 切换到第 {Page + 1} 页") Log($"[Download] Mod 切换到第 {Page + 1} 页")
RunInThread(Sub() RunInThread(
Thread.Sleep(100) '等待向上滚的动画结束 Sub()
RunInUi(Sub() CardPages.IsEnabled = True) Thread.Sleep(100) '等待向上滚的动画结束
Loader.Start() RunInUi(Sub() CardPages.IsEnabled = True)
End Sub) Loader.Start()
End Sub)
End Sub End Sub
#Region "搜索" #Region "搜索"
@@ -0,0 +1,27 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadNeoForge"
PanScroll="{Binding ElementName=PanBack}">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="5">
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="NeoForge 简介" x:Name="CardTip">
<StackPanel Margin="25,40,15,20">
<TextBlock Margin="0,0,0,11" Text="NeoForge 是 Minecraft 1.19+ 的 Mod 加载器,你需要先安装它才能安装各种 NeoForge 模组。&#xa;本页面提供 NeoForge 安装器下载,在下载后你需要手动打开安装器进行安装。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight"
EventType="打开网页" EventData="https://neoforged.net/" />
</Grid>
</StackPanel>
</local:MyCard>
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
<local:MyCard HorizontalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
<local:MyLoading Text="正在获取 NeoForge 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,34 @@
Public Class PageDownloadNeoForge
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlNeoForgeListLoader, AddressOf Load_OnFinish)
End Sub
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
Private Sub Load_OnFinish()
'结果数据化
Try
'归类
Dim Dict = DlNeoForgeListLoader.Output.Value.GroupBy(Function(d) d.Inherit).OrderByDescending(Function(g) g.Key).
ToDictionary(Function(g) g.Key, Function(g) g.ToList())
'清空当前
PanMain.Children.Clear()
'转化为 UI
For Each Pair As KeyValuePair(Of String, List(Of DlNeoForgeListEntry)) In Dict
If Not Pair.Value.Any() Then Continue For
'增加卡片
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 13}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
NewCard.IsSwaped = True
PanMain.Children.Add(NewCard)
Next
Catch ex As Exception
Log(ex, "可视化 NeoForge 版本列表出错", LogLevel.Feedback)
End Try
End Sub
End Class
@@ -13,7 +13,7 @@
'归类 '归类
Dim Dict As New Dictionary(Of String, List(Of DlOptiFineListEntry)) Dim Dict As New Dictionary(Of String, List(Of DlOptiFineListEntry))
Dict.Add("快照版本", New List(Of DlOptiFineListEntry)) Dict.Add("快照版本", New List(Of DlOptiFineListEntry))
For VersionCode As Integer = 30 To 0 Step -1 For VersionCode As Integer = 50 To 0 Step -1
Dict.Add("1." & VersionCode, New List(Of DlOptiFineListEntry)) Dict.Add("1." & VersionCode, New List(Of DlOptiFineListEntry))
Next Next
For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
@@ -42,14 +42,10 @@
PanMain.Children.Add(NewCard) PanMain.Children.Add(NewCard)
Next Next
Catch ex As Exception Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback) Log(ex, "可视化 OptiFine 版本列表出错", LogLevel.Feedback)
End Try End Try
End Sub End Sub
Public Sub DownloadStart(sender As MyListItem, e As Object)
McDownloadOptiFine(sender.Tag)
End Sub
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
OpenWebsite("https://www.optifine.net/") OpenWebsite("https://www.optifine.net/")
End Sub End Sub
@@ -32,6 +32,7 @@
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本" Margin="0,0,18,0" /> <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:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="1" IsEditable="True" MaxDropDownHeight="320">
<local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" /> <local:MyComboBoxItem Content="全部 (也可自行输入)" IsSelected="True" />
<local:MyComboBoxItem Content="1.21" />
<local:MyComboBoxItem Content="1.20.6" /> <local:MyComboBoxItem Content="1.20.6" />
<local:MyComboBoxItem Content="1.20.4" /> <local:MyComboBoxItem Content="1.20.4" />
<local:MyComboBoxItem Content="1.20.1" /> <local:MyComboBoxItem Content="1.20.1" />
@@ -39,12 +39,14 @@
Visibility.Visible, Visibility.Collapsed) Visibility.Visible, Visibility.Collapsed)
LabPage.Text = Page + 1 LabPage.Text = Page + 1
BtnPageFirst.IsEnabled = Page > 1 BtnPageFirst.IsEnabled = Page > 1
BtnPageFirst.Opacity = If(BtnPageFirst.IsEnabled, 1, 0.2) BtnPageFirst.Opacity = If(Page > 1, 1, 0.2)
BtnPageLeft.IsEnabled = Page > 0 BtnPageLeft.IsEnabled = Page > 0
BtnPageLeft.Opacity = If(BtnPageLeft.IsEnabled, 1, 0.2) BtnPageLeft.Opacity = If(Page > 0, 1, 0.2)
BtnPageRight.IsEnabled = Storage.Results.Count > PageSize * (Page + 1) OrElse Dim IsRightEnabled As Boolean = '由于 WPF 的未知 bug,读取到的 IsEnabled 可能是错误的值(#3319)
Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal Storage.Results.Count > PageSize * (Page + 1) OrElse
BtnPageRight.Opacity = If(BtnPageRight.IsEnabled, 1, 0.2) Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal
BtnPageRight.IsEnabled = IsRightEnabled
BtnPageRight.Opacity = If(IsRightEnabled, 1, 0.2)
'错误信息 '错误信息
If Storage.ErrorMessage Is Nothing Then If Storage.ErrorMessage Is Nothing Then
HintError.Visibility = Visibility.Collapsed HintError.Visibility = Visibility.Collapsed
@@ -241,7 +241,7 @@ Retry:
{"Translator-Chinese", "Crowdin 中文翻译者披风"}, {"Translator", "Crowdin 翻译者披风"}, {"Cobalt", "Cobalt 披风"}, {"Translator-Chinese", "Crowdin 中文翻译者披风"}, {"Translator", "Crowdin 翻译者披风"}, {"Cobalt", "Cobalt 披风"},
{"Vanilla", "原版披风"}, {"Minecon2011", "Minecon 2011 参与者披风"}, {"Minecon2012", "Minecon 2012 参与者披风"}, {"Vanilla", "原版披风"}, {"Minecon2011", "Minecon 2011 参与者披风"}, {"Minecon2012", "Minecon 2012 参与者披风"},
{"Minecon2013", "Minecon 2013 参与者披风"}, {"Minecon2015", "Minecon 2015 参与者披风"}, {"Minecon2016", "Minecon 2016 参与者披风"}, {"Minecon2013", "Minecon 2013 参与者披风"}, {"Minecon2015", "Minecon 2015 参与者披风"}, {"Minecon2016", "Minecon 2016 参与者披风"},
{"Cherry Blossom", "樱花披风"}, {"15th Anniversary", "15 周年纪念披风"}, {"Purple Heart", "紫色心形披风"} {"Cherry Blossom", "樱花披风"}, {"15th Anniversary", "15 周年纪念披风"}, {"Purple Heart", "紫色心形披风"}, {"Follower's", "追随者披风"}
} }
Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}} Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}}
For Each Cape In SkinData("capes") For Each Cape In SkinData("capes")
@@ -21,6 +21,19 @@
'加载版本 '加载版本
RunInNewThread( RunInNewThread(
Sub() Sub()
''自动整合包安装:准备
'Dim PackInstallPath As String = Nothing
'If File.Exists(Path & "modpack.zip") Then PackInstallPath = Path & "modpack.zip"
'If File.Exists(Path & "modpack.mrpack") Then PackInstallPath = Path & "modpack.mrpack"
'If PackInstallPath IsNot Nothing Then
' Log("[Launch] 需自动安装整合包:" & PackInstallPath, LogLevel.Debug)
' If Not Directory.Exists(Path & ".minecraft\") Then
' Directory.CreateDirectory(Path & ".minecraft\")
' Directory.CreateDirectory(Path & ".minecraft\versions\")
' McFolderLauncherProfilesJsonCreate(Path & ".minecraft\")
' End If
' Setup.Set("LaunchFolderSelect", "$.minecraft\")
'End If
'确认 Minecraft 文件夹存在 '确认 Minecraft 文件夹存在
PathMcFolder = Setup.Get("LaunchFolderSelect").ToString.Replace("$", Path) PathMcFolder = Setup.Get("LaunchFolderSelect").ToString.Replace("$", Path)
If PathMcFolder = "" OrElse Not Directory.Exists(PathMcFolder) Then If PathMcFolder = "" OrElse Not Directory.Exists(PathMcFolder) Then
@@ -35,17 +48,21 @@
End If End If
Log("[Launch] Minecraft 文件夹:" & PathMcFolder) Log("[Launch] Minecraft 文件夹:" & PathMcFolder)
If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(500, 3000)) If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(500, 3000))
''自动整合包安装
'If PackInstallPath IsNot Nothing Then
' If ModpackInstall(PackInstallPath) Then
' Log("[Launch] 自动安装整合包成功:" & PackInstallPath)
' File.Delete(PackInstallPath)
' Else
' Log("[Launch] 自动安装整合包失败:" & PackInstallPath)
' End If
'End If
'确认 Minecraft 版本存在 '确认 Minecraft 版本存在
Dim Selection As String = Setup.Get("LaunchVersionSelect") Dim Selection As String = Setup.Get("LaunchVersionSelect")
Dim Version As McVersion Dim Version As McVersion = If(Selection = "", Nothing, New McVersion(Selection))
If Selection = "" Then If Version Is Nothing OrElse Not (Version.Path.StartsWith(PathMcFolder) AndAlso Version.Check) Then
Version = Nothing
Else
Version = New McVersion(Selection)
End If
If IsNothing(Version) OrElse Not (Version.Path.StartsWith(PathMcFolder) AndAlso Version.Check) Then
'无效的版本 '无效的版本
Log("[Launch] Minecraft 版本无效" & If(IsNothing(Version), ",没有有效版本", ":" & Version.Path), If(IsNothing(Version), LogLevel.Normal, LogLevel.Debug)) Log("[Launch] Minecraft 版本无效" & If(Version Is Nothing, ",没有有效版本", ":" & Version.Path), If(IsNothing(Version), LogLevel.Normal, LogLevel.Debug))
If Not McVersionListLoader.State = LoadState.Finished Then LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True) If Not McVersionListLoader.State = LoadState.Finished Then LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True)
If Not McVersionList.Any() OrElse McVersionList.First.Value(0).Logo.Contains("RedstoneBlock") Then If Not McVersionList.Any() OrElse McVersionList.First.Value(0).Logo.Contains("RedstoneBlock") Then
Version = Nothing Version = Nothing
@@ -619,7 +636,7 @@ Finish:
Log("[Minecraft] 启动按钮:正在加载 Minecraft 版本") Log("[Minecraft] 启动按钮:正在加载 Minecraft 版本")
FrmLaunchLeft.BtnLaunch.Text = "正在加载" FrmLaunchLeft.BtnLaunch.Text = "正在加载"
FrmLaunchLeft.BtnLaunch.IsEnabled = False FrmLaunchLeft.BtnLaunch.IsEnabled = False
FrmLaunchLeft.LabVersion.Text = "正在加载版本列表,请稍候" FrmLaunchLeft.LabVersion.Text = "正在加载中,请稍候"
FrmLaunchLeft.BtnVersion.IsEnabled = False FrmLaunchLeft.BtnVersion.IsEnabled = False
FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
Case 1 Case 1
@@ -27,15 +27,16 @@
''' 刷新自定义主页。 ''' 刷新自定义主页。
''' </summary> ''' </summary>
Private Sub Refresh() Handles Me.Loaded Private Sub Refresh() Handles Me.Loaded
RunInNewThread(Sub() RunInNewThread(
Try Sub()
SyncLock RefreshLock Try
RefreshReal() SyncLock RefreshLock
End SyncLock RefreshReal()
Catch ex As Exception End SyncLock
Log(ex, "加载 PCL 主页自定义信息失败", LogLevel.Msgbox) Catch ex As Exception
End Try Log(ex, "加载 PCL 主页自定义信息失败", LogLevel.Msgbox)
End Sub, $"刷新自定义主页 #{GetUuid()}") End Try
End Sub, $"刷新自定义主页 #{GetUuid()}")
End Sub End Sub
Private Sub RefreshReal() Private Sub RefreshReal()
Dim Content As String = "" Dim Content As String = ""
@@ -155,7 +156,6 @@ Download:
Else Else
Log(ex, $"联网下载自定义主页失败({Address})") Log(ex, $"联网下载自定义主页失败({Address})")
End If End If
Address = ""
End Try End Try
End Sub End Sub
@@ -204,7 +204,7 @@ Download:
End If End If
Content = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"">" & Content & "</StackPanel>" Content = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"">" & Content & "</StackPanel>"
Content = HelpArgumentReplace(Content) Content = HelpArgumentReplace(Content)
Log($"[Page] 实例化:加载自定义主页 UI,最终内容长度:{Content.Count}") Log($"[Page] 实例化:加载自定义主页 UI 开始,最终内容长度:{Content.Count}")
Try Try
PanCustom.Children.Add(GetObjectFromXML(Content)) PanCustom.Children.Add(GetObjectFromXML(Content))
Catch ex As Exception Catch ex As Exception
@@ -71,9 +71,9 @@
End Sub End Sub
Private Sub Btn_Click(sender As Object, e As EventArgs) Handles BtnLink.Click Private Sub Btn_Click(sender As Object, e As EventArgs) Handles BtnLink.Click
If BtnLink.Content = "注册账号" Then If BtnLink.Content = "注册账号" Then
OpenWebsite(If(McVersionCurrent Is Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister"))) OpenWebsite(If(McVersionCurrent IsNot Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister")))
Else Else
Dim Website As String = If(McVersionCurrent Is Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister")) Dim Website As String = If(McVersionCurrent IsNot Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister"))
OpenWebsite(Website.Replace("/auth/register", "/auth/forgot")) OpenWebsite(Website.Replace("/auth/register", "/auth/forgot"))
End If End If
End Sub End Sub
@@ -39,14 +39,15 @@
Public Shared Function GetLoginData() As McLoginMs Public Shared Function GetLoginData() As McLoginMs
If FrmLoginMs Is Nothing Then Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")} If FrmLoginMs Is Nothing Then Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")}
Dim Result As McLoginMs = Nothing Dim Result As McLoginMs = Nothing
RunInUiWait(Sub() RunInUiWait(
If FrmLoginMs.ComboAccounts.SelectedIndex = 0 Then Sub()
Result = New McLoginMs If FrmLoginMs.ComboAccounts.SelectedIndex = 0 Then
Else Result = New McLoginMs
Dim Item As MyListItem = FrmLoginMs.ComboAccounts.SelectedItem Else
Result = New McLoginMs With {.OAuthRefreshToken = Item.Tag, .UserName = Item.Title} Dim Item As MyListItem = FrmLoginMs.ComboAccounts.SelectedItem
End If Result = New McLoginMs With {.OAuthRefreshToken = Item.Tag, .UserName = Item.Title}
End Sub) End If
End Sub)
Return Result Return Result
End Function End Function
''' <summary> ''' <summary>
@@ -104,139 +104,312 @@
</local:MyCard> </local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="赞助者"> <local:MyCard Margin="0,0,0,15" Title="赞助者">
<StackPanel Margin="25,40,10,20"> <StackPanel Margin="25,40,10,20">
<TextBlock HorizontalAlignment="Left" Text="以下是 2024 年 4 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" /> <TextBlock HorizontalAlignment="Left" Text="以下是 2024 年 5~6 月的高级赞助者们!感谢各位对 PCL 和伟大的咕咕咕事业的支持!" Margin="0,0,25,5.5" TextTrimming="None" TextWrapping="WrapWithOverflow" />
<WrapPanel Margin="0,0,0,10"> <WrapPanel Margin="0,0,0,10">
<TextBlock Width="120" Margin="0,1.5" Text="道士师傅" /> <TextBlock Width="120" Margin="0,1.5" Text="哈哈哈哈哈" />
<TextBlock Width="120" Margin="0,1.5" Text="狗群主群狗" /> <TextBlock Width="120" Margin="0,1.5" Text="江户川柯南" />
<TextBlock Width="120" Margin="0,1.5" Text="Alioth陳" /> <TextBlock Width="120" Margin="0,1.5" Text="loner..?" />
<TextBlock Width="120" Margin="0,1.5" Text="shyzysa" /> <TextBlock Width="120" Margin="0,1.5" Text="野比大豆" />
<TextBlock Width="120" Margin="0,1.5" Text="死んだライオン" /> <TextBlock Width="120" Margin="0,1.5" Text="无心之举" />
<TextBlock Width="120" Margin="0,1.5" Text="mc沙漠之狐隆帅" /> <TextBlock Width="120" Margin="0,1.5" Text="林禊" />
<TextBlock Width="120" Margin="0,1.5" Text="123456胡杨" /> <TextBlock Width="120" Margin="0,1.5" Text="??!" />
<TextBlock Width="120" Margin="0,1.5" Text="香蕉风味" /> <TextBlock Width="120" Margin="0,1.5" Text="Petrichor" />
<TextBlock Width="120" Margin="0,1.5" Text="毛哥" /> <TextBlock Width="120" Margin="0,1.5" Text="一只可爱的frisk啊" />
<TextBlock Width="120" Margin="0,1.5" Text="leon" /> <TextBlock Width="120" Margin="0,1.5" Text="luvFwt" />
<TextBlock Width="120" Margin="0,1.5" Text="clnb" /> <TextBlock Width="120" Margin="0,1.5" Text="厨师长" />
<TextBlock Width="120" Margin="0,1.5" Text="123" /> <TextBlock Width="120" Margin="0,1.5" Text="星輝月下゛" />
<TextBlock Width="120" Margin="0,1.5" Text="lihaoran0313" /> <TextBlock Width="120" Margin="0,1.5" Text="密早宪综籽" />
<TextBlock Width="120" Margin="0,1.5" Text="贵友" /> <TextBlock Width="120" Margin="0,1.5" Text="黑云月稀" />
<TextBlock Width="120" Margin="0,1.5" Text="蒸福啦" /> <TextBlock Width="120" Margin="0,1.5" Text="星月球" />
<TextBlock Width="120" Margin="0,1.5" Text="狐狸涩" /> <TextBlock Width="120" Margin="0,1.5" Text="ADerAQi" />
<TextBlock Width="120" Margin="0,1.5" Text="皓垣Faraway" /> <TextBlock Width="120" Margin="0,1.5" Text="van" />
<TextBlock Width="120" Margin="0,1.5" Text="冷月溪影" /> <TextBlock Width="120" Margin="0,1.5" Text="Eterfrusa" />
<TextBlock Width="120" Margin="0,1.5" Text="狮青椒" /> <TextBlock Width="120" Margin="0,1.5" Text="kpocc07" />
<TextBlock Width="120" Margin="0,1.5" Text="多金的爸爸" /> <TextBlock Width="120" Margin="0,1.5" Text="觉莫" />
<TextBlock Width="120" Margin="0,1.5" Text="陈师傅" /> <TextBlock Width="120" Margin="0,1.5" Text="我是DGHSFG" />
<TextBlock Width="120" Margin="0,1.5" Text="王舒心" /> <TextBlock Width="120" Margin="0,1.5" Text="lhw0616" />
<TextBlock Width="120" Margin="0,1.5" Text="Akn123" /> <TextBlock Width="120" Margin="0,1.5" Text="2DGIRL" />
<TextBlock Width="120" Margin="0,1.5" Text="Dfkeit" /> <TextBlock Width="120" Margin="0,1.5" Text="雨猫霖" />
<TextBlock Width="120" Margin="0,1.5" Text="CloudLonngLee" /> <TextBlock Width="120" Margin="0,1.5" Text="Grazie" />
<TextBlock Width="120" Margin="0,1.5" Text="别再错过月亮了" /> <TextBlock Width="120" Margin="0,1.5" Text="鲲鹏roc" />
<TextBlock Width="120" Margin="0,1.5" Text="特别周冠宇" /> <TextBlock Width="120" Margin="0,1.5" Text="皮皮苏" />
<TextBlock Width="120" Margin="0,1.5" Text="哆啦哆啦" />
<TextBlock Width="120" Margin="0,1.5" Text="serendipity" />
<TextBlock Width="120" Margin="0,1.5" Text="W-Qi" />
<TextBlock Width="120" Margin="0,1.5" Text="tenneidp" />
<TextBlock Width="120" Margin="0,1.5" Text="叢沄" />
<TextBlock Width="120" Margin="0,1.5" Text="jian_ke" />
<TextBlock Width="120" Margin="0,1.5" Text="ZHypocrite" />
<TextBlock Width="120" Margin="0,1.5" Text="浑荀" />
<TextBlock Width="120" Margin="0,1.5" Text="yoo-ovo" />
<TextBlock Width="120" Margin="0,1.5" Text="洛梓风anemo" />
<TextBlock Width="120" Margin="0,1.5" Text="胡桃的狗" />
<TextBlock Width="120" Margin="0,1.5" Text="落灯花" />
<TextBlock Width="120" Margin="0,1.5" Text="涩图来一份" />
<TextBlock Width="120" Margin="0,1.5" Text="FSAH217" />
<TextBlock Width="120" Margin="0,1.5" Text="炽绪" />
<TextBlock Width="120" Margin="0,1.5" Text="JUBEYsl" />
<TextBlock Width="120" Margin="0,1.5" Text="阿祺27" />
<TextBlock Width="120" Margin="0,1.5" Text="江上数峰青" />
<TextBlock Width="120" Margin="0,1.5" Text="ECHO" />
<TextBlock Width="120" Margin="0,1.5" Text="路易斯" />
<TextBlock Width="120" Margin="0,1.5" Text="别曹曹了" />
<TextBlock Width="120" Margin="0,1.5" Text="Szy" />
<TextBlock Width="120" Margin="0,1.5" Text="长安常安" />
<TextBlock Width="120" Margin="0,1.5" Text="鲨鲨" />
<TextBlock Width="120" Margin="0,1.5" Text="对白拼拼凑凑" />
<TextBlock Width="120" Margin="0,1.5" Text="月下吃米糖" />
<TextBlock Width="120" Margin="0,1.5" Text="小雨要" />
<TextBlock Width="120" Margin="0,1.5" Text="臻榛搸殝" /> <TextBlock Width="120" Margin="0,1.5" Text="臻榛搸殝" />
<TextBlock Width="120" Margin="0,1.5" Text="GT" /> <TextBlock Width="120" Margin="0,1.5" Text="王富贵" />
<TextBlock Width="120" Margin="0,1.5" Text="夜也" /> <TextBlock Width="120" Margin="0,1.5" Text="久久" />
<TextBlock Width="120" Margin="0,1.5" Text="is步行街" /> <TextBlock Width="120" Margin="0,1.5" Text="嗯哼?" />
<TextBlock Width="120" Margin="0,1.5" Text="狮心人面人" /> <TextBlock Width="120" Margin="0,1.5" Text="木沐" />
<TextBlock Width="120" Margin="0,1.5" Text="小刀李" /> <TextBlock Width="120" Margin="0,1.5" Text="永久里" />
<TextBlock Width="120" Margin="0,1.5" Text="空染" /> <TextBlock Width="120" Margin="0,1.5" Text="小白狐" />
<TextBlock Width="120" Margin="0,1.5" Text="歪歪的示波器" /> <TextBlock Width="120" Margin="0,1.5" Text="Z." />
<TextBlock Width="120" Margin="0,1.5" Text="SYF" /> <TextBlock Width="120" Margin="0,1.5" Text="芝惑鱼" />
<TextBlock Width="120" Margin="0,1.5" Text="帝王尬笑" /> <TextBlock Width="120" Margin="0,1.5" Text="MegnaAegwynn " />
<TextBlock Width="120" Margin="0,1.5" Text="DarkKCat" /> <TextBlock Width="120" Margin="0,1.5" Text="DJLD" />
<TextBlock Width="120" Margin="0,1.5" Text="我将如闪电般归来" /> <TextBlock Width="120" Margin="0,1.5" Text="曦月" />
<TextBlock Width="120" Margin="0,1.5" Text="TSLOLY" /> <TextBlock Width="120" Margin="0,1.5" Text="TylerDeng" />
<TextBlock Width="120" Margin="0,1.5" Text="JackX" /> <TextBlock Width="120" Margin="0,1.5" Text="1899年的提拉米苏" />
<TextBlock Width="120" Margin="0,1.5" Text="挽安" /> <TextBlock Width="120" Margin="0,1.5" Text="bzwm" />
<TextBlock Width="120" Margin="0,1.5" Text="花衔镜" /> <TextBlock Width="120" Margin="0,1.5" Text="GhaMZz" />
<TextBlock Width="120" Margin="0,1.5" Text="玄言" /> <TextBlock Width="120" Margin="0,1.5" Text="雪游" />
<TextBlock Width="120" Margin="0,1.5" Text="硫酸梅" /> <TextBlock Width="120" Margin="0,1.5" Text="奇怪的大土豆" />
<TextBlock Width="120" Margin="0,1.5" Text="ムーの小雨" /> <TextBlock Width="120" Margin="0,1.5" Text="Moonlight-池绾" />
<TextBlock Width="120" Margin="0,1.5" Text="潘某" /> <TextBlock Width="120" Margin="0,1.5" Text="fusocietyck" />
<TextBlock Width="120" Margin="0,1.5" Text="颐葭" /> <TextBlock Width="120" Margin="0,1.5" Text="爬爬鸡" />
<TextBlock Width="120" Margin="0,1.5" Text="Vaincre_VV" /> <TextBlock Width="120" Margin="0,1.5" Text="山千海千" />
<TextBlock Width="120" Margin="0,1.5" Text="小明爱睡觉" /> <TextBlock Width="120" Margin="0,1.5" Text="氿离Yoi" />
<TextBlock Width="120" Margin="0,1.5" Text="YHLin" /> <TextBlock Width="120" Margin="0,1.5" Text="如风沐烟" />
<TextBlock Width="120" Margin="0,1.5" Text="翁yy" /> <TextBlock Width="120" Margin="0,1.5" Text="一条博子" />
<TextBlock Width="120" Margin="0,1.5" Text="午睡不爱睡觉" /> <TextBlock Width="120" Margin="0,1.5" Text="m1679" />
<TextBlock Width="120" Margin="0,1.5" Text="tanglin" /> <TextBlock Width="120" Margin="0,1.5" Text="snow" />
<TextBlock Width="120" Margin="0,1.5" Text="Quittskii" /> <TextBlock Width="120" Margin="0,1.5" Text="3瓶奶茶" />
<TextBlock Width="120" Margin="0,1.5" Text="W2erty" /> <TextBlock Width="120" Margin="0,1.5" Text="Elkanah_" />
<TextBlock Width="120" Margin="0,1.5" Text="Chris_Dream" /> <TextBlock Width="120" Margin="0,1.5" Text="孤默少言" />
<TextBlock Width="120" Margin="0,1.5" Text="sanrenxin" /> <TextBlock Width="120" Margin="0,1.5" Text="也要拿出真本事" />
<TextBlock Width="120" Margin="0,1.5" Text="BBK" /> <TextBlock Width="120" Margin="0,1.5" Text="武彩鱼" />
<TextBlock Width="120" Margin="0,1.5" Text="京北的洋" /> <TextBlock Width="120" Margin="0,1.5" Text="雷霆兴哥" />
<TextBlock Width="120" Margin="0,1.5" Text="喵木仔" /> <TextBlock Width="120" Margin="0,1.5" Text="EnsoNani" />
<TextBlock Width="120" Margin="0,1.5" Text="abstudio" /> <TextBlock Width="120" Margin="0,1.5" Text="Ann.Midnight" />
<TextBlock Width="120" Margin="0,1.5" Text="洛惜惜缘" /> <TextBlock Width="120" Margin="0,1.5" Text="郁子恒是FW" />
<TextBlock Width="120" Margin="0,1.5" Text="熊心万花镜" /> <TextBlock Width="120" Margin="0,1.5" Text="ZIHE_kk" />
<TextBlock Width="120" Margin="0,1.5" Text="tianguaren" /> <TextBlock Width="120" Margin="0,1.5" Text="文八" />
<TextBlock Width="120" Margin="0,1.5" Text="bitlogi" /> <TextBlock Width="120" Margin="0,1.5" Text="寂月星落" />
<TextBlock Width="120" Margin="0,1.5" Text="彬彬爆" /> <TextBlock Width="120" Margin="0,1.5" Text="Writer_DaMao" />
<TextBlock Width="120" Margin="0,1.5" Text="超爱小辣椒" /> <TextBlock Width="120" Margin="0,1.5" Text="gwd233" />
<TextBlock Width="120" Margin="0,1.5" Text="Kkigoo" /> <TextBlock Width="120" Margin="0,1.5" Text="Sutvh" />
<TextBlock Width="120" Margin="0,1.5" Text="于书墨" /> <TextBlock Width="120" Margin="0,1.5" Text="崔东山" />
<TextBlock Width="120" Margin="0,1.5" Text="御坂1354号" /> <TextBlock Width="120" Margin="0,1.5" Text="Botaiii" />
<TextBlock Width="120" Margin="0,1.5" Text="t7fihb8" /> <TextBlock Width="120" Margin="0,1.5" Text="凛仙子D-" />
<TextBlock Width="120" Margin="0,1.5" Text="44.5GB" /> <TextBlock Width="120" Margin="0,1.5" Text="MooFaH" />
<TextBlock Width="120" Margin="0,1.5" Text="寰宇第一激推希儿" /> <TextBlock Width="120" Margin="0,1.5" Text="嘿哈吼" />
<TextBlock Width="120" Margin="0,1.5" Text="拳打羽酱脚踢军师" /> <TextBlock Width="120" Margin="0,1.5" Text="下山吃肉的兔子" />
<TextBlock Width="120" Margin="0,1.5" Text="戌亥ピカ" /> <TextBlock Width="120" Margin="0,1.5" Text="warship" />
<TextBlock Width="120" Margin="0,1.5" Text="乔巴诺" /> <TextBlock Width="120" Margin="0,1.5" Text="木落微雨" />
<TextBlock Width="120" Margin="0,1.5" Text="LING-DIAN" /> <TextBlock Width="120" Margin="0,1.5" Text="杨阳baby" />
<TextBlock Width="120" Margin="0,1.5" Text="你太迷人" /> <TextBlock Width="120" Margin="0,1.5" Text="白茶" />
<TextBlock Width="120" Margin="0,1.5" Text="夏目龙羽" /> <TextBlock Width="120" Margin="0,1.5" Text="路过一下的尘垒" />
<TextBlock Width="120" Margin="0,1.5" Text="小烨爱吃尖椒鸡" /> <TextBlock Width="120" Margin="0,1.5" Text="counterea" />
<TextBlock Width="120" Margin="0,1.5" Text="七色的魔法死" /> <TextBlock Width="120" Margin="0,1.5" Text="雨中盛开的花朵" />
<TextBlock Width="120" Margin="0,1.5" Text="沫世" /> <TextBlock Width="120" Margin="0,1.5" Text="珊瑚宫心海" />
<TextBlock Width="120" Margin="0,1.5" Text="我的神a啊" /> <TextBlock Width="120" Margin="0,1.5" Text="luner" />
<TextBlock Width="120" Margin="0,1.5" Text="转角" /> <TextBlock Width="120" Margin="0,1.5" Text="时崎王罪丶" />
<TextBlock Width="120" Margin="0,1.5" Text="做强做盛.步步升高" /> <TextBlock Width="120" Margin="0,1.5" Text="Nicht" />
<TextBlock Width="120" Margin="0,1.5" Text="火箭空降" /> <TextBlock Width="120" Margin="0,1.5" Text="冰薇" />
<TextBlock Width="120" Margin="0,1.5" Text="嚯嚯嚯哈哈哈哈" /> <TextBlock Width="120" Margin="0,1.5" Text="Archetto" />
<TextBlock Width="120" Margin="0,1.5" Text="醉梦" /> <TextBlock Width="120" Margin="0,1.5" Text="蓝冰之刃" />
<TextBlock Width="120" Margin="0,1.5" Text="zzyd" /> <TextBlock Width="120" Margin="0,1.5" Text="Baguette" />
<TextBlock Width="120" Margin="0,1.5" Text="御影" /> <TextBlock Width="120" Margin="0,1.5" Text="KenshenLove" />
<TextBlock Width="120" Margin="0,1.5" Text="Xephyrs" /> <TextBlock Width="120" Margin="0,1.5" Text="风见翎" />
<TextBlock Width="120" Margin="0,1.5" Text="Sovtheia" /> <TextBlock Width="120" Margin="0,1.5" Text="雷霆" />
<TextBlock Width="120" Margin="0,1.5" Text="CRANK" /> <TextBlock Width="120" Margin="0,1.5" Text="[擦汗]" />
<TextBlock Width="120" Margin="0,1.5" Text="本太子的作业满天飞" /> <TextBlock Width="120" Margin="0,1.5" Text="远东雪橇猫" />
<TextBlock Width="120" Margin="0,1.5" Text="超级无敌旋风小猪猪" /> <TextBlock Width="120" Margin="0,1.5" Text="安夏洛克" />
<TextBlock Width="120" Margin="0,1.5" Text="泽希尔·S+" /> <TextBlock Width="120" Margin="0,1.5" Text="acac" />
<TextBlock Width="120" Margin="0,1.5" Text="erliang_ya" /> <TextBlock Width="120" Margin="0,1.5" Text="瑞风" />
<TextBlock Width="120" Margin="0,1.5" Text="明酱酱" /> <TextBlock Width="120" Margin="0,1.5" Text="xiankeQAQ" />
<TextBlock Width="120" Margin="0,1.5" Text="玐煲粥" /> <TextBlock Width="120" Margin="0,1.5" Text="BDUCK" />
<TextBlock Width="120" Margin="0,1.5" Text="The_follow" /> <TextBlock Width="120" Margin="0,1.5" Text="fuaglove" />
<TextBlock Width="120" Margin="0,1.5" Text="王八" /> <TextBlock Width="120" Margin="0,1.5" Text="prprprrrpop" />
<TextBlock Width="120" Margin="0,1.5" Text="joker" /> <TextBlock Width="120" Margin="0,1.5" Text="YOCE" />
<TextBlock Width="120" Margin="0,1.5" Text="north-cool" /> <TextBlock Width="120" Margin="0,1.5" Text="忹." />
<TextBlock Width="120" Margin="0,1.5" Text="JJ" /> <TextBlock Width="120" Margin="0,1.5" Text="夜青" />
<TextBlock Width="120" Margin="0,1.5" Text="小石" /> <TextBlock Width="120" Margin="0,1.5" Text="橘糸侑You" />
<TextBlock Width="120" Margin="0,1.5" Text="XiaomQ928" /> <TextBlock Width="120" Margin="0,1.5" Text="薇克波顿" />
<TextBlock Width="120" Margin="0,1.5" Text="Fly with You!!" /> <TextBlock Width="120" Margin="0,1.5" Text="夂冬螽" />
<TextBlock Width="120" Margin="0,1.5" Text="海上乘鲸客" /> <TextBlock Width="120" Margin="0,1.5" Text="Colitary" />
<TextBlock Width="120" Margin="0,1.5" Text="miku" /> <TextBlock Width="120" Margin="0,1.5" Text="Harm_b10ck" />
<TextBlock Width="120" Margin="0,1.5" Text="小雯" /> <TextBlock Width="120" Margin="0,1.5" Text="乆月" />
<TextBlock Width="120" Margin="0,1.5" Text="woainad" /> <TextBlock Width="120" Margin="0,1.5" Text="Kaoukala" />
<TextBlock Width="120" Margin="0,1.5" Text="wqaycm" /> <TextBlock Width="120" Margin="0,1.5" Text="墨染★希" />
<TextBlock Width="120" Margin="0,1.5" Text="白豆" /> <TextBlock Width="120" Margin="0,1.5" Text="松菀" />
<TextBlock Width="120" Margin="0,1.5" Text="Alex" /> <TextBlock Width="120" Margin="0,1.5" Text="疾驰火车" />
<TextBlock Width="120" Margin="0,1.5" Text="大地风暴" /> <TextBlock Width="120" Margin="0,1.5" Text="疾影烬" />
<TextBlock Width="120" Margin="0,1.5" Text="曾and田某人" /> <TextBlock Width="120" Margin="0,1.5" Text="Awfrlu+" />
<TextBlock Width="120" Margin="0,1.5" Text="栀玖夕夏" /> <TextBlock Width="120" Margin="0,1.5" Text="Lava_drop_" />
<TextBlock Width="120" Margin="0,1.5" Text="小卌丯" /> <TextBlock Width="120" Margin="0,1.5" Text="? *???* ?" />
<TextBlock Width="120" Margin="0,1.5" Text="旧言" /> <TextBlock Width="120" Margin="0,1.5" Text="Gwynsur" />
<TextBlock Width="120" Margin="0,1.5" Text="?的不行 ?的难受" /> <TextBlock Width="120" Margin="0,1.5" Text="许淼淼" />
<TextBlock Width="120" Margin="0,1.5" Text="ElliottZChan" /> <TextBlock Width="120" Margin="0,1.5" Text="waneng0807" />
<TextBlock Width="120" Margin="0,1.5" Text="沐子冷落" /> <TextBlock Width="120" Margin="0,1.5" Text="安anLa" />
<TextBlock Width="120" Margin="0,1.5" Text="_Blessing" /> <TextBlock Width="120" Margin="0,1.5" Text="MQDCB" />
<TextBlock Width="120" Margin="0,1.5" Text="友酒歌" /> <TextBlock Width="120" Margin="0,1.5" Text="我dnmd" />
<TextBlock Width="120" Margin="0,1.5" Text="鲸以歌" /> <TextBlock Width="120" Margin="0,1.5" Text="猫舍旁边有恶犬" />
<TextBlock Width="120" Margin="0,1.5" Text="花好月圆" /> <TextBlock Width="120" Margin="0,1.5" Text="yk" />
<TextBlock Width="120" Margin="0,1.5" Text="n3v3r" /> <TextBlock Width="120" Margin="0,1.5" Text="Cik-z" />
<TextBlock Width="120" Margin="0,1.5" Text="七星灯" /> <TextBlock Width="120" Margin="0,1.5" Text="胡桃不是桃丫" />
<TextBlock Width="120" Margin="0,1.5" Text="Theia" /> <TextBlock Width="120" Margin="0,1.5" Text="陌白" />
<TextBlock Width="120" Margin="0,1.5" Text="C418" />
<TextBlock Width="120" Margin="0,1.5" Text="醉梦仙露" />
<TextBlock Width="240" Margin="0,1.5" Text="Re.从零开始跟猪鲨鲨恋爱" />
<TextBlock Width="120" Margin="0,1.5" Text="玄?" />
<TextBlock Width="120" Margin="0,1.5" Text="olwlm" />
<TextBlock Width="120" Margin="0,1.5" Text="XiaoLe_SH" />
<TextBlock Width="120" Margin="0,1.5" Text="龙大炮" />
<TextBlock Width="120" Margin="0,1.5" Text="陆阿藏" />
<TextBlock Width="120" Margin="0,1.5" Text="lo" />
<TextBlock Width="120" Margin="0,1.5" Text="七夜英理" />
<TextBlock Width="120" Margin="0,1.5" Text="lizi" />
<TextBlock Width="120" Margin="0,1.5" Text="范德Fa" />
<TextBlock Width="120" Margin="0,1.5" Text="云自无心" />
<TextBlock Width="120" Margin="0,1.5" Text="尚可" />
<TextBlock Width="120" Margin="0,1.5" Text="回转命运" />
<TextBlock Width="120" Margin="0,1.5" Text="恶搞的人格" />
<TextBlock Width="120" Margin="0,1.5" Text="安安生生" />
<TextBlock Width="120" Margin="0,1.5" Text="蛋仔派对-小冷" />
<TextBlock Width="120" Margin="0,1.5" Text="间铃" />
<TextBlock Width="120" Margin="0,1.5" Text="瀧柳" />
<TextBlock Width="120" Margin="0,1.5" Text="IRasciblebh" />
<TextBlock Width="120" Margin="0,1.5" Text="15183318101" />
<TextBlock Width="120" Margin="0,1.5" Text="LALALA" />
<TextBlock Width="120" Margin="0,1.5" Text="大香蕉" />
<TextBlock Width="120" Margin="0,1.5" Text="Another0" />
<TextBlock Width="120" Margin="0,1.5" Text="丢天帝" />
<TextBlock Width="120" Margin="0,1.5" Text="魔法喵酱" />
<TextBlock Width="120" Margin="0,1.5" Text="wshilaoliu" />
<TextBlock Width="120" Margin="0,1.5" Text="PangDaHusky" />
<TextBlock Width="120" Margin="0,1.5" Text="qi_lu" />
<TextBlock Width="120" Margin="0,1.5" Text="LetvGodyan" />
<TextBlock Width="120" Margin="0,1.5" Text="Amo" />
<TextBlock Width="120" Margin="0,1.5" Text="liang" />
<TextBlock Width="120" Margin="0,1.5" Text="baijillys" />
<TextBlock Width="120" Margin="0,1.5" Text="栗悟飯とカメハメ波" />
<TextBlock Width="120" Margin="0,1.5" Text="姜路扬" />
<TextBlock Width="120" Margin="0,1.5" Text="LuluPipi" />
<TextBlock Width="120" Margin="0,1.5" Text="Atuo" />
<TextBlock Width="120" Margin="0,1.5" Text="泳圈鼬用攀瀑" />
<TextBlock Width="120" Margin="0,1.5" Text="EWD" />
<TextBlock Width="120" Margin="0,1.5" Text="孟然君" />
<TextBlock Width="120" Margin="0,1.5" Text="num61" />
<TextBlock Width="120" Margin="0,1.5" Text="Elysia_mc" />
<TextBlock Width="120" Margin="0,1.5" Text="Wehrmacht" />
<TextBlock Width="120" Margin="0,1.5" Text="野生的小乐子" />
<TextBlock Width="120" Margin="0,1.5" Text="星韵林" />
<TextBlock Width="120" Margin="0,1.5" Text="剁椒鱼头" />
<TextBlock Width="120" Margin="0,1.5" Text="Jking" />
<TextBlock Width="240" Margin="0,1.5" Text="抖音搜索:清凉夏日一只瓜" />
<TextBlock Width="120" Margin="0,1.5" Text="HEARLEY" />
<TextBlock Width="120" Margin="0,1.5" Text="woaini_awa" />
<TextBlock Width="120" Margin="0,1.5" Text="龙天行" />
<TextBlock Width="120" Margin="0,1.5" Text="亦羽君" />
<TextBlock Width="120" Margin="0,1.5" Text="言十七" />
<TextBlock Width="120" Margin="0,1.5" Text="zzc" />
<TextBlock Width="120" Margin="0,1.5" Text="w?z?r?y" />
<TextBlock Width="120" Margin="0,1.5" Text="havoc" />
<TextBlock Width="120" Margin="0,1.5" Text="一条咸鱼" />
<TextBlock Width="120" Margin="0,1.5" Text="大鸡翅膀" />
<TextBlock Width="120" Margin="0,1.5" Text="月语" />
<TextBlock Width="120" Margin="0,1.5" Text="BBQ" />
<TextBlock Width="120" Margin="0,1.5" Text="糖糖" />
<TextBlock Width="120" Margin="0,1.5" Text="七月一" />
<TextBlock Width="120" Margin="0,1.5" Text="独角受" />
<TextBlock Width="120" Margin="0,1.5" Text="10000cituitui" />
<TextBlock Width="120" Margin="0,1.5" Text="Television" />
<TextBlock Width="120" Margin="0,1.5" Text="......" />
<TextBlock Width="120" Margin="0,1.5" Text="LONG11" />
<TextBlock Width="120" Margin="0,1.5" Text="OP仙人" />
<TextBlock Width="120" Margin="0,1.5" Text="陌音依矢—笠风" />
<TextBlock Width="120" Margin="0,1.5" Text="kinno_mc" />
<TextBlock Width="120" Margin="0,1.5" Text="Avid" />
<TextBlock Width="120" Margin="0,1.5" Text="brimobe" />
<TextBlock Width="120" Margin="0,1.5" Text="Momoki" />
<TextBlock Width="120" Margin="0,1.5" Text="徐小疯" />
<TextBlock Width="120" Margin="0,1.5" Text="我爱龙猫!!!" />
<TextBlock Width="120" Margin="0,1.5" Text="233" />
<TextBlock Width="120" Margin="0,1.5" Text="礼尚往来" />
<TextBlock Width="120" Margin="0,1.5" Text="会吐槽的毛熊" />
<TextBlock Width="120" Margin="0,1.5" Text="耶梦加得" />
<TextBlock Width="120" Margin="0,1.5" Text="pumpkin" />
<TextBlock Width="120" Margin="0,1.5" Text="Solaray3" />
<TextBlock Width="120" Margin="0,1.5" Text="m1a0w0" />
<TextBlock Width="120" Margin="0,1.5" Text="懿轩" />
<TextBlock Width="120" Margin="0,1.5" Text="圆圆xyz" />
<TextBlock Width="120" Margin="0,1.5" Text="EchoLong" />
<TextBlock Width="120" Margin="0,1.5" Text="光与影的对白" />
<TextBlock Width="120" Margin="0,1.5" Text="AptS:1547" />
<TextBlock Width="120" Margin="0,1.5" Text="中转站" />
<TextBlock Width="120" Margin="0,1.5" Text="情猫" />
<TextBlock Width="120" Margin="0,1.5" Text="胡桃Mahero" />
<TextBlock Width="120" Margin="0,1.5" Text="Ew_o" />
<TextBlock Width="120" Margin="0,1.5" Text="叽里呱啦" />
<TextBlock Width="120" Margin="0,1.5" Text="MHNIO" />
<TextBlock Width="120" Margin="0,1.5" Text="小洺" />
<TextBlock Width="120" Margin="0,1.5" Text="龙儿" />
<TextBlock Width="120" Margin="0,1.5" Text="ccll48" />
<TextBlock Width="120" Margin="0,1.5" Text="Ling7844" />
<TextBlock Width="120" Margin="0,1.5" Text="不会写网名的屑" />
<TextBlock Width="120" Margin="0,1.5" Text="Aresposeidon1124" />
<TextBlock Width="120" Margin="0,1.5" Text="钻石Daiyamondo" />
<TextBlock Width="120" Margin="0,1.5" Text="七月无风" />
<TextBlock Width="120" Margin="0,1.5" Text="YuTian" />
<TextBlock Width="120" Margin="0,1.5" Text="csleep" />
<TextBlock Width="120" Margin="0,1.5" Text="小天使" />
<TextBlock Width="120" Margin="0,1.5" Text="墨水" />
<TextBlock Width="120" Margin="0,1.5" Text="阿耀" />
<TextBlock Width="120" Margin="0,1.5" Text="青绵kipilu" />
<TextBlock Width="120" Margin="0,1.5" Text="IWI_Margarita" />
<TextBlock Width="120" Margin="0,1.5" Text="小林カンナ" />
<TextBlock Width="120" Margin="0,1.5" Text="TD-Clotys" />
<TextBlock Width="120" Margin="0,1.5" Text="哈先生" />
<TextBlock Width="120" Margin="0,1.5" Text="老潘" />
<TextBlock Width="120" Margin="0,1.5" Text="绝少" />
<TextBlock Width="120" Margin="0,1.5" Text="咸鱼汤鱼咸" />
<TextBlock Width="120" Margin="0,1.5" Text="Celery" />
<TextBlock Width="120" Margin="0,1.5" Text="简称FV" />
<TextBlock Width="120" Margin="0,1.5" Text="飞翔的PUMA" />
<TextBlock Width="120" Margin="0,1.5" Text="123456。?" />
<TextBlock Width="120" Margin="0,1.5" Text="heitong_shu" />
<TextBlock Width="120" Margin="0,1.5" Text="Lan" />
<TextBlock Width="120" Margin="0,1.5" Text="sanjuou" />
<TextBlock Width="120" Margin="0,1.5" Text="芙芙" />
<TextBlock Width="120" Margin="0,1.5" Text="zyc11230170" />
<TextBlock Width="120" Margin="0,1.5" Text="TOUHOULUO" />
<TextBlock Width="120" Margin="0,1.5" Text="在下雾切" />
<TextBlock Width="120" Margin="0,1.5" Text="exusiai2357" />
<TextBlock Width="120" Margin="0,1.5" Text="???" />
<TextBlock Width="120" Margin="0,1.5" Text="润煌Ricardo" />
<TextBlock Width="120" Margin="0,1.5" Text="无风" />
<TextBlock Width="120" Margin="0,1.5" Text="缘花乐" />
<TextBlock Width="120" Margin="0,1.5" Text="Willian" />
<TextBlock Width="120" Margin="0,1.5" Text="墨尘烟雨" />
<TextBlock Width="120" Margin="0,1.5" Text="加五九九五" />
<TextBlock Width="120" Margin="0,1.5" Text="白裘峪" />
<TextBlock Width="120" Margin="0,1.5" Text="加载中..." />
<TextBlock Width="120" Margin="0,1.5" Text="Стразар" />
<TextBlock Width="120" Margin="0,1.5" Text="夜语霖" />
<TextBlock Width="120" Margin="0,1.5" Text="Wolfgang_233" />
<TextBlock Width="120" Margin="0,1.5" Text="小螺浩" />
<TextBlock Width="120" Margin="0,1.5" Text="rtoe332" />
<TextBlock Width="120" Margin="0,1.5" Text="lliiooll" />
<TextBlock Width="120" Margin="0,1.5" Text="QFwushang" />
<TextBlock Width="120" Margin="0,1.5" Text="竹翼" />
<TextBlock Width="120" Margin="0,1.5" Text="没差" />
<TextBlock Width="120" Margin="0,1.5" Text="用户13223" />
<TextBlock Width="120" Margin="0,1.5" Text="猫羽喵" />
</WrapPanel> </WrapPanel>
<Grid Height="35"> <Grid Height="35">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -27,7 +27,7 @@
Public Shared Sub CopyUniqueAddress() Handles BtnDonateCopy.Click Public Shared Sub CopyUniqueAddress() Handles BtnDonateCopy.Click
ClipboardSet(UniqueAddress) ClipboardSet(UniqueAddress)
End Sub End Sub
Private Sub DonateCodeInput() Handles BtnDonateInput.Click Private Sub BtnDonateCodeInput_Click() Handles BtnDonateInput.Click
DonateCodeInput() DonateCodeInput()
End Sub End Sub
@@ -38,17 +38,21 @@
CardName = "常规版本" CardName = "常规版本"
Case McVersionCardType.API Case McVersionCardType.API
Dim IsForgeExists As Boolean = False Dim IsForgeExists As Boolean = False
Dim IsNeoForgeExists As Boolean = False
Dim IsFabricExists As Boolean = False Dim IsFabricExists As Boolean = False
Dim IsLiteExists As Boolean = False Dim IsLiteExists As Boolean = False
For Each Version As McVersion In Card.Value For Each Version As McVersion In Card.Value
If Version.Version.HasFabric Then IsFabricExists = True If Version.Version.HasFabric Then IsFabricExists = True
If Version.Version.HasLiteLoader Then IsLiteExists = True If Version.Version.HasLiteLoader Then IsLiteExists = True
If Version.Version.HasForge Then IsForgeExists = True If Version.Version.HasForge Then IsForgeExists = True
If Version.Version.HasNeoForge Then IsNeoForgeExists = True
Next Next
If If(IsLiteExists, 1, 0) + If(IsForgeExists, 1, 0) + If(IsFabricExists, 1, 0) > 1 Then If If(IsLiteExists, 1, 0) + If(IsForgeExists, 1, 0) + If(IsFabricExists, 1, 0) + If(IsNeoForgeExists, 1, 0) > 1 Then
CardName = "可安装 Mod" CardName = "可安装 Mod"
ElseIf IsForgeExists Then ElseIf IsForgeExists Then
CardName = "Forge 版本" CardName = "Forge 版本"
ElseIf IsNeoForgeExists Then
CardName = "NeoForge 版本"
ElseIf IsLiteExists Then ElseIf IsLiteExists Then
CardName = "LiteLoader 版本" CardName = "LiteLoader 版本"
Else Else
@@ -210,8 +214,8 @@
FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall) FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
End Sub End Sub
'修改此代码时,同时修改 PageVersionOverall 中的代码
Public Shared Sub DeleteVersion(Item As MyListItem, Version As McVersion) Public Shared Sub DeleteVersion(Item As MyListItem, Version As McVersion)
'修改此代码时,同时修改 PageVersionOverall 中的代码
Try Try
Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
Dim IsHintIndie As Boolean = Version.State <> McVersionState.Error AndAlso Version.PathIndie <> PathMcFolder Dim IsHintIndie As Boolean = Version.State <> McVersionState.Error AndAlso Version.PathIndie <> PathMcFolder
@@ -163,6 +163,7 @@
{"VersionAdvanceRunWait", New SetupEntry(True, Source:=SetupSource.Version)}, {"VersionAdvanceRunWait", New SetupEntry(True, Source:=SetupSource.Version)},
{"VersionRamType", New SetupEntry(2, Source:=SetupSource.Version)}, {"VersionRamType", New SetupEntry(2, Source:=SetupSource.Version)},
{"VersionRamCustom", New SetupEntry(15, Source:=SetupSource.Version)}, {"VersionRamCustom", New SetupEntry(15, Source:=SetupSource.Version)},
{"VersionRamOptimize", New SetupEntry(0, Source:=SetupSource.Version)},
{"VersionArgumentTitle", New SetupEntry("", Source:=SetupSource.Version)}, {"VersionArgumentTitle", New SetupEntry("", Source:=SetupSource.Version)},
{"VersionArgumentInfo", New SetupEntry("", Source:=SetupSource.Version)}, {"VersionArgumentInfo", New SetupEntry("", Source:=SetupSource.Version)},
{"VersionArgumentIndie", New SetupEntry(-1, Source:=SetupSource.Version)}, {"VersionArgumentIndie", New SetupEntry(-1, Source:=SetupSource.Version)},
@@ -206,10 +206,8 @@
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 1.5) / 0.5) + 12 SliderRamCustom.MaxValue = Math.Floor((RamTotal - 1.5) / 0.5) + 12
ElseIf RamTotal <= 16 Then ElseIf RamTotal <= 16 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 8) / 1) + 25 SliderRamCustom.MaxValue = Math.Floor((RamTotal - 8) / 1) + 25
ElseIf RamTotal <= 32 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 16) / 2) + 33
Else Else
SliderRamCustom.MaxValue = Math.Min(Math.Floor((RamTotal - 32) / 4) + 41, 49) SliderRamCustom.MaxValue = Math.Min(Math.Floor((RamTotal - 16) / 2) + 33, 41)
End If End If
'设置文本 '设置文本
LabRamGame.Text = If(RamGame = Math.Floor(RamGame), RamGame & ".0", RamGame) & " GB" & LabRamGame.Text = If(RamGame = Math.Floor(RamGame), RamGame & ".0", RamGame) & " GB" &
@@ -259,7 +257,6 @@
End If End If
If RamTextLeft <> Left Then If RamTextLeft <> Left Then
RamTextLeft = Left RamTextLeft = Left
'If AniControlEnabled = 0 Then
Select Case Left Select Case Left
Case 0 Case 0
AniStart({ AniStart({
@@ -280,22 +277,6 @@
AaOpacity(LabRamUsedTitle, 0.7 - LabRamUsedTitle.Opacity, 100) AaOpacity(LabRamUsedTitle, 0.7 - LabRamUsedTitle.Opacity, 100)
}, "SetupLaunch Ram TextLeft") }, "SetupLaunch Ram TextLeft")
End Select End Select
'Else
' Select Case Left
' Case 0
' LabRamUsed.Opacity = 0
' LabRamTotal.Opacity = 0
' LabRamUsedTitle.Opacity = 0
' Case 1
' LabRamUsed.Opacity = 1
' LabRamTotal.Opacity = 0
' LabRamUsedTitle.Opacity = 0.7
' Case 2
' LabRamUsed.Opacity = 1
' LabRamTotal.Opacity = 1
' LabRamUsedTitle.Opacity = 0.7
' End Select
'End If
End If End If
'右侧 '右侧
Dim Right As Integer Dim Right As Integer
@@ -404,15 +385,14 @@ PreFin:
RamGive = (Value - 12) * 0.5 + 1.5 RamGive = (Value - 12) * 0.5 + 1.5
ElseIf Value <= 33 Then ElseIf Value <= 33 Then
RamGive = (Value - 25) * 1 + 8 RamGive = (Value - 25) * 1 + 8
ElseIf Value <= 41 Then
RamGive = (Value - 33) * 2 + 16
Else Else
RamGive = (Value - 41) * 4 + 32 RamGive = (Value - 33) * 2 + 16
End If End If
End If End If
'若使用 32 位 Java,则限制为 1G '若使用 32 位 Java,则限制为 1G
If If(Is32BitJava, Not JavaIs64Bit(If(UseVersionJavaSetup, Version, Nothing))) Then RamGive = Math.Min(1, RamGive) If If(Is32BitJava, Not JavaIs64Bit(If(UseVersionJavaSetup, Version, Nothing))) Then RamGive = Math.Min(1, RamGive)
Return RamGive '封顶 32G
Return Math.Min(32, RamGive)
End Function End Function
#End Region #End Region
@@ -557,8 +537,8 @@ PreFin:
Private Sub CheckArgumentRam_Change() Handles CheckArgumentRam.Change Private Sub CheckArgumentRam_Change() Handles CheckArgumentRam.Change
If AniControlEnabled <> 0 Then Exit Sub If AniControlEnabled <> 0 Then Exit Sub
If Not CheckArgumentRam.Checked Then Return If Not CheckArgumentRam.Checked Then Return
If MyMsgBox("内存优化耗时较长,这会拖慢游戏的启动过程,建议仅在电脑内存不充裕时开启此选项。" & vbCrLf & If MyMsgBox("内存优化会显著延长启动耗时,建议仅在内存不足时开启。" & vbCrLf &
"如果你在使用机械硬盘,这还可能会导致一小段时间的严重卡顿。" & "如果你在使用机械硬盘,这还可能导致一小段时间的严重卡顿。" &
If(IsAdmin(), "", $"{vbCrLf}{vbCrLf}每次启动游戏,PCL 都需要申请管理员权限以进行内存优化。{vbCrLf}若想自动授予权限,可以右键 PCL,打开 属性 → 兼容性 → 以管理员身份运行此程序。"), If(IsAdmin(), "", $"{vbCrLf}{vbCrLf}每次启动游戏,PCL 都需要申请管理员权限以进行内存优化。{vbCrLf}若想自动授予权限,可以右键 PCL,打开 属性 → 兼容性 → 以管理员身份运行此程序。"),
"提醒", "确定", "取消") = 2 Then "提醒", "确定", "取消") = 2 Then
CheckArgumentRam.Checked = False CheckArgumentRam.Checked = False
@@ -41,8 +41,8 @@
'设置解锁 '设置解锁
If Not RadioLauncherTheme8.IsEnabled Then LabLauncherTheme8Copy.ToolTip = "累积赞助达到 ¥23.33 后,在爱发电私信发送【解锁码】以解锁。" & vbCrLf & "右键打开赞助页面,如果觉得 PCL 做得还不错就支持一下吧 =w=!" If Not RadioLauncherTheme8.IsEnabled Then LabLauncherTheme8Copy.ToolTip = "累积赞助达到 ¥23.33 后,在爱发电私信发送【解锁码】以解锁。" & vbCrLf & "右键打开赞助页面,如果觉得 PCL 做得还不错就支持一下吧 =w=!"
RadioLauncherTheme8.ToolTip = "累积赞助达到 ¥23.33 后,在爱发电私信发送【解锁码】以解锁" RadioLauncherTheme8.ToolTip = "累积赞助达到 ¥23.33 后,在爱发电私信发送【解锁码】以解锁"
If Not RadioLauncherTheme9.IsEnabled Then LabLauncherTheme9Copy.ToolTip = "· 反馈一个 Bug,在 Issue 标记为 [已完成] 后回复 Issue 要求解锁(右键打开反馈页面)" & vbCrLf & "· 向帮助库提交 Pull Request,在龙猫合并后解锁" If Not RadioLauncherTheme9.IsEnabled Then LabLauncherTheme9Copy.ToolTip = "· 反馈一个 Bug,在标记为 [完成] 后回复识别码要求解锁(右键打开反馈页面)" & vbCrLf & "· 提交一个 Pull Request,在合并后回复识别码要求解锁"
RadioLauncherTheme9.ToolTip = "· 反馈一个 Bug,在反馈标记为 [完成] 后回复 Issue 要求解锁" & vbCrLf & "· 向帮助库提交 Pull Request,在龙猫合并后解锁" RadioLauncherTheme9.ToolTip = "· 反馈一个 Bug,在标记为 [完成] 后回复识别码要求解锁" & vbCrLf & "· 提交一个 Pull Request,在合并后回复识别码要求解锁"
'极客蓝的处理在 ThemeCheck 中 '极客蓝的处理在 ThemeCheck 中
End Sub End Sub
@@ -83,7 +83,11 @@
MusicRefreshUI() MusicRefreshUI()
'主页 '主页
ComboCustomPreset.SelectedIndex = Setup.Get("UiCustomPreset") Try
ComboCustomPreset.SelectedIndex = Setup.Get("UiCustomPreset")
Catch
Setup.Reset("UiCustomPreset")
End Try
CType(FindName("RadioCustomType" & Setup.Load("UiCustomType")), MyRadioBox).Checked = True CType(FindName("RadioCustomType" & Setup.Load("UiCustomType")), MyRadioBox).Checked = True
TextCustomNet.Text = Setup.Get("UiCustomNet") TextCustomNet.Text = Setup.Get("UiCustomNet")
@@ -360,27 +364,28 @@ Refresh:
End Sub End Sub
Private Sub BtnMusicClear_Click(sender As Object, e As EventArgs) Handles BtnMusicClear.Click Private Sub BtnMusicClear_Click(sender As Object, e As EventArgs) Handles BtnMusicClear.Click
If MyMsgBox("即将删除背景音乐文件夹中的所有文件。" & vbCrLf & "此操作不可撤销,是否确定?", "警告",, "取消", IsWarn:=True) = 1 Then If MyMsgBox("即将删除背景音乐文件夹中的所有文件。" & vbCrLf & "此操作不可撤销,是否确定?", "警告",, "取消", IsWarn:=True) = 1 Then
RunInThread(Sub() RunInThread(
Hint("正在删除背景音乐……") Sub()
'停止播放音乐 Hint("正在删除背景音乐……")
MusicNAudio = Nothing '停止播放音乐
MusicWaitingList = New List(Of String) MusicNAudio = Nothing
MusicAllList = New List(Of String) MusicWaitingList = New List(Of String)
Thread.Sleep(200) MusicAllList = New List(Of String)
'删除文件 Thread.Sleep(200)
Try '删除文件
DeleteDirectory(Path & "PCL\Musics") Try
Hint("背景音乐已删除!", HintType.Finish) DeleteDirectory(Path & "PCL\Musics")
Catch ex As Exception Hint("背景音乐已删除!", HintType.Finish)
Log(ex, "删除背景音乐失败", LogLevel.Msgbox) Catch ex As Exception
End Try Log(ex, "删除背景音乐失败", LogLevel.Msgbox)
Try End Try
Directory.CreateDirectory(Path & "PCL\Musics") Try
RunInUi(Sub() MusicRefreshPlay(False)) Directory.CreateDirectory(Path & "PCL\Musics")
Catch ex As Exception RunInUi(Sub() MusicRefreshPlay(False))
Log(ex, "重建背景音乐文件夹失败", LogLevel.Msgbox) Catch ex As Exception
End Try Log(ex, "重建背景音乐文件夹失败", LogLevel.Msgbox)
End Sub) End Try
End Sub)
End If End If
End Sub End Sub
Private Sub CheckMusicStart_Change() Handles CheckMusicStart.Change Private Sub CheckMusicStart_Change() Handles CheckMusicStart.Change
@@ -423,9 +428,9 @@ Refresh:
RadioLauncherTheme5Gray.Opacity -= 0.23 RadioLauncherTheme5Gray.Opacity -= 0.23
RadioLauncherTheme5.Opacity += 0.23 RadioLauncherTheme5.Opacity += 0.23
AniStart({ AniStart({
AaOpacity(RadioLauncherTheme5Gray, 1, 1000), AaOpacity(RadioLauncherTheme5Gray, 1, 1000),
AaOpacity(RadioLauncherTheme5, -1, 1000) AaOpacity(RadioLauncherTheme5, -1, 1000)
}, "ThemeUnlock") }, "ThemeUnlock")
If RadioLauncherTheme5Gray.Opacity < 0.08 Then If RadioLauncherTheme5Gray.Opacity < 0.08 Then
ThemeUnlock(5, UnlockHint:="隐藏主题 玄素黑 已解锁!") ThemeUnlock(5, UnlockHint:="隐藏主题 玄素黑 已解锁!")
AniStop("ThemeUnlock") AniStop("ThemeUnlock")
@@ -433,7 +438,7 @@ Refresh:
End If End If
End Sub End Sub
Private Sub LabLauncherTheme11Click_MouseLeftButtonUp() Handles LabLauncherTheme11Click.MouseLeftButtonUp, RadioLauncherTheme11.MouseRightButtonUp Private Sub LabLauncherTheme11Click_MouseLeftButtonUp() Handles LabLauncherTheme11Click.MouseLeftButtonUp, RadioLauncherTheme11.MouseRightButtonUp
If LabLauncherTheme11Click.Visibility = Visibility.Collapsed OrElse LabLauncherTheme11Click.ToolTip.ToString.Contains("点击") Then If LabLauncherTheme11Click.Visibility = Visibility.Collapsed OrElse If(LabLauncherTheme11Click.ToolTip, "").ToString.Contains("点击") Then
If MyMsgBox( If MyMsgBox(
"1. 不爬取或攻击相关服务或网站,不盗取相关账号,没有谜题可以或需要以此来解决。" & vbCrLf & "1. 不爬取或攻击相关服务或网站,不盗取相关账号,没有谜题可以或需要以此来解决。" & vbCrLf &
"2. 不得篡改或损毁相关公开信息,请尽量让它们保持原状。" & vbCrLf & "2. 不得篡改或损毁相关公开信息,请尽量让它们保持原状。" & vbCrLf &
@@ -664,18 +669,10 @@ Refresh:
'滑动条 '滑动条
Private Sub SliderLoad() Private Sub SliderLoad()
SliderMusicVolume.GetHintText = Function(Value As Integer) SliderMusicVolume.GetHintText = Function(v) Math.Ceiling(v * 0.1) & "%"
Return Math.Ceiling(Value * 0.1) & "%" SliderLauncherOpacity.GetHintText = Function(v) Math.Round(40 + v * 0.1) & "%"
End Function SliderLauncherHue.GetHintText = Function(v) v & "°"
SliderLauncherOpacity.GetHintText = Function(Value As Integer) SliderLauncherSat.GetHintText = Function(v) v & "%"
Return Math.Round(40 + Value * 0.1) & "%"
End Function
SliderLauncherHue.GetHintText = Function(Value As Integer)
Return Value & "°"
End Function
SliderLauncherSat.GetHintText = Function(Value As Integer)
Return Value & "%"
End Function
SliderLauncherDelta.GetHintText = Function(Value As Integer) SliderLauncherDelta.GetHintText = Function(Value As Integer)
If Value > 90 Then If Value > 90 Then
Return "+" & (Value - 90) Return "+" & (Value - 90)
@@ -694,12 +691,8 @@ Refresh:
Return Value - 20 Return Value - 20
End If End If
End Function End Function
SliderBackgroundOpacity.GetHintText = Function(Value As Integer) SliderBackgroundOpacity.GetHintText = Function(v) Math.Round(v * 0.1) & "%"
Return Math.Round(Value * 0.1) & "%" SliderBackgroundBlur.GetHintText = Function(v) v & " 像素"
End Function
SliderBackgroundBlur.GetHintText = Function(Value As Integer)
Return Value & " 像素"
End Function
End Sub End Sub
End Class End Class
@@ -607,8 +607,10 @@
If ModEntry.Comp IsNot Nothing Then If ModEntry.Comp IsNot Nothing Then
'跳转到 Mod 下载页面 '跳转到 Mod 下载页面
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.CompDetail, FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.CompDetail,
.Additional = {ModEntry.Comp, New List(Of String), PageVersionLeft.Version.Version.McName, .Additional = {ModEntry.Comp, New List(Of String), PageVersionLeft.Version.Version.McName,
If(PageVersionLeft.Version.Version.HasForge, CompModLoaderType.Forge, If(PageVersionLeft.Version.Version.HasFabric, CompModLoaderType.Fabric, CompModLoaderType.Any))}}) If(PageVersionLeft.Version.Version.HasForge, CompModLoaderType.Forge,
If(PageVersionLeft.Version.Version.HasNeoForge, CompModLoaderType.NeoForge,
If(PageVersionLeft.Version.Version.HasFabric, CompModLoaderType.Fabric, CompModLoaderType.Any)))}})
Else Else
'获取信息 '获取信息
Dim ContentLines As New List(Of String) Dim ContentLines As New List(Of String)
@@ -22,7 +22,7 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="4" Margin="0,0,0,9" HorizontalAlignment="Center" Text="该版本不可使用 Mod" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" /> <TextBlock Grid.Row="0" Grid.ColumnSpan="4" Margin="0,0,0,9" HorizontalAlignment="Center" Text="该版本不可使用 Mod" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle Grid.Row="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" /> <Rectangle Grid.Row="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="2" Grid.ColumnSpan="4" Margin="10,15,10,5" Text="你需要先安装 Forge 或 Fabric 等 Mod 加载器才能使用 Mod,请在下载页面重新安装这些版本。&#xa;如果你已经安装过了 Mod 加载器,那么你很可能选择了错误的版本,请点击版本选择按钮切换版本,并注意 Forge 在版本选择列表中的图标为铁砧,Fabric 的图标为丝绸。" TextWrapping="Wrap" /> <TextBlock Grid.Row="2" Grid.ColumnSpan="4" Margin="10,15,10,5" Text="你需要先安装 Forge、Fabric 等 Mod 加载器才能使用 Mod,请在下载页面安装这些版本。&#xa;如果你已经安装过了 Mod 加载器,那么你很可能选择了错误的版本,请点击版本选择按钮切换版本。" TextWrapping="Wrap" />
<local:MyButton Grid.Row="3" Grid.Column="1" Height="35" HorizontalAlignment="Center" x:Name="BtnDownload" MinWidth="140" Text="转到下载页面" Margin="10,10,10,0" Padding="13,0" ColorType="Highlight" /> <local:MyButton Grid.Row="3" Grid.Column="1" Height="35" HorizontalAlignment="Center" x:Name="BtnDownload" MinWidth="140" Text="转到下载页面" Margin="10,10,10,0" Padding="13,0" ColorType="Highlight" />
<local:MyButton Grid.Row="3" Grid.Column="2" Height="35" HorizontalAlignment="Center" x:Name="BtnVersion" MinWidth="140" Text="版本选择" Margin="10,10,10,0" Padding="13,0" /> <local:MyButton Grid.Row="3" Grid.Column="2" Height="35" HorizontalAlignment="Center" x:Name="BtnVersion" MinWidth="140" Text="版本选择" Margin="10,10,10,0" Padding="13,0" />
</Grid> </Grid>
@@ -37,6 +37,7 @@
<local:MyComboBoxItem Content="红石灯(关)" Tag="pack://application:,,,/images/Blocks/RedstoneLampOff.png" /> <local:MyComboBoxItem Content="红石灯(关)" Tag="pack://application:,,,/images/Blocks/RedstoneLampOff.png" />
<local:MyComboBoxItem Content="鸡蛋" Tag="pack://application:,,,/images/Blocks/Egg.png" /> <local:MyComboBoxItem Content="鸡蛋" Tag="pack://application:,,,/images/Blocks/Egg.png" />
<local:MyComboBoxItem Content="布料(Fabric)" Tag="pack://application:,,,/images/Blocks/Fabric.png" /> <local:MyComboBoxItem Content="布料(Fabric)" Tag="pack://application:,,,/images/Blocks/Fabric.png" />
<local:MyComboBoxItem Content="狐狸(NeoForge)" Tag="pack://application:,,,/images/Blocks/NeoForge.png" />
</local:MyComboBox> </local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="分类" Margin="0,0,25,0" /> <TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="分类" Margin="0,0,25,0" />
<local:MyComboBox Grid.Column="1" Grid.Row="2" x:Name="ComboDisplayType"> <local:MyComboBox Grid.Column="1" Grid.Row="2" x:Name="ComboDisplayType">
@@ -127,6 +127,8 @@
'重命名主文件夹 '重命名主文件夹
My.Computer.FileSystem.RenameDirectory(OldPath, TempName) My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
My.Computer.FileSystem.RenameDirectory(TempPath, NewName) My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
'清理 ini 缓存
IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
'遍历重命名所有文件与文件夹 '遍历重命名所有文件与文件夹
For Each Entry As DirectoryInfo In New DirectoryInfo(NewPath).EnumerateDirectories For Each Entry As DirectoryInfo In New DirectoryInfo(NewPath).EnumerateDirectories
If Not Entry.Name.Contains(OldName) Then Continue For If Not Entry.Name.Contains(OldName) Then Continue For
@@ -292,16 +294,17 @@
End SyncLock End SyncLock
'启动 '启动
Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload, False)) Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload, False))
Loader.OnStateChanged = Sub() Loader.OnStateChanged =
Select Case Loader.State Sub()
Case LoadState.Finished Select Case Loader.State
Hint(Loader.Name & "成功!", HintType.Finish) Case LoadState.Finished
Case LoadState.Failed Hint(Loader.Name & "成功!", HintType.Finish)
Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical) Case LoadState.Failed
Case LoadState.Aborted Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
Hint(Loader.Name & "已取消!", HintType.Info) Case LoadState.Aborted
End Select Hint(Loader.Name & "已取消!", HintType.Info)
End Sub End Select
End Sub
Loader.Start(PageVersionLeft.Version.Name) Loader.Start(PageVersionLeft.Version.Name)
LoaderTaskbarAdd(Loader) LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh() FrmMain.BtnExtraDownload.ShowRefresh()
@@ -312,8 +315,8 @@
End Sub End Sub
'删除版本 '删除版本
'修改此代码时,同时修改 PageSelectRight 中的代码
Private Sub BtnManageDelete_Click(sender As Object, e As EventArgs) Handles BtnManageDelete.Click Private Sub BtnManageDelete_Click(sender As Object, e As EventArgs) Handles BtnManageDelete.Click
'修改此代码时,同时修改 PageSelectRight 中的代码
Try Try
Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
Dim IsHintIndie As Boolean = PageVersionLeft.Version.State <> McVersionState.Error AndAlso PageVersionLeft.Version.PathIndie <> PathMcFolder Dim IsHintIndie As Boolean = PageVersionLeft.Version.State <> McVersionState.Error AndAlso PageVersionLeft.Version.PathIndie <> PathMcFolder
@@ -321,6 +324,7 @@
If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""), If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
"版本删除确认", , "取消",, IsHintIndie OrElse IsShiftPressed) "版本删除确认", , "取消",, IsHintIndie OrElse IsShiftPressed)
Case 1 Case 1
IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
If IsShiftPressed Then If IsShiftPressed Then
DeleteDirectory(PageVersionLeft.Version.Path) DeleteDirectory(PageVersionLeft.Version.Path)
Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish) Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish)
@@ -77,6 +77,22 @@
<local:MySlider Grid.Row="3" Grid.Column="1" IsEnabled="False" x:Name="SliderRamCustom" Tag="VersionRamCustom" MaxValue="49" Value="13" /> <local:MySlider Grid.Row="3" Grid.Column="1" IsEnabled="False" x:Name="SliderRamCustom" Tag="VersionRamCustom" MaxValue="49" Value="13" />
<!--<local:MyTextBox Grid.Row="2" Grid.Column="3" Width="100" VerticalAlignment="Center" Margin="30,0,0,0" Text="2048 MB" />--> <!--<local:MyTextBox Grid.Row="2" Grid.Column="3" Width="100" VerticalAlignment="Center" Margin="30,0,0,0" Text="2048 MB" />-->
</Grid> </Grid>
<Grid Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock Margin="0,6,30,0" Text="启动游戏前进行内存优化" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" />
<local:MyComboBox x:Name="ComboRamOptimize" Margin="10,0,0,0" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="2" Tag="VersionRamOptimize">
<local:MyComboBoxItem Content="使用全局设置" IsSelected="True" />
<local:MyComboBoxItem Content="开启" />
<local:MyComboBoxItem Content="关闭" />
</local:MyComboBox>
</Grid>
<Grid x:Name="PanRamDisplay" Margin="0,11,2,0" SnapsToDevicePixels="True" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="1"> <Grid x:Name="PanRamDisplay" Margin="0,11,2,0" SnapsToDevicePixels="True" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="1">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnRamUsed" Width="4.7*"/> <ColumnDefinition x:Name="ColumnRamUsed" Width="4.7*"/>
@@ -51,6 +51,7 @@
'游戏内存 '游戏内存
CType(FindName("RadioRamType" & Setup.Load("VersionRamType", Version:=PageVersionLeft.Version)), MyRadioBox).Checked = True CType(FindName("RadioRamType" & Setup.Load("VersionRamType", Version:=PageVersionLeft.Version)), MyRadioBox).Checked = True
SliderRamCustom.Value = Setup.Get("VersionRamCustom", Version:=PageVersionLeft.Version) SliderRamCustom.Value = Setup.Get("VersionRamCustom", Version:=PageVersionLeft.Version)
ComboRamOptimize.SelectedIndex = Setup.Get("VersionRamOptimize", Version:=PageVersionLeft.Version)
'服务器 '服务器
TextServerEnter.Text = Setup.Get("VersionServerEnter", Version:=PageVersionLeft.Version) TextServerEnter.Text = Setup.Get("VersionServerEnter", Version:=PageVersionLeft.Version)
@@ -95,6 +96,7 @@
Setup.Set("VersionArgumentIndie", 0, Version:=PageVersionLeft.Version) Setup.Set("VersionArgumentIndie", 0, Version:=PageVersionLeft.Version)
Setup.Reset("VersionRamType", Version:=PageVersionLeft.Version) Setup.Reset("VersionRamType", Version:=PageVersionLeft.Version)
Setup.Reset("VersionRamCustom", Version:=PageVersionLeft.Version) Setup.Reset("VersionRamCustom", Version:=PageVersionLeft.Version)
Setup.Reset("VersionRamOptimize", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceJvm", Version:=PageVersionLeft.Version) Setup.Reset("VersionAdvanceJvm", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceGame", Version:=PageVersionLeft.Version) Setup.Reset("VersionAdvanceGame", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceAssets", Version:=PageVersionLeft.Version) Setup.Reset("VersionAdvanceAssets", Version:=PageVersionLeft.Version)
@@ -130,7 +132,7 @@
Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderRamCustom.Change Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderRamCustom.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value, Version:=PageVersionLeft.Version) If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value, Version:=PageVersionLeft.Version)
End Sub End Sub
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboArgumentIndie.SelectionChanged Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboArgumentIndie.SelectionChanged, ComboRamOptimize.SelectionChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex, Version:=PageVersionLeft.Version) If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex, Version:=PageVersionLeft.Version)
End Sub End Sub
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckAdvanceRunWait.Change, CheckAdvanceAssetsV2.Change, CheckAdvanceJava.Change Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckAdvanceRunWait.Change, CheckAdvanceAssetsV2.Change, CheckAdvanceJava.Change
@@ -163,10 +165,8 @@
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 1.5) / 0.5) + 12 SliderRamCustom.MaxValue = Math.Floor((RamTotal - 1.5) / 0.5) + 12
ElseIf RamTotal <= 16 Then ElseIf RamTotal <= 16 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 8) / 1) + 25 SliderRamCustom.MaxValue = Math.Floor((RamTotal - 8) / 1) + 25
ElseIf RamTotal <= 32 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 16) / 2) + 33
Else Else
SliderRamCustom.MaxValue = Math.Min(Math.Floor((RamTotal - 32) / 4) + 41, 49) SliderRamCustom.MaxValue = Math.Min(Math.Floor((RamTotal - 16) / 2) + 33, 41)
End If End If
'设置文本 '设置文本
LabRamGame.Text = If(RamGame = Math.Floor(RamGame), RamGame & ".0", RamGame) & " GB" & LabRamGame.Text = If(RamGame = Math.Floor(RamGame), RamGame & ".0", RamGame) & " GB" &
@@ -351,15 +351,14 @@ PreFin:
RamGive = (Value - 12) * 0.5 + 1.5 RamGive = (Value - 12) * 0.5 + 1.5
ElseIf Value <= 33 Then ElseIf Value <= 33 Then
RamGive = (Value - 25) * 1 + 8 RamGive = (Value - 25) * 1 + 8
ElseIf Value <= 41 Then
RamGive = (Value - 33) * 2 + 16
Else Else
RamGive = (Value - 41) * 4 + 32 RamGive = (Value - 33) * 2 + 16
End If End If
End If End If
'若使用 32 位 Java,则限制为 1G '若使用 32 位 Java,则限制为 1G
If If(Is32BitJava, Not JavaIs64Bit(PageVersionLeft.Version)) Then RamGive = Math.Min(1, RamGive) If If(Is32BitJava, Not JavaIs64Bit(PageVersionLeft.Version)) Then RamGive = Math.Min(1, RamGive)
Return RamGive '封顶 32G
Return Math.Min(32, RamGive)
End Function End Function
#End Region #End Region
@@ -38,7 +38,7 @@
<DefineDebug>false</DefineDebug> <DefineDebug>false</DefineDebug>
<DefineTrace>false</DefineTrace> <DefineTrace>false</DefineTrace>
<IncrementalBuild>true</IncrementalBuild> <IncrementalBuild>true</IncrementalBuild>
<OutputPath>D:\Minecraft\程序\</OutputPath> <OutputPath>.\bin\</OutputPath>
<DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile> <DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile>
<NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314</NoWarn> <NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314</NoWarn>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
@@ -55,7 +55,7 @@
<DefineTrace>false</DefineTrace> <DefineTrace>false</DefineTrace>
<IncrementalBuild>false</IncrementalBuild> <IncrementalBuild>false</IncrementalBuild>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>D:\Minecraft\程序\</OutputPath> <OutputPath>.\bin\</OutputPath>
<DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile> <DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile>
<NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314</NoWarn> <NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314</NoWarn>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
@@ -100,7 +100,7 @@
<SignManifests>false</SignManifests> <SignManifests>false</SignManifests>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Snapshot|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Snapshot|AnyCPU'">
<OutputPath>D:\Minecraft\程序\</OutputPath> <OutputPath>.\bin\</OutputPath>
<DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile> <DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<WarningLevel>1</WarningLevel> <WarningLevel>1</WarningLevel>
@@ -111,7 +111,7 @@
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'BETA|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'BETA|AnyCPU'">
<OutputPath>D:\Minecraft\程序\</OutputPath> <OutputPath>.\bin\</OutputPath>
<DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile> <DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<WarningLevel>1</WarningLevel> <WarningLevel>1</WarningLevel>
@@ -129,7 +129,7 @@
</AssemblyOriginatorKeyFile> </AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseUpdate|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseUpdate|AnyCPU'">
<OutputPath>D:\Minecraft\程序\</OutputPath> <OutputPath>.\bin\</OutputPath>
<DefineConstants>RELEASE,BY_UPDATE</DefineConstants> <DefineConstants>RELEASE,BY_UPDATE</DefineConstants>
<DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile> <DocumentationFile>Plain Craft Launcher 2.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
@@ -244,6 +244,9 @@
<Compile Include="Pages\PageDownload\PageDownloadCompDetail.xaml.vb"> <Compile Include="Pages\PageDownload\PageDownloadCompDetail.xaml.vb">
<DependentUpon>PageDownloadCompDetail.xaml</DependentUpon> <DependentUpon>PageDownloadCompDetail.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Pages\PageDownload\PageDownloadNeoForge.xaml.vb">
<DependentUpon>PageDownloadNeoForge.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\PageDownload\PageDownloadPack.xaml.vb"> <Compile Include="Pages\PageDownload\PageDownloadPack.xaml.vb">
<DependentUpon>PageDownloadPack.xaml</DependentUpon> <DependentUpon>PageDownloadPack.xaml</DependentUpon>
</Compile> </Compile>
@@ -497,6 +500,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Pages\PageDownload\PageDownloadNeoForge.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\PageDownload\PageDownloadPack.xaml"> <Page Include="Pages\PageDownload\PageDownloadPack.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@@ -925,6 +932,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<Resource Include="Images\Blocks\NeoForge.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project> </Project>
+20 -14
View File
@@ -79,7 +79,11 @@
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
Text="在 EventData 后面添加一条竖线(|),竖线后填写服务器 IP,即可在启动该版本的同时自动进入服务器。" /> Text="在 EventData 后面添加一条竖线(|),竖线后填写服务器 IP,即可在启动该版本的同时自动进入服务器。" />
<local:MyButton Margin="0,4,0,0" Width="250" Height="35" <local:MyButton Margin="0,4,0,0" Width="250" Height="35"
Text="启动 1.12.2 并进入 Hypixel" EventType="启动游戏" EventData="1.12.2|mc.hypixel.net" ToolTip="服务器 IP:mc.hypixel.net" /> Text="启动 1.20.1 并进入 Hypixel" EventType="启动游戏" EventData="1.20.1|mc.hypixel.net" ToolTip="服务器 IP:mc.hypixel.net" />
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
Text="在 EventData 中填写 \current,表示启动当前被选中的游戏版本,同样可以在后面填写服务器 IP。" />
<local:MyButton Margin="0,4,0,10" Width="250" Height="35"
Text="启动当前选中版本并进入 Hypixel" EventType="启动游戏" EventData="\current|mc.hypixel.net" ToolTip="启动当前版本" />
</StackPanel> </StackPanel>
</local:MyCard> </local:MyCard>
@@ -144,7 +148,7 @@
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0" <local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" /> Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" />
<local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0" <local:MyButton Margin="0,0,10,0" Width="140" Height="35" HorizontalAlignment="Left" Padding="13,0,13,0"
Text="打开画图" EventType="打开文件" EventData="mspaint.exe" /> Text="打开记事本" EventType="打开文件" EventData="notepad" />
</StackPanel> </StackPanel>
<!-- 这是第二行 --> <!-- 这是第二行 -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
@@ -180,28 +184,30 @@
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
Text="PCL 内置了一些 Minecraft 方块与物品图片,可以直接使用。"/> Text="PCL 内置了一些 Minecraft 方块与物品图片,可以直接使用。"/>
<StackPanel Orientation="Horizontal" Margin="10,8,0,15" Height="30"> <StackPanel Orientation="Horizontal" Margin="10,8,0,15" Height="30">
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/CommandBlock.png"/>
<!-- 命令方块 --> <!-- 命令方块 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Cobblestone.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/CommandBlock.png"/>
<!-- 圆石 --> <!-- 圆石 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GoldBlock.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Cobblestone.png"/>
<!-- 金块 --> <!-- 金块 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Grass.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GoldBlock.png"/>
<!-- 草方块 --> <!-- 草方块 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GrassPath.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Grass.png"/>
<!-- 草径 --> <!-- 草径 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Anvil.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/GrassPath.png"/>
<!-- 铁砧 --> <!-- 铁砧 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneBlock.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Anvil.png"/>
<!-- 红石块 --> <!-- 红石块 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOn.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneBlock.png"/>
<!-- 红石灯(亮) --> <!-- 红石灯(亮) -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOff.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOn.png"/>
<!-- 红石灯(灭) --> <!-- 红石灯(灭) -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Egg.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/RedstoneLampOff.png"/>
<!-- 鸡蛋 --> <!-- 鸡蛋 -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Fabric.png"/> <Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Egg.png"/>
<!-- 布料(Fabric 图标) --> <!-- 布料(Fabric 图标) -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/Fabric.png"/>
<!-- 狐狸(NeoForge 图标) -->
<Image Width="30" Margin="5,0,0,0" Source="pack://application:,,,/images/Blocks/NeoForge.png"/>
</StackPanel> </StackPanel>
<TextBlock TextWrapping="Wrap" Margin="0,0,0,4" <TextBlock TextWrapping="Wrap" Margin="0,0,0,4"
Text="使用时,将上方对应行的 Source 复制到 MyListItem 的 Logo 属性处即可。"/> Text="使用时,将上方对应行的 Source 复制到 MyListItem 的 Logo 属性处即可。"/>
@@ -264,7 +270,7 @@
<local:MyButton Grid.Column="1" Margin="0,0,10,0" Height="35" <local:MyButton Grid.Column="1" Margin="0,0,10,0" Height="35"
Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" /> Text="进入 Hypixel" EventType="启动游戏" EventData="1.16.3|mc.hypixel.net" ToolTip="使用 Minecraft 1.16.3 进入 Hypixel" />
<local:MyButton Grid.Column="2" Margin="0,0,10,0" Height="35" <local:MyButton Grid.Column="2" Margin="0,0,10,0" Height="35"
Text="打开画图" EventType="打开文件" EventData="mspaint.exe" /> Text="打开记事本" EventType="打开文件" EventData="notepad" />
</Grid> </Grid>
</StackPanel> </StackPanel>
</local:MyCard> </local:MyCard>
Binary file not shown.