PageVersionOverall.xaml.vb 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. Public Class PageVersionOverall
  2. Private IsLoad As Boolean = False
  3. Private Sub PageSetupLaunch_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
  4. '重复加载部分
  5. PanBack.ScrollToHome()
  6. '更新设置
  7. ItemDisplayLogoCustom.Tag = "PCL\Logo.png"
  8. Reload()
  9. '非重复加载部分
  10. If IsLoad Then Return
  11. IsLoad = True
  12. PanDisplay.TriggerForceResize()
  13. End Sub
  14. Public ItemVersion As MyListItem
  15. ''' <summary>
  16. ''' 确保当前页面上的信息已正确显示。
  17. ''' </summary>
  18. Private Sub Reload()
  19. AniControlEnabled += 1
  20. '刷新设置项目
  21. ComboDisplayType.SelectedIndex = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto)
  22. BtnDisplayStar.Text = If(PageVersionLeft.Version.IsStar, "从收藏夹中移除", "加入收藏夹")
  23. BtnFolderMods.Visibility = If(PageVersionLeft.Version.Modable, Visibility.Visible, Visibility.Collapsed)
  24. '刷新版本显示
  25. PanDisplayItem.Children.Clear()
  26. ItemVersion = PageSelectRight.McVersionListItem(PageVersionLeft.Version)
  27. ItemVersion.IsHitTestVisible = False
  28. PanDisplayItem.Children.Add(ItemVersion)
  29. FrmMain.PageNameRefresh()
  30. '刷新版本图标
  31. ComboDisplayLogo.SelectedIndex = 0
  32. Dim Logo As String = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "Logo", "")
  33. Dim LogoCustom As Boolean = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "LogoCustom", "False")
  34. If LogoCustom Then
  35. For Each Selection As MyComboBoxItem In ComboDisplayLogo.Items
  36. If Selection.Tag = Logo OrElse (Selection.Tag = "PCL\Logo.png" AndAlso Logo.EndsWith("PCL\Logo.png")) Then
  37. ComboDisplayLogo.SelectedItem = Selection
  38. Exit For
  39. End If
  40. Next
  41. End If
  42. AniControlEnabled -= 1
  43. End Sub
  44. #Region "卡片:个性化"
  45. '版本分类
  46. Private Sub ComboDisplayType_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayType.SelectionChanged
  47. If Not (IsLoad AndAlso AniControlEnabled = 0) Then Return
  48. If ComboDisplayType.SelectedIndex <> 1 Then
  49. '改为不隐藏
  50. Try
  51. '若设置分类为可安装 Mod,则显示正常的 Mod 管理页面
  52. WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", ComboDisplayType.SelectedIndex)
  53. PageVersionLeft.Version.DisplayType = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto)
  54. FrmVersionLeft.RefreshModDisabled()
  55. WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存
  56. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  57. Catch ex As Exception
  58. Log(ex, "修改版本分类失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
  59. End Try
  60. Reload() '更新 “打开 Mod 文件夹” 按钮
  61. Else
  62. '改为隐藏
  63. Try
  64. If Not Setup.Get("HintHide") Then
  65. If MyMsgBox("确认要从版本列表中隐藏该版本吗?隐藏该版本后,它将不再出现于 PCL 显示的版本列表中。" & vbCrLf & "此后,在版本列表页面按下 F11 才可以查看被隐藏的版本。", "隐藏版本提示",, "取消") <> 1 Then
  66. ComboDisplayType.SelectedIndex = 0
  67. Return
  68. End If
  69. Setup.Set("HintHide", True)
  70. End If
  71. WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Hidden)
  72. WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存
  73. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  74. Catch ex As Exception
  75. Log(ex, "隐藏版本 " & PageVersionLeft.Version.Name & " 失败", LogLevel.Feedback)
  76. End Try
  77. End If
  78. End Sub
  79. '更改描述
  80. Private Sub BtnDisplayDesc_Click(sender As Object, e As EventArgs) Handles BtnDisplayDesc.Click
  81. Try
  82. Dim OldInfo As String = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "CustomInfo")
  83. Dim NewInfo As String = MyMsgBoxInput("更改描述", "修改版本的描述文本,留空则使用 PCL 的默认描述。", OldInfo, New ObjectModel.Collection(Of Validate), "默认描述")
  84. If NewInfo IsNot Nothing AndAlso OldInfo <> NewInfo Then WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "CustomInfo", NewInfo)
  85. PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
  86. Reload()
  87. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  88. Catch ex As Exception
  89. Log(ex, "版本 " & PageVersionLeft.Version.Name & " 描述更改失败", LogLevel.Msgbox)
  90. End Try
  91. End Sub
  92. '重命名版本
  93. Private Sub BtnDisplayRename_Click(sender As Object, e As EventArgs) Handles BtnDisplayRename.Click
  94. Try
  95. '确认输入的新名称
  96. Dim OldName As String = PageVersionLeft.Version.Name
  97. Dim OldPath As String = PageVersionLeft.Version.Path
  98. '修改此部分的同时修改快速安装的版本名检测*
  99. Dim NewName As String = MyMsgBoxInput("重命名版本", "", OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)})
  100. If String.IsNullOrWhiteSpace(NewName) Then Return
  101. Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
  102. '获取临时中间名,以防止仅修改大小写的重命名失败
  103. Dim TempName As String = NewName & "_temp"
  104. Dim TempPath As String = PathMcFolder & "versions\" & TempName & "\"
  105. Dim IsCaseChangedOnly As Boolean = NewName.ToLower = OldName.ToLower
  106. '读取版本 JSON 信息
  107. Dim JsonObject As JObject
  108. Dim OldJsonPath As String = ""
  109. Try
  110. OldJsonPath = PageVersionLeft.Version.GetJsonPath()
  111. JsonObject = GetJson(ReadFile(OldJsonPath))
  112. Catch ex As Exception
  113. Log(ex, "在重命名读取 json 时失败")
  114. JsonObject = PageVersionLeft.Version.JsonObject
  115. End Try
  116. '重命名主文件夹
  117. My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
  118. My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
  119. '清理 ini 缓存
  120. IniClearCache(PageVersionLeft.Version.PathIndie & "options.txt")
  121. IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
  122. '重命名 jar 文件与 natives 文件夹
  123. '不能进行遍历重命名,否则在版本名很短的时候容易误伤其他文件(#6443)
  124. If Directory.Exists($"{NewPath}{OldName}-natives") Then
  125. If IsCaseChangedOnly Then
  126. My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives", $"{OldName}natives_temp")
  127. My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives_temp", $"{NewName}-natives")
  128. Else
  129. DeleteDirectory($"{NewPath}{NewName}-natives")
  130. My.Computer.FileSystem.RenameDirectory($"{NewPath}{OldName}-natives", $"{NewName}-natives")
  131. End If
  132. End If
  133. If File.Exists($"{NewPath}{OldName}.jar") Then
  134. If IsCaseChangedOnly Then
  135. My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}.jar", $"{OldName}_temp.jar")
  136. My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}_temp.jar", $"{NewName}.jar")
  137. Else
  138. File.Delete($"{NewPath}{NewName}.jar")
  139. My.Computer.FileSystem.RenameFile($"{NewPath}{OldName}.jar", $"{NewName}.jar")
  140. End If
  141. End If
  142. '替换版本设置文件中的路径
  143. If File.Exists(NewPath & "PCL\Setup.ini") Then
  144. WriteFile(NewPath & "PCL\Setup.ini", ReadFile(NewPath & "PCL\Setup.ini").Replace(OldPath, NewPath))
  145. End If
  146. '更改已选中的版本
  147. If ReadIni(PathMcFolder & "PCL.ini", "Version") = OldName Then
  148. WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
  149. End If
  150. '处理JSON文件:先写入新文件,再删除旧文件
  151. Try
  152. '更新JSON内容中的id
  153. JsonObject("id") = NewName
  154. '写入新的JSON文件
  155. WriteFile(NewPath & NewName & ".json", JsonObject.ToString)
  156. '删除旧的JSON文件(现在在新路径下)
  157. Dim OldJsonInNewPath As String = NewPath & OldName & ".json"
  158. If File.Exists(OldJsonInNewPath) Then
  159. File.Delete(OldJsonInNewPath)
  160. End If
  161. Catch ex As Exception
  162. Log(ex, "重命名版本 json 失败")
  163. '如果JSON处理失败,尝试回滚整个操作
  164. Try
  165. '首先尝试恢复文件夹名
  166. If Directory.Exists(NewPath) AndAlso Not Directory.Exists(OldPath) Then
  167. '还原jar文件名
  168. If File.Exists($"{NewPath}{NewName}.jar") Then
  169. Try
  170. My.Computer.FileSystem.RenameFile($"{NewPath}{NewName}.jar", $"{OldName}.jar")
  171. Catch
  172. '忽略jar文件还原失败
  173. End Try
  174. End If
  175. '还原natives文件夹名
  176. If Directory.Exists($"{NewPath}{NewName}-natives") Then
  177. Try
  178. My.Computer.FileSystem.RenameDirectory($"{NewPath}{NewName}-natives", $"{OldName}-natives")
  179. Catch
  180. '忽略natives文件夹还原失败
  181. End Try
  182. End If
  183. '还原文件夹名
  184. My.Computer.FileSystem.RenameDirectory(NewPath, OldName)
  185. Hint("重命名失败:无法处理版本配置文件,已回滚更改", HintType.Critical)
  186. Return
  187. End If
  188. Catch rollbackEx As Exception
  189. Log(rollbackEx, "重命名失败后尝试回滚也失败")
  190. Hint("重命名失败:版本文件可能已损坏,请检查版本文件夹", HintType.Critical)
  191. Return
  192. End Try
  193. Throw ex
  194. End Try
  195. '刷新与提示
  196. Hint("重命名成功!", HintType.Finish)
  197. PageVersionLeft.Version = New McVersion(NewName).Load()
  198. If Not IsNothing(McVersionCurrent) AndAlso McVersionCurrent.Equals(PageVersionLeft.Version) Then WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
  199. Reload()
  200. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  201. Catch ex As Exception
  202. Log(ex, "重命名版本失败", LogLevel.Msgbox)
  203. End Try
  204. End Sub
  205. '版本图标
  206. Private Sub ComboDisplayLogo_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
  207. If Not (IsLoad AndAlso AniControlEnabled = 0) Then Return
  208. '选择 自定义 时修改图片
  209. Try
  210. If ComboDisplayLogo.SelectedItem Is ItemDisplayLogoCustom Then
  211. Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpeg;*.jpg;*.gif;*.webp)|*.png;*.jpeg;*.jpg;*.gif;*.webp", "选择图片")
  212. If FileName = "" Then
  213. Reload() '还原选项
  214. Return
  215. End If
  216. CopyFile(FileName, PageVersionLeft.Version.Path & "PCL\Logo.png")
  217. Else
  218. File.Delete(PageVersionLeft.Version.Path & "PCL\Logo.png")
  219. End If
  220. Catch ex As Exception
  221. Log(ex, "更改自定义版本图标失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
  222. End Try
  223. '进行更改
  224. Try
  225. Dim NewLogo As String = ComboDisplayLogo.SelectedItem.Tag
  226. WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "Logo", NewLogo)
  227. WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "LogoCustom", Not NewLogo = "")
  228. '刷新显示
  229. WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存
  230. PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
  231. Reload()
  232. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  233. Catch ex As Exception
  234. Log(ex, "更改版本图标失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
  235. End Try
  236. End Sub
  237. '收藏夹
  238. Private Sub BtnDisplayStar_Click(sender As Object, e As EventArgs) Handles BtnDisplayStar.Click
  239. Try
  240. WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "IsStar", Not PageVersionLeft.Version.IsStar)
  241. PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
  242. Reload()
  243. McVersionListForceRefresh = True
  244. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  245. Catch ex As Exception
  246. Log(ex, "版本 " & PageVersionLeft.Version.Name & " 收藏状态更改失败", LogLevel.Msgbox)
  247. End Try
  248. End Sub
  249. #End Region
  250. #Region "卡片:快捷方式"
  251. '版本文件夹
  252. Private Sub BtnFolderVersion_Click() Handles BtnFolderVersion.Click
  253. OpenVersionFolder(PageVersionLeft.Version)
  254. End Sub
  255. Public Shared Sub OpenVersionFolder(Version As McVersion)
  256. OpenExplorer(Version.Path)
  257. End Sub
  258. '存档文件夹
  259. Private Sub BtnFolderSaves_Click() Handles BtnFolderSaves.Click
  260. Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "saves\"
  261. Directory.CreateDirectory(FolderPath)
  262. OpenExplorer(FolderPath)
  263. End Sub
  264. 'Mod 文件夹
  265. Private Sub BtnFolderMods_Click() Handles BtnFolderMods.Click
  266. Dim FolderPath As String = PageVersionLeft.Version.PathIndie & "mods\"
  267. Directory.CreateDirectory(FolderPath)
  268. OpenExplorer(FolderPath)
  269. End Sub
  270. #End Region
  271. #Region "卡片:管理"
  272. '导出启动脚本
  273. Private Sub BtnManageScript_Click() Handles BtnManageScript.Click
  274. Try
  275. '弹窗要求指定脚本的保存位置
  276. Dim SavePath As String = SelectSaveFile("选择脚本保存位置", "启动 " & PageVersionLeft.Version.Name & ".bat", "批处理文件(*.bat)|*.bat")
  277. If SavePath = "" Then Return
  278. '检查中断(等玩家选完弹窗指不定任务就结束了呢……)
  279. If McLaunchLoader.State = LoadState.Loading Then
  280. Hint("请在当前启动任务结束后再试!", HintType.Critical)
  281. Return
  282. End If
  283. '生成脚本
  284. If McLaunchStart(New McLaunchOptions With {.SaveBatch = SavePath, .Version = PageVersionLeft.Version}) Then
  285. If Setup.Get("LoginType") = McLoginType.Legacy Then
  286. Hint("正在导出启动脚本……")
  287. Else
  288. Hint("正在导出启动脚本……(注意,使用脚本启动可能会导致登录失效!)")
  289. End If
  290. End If
  291. Catch ex As Exception
  292. Log(ex, "导出启动脚本失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Msgbox)
  293. End Try
  294. End Sub
  295. '补全文件
  296. Private Sub BtnManageCheck_Click(sender As Object, e As EventArgs) Handles BtnManageCheck.Click
  297. Try
  298. '忽略文件检查提示
  299. If ShouldIgnoreFileCheck(PageVersionLeft.Version) Then
  300. Hint("请先关闭 [版本设置 → 设置 → 高级启动选项 → 关闭文件校验],然后再尝试补全文件!", HintType.Info)
  301. Return
  302. End If
  303. '重复任务检查
  304. For Each OngoingLoader In LoaderTaskbar
  305. If OngoingLoader.Name <> PageVersionLeft.Version.Name & " 文件补全" Then Continue For
  306. Hint("正在处理中,请稍候!", HintType.Critical)
  307. Return
  308. Next
  309. '启动
  310. Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload))
  311. Loader.OnStateChanged =
  312. Sub()
  313. Select Case Loader.State
  314. Case LoadState.Finished
  315. Hint(Loader.Name & "成功!", HintType.Finish)
  316. Case LoadState.Failed
  317. Hint(Loader.Name & "失败:" & GetExceptionSummary(Loader.Error), HintType.Critical)
  318. Case LoadState.Aborted
  319. Hint(Loader.Name & "已取消!", HintType.Info)
  320. End Select
  321. End Sub
  322. Loader.Start(PageVersionLeft.Version.Name)
  323. LoaderTaskbarAdd(Loader)
  324. FrmMain.BtnExtraDownload.ShowRefresh()
  325. FrmMain.BtnExtraDownload.Ribble()
  326. Catch ex As Exception
  327. Log(ex, "尝试补全文件失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Msgbox)
  328. End Try
  329. End Sub
  330. '删除版本
  331. '修改此代码时,同时修改 PageSelectRight 中的代码
  332. Private Sub BtnManageDelete_Click(sender As Object, e As EventArgs) Handles BtnManageDelete.Click
  333. Try
  334. Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
  335. Dim IsHintIndie As Boolean = PageVersionLeft.Version.State <> McVersionState.Error AndAlso PageVersionLeft.Version.PathIndie <> PathMcFolder
  336. Select Case MyMsgBox($"你确定要{If(IsShiftPressed, "永久", "")}删除版本 {PageVersionLeft.Version.Name} 吗?" &
  337. If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
  338. "版本删除确认", , "取消",, IsHintIndie OrElse IsShiftPressed)
  339. Case 1
  340. IniClearCache(PageVersionLeft.Version.PathIndie & "options.txt")
  341. IniClearCache(PageVersionLeft.Version.Path & "PCL\Setup.ini")
  342. If IsShiftPressed Then
  343. DeleteDirectory(PageVersionLeft.Version.Path)
  344. Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish)
  345. Else
  346. FileIO.FileSystem.DeleteDirectory(PageVersionLeft.Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
  347. Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
  348. End If
  349. Case 2
  350. Return
  351. End Select
  352. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  353. FrmMain.PageBack()
  354. Catch ex As OperationCanceledException
  355. Log(ex, "删除版本 " & PageVersionLeft.Version.Name & " 被主动取消")
  356. Catch ex As Exception
  357. Log(ex, "删除版本 " & PageVersionLeft.Version.Name & " 失败", LogLevel.Msgbox)
  358. End Try
  359. End Sub
  360. #End Region
  361. End Class