PageVersionExport.xaml.vb 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. Public Class PageVersionExport
  2. Private CurrentVer As String = ""
  3. Private Sub PageVersionExport_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
  4. Reload()
  5. End Sub
  6. Public ItemVersion As MyListItem
  7. Public Sub Reload()
  8. AniControlEnabled += 1
  9. If CurrentVer <> PageVersionLeft.Version.Path Then
  10. '说明切换到另一个版本了,所有的设置都要重置
  11. CurrentPath = ""
  12. Selected = New List(Of String)
  13. CurrentVer = PageVersionLeft.Version.Path
  14. TbExportName.Text = ""
  15. TbExportVersion.Text = ""
  16. 'ComboDisplayLogo.SelectedIndex = 0
  17. CustomLogoVal = Nothing
  18. TbExportDesc.Text = ""
  19. End If
  20. TbExportName.ShowValidateResult = True
  21. TbExportName.ValidateRules = New ObjectModel.Collection(Of Validate) From {New ValidateFileName() With {.AllowNull = True}}
  22. TbExportName.Validate()
  23. TbExportName.HintText = PageVersionLeft.Version.Name
  24. TbExportDesc.HintText = PageVersionLeft.Version.Info
  25. PanDisplayItem.Children.Clear()
  26. ItemVersion = PageSelectRight.McVersionListItem(PageVersionLeft.Version.Load())
  27. ItemVersion.IsHitTestVisible = False
  28. If Not String.IsNullOrEmpty(CustomLogo) Then ItemVersion.Logo = CustomLogo
  29. PanDisplayItem.Children.Add(ItemVersion)
  30. ItemVersion.Title = If(String.IsNullOrWhiteSpace(TbExportName.Text), PageVersionLeft.Version.Name, TbExportName.Text)
  31. ItemVersion.Info = If(String.IsNullOrWhiteSpace(TbExportDesc.Text), PageVersionLeft.Version.Info, TbExportDesc.Text)
  32. #If BETA Then
  33. CheckIncludePCL.IsEnabled = True
  34. #Else
  35. CheckIncludePCL.IsEnabled = False
  36. TbHint.Text = "你可以在此勾选需要包含进整合包的文件或文件夹,其他文件或文件夹在高级选项添加。" & vbCrLf & "你当前的 PCL 不是正式版,有二次分发的限制,因此整合包不能包含 PCL 程序。"
  37. #End If
  38. CheckIncludeSetup.IsEnabled = CheckIncludePCL.IsEnabled
  39. ReloadFileList(CurrentPath)
  40. AniControlEnabled -= 1
  41. End Sub
  42. #Region "文件列表"
  43. ''' <summary>
  44. ''' 当前所在的文件夹。注意是绝对路径!以 \ 结尾。
  45. ''' </summary>
  46. Private CurrentPath As String = ""
  47. Private Sub ReloadFileList(Optional NewPath As String = "")
  48. If String.IsNullOrWhiteSpace(NewPath) OrElse NewPath = PathMcFolder Then NewPath = PageVersionLeft.Version.Path
  49. If Not NewPath.EndsWithF("\") Then NewPath &= "\"
  50. Dim tb As TextBlock = PanFileList.Children(0)
  51. PanFileList.Children.Clear()
  52. PanFileList.Children.Add(tb)
  53. If NewPath <> PageVersionLeft.Version.Path Then
  54. Dim listItem As New MyListItem With {.Title = "返回上一级目录", .Tag = "..", .Height = 35, .Type = MyListItem.CheckType.Clickable}
  55. AddHandler listItem.Click, AddressOf ListItem_Click
  56. PanFileList.Children.Add(listItem)
  57. End If
  58. Dim fileCount As Integer = 0
  59. Dim directories = Directory.EnumerateDirectories(NewPath)
  60. Dim files = Directory.EnumerateFiles(NewPath)
  61. If (NewPath = PageVersionLeft.Version.Path) AndAlso PageVersionLeft.Version.PathIndie = PathMcFolder Then
  62. '未开启版本隔离时 .minecraft 下的文件
  63. directories = directories.Concat(Directory.EnumerateDirectories(PathMcFolder))
  64. files = files.Concat(Directory.EnumerateFiles(PathMcFolder))
  65. End If
  66. For Each d In directories
  67. If Directory.EnumerateFileSystemEntries(d).Count = 0 Then Continue For
  68. If IsVerRedundant(d) OrElse IsMustExport(d) Then Continue For
  69. Dim title As String = ""
  70. Dim listItem As New MyListItem
  71. If Titles.TryGetValue(GetFolderNameFromPath(d), title) Then 'title 作为引用类型传入
  72. listItem.Title = title
  73. Else
  74. listItem.Title = GetFolderNameFromPath(d)
  75. End If
  76. listItem.Info = d
  77. '图标按钮
  78. Dim btnSwap As New MyIconButton
  79. btnSwap.Logo = Logo.IconButtonRight
  80. btnSwap.LogoScale = 1.0
  81. btnSwap.Tag = d & "\"
  82. AddHandler btnSwap.Click, AddressOf BtnSwap_Click
  83. listItem.Buttons = {btnSwap}
  84. listItem.Type = MyListItem.CheckType.CheckBox
  85. listItem.Height = 35
  86. listItem.Logo = Logo.IconButtonOpen
  87. listItem.Tag = d & "\"
  88. Select Case IsSelected(d & "\")
  89. Case 1
  90. listItem.Half = True
  91. Case 2
  92. listItem.Checked = True
  93. End Select
  94. AddHandler listItem.Click, AddressOf ListItem_Click
  95. PanFileList.Children.Add(listItem)
  96. fileCount += 1
  97. Next
  98. For Each f In files
  99. If IsVerRedundant(f) OrElse IsMustExport(f) Then Continue For
  100. Dim title As String = ""
  101. Dim listItem As New MyListItem
  102. If Titles.TryGetValue(f, title) Then 'title 作为引用类型传入
  103. listItem.Title = title
  104. Else
  105. listItem.Title = GetFileNameFromPath(f)
  106. End If
  107. listItem.Info = f
  108. listItem.Type = MyListItem.CheckType.CheckBox
  109. listItem.Height = 35
  110. listItem.Tag = f
  111. listItem.Checked = (IsSelected(f) = 2)
  112. AddHandler listItem.Click, AddressOf ListItem_Click
  113. PanFileList.Children.Add(listItem)
  114. fileCount += 1
  115. Next
  116. CurrentPath = NewPath
  117. CardMore.Title = If(NewPath = PageVersionLeft.Version.Path, "高级选项", $"高级选项 ({NewPath.Replace(PageVersionLeft.Version.Path, "").TrimEnd("\")})")
  118. End Sub
  119. Private Titles As New Dictionary(Of String, String) From {
  120. {"saves", "存档"},
  121. {"resourcepacks", "资源包"},
  122. {"config", "Mod 配置"},
  123. {"shaderpacks", "光影包"},
  124. {"options.txt", "游戏配置"},
  125. {"servers.dat", "服务器列表"}
  126. }
  127. Private Sub BtnSwap_Click(sender As MyIconButton, e As Object)
  128. Dim actualPath As String = sender.Tag
  129. 'Dim relative As String = actualPath.Replace(PageVersionLeft.Version.Path, "")
  130. If Not Directory.Exists(actualPath) Then
  131. Hint($"找不到目录:{actualPath}", HintType.Critical)
  132. Exit Sub
  133. End If
  134. ReloadFileList(actualPath)
  135. End Sub
  136. ''' <summary>
  137. ''' 选中的文件列表,绝对路径。
  138. ''' </summary>
  139. Private Selected As New List(Of String)
  140. Private Sub SelectedChange(IsAdd As Boolean, TargetPath As String)
  141. If File.Exists(TargetPath) Then
  142. If IsAdd Then Selected.Add(TargetPath) Else Selected.Remove(TargetPath)
  143. Exit Sub
  144. End If
  145. If Directory.Exists(TargetPath) Then
  146. For Each d In Directory.EnumerateDirectories(TargetPath)
  147. SelectedChange(IsAdd, d)
  148. Next
  149. For Each f In Directory.EnumerateFiles(TargetPath)
  150. If IsAdd Then Selected.Add(f) Else Selected.Remove(f)
  151. Next
  152. End If
  153. Selected = Selected.Distinct().ToList()
  154. End Sub
  155. ''' <summary>
  156. ''' 获取 TargetPath 是否选中。
  157. ''' </summary>
  158. ''' <returns>全部未选中为 0,部分选中为 1,全部选中为 2。</returns>
  159. Private Function IsSelected(TargetPath As String, Optional AllowEmpty As Boolean = False) As Integer
  160. If File.Exists(TargetPath) Then
  161. Return If(Selected.Contains(TargetPath), 2, 0)
  162. End If
  163. If Directory.Exists(TargetPath) Then
  164. Dim di As New DirectoryInfo(TargetPath)
  165. If di.GetDirectories.Length + di.GetFiles.Length = 0 Then Return If(AllowEmpty, 2, 0)
  166. '如果有一个文件不在列表,则 hasExclude = True
  167. Dim hasExclude As Boolean = False
  168. '如果有一个文件在列表,则 hasInclude = True
  169. Dim hasInclude As Boolean = False
  170. For Each d In Directory.EnumerateDirectories(TargetPath)
  171. If Directory.EnumerateFileSystemEntries(d).Count = 0 Then Continue For
  172. Select Case IsSelected(d, True)
  173. Case 0
  174. hasExclude = True
  175. Case 1
  176. Return 1
  177. Case 2
  178. hasInclude = True
  179. End Select
  180. If hasInclude AndAlso hasExclude Then Return 1 '如果有文件在、有文件不在列表中,可以断定部分选中
  181. Next
  182. For Each f In Directory.EnumerateFiles(TargetPath)
  183. If Selected.Contains(f) Then hasInclude = True Else hasExclude = True
  184. If hasInclude AndAlso hasExclude Then Return 1 '如果有文件在、有文件不在列表中,可以断定部分选中
  185. Next
  186. If hasExclude AndAlso Not hasInclude Then Return 0
  187. If hasInclude AndAlso Not hasExclude Then Return 2
  188. End If
  189. Return 0
  190. End Function
  191. Private Sub ListItem_Click(sender As MyListItem, e As Object)
  192. If sender.Tag = ".." Then '回到上一级目录
  193. ReloadFileList(GetPathFromFullPath(CurrentPath))
  194. Exit Sub
  195. End If
  196. SelectedChange(Not sender.Checked, '非常难绷的逻辑,很难描述清楚,自己打断点看 Checked 属性值吧……
  197. sender.Tag)
  198. End Sub
  199. 'Private ReadOnly Property Saves As List(Of String)
  200. ' Get
  201. ' If Directory.Exists(PageVersionLeft.Version.Path & "saves\") Then
  202. ' Return Directory.EnumerateDirectories(PageVersionLeft.Version.Path & "saves\").ToList
  203. ' End If
  204. ' Return New List(Of String)
  205. ' End Get
  206. 'End Property
  207. '复选框与高级选项同步
  208. Private Sub PanCommonFiles_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles PanCommonFiles.MouseLeftButtonUp
  209. For Each c In PanCommonFiles.Children
  210. If String.IsNullOrEmpty(c.Tag) Then Continue For
  211. For Each l In PanFileList.Children
  212. If TypeOf l Is MyListItem Then
  213. If If(l.Tag.EndsWith("\"), GetFolderNameFromPath(l.Tag), GetFileNameFromPath(l.Tag)) = c.Tag Then
  214. l.Checked = c.Checked
  215. SelectedChange(c.Checked, PageVersionLeft.Version.Path & c.Tag)
  216. End If
  217. End If
  218. Next
  219. Next
  220. End Sub
  221. '高级选项与复选框同步
  222. Private Sub PanFileList_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles PanFileList.MouseLeftButtonUp
  223. For Each c In PanCommonFiles.Children
  224. If TypeOf c Is MyCheckBox Then
  225. c.Checked = IsSelected(PageVersionLeft.Version.Path & c.Tag) = 2 OrElse IsSelected(PathMcFolder & c.Tag) = 2
  226. End If
  227. Next
  228. End Sub
  229. #End Region
  230. #Region "整合包信息 & 预览栏"
  231. Private Sub TbExportName_TextChanged(sender As MyTextBox, e As TextChangedEventArgs) Handles TbExportName.TextChanged
  232. If String.IsNullOrEmpty(TbExportName.ValidateResult) Then
  233. ItemVersion.Title = If(String.IsNullOrWhiteSpace(sender.Text), PageVersionLeft.Version.Name, sender.Text)
  234. End If
  235. End Sub
  236. Private Sub TbExportDesc_TextChanged(sender As MyTextBox, e As TextChangedEventArgs) Handles TbExportDesc.TextChanged
  237. ItemVersion.Info = If(String.IsNullOrWhiteSpace(sender.Text), PageVersionLeft.Version.Info, sender.Text)
  238. End Sub
  239. Private CustomLogoVal As String
  240. ''' <summary>
  241. ''' 自定义 Logo 的路径。
  242. ''' </summary>
  243. Public Property CustomLogo() As String
  244. Get
  245. Return CustomLogoVal
  246. End Get
  247. Set(value As String)
  248. If AniControlEnabled <> 0 Then Exit Property
  249. CustomLogoVal = value
  250. ItemVersion.Logo = value
  251. Reload()
  252. End Set
  253. End Property
  254. 'Private Sub ComboDisplayLogo_SelectionChanged(sender As MyComboBox, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
  255. ' If Not AniControlEnabled = 0 Then Exit Sub
  256. ' '选择 自定义 时修改图片
  257. ' If ComboDisplayLogo.SelectedItem Is ItemDisplayLogoCustom Then
  258. ' Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
  259. ' If String.IsNullOrWhiteSpace(FileName) Then Exit Sub
  260. ' CustomLogo = FileName
  261. ' Else
  262. ' CustomLogo = sender.SelectedItem.Tag
  263. ' End If
  264. 'End Sub
  265. #End Region
  266. #Region "基本信息"
  267. Private Sub CheckIncludePCL_Change(sender As Object, user As Boolean) Handles CheckIncludePCL.Change
  268. CheckIncludeSetup.IsEnabled = CheckIncludePCL.IsEnabled
  269. End Sub
  270. #End Region
  271. #Region "导出"
  272. 'Private Sub ComboExportType_Change(sender As ComboBox, e As SelectionChangedEventArgs) Handles ComboExportType.SelectionChanged
  273. ' If AniControlEnabled <> 0 Then Exit Sub
  274. ' Type = sender.SelectedIndex
  275. ' Select Case Type
  276. ' Case ModpackType.Modrinth
  277. ' If IncludePCL() Then 'TODO:修改这里的条件
  278. ' If GridCompressed IsNot Nothing Then GridCompressed.Visibility = Visibility.Visible
  279. ' If GridModrinth IsNot Nothing Then GridModrinth.Visibility = Visibility.Collapsed
  280. ' Else
  281. ' If GridCompressed IsNot Nothing Then GridCompressed.Visibility = Visibility.Collapsed
  282. ' If GridModrinth IsNot Nothing Then GridModrinth.Visibility = Visibility.Visible
  283. ' End If
  284. ' End Select
  285. ' CardExport.TriggerForceResize()
  286. 'End Sub
  287. Private Sub BtnExportExport_Click() Handles BtnExportExport.Click
  288. Dim savePath As String = SelectAs(
  289. "选择导出位置", $"整合包 - {If(String.IsNullOrWhiteSpace(TbExportName.Text), PageVersionLeft.Version.Name, TbExportName.Text)}" & If(CheckIncludePCL.Checked, ".zip", ".mrpack"),
  290. If(CheckIncludePCL.Checked, "整合包文件(*.zip)|*.zip", "Modrinth 整合包(*.mrpack)|*.mrpack"))
  291. If String.IsNullOrEmpty(savePath) Then Exit Sub
  292. '获取需要包含的文件
  293. Dim contains As List(Of String) = Selected
  294. For Each c In PanCommonFiles.Children
  295. If TypeOf c IsNot MyCheckBox Then Continue For
  296. If String.IsNullOrEmpty(c.Tag) Then Continue For
  297. If c.Checked Then contains.Add(PageVersionLeft.Version.Path & c.Tag)
  298. Next
  299. '重复任务检查
  300. For Each OngoingLoader In LoaderTaskbar
  301. If OngoingLoader.Name <> $"导出整合包 {PageVersionLeft.Version.Name}" Then Continue For
  302. Hint("正在处理中,请稍候!", HintType.Critical)
  303. Exit Sub
  304. Next
  305. '启动!
  306. Dim Loader As New LoaderTask(Of ExportOptions, Boolean)($"导出整合包 {PageVersionLeft.Version.Name}",
  307. Sub(Task As LoaderTask(Of ExportOptions, Boolean))
  308. Task.Output = ModpackExport(Task)
  309. Task.Progress = 1.0
  310. If Task.Output Then
  311. Hint($"{Task.Name} 成功!", HintType.Finish)
  312. OpenExplorer($"/select,""{Task.Input.Dest}""")
  313. End If
  314. End Sub)
  315. Dim Combo = New LoaderCombo(Of ExportOptions)($"导出整合包 {PageVersionLeft.Version.Name}", {Loader})
  316. Combo.Start(New ExportOptions(PageVersionLeft.Version, savePath, CheckIncludePCL.Checked, contains.Distinct.ToArray,
  317. PCLSetupGlobal:=CheckIncludeSetup.Checked, Name:=TbExportName.Text, Desc:=TbExportDesc.Text,
  318. VerID:=TbExportVersion.Text))
  319. LoaderTaskbarAdd(Combo)
  320. End Sub
  321. #End Region
  322. End Class