diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb
index 89f1887..4e3d9bb 100644
--- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb
+++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb
@@ -178,6 +178,10 @@ Public Module ModBase
'''
Public Const IconButtonOffline As String = "M533.293176 788.841412a60.235294 60.235294 0 1 1 85.202824 85.202823l-42.616471 42.586353c-129.355294 129.385412-339.124706 129.385412-468.510117 0-129.385412-129.385412-129.385412-339.124706 0-468.510117l42.586353-42.616471a60.235294 60.235294 0 1 1 85.202823 85.202824l-42.61647 42.586352a210.823529 210.823529 0 1 0 298.164706 298.164706l42.586352-42.61647z m255.548236-255.548236l42.61647-42.586352a210.823529 210.823529 0 1 0-298.164706-298.164706l-42.586352 42.61647a60.235294 60.235294 0 1 1-85.202824-85.202823l42.616471-42.586353c129.355294-129.385412 339.124706-129.385412 468.510117 0 129.385412 129.385412 129.385412 339.124706 0 468.510117l-42.586353 42.616471a60.235294 60.235294 0 1 1-85.202823-85.202824zM192.542118 192.542118a60.235294 60.235294 0 0 1 85.202823 0l553.712941 553.712941a60.235294 60.235294 0 0 1-85.202823 85.202823L192.542118 277.744941a60.235294 60.235294 0 0 1 0-85.202823z"
'''
+ ''' 图标,向右箭头,1x
+ '''
+ Public Const IconButtonRight As String = "M757.792745 435.407215L419.597482 96.904967c-40.010393-40.010393-104.886579-40.010393-144.896972 0-40.010393 40.010393-40.010393 104.988908 0 144.9993L540.344959 507.855701 274.70051 773.807135c-40.010393 40.112721-40.010393 104.988908 0 144.9993 40.010393 40.010393 104.886579 40.010393 144.896972 0l338.092935-338.39992c40.112721-40.010393 40.112721-104.988908 0.102328-144.9993z"
+ '''
''' 图标,音符,1x
'''
Public Const IconMusic As String = "M348.293565 716.53287V254.797913c0-41.672348 28.004174-78.358261 68.919652-90.37913L815.994435 40.826435c62.775652-18.610087 125.907478 26.579478 125.907478 89.933913v539.158261c8.013913 42.25113-8.94887 89.177043-47.014956 127.109565a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c21.014261 1.024 40.514783 5.164522 57.878261 12.065391V233.338435c0-12.109913-10.551652-20.034783-20.569044-20.034783a24.620522 24.620522 0 0 0-5.787826 0.934957L439.785739 338.18713a19.545043 19.545043 0 0 0-14.825739 19.144348v438.984348H423.846957c11.53113 43.987478-5.164522 94.208-45.412174 134.322087a232.848696 232.848696 0 0 1-170.785392 65.758609c-61.885217-2.938435-111.081739-33.435826-129.113043-80.050087-18.031304-46.614261-2.137043-102.177391 41.672348-145.853218a232.848696 232.848696 0 0 1 170.785391-65.80313c20.791652 1.024 40.069565 5.075478 57.299478 11.842783z"
diff --git a/Plain Craft Launcher 2/Modules/Base/ModValidate.vb b/Plain Craft Launcher 2/Modules/Base/ModValidate.vb
index b7f818b..c9b6aa0 100644
--- a/Plain Craft Launcher 2/Modules/Base/ModValidate.vb
+++ b/Plain Craft Launcher 2/Modules/Base/ModValidate.vb
@@ -260,6 +260,7 @@ Public Class ValidateFileName
Public Property IgnoreCase As Boolean = True
Public Property ParentFolder As String = Nothing
Public Property RequireParentFolderExists = True
+ Public Property AllowNull As Boolean = False
Public Sub New()
End Sub
Public Sub New(Name As String, Optional UseMinecraftCharCheck As Boolean = True, Optional IgnoreCase As Boolean = True)
@@ -269,14 +270,16 @@ Public Class ValidateFileName
End Sub
Public Overrides Function Validate(Str As String) As String
Try
- '检查是否为空
- Dim LengthCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
- If Not LengthCheck = "" Then Return LengthCheck
+ If Not AllowNull Then
+ '检查是否为空
+ Dim NullCheck As String = New ValidateNullOrWhiteSpace().Validate(Str)
+ If Not NullCheck = "" Then Return NullCheck
+ End If
'检查空格
If Str.StartsWithF(" ") Then Return "文件名不能以空格开头!"
If Str.EndsWithF(" ") Then Return "文件名不能以空格结尾!"
'检查长度
- LengthCheck = New ValidateLength(1, 253).Validate(Str & If(ParentFolder, ""))
+ Dim LengthCheck = New ValidateLength(If(AllowNull, 0, 1), 253).Validate(Str & If(ParentFolder, ""))
If Not LengthCheck = "" Then Return LengthCheck
'检查尾部小数点
If Str.EndsWithF(".") Then Return "文件名不能以小数点结尾!"
diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
index 7e2e56e..2fa0141 100644
--- a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
+++ b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb
@@ -956,7 +956,7 @@ Retry:
}
Public Function IsVerRedundant(FilePath As String) As Boolean
For Each regex In VersionRedundant
- If RegexCheck(GetFileNameFromPath(FilePath).ToLower(), regex) Then Return True
+ If RegexCheck(GetFileNameFromPath(FilePath), regex, RegularExpressions.RegexOptions.IgnoreCase) Then Return True
If FilePath.Replace("/", "\").EndsWithF("\journeymap\data\") OrElse
FilePath.Replace("/", "\").EndsWithF("\journeymap\data") Then
Return True
@@ -964,6 +964,15 @@ Retry:
Next
Return False
End Function
+ Private MustExport As String() = {
+ "mods", "PCL", ".*\.json"
+ }
+ Public Function IsMustExport(FileName As String) As Boolean
+ For Each regex In MustExport
+ If RegexCheck(FileName, regex, RegularExpressions.RegexOptions.IgnoreCase) Then Return True
+ Next
+ Return False
+ End Function
#End Region
#Region "不同类型整合包的导出方法"
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
index f912938..f0786e2 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml
@@ -38,7 +38,11 @@
-
+
+
+
+
+
@@ -68,7 +72,7 @@
-
+
@@ -88,7 +92,7 @@
+ Tag="servers.dat" ToolTip="servers.dat 文件" />
-
+
-
+
diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
index e3c25e1..708a09b 100644
--- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
+++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionExport.xaml.vb
@@ -1,13 +1,19 @@
Public Class PageVersionExport
+ Private CurrentVer As String = ""
Private Sub PageVersionExport_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Reload()
End Sub
Public ItemVersion As MyListItem
- Private SelectedEntries As New List(Of String)
Public Sub Reload()
AniControlEnabled += 1
+ If CurrentVer <> PageVersionLeft.Version.Path Then
+ '说明切换到另一个版本了,所有的绝对路径都要重置,否则爆炸
+ CurrentPath = ""
+ Selected = New List(Of String)
+ CurrentVer = PageVersionLeft.Version.Path
+ End If
TbExportName.HintText = PageVersionLeft.Version.Name
TbExportDesc.HintText = PageVersionLeft.Version.Info
PanDisplayItem.Children.Clear()
@@ -21,22 +27,37 @@
CheckIncludePCL.IsEnabled = True
#Else
CheckIncludePCL.IsEnabled = False
- TbHint.Text = "你可以在此勾选需要包含进整合包的文件或文件夹,其他文件或文件夹在高级选项添加。" & vbCrLf & "你当前的 PCL 不是正式版,有二次分发的限制,因此不能选择是否包含 PCL 程序。"
+ TbHint.Text = "你可以在此勾选需要包含进整合包的文件或文件夹,其他文件或文件夹在高级选项添加。" & vbCrLf & "你当前的 PCL 不是正式版,有二次分发的限制,因此整合包不能包含 PCL 程序。"
#End If
CheckIncludeSetup.IsEnabled = CheckIncludePCL.IsEnabled
- ReloadFileList()
+ ReloadFileList(CurrentPath)
AniControlEnabled -= 1
End Sub
- Private Sub ReloadFileList()
+
+#Region "文件列表"
+ '''
+ ''' 当前所在的文件夹。注意是绝对路径!以 \ 结尾。
+ '''
+ Private CurrentPath As String = ""
+ Private Sub ReloadFileList(Optional NewPath As String = "")
+ If String.IsNullOrWhiteSpace(NewPath) Then NewPath = PageVersionLeft.Version.Path
Dim tb As TextBlock = PanFileList.Children(0)
PanFileList.Children.Clear()
PanFileList.Children.Add(tb)
- For Each d In Directory.EnumerateDirectories(PageVersionLeft.Version.Path)
+ If NewPath <> PageVersionLeft.Version.Path Then
+ Dim listItem As New MyListItem With {.Title = "返回上一级目录", .Tag = "..", .Height = 35, .Type = MyListItem.CheckType.Clickable}
+ AddHandler listItem.Click, AddressOf ListItem_Click
+ PanFileList.Children.Add(listItem)
+ End If
+
+ Dim fileCount As Integer = 0
+
+ For Each d In Directory.EnumerateDirectories(NewPath)
If Directory.EnumerateFileSystemEntries(d).Count = 0 Then Continue For
d = GetFolderNameFromPath(d)
- If IsVerRedundant(d) Then Continue For
+ If IsVerRedundant(NewPath & d) OrElse IsMustExport(d) Then Continue For
Dim title As String = ""
Dim listItem As New MyListItem
If Titles.TryGetValue(d, title) Then 'title 作为引用类型传入
@@ -47,14 +68,44 @@
End If
'图标按钮
Dim btnSwap As New MyIconButton
- btnSwap.Path = New Shapes.Path With {.HorizontalAlignment = HorizontalAlignment.Right, .Stretch = Stretch.Uniform, .Height = 6, .Width = 10, .VerticalAlignment = VerticalAlignment.Top, .Margin = New Thickness(0, 17, 16, 0), .Data = New GeometryConverter().ConvertFromString("M2,4 l-2,2 10,10 10,-10 -2,-2 -8,8 -8,-8 z"), .RenderTransform = New RotateTransform(180), .RenderTransformOrigin = New Point(0.5, 0.5)}
+ btnSwap.Logo = Logo.IconButtonRight
+ btnSwap.LogoScale = 1.0
+ btnSwap.Tag = d
AddHandler btnSwap.Click, AddressOf BtnSwap_Click
listItem.Buttons = {btnSwap}
listItem.Type = MyListItem.CheckType.CheckBox
listItem.Height = 35
listItem.Logo = Logo.IconButtonOpen
+ listItem.Tag = d & "\"
+ If IsSelected(NewPath & d & "\") Then listItem.Checked = True
+ AddHandler listItem.Click, AddressOf ListItem_Click
PanFileList.Children.Add(listItem)
+ fileCount += 1
Next
+
+ For Each f In Directory.EnumerateFiles(NewPath)
+ f = GetFileNameFromPath(f)
+ If IsVerRedundant(NewPath & f) OrElse IsMustExport(f) Then Continue For
+ Dim title As String = ""
+ Dim listItem As New MyListItem
+ If Titles.TryGetValue(f, title) Then 'title 作为引用类型传入
+ listItem.Title = title
+ listItem.Info = f
+ Else
+ listItem.Title = f
+ End If
+ listItem.Info = (NewPath & f).Replace(GetPathFromFullPath(PageVersionLeft.Version.Path), "")
+ listItem.Type = MyListItem.CheckType.CheckBox
+ listItem.Height = 35
+ listItem.Tag = f
+ If IsSelected(NewPath & f) Then listItem.Checked = True
+ AddHandler listItem.Click, AddressOf ListItem_Click
+ PanFileList.Children.Add(listItem)
+ fileCount += 1
+ Next
+
+ CurrentPath = NewPath
+ CardMore.Title = If(NewPath = PageVersionLeft.Version.Path, "高级选项", $"高级选项 ({NewPath.Replace(PageVersionLeft.Version.Path, "").TrimEnd("\")})")
End Sub
Private Titles As New Dictionary(Of String, String) From {
{"saves", "存档"},
@@ -65,16 +116,86 @@
{"servers.dat", "服务器列表"}
}
Private Sub BtnSwap_Click(sender As MyIconButton, e As Object)
- MsgBox("测试") 'TODO:处理展开操作
+ Dim actualPath As String = CurrentPath & sender.Tag & "\"
+ 'Dim relative As String = actualPath.Replace(PageVersionLeft.Version.Path, "")
+
+ If Not Directory.Exists(actualPath) Then
+ Hint($"找不到目录:{actualPath}", HintType.Critical)
+ Exit Sub
+ End If
+ ReloadFileList(actualPath)
End Sub
- Private ReadOnly Property Saves As List(Of String)
- Get
- If Directory.Exists(PageVersionLeft.Version.Path & "saves\") Then
- Return Directory.EnumerateDirectories(PageVersionLeft.Version.Path & "saves\").ToList
- End If
- Return New List(Of String)
- End Get
- End Property
+ '''
+ ''' 选中的文件列表,绝对路径。
+ '''
+ Private Selected As New List(Of String)
+ Private Sub SelectedChange(IsAdd As Boolean, TargetPath As String)
+ If File.Exists(TargetPath) Then
+ If IsAdd Then Selected.Add(TargetPath) Else Selected.Remove(TargetPath)
+ Exit Sub
+ End If
+ If Directory.Exists(TargetPath) Then
+ For Each d In Directory.EnumerateDirectories(TargetPath)
+ SelectedChange(IsAdd, d)
+ Next
+ For Each f In Directory.EnumerateFiles(TargetPath)
+ If IsAdd Then Selected.Add(f) Else Selected.Remove(f)
+ Next
+ End If
+ End Sub
+ Private Function IsSelected(TargetPath As String) As Boolean
+ If File.Exists(TargetPath) Then
+ Return Selected.Contains(TargetPath)
+ End If
+ If Directory.Exists(TargetPath) Then
+ Return Directory.EnumerateDirectories(TargetPath).All(Function(s) IsSelected(s)) AndAlso
+ Directory.EnumerateFiles(TargetPath).All(Function(s) Selected.Contains(s))
+ End If
+ Return False
+ End Function
+ Private Sub ListItem_Click(sender As MyListItem, e As Object)
+ If sender.Tag = ".." Then '回到上一级目录
+ ReloadFileList(GetPathFromFullPath(CurrentPath))
+ Exit Sub
+ End If
+ SelectedChange(Not sender.Checked, '非常难绷的逻辑,很难描述清楚,自己打断点看 Checked 属性值吧……
+ CurrentPath & sender.Tag)
+ End Sub
+
+ 'Private ReadOnly Property Saves As List(Of String)
+ ' Get
+ ' If Directory.Exists(PageVersionLeft.Version.Path & "saves\") Then
+ ' Return Directory.EnumerateDirectories(PageVersionLeft.Version.Path & "saves\").ToList
+ ' End If
+ ' Return New List(Of String)
+ ' End Get
+ 'End Property
+
+ '复选框与高级选项同步
+ Private Sub PanCommonFiles_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles PanCommonFiles.MouseLeftButtonUp
+ For Each c In PanCommonFiles.Children
+ If TypeOf c IsNot MyCheckBox Then Continue For
+ If String.IsNullOrEmpty(c.Tag) Then Continue For
+ For Each l In PanFileList.Children
+ If TypeOf l Is MyListItem Then
+ If l.Tag.Replace("\", "") = c.Tag Then l.Checked = c.Checked
+ End If
+ Next
+ Next
+ End Sub
+ '高级选项与复选框同步
+ Private Sub PanFileList_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles PanFileList.MouseLeftButtonUp
+ For Each l In PanFileList.Children
+ If TypeOf l IsNot MyListItem Then Continue For
+ If String.IsNullOrEmpty(l.Tag) Then Continue For
+ For Each c In PanCommonFiles.Children
+ If TypeOf c Is MyCheckBox Then
+ If c.Tag = l.Tag.Replace("\", "") Then c.Checked = l.Checked
+ End If
+ Next
+ Next
+ End Sub
+#End Region
#Region "整合包信息 & 预览栏"
Private Sub TbExportName_TextChanged(sender As MyTextBox, e As TextChangedEventArgs) Handles TbExportName.TextChanged
@@ -137,18 +258,19 @@
' CardExport.TriggerForceResize()
'End Sub
Private Sub BtnExportExport_Click() Handles BtnExportExport.Click
- '获取需要包含的文件夹
- Dim contains As New List(Of String)
- For Each c In PanFiles.Children
- If TypeOf c IsNot MyCheckBox Then Continue For
- If String.IsNullOrEmpty(c.Tag) Then Continue For
- contains.Add(c.Tag)
- Next
Dim savePath As String = SelectAs(
"选择导出位置", $"整合包 - {If(String.IsNullOrWhiteSpace(TbExportName.Text), PageVersionLeft.Version.Name, TbExportName.Text)}" & If(CheckIncludePCL.Checked, ".zip", ".mrpack"),
If(CheckIncludePCL.Checked, "整合包文件(*.zip)|*.zip", "Modrinth 整合包(*.mrpack)|*.mrpack"))
If String.IsNullOrEmpty(savePath) Then Exit Sub
- ModpackExport(New ExportOptions(PageVersionLeft.Version, savePath, CheckIncludePCL.Checked, {}, 'TODO:改成要保留的文件列表
+
+ '获取需要包含的文件夹
+ Dim contains As New List(Of String)
+ For Each c In PanCommonFiles.Children
+ If TypeOf c IsNot MyCheckBox Then Continue For
+ If String.IsNullOrEmpty(c.Tag) Then Continue For
+ contains.Add(c.Tag)
+ Next
+ ModpackExport(New ExportOptions(PageVersionLeft.Version, savePath, CheckIncludePCL.Checked, Selected.ToArray,
PCLSetupGlobal:=CheckIncludeSetup.Checked, Name:=TbExportName.Text, VerID:=TbExportVersion.Text))
End Sub