PageDownloadInstall.xaml.vb 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. Public Class PageDownloadInstall
  2. Private Sub LoaderInit() Handles Me.Initialized
  3. PageLoaderInit(LoadMinecraft, PanLoad, PanBack, Nothing, DlClientListLoader, AddressOf LoadMinecraft_OnFinish)
  4. End Sub
  5. Private IsLoad As Boolean = False
  6. Private Sub Init() Handles Me.Loaded
  7. PanBack.ScrollToHome()
  8. DlOptiFineListLoader.Start()
  9. DlLiteLoaderListLoader.Start()
  10. DlFabricListLoader.Start()
  11. DlNeoForgeListLoader.Start()
  12. '重载预览
  13. TextSelectName.ValidateRules = New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions")}
  14. TextSelectName.Validate()
  15. SelectReload()
  16. '非重复加载部分
  17. If IsLoad Then Exit Sub
  18. IsLoad = True
  19. McDownloadForgeRecommendedRefresh()
  20. LoadOptiFine.State = DlOptiFineListLoader
  21. LoadLiteLoader.State = DlLiteLoaderListLoader
  22. LoadFabric.State = DlFabricListLoader
  23. LoadFabricApi.State = DlFabricApiLoader
  24. LoadNeoForge.State = DlNeoForgeListLoader
  25. LoadOptiFabric.State = DlOptiFabricLoader
  26. End Sub
  27. #Region "页面切换"
  28. '页面切换动画
  29. Public IsInSelectPage As Boolean = False
  30. Private IsFirstLoaded As Boolean = False
  31. Private Sub EnterSelectPage()
  32. If IsInSelectPage Then Exit Sub
  33. IsInSelectPage = True
  34. AutoSelectedFabricApi = False
  35. AutoSelectedOptiFabric = False
  36. IsSelectNameEdited = False
  37. PanSelect.Visibility = Visibility.Visible
  38. PanSelect.IsHitTestVisible = True
  39. PanMinecraft.IsHitTestVisible = False
  40. PanBack.IsHitTestVisible = False
  41. PanBack.ScrollToHome()
  42. CardMinecraft.IsSwaped = True
  43. CardOptiFine.IsSwaped = True
  44. CardLiteLoader.IsSwaped = True
  45. CardForge.IsSwaped = True
  46. CardNeoForge.IsSwaped = True
  47. CardFabric.IsSwaped = True
  48. CardFabricApi.IsSwaped = True
  49. CardOptiFabric.IsSwaped = True
  50. If Not Setup.Get("HintInstallBack") Then
  51. Setup.Set("HintInstallBack", True)
  52. Hint("点击 Minecraft 项即可返回游戏主版本选择页面!")
  53. End If
  54. '如果在选择页面按了刷新键,选择页的东西可能会由于动画被隐藏,但不会由于加载结束而再次显示,因此这里需要手动恢复
  55. For Each Card In GetAllAnimControls(PanSelect)
  56. Card.Opacity = 1
  57. Card.RenderTransform = New TranslateTransform
  58. Next
  59. '启动 Forge 加载
  60. If SelectedMinecraftId.StartsWith("1.") Then
  61. Dim ForgeLoader = New LoaderTask(Of String, List(Of DlForgeVersionEntry))("DlForgeVersion " & SelectedMinecraftId, AddressOf DlForgeVersionMain)
  62. LoadForge.State = ForgeLoader
  63. ForgeLoader.Start(SelectedMinecraftId)
  64. End If
  65. '启动 Fabric API、OptiFabric 加载
  66. DlFabricApiLoader.Start()
  67. DlOptiFabricLoader.Start()
  68. AniStart({
  69. AaOpacity(PanMinecraft, -PanMinecraft.Opacity, 100, 10),
  70. AaTranslateX(PanMinecraft, -50 - CType(PanMinecraft.RenderTransform, TranslateTransform).X, 110, 10),
  71. AaCode(
  72. Sub()
  73. PanBack.ScrollToHome()
  74. TextSelectName.Validate()
  75. OptiFine_Loaded()
  76. LiteLoader_Loaded()
  77. Forge_Loaded()
  78. NeoForge_Loaded()
  79. Fabric_Loaded()
  80. FabricApi_Loaded()
  81. OptiFabric_Loaded()
  82. SelectReload()
  83. End Sub, After:=True),
  84. AaOpacity(PanSelect, 1 - PanSelect.Opacity, 250, 150),
  85. AaTranslateX(PanSelect, -CType(PanSelect.RenderTransform, TranslateTransform).X, 500, 150, Ease:=New AniEaseOutBack(AniEasePower.Weak)),
  86. AaCode(
  87. Sub()
  88. PanMinecraft.Visibility = Visibility.Collapsed
  89. PanBack.IsHitTestVisible = True
  90. '初始化 Binding
  91. If IsFirstLoaded Then Exit Sub
  92. IsFirstLoaded = True
  93. BtnOptiFineClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFine.MainTextBlock, .Mode = BindingMode.OneWay})
  94. BtnLiteLoaderClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardLiteLoader.MainTextBlock, .Mode = BindingMode.OneWay})
  95. BtnForgeClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardForge.MainTextBlock, .Mode = BindingMode.OneWay})
  96. BtnNeoForgeClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardNeoForge.MainTextBlock, .Mode = BindingMode.OneWay})
  97. BtnFabricClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardFabric.MainTextBlock, .Mode = BindingMode.OneWay})
  98. BtnFabricApiClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardFabricApi.MainTextBlock, .Mode = BindingMode.OneWay})
  99. BtnOptiFabricClearInner.SetBinding(Shapes.Path.FillProperty, New Binding("Foreground") With {.Source = CardOptiFabric.MainTextBlock, .Mode = BindingMode.OneWay})
  100. End Sub,, True)
  101. }, "FrmDownloadInstall SelectPageSwitch", True)
  102. End Sub
  103. Public Sub ExitSelectPage()
  104. If Not IsInSelectPage Then Exit Sub
  105. IsInSelectPage = False
  106. SelectClear() '清除已选择项
  107. PanMinecraft.Visibility = Visibility.Visible
  108. PanSelect.IsHitTestVisible = False
  109. PanMinecraft.IsHitTestVisible = True
  110. PanBack.IsHitTestVisible = False
  111. PanBack.ScrollToHome()
  112. AniStart({
  113. AaOpacity(PanSelect, -PanSelect.Opacity, 90, 10),
  114. AaTranslateX(PanSelect, 50 - CType(PanSelect.RenderTransform, TranslateTransform).X, 100, 10),
  115. AaCode(Sub() PanBack.ScrollToHome(), After:=True),
  116. AaOpacity(PanMinecraft, 1 - PanMinecraft.Opacity, 150, 100),
  117. AaTranslateX(PanMinecraft, -CType(PanMinecraft.RenderTransform, TranslateTransform).X, 400, 100, Ease:=New AniEaseOutBack(AniEasePower.Weak)),
  118. AaCode(Sub()
  119. PanSelect.Visibility = Visibility.Collapsed
  120. PanBack.IsHitTestVisible = True
  121. End Sub,, True)
  122. }, "FrmDownloadInstall SelectPageSwitch")
  123. End Sub
  124. '页面切换触发
  125. Public Sub MinecraftSelected(sender As MyListItem, e As MouseButtonEventArgs)
  126. SelectedMinecraftId = sender.Title
  127. SelectedMinecraftJsonUrl = sender.Tag("url").ToString
  128. SelectedMinecraftIcon = sender.Logo
  129. EnterSelectPage()
  130. End Sub
  131. Private Sub CardMinecraft_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardMinecraft.PreviewSwap
  132. ExitSelectPage()
  133. e.Handled = True
  134. End Sub
  135. #End Region
  136. #Region "选择"
  137. 'Minecraft
  138. Private SelectedMinecraftId As String
  139. Private SelectedMinecraftJsonUrl As String
  140. Private SelectedMinecraftIcon As String
  141. 'OptiFine
  142. Private SelectedOptiFine As DlOptiFineListEntry = Nothing
  143. Private Sub SetOptiFineInfoShow(IsShow As String)
  144. If PanOptiFineInfo.Tag = IsShow Then Exit Sub
  145. PanOptiFineInfo.Tag = IsShow
  146. If IsShow = "True" Then
  147. '显示信息栏
  148. AniStart({
  149. AaTranslateY(PanOptiFineInfo, -CType(PanOptiFineInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  150. AaOpacity(PanOptiFineInfo, 1 - PanOptiFineInfo.Opacity, 100, 90)
  151. }, "SetOptiFineInfoShow")
  152. Else
  153. '隐藏信息栏
  154. AniStart({
  155. AaTranslateY(PanOptiFineInfo, 6 - CType(PanOptiFineInfo.RenderTransform, TranslateTransform).Y, 200),
  156. AaOpacity(PanOptiFineInfo, -PanOptiFineInfo.Opacity, 100)
  157. }, "SetOptiFineInfoShow")
  158. End If
  159. End Sub
  160. 'LiteLoader
  161. Private SelectedLiteLoader As DlLiteLoaderListEntry = Nothing
  162. Private Sub SetLiteLoaderInfoShow(IsShow As String)
  163. If PanLiteLoaderInfo.Tag = IsShow Then Exit Sub
  164. PanLiteLoaderInfo.Tag = IsShow
  165. If IsShow = "True" Then
  166. '显示信息栏
  167. AniStart({
  168. AaTranslateY(PanLiteLoaderInfo, -CType(PanLiteLoaderInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  169. AaOpacity(PanLiteLoaderInfo, 1 - PanLiteLoaderInfo.Opacity, 100, 90)
  170. }, "SetLiteLoaderInfoShow")
  171. Else
  172. '隐藏信息栏
  173. AniStart({
  174. AaTranslateY(PanLiteLoaderInfo, 6 - CType(PanLiteLoaderInfo.RenderTransform, TranslateTransform).Y, 200),
  175. AaOpacity(PanLiteLoaderInfo, -PanLiteLoaderInfo.Opacity, 100)
  176. }, "SetLiteLoaderInfoShow")
  177. End If
  178. End Sub
  179. 'Forge
  180. Private SelectedForge As DlForgeVersionEntry = Nothing
  181. Private Sub SetForgeInfoShow(IsShow As String)
  182. If PanForgeInfo.Tag = IsShow Then Exit Sub
  183. PanForgeInfo.Tag = IsShow
  184. If IsShow = "True" Then
  185. '显示信息栏
  186. AniStart({
  187. AaTranslateY(PanForgeInfo, -CType(PanForgeInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  188. AaOpacity(PanForgeInfo, 1 - PanForgeInfo.Opacity, 100, 90)
  189. }, "SetForgeInfoShow")
  190. Else
  191. '隐藏信息栏
  192. AniStart({
  193. AaTranslateY(PanForgeInfo, 6 - CType(PanForgeInfo.RenderTransform, TranslateTransform).Y, 200),
  194. AaOpacity(PanForgeInfo, -PanForgeInfo.Opacity, 100)
  195. }, "SetForgeInfoShow")
  196. End If
  197. End Sub
  198. 'NeoForge
  199. Private SelectedNeoForge As DlNeoForgeListEntry = Nothing
  200. Private Sub SetNeoForgeInfoShow(IsShow As String)
  201. If PanNeoForgeInfo.Tag = IsShow Then Exit Sub
  202. PanNeoForgeInfo.Tag = IsShow
  203. If IsShow = "True" Then
  204. '显示信息栏
  205. AniStart({
  206. AaTranslateY(PanNeoForgeInfo, -CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  207. AaOpacity(PanNeoForgeInfo, 1 - PanNeoForgeInfo.Opacity, 100, 90)
  208. }, "SetNeoForgeInfoShow")
  209. Else
  210. '隐藏信息栏
  211. AniStart({
  212. AaTranslateY(PanNeoForgeInfo, 6 - CType(PanNeoForgeInfo.RenderTransform, TranslateTransform).Y, 200),
  213. AaOpacity(PanNeoForgeInfo, -PanNeoForgeInfo.Opacity, 100)
  214. }, "SetNeoForgeInfoShow")
  215. End If
  216. End Sub
  217. 'Fabric
  218. Private SelectedFabric As String = Nothing
  219. Private Sub SetFabricInfoShow(IsShow As String)
  220. If PanFabricInfo.Tag = IsShow Then Exit Sub
  221. PanFabricInfo.Tag = IsShow
  222. If IsShow = "True" Then
  223. '显示信息栏
  224. AniStart({
  225. AaTranslateY(PanFabricInfo, -CType(PanFabricInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  226. AaOpacity(PanFabricInfo, 1 - PanFabricInfo.Opacity, 100, 90)
  227. }, "SetFabricInfoShow")
  228. Else
  229. '隐藏信息栏
  230. AniStart({
  231. AaTranslateY(PanFabricInfo, 6 - CType(PanFabricInfo.RenderTransform, TranslateTransform).Y, 200),
  232. AaOpacity(PanFabricInfo, -PanFabricInfo.Opacity, 100)
  233. }, "SetFabricInfoShow")
  234. End If
  235. End Sub
  236. 'FabricApi
  237. Private SelectedFabricApi As CompFile = Nothing
  238. Private Sub SetFabricApiInfoShow(IsShow As String)
  239. If PanFabricApiInfo.Tag = IsShow Then Exit Sub
  240. PanFabricApiInfo.Tag = IsShow
  241. If IsShow = "True" Then
  242. '显示信息栏
  243. AniStart({
  244. AaTranslateY(PanFabricApiInfo, -CType(PanFabricApiInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  245. AaOpacity(PanFabricApiInfo, 1 - PanFabricApiInfo.Opacity, 100, 90)
  246. }, "SetFabricApiInfoShow")
  247. Else
  248. '隐藏信息栏
  249. AniStart({
  250. AaTranslateY(PanFabricApiInfo, 6 - CType(PanFabricApiInfo.RenderTransform, TranslateTransform).Y, 200),
  251. AaOpacity(PanFabricApiInfo, -PanFabricApiInfo.Opacity, 100)
  252. }, "SetFabricApiInfoShow")
  253. End If
  254. End Sub
  255. 'OptiFabric
  256. Private SelectedOptiFabric As CompFile = Nothing
  257. Private Sub SetOptiFabricInfoShow(IsShow As String)
  258. If PanOptiFabricInfo.Tag = IsShow Then Exit Sub
  259. PanOptiFabricInfo.Tag = IsShow
  260. If IsShow = "True" Then
  261. '显示信息栏
  262. AniStart({
  263. AaTranslateY(PanOptiFabricInfo, -CType(PanOptiFabricInfo.RenderTransform, TranslateTransform).Y, 270, 100, Ease:=New AniEaseOutBack),
  264. AaOpacity(PanOptiFabricInfo, 1 - PanOptiFabricInfo.Opacity, 100, 90)
  265. }, "SetOptiFabricInfoShow")
  266. Else
  267. '隐藏信息栏
  268. AniStart({
  269. AaTranslateY(PanOptiFabricInfo, 6 - CType(PanOptiFabricInfo.RenderTransform, TranslateTransform).Y, 200),
  270. AaOpacity(PanOptiFabricInfo, -PanOptiFabricInfo.Opacity, 100)
  271. }, "SetOptiFabricInfoShow")
  272. End If
  273. End Sub
  274. Private IsReloading As Boolean = False '#3742 中,LoadOptiFineGetError 会初始化 LoadOptiFine,触发事件 LoadOptiFine.StateChanged,导致再次调用 SelectReload
  275. ''' <summary>
  276. ''' 重载已选择的项目的显示。
  277. ''' </summary>
  278. 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
  279. If SelectedMinecraftId Is Nothing OrElse IsReloading Then Exit Sub
  280. IsReloading = True
  281. '主预览
  282. SelectNameUpdate()
  283. ItemSelect.Title = TextSelectName.Text
  284. ItemSelect.Info = GetSelectInfo()
  285. ItemSelect.Logo = GetSelectLogo()
  286. 'Minecraft
  287. LabMinecraft.Text = SelectedMinecraftId
  288. ImgMinecraft.Source = New MyBitmap(SelectedMinecraftIcon)
  289. 'OptiFine
  290. Dim OptiFineError As String = LoadOptiFineGetError()
  291. CardOptiFine.MainSwap.Visibility = If(OptiFineError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  292. If OptiFineError IsNot Nothing Then CardOptiFine.IsSwaped = True '例如在同时展开卡片时选择了不兼容项则强制折叠
  293. SetOptiFineInfoShow(CardOptiFine.IsSwaped)
  294. If SelectedOptiFine Is Nothing Then
  295. BtnOptiFineClear.Visibility = Visibility.Collapsed
  296. ImgOptiFine.Visibility = Visibility.Collapsed
  297. LabOptiFine.Text = If(OptiFineError, "点击选择")
  298. LabOptiFine.Foreground = ColorGray4
  299. Else
  300. BtnOptiFineClear.Visibility = Visibility.Visible
  301. ImgOptiFine.Visibility = Visibility.Visible
  302. LabOptiFine.Text = SelectedOptiFine.NameDisplay.Replace(SelectedMinecraftId & " ", "")
  303. LabOptiFine.Foreground = ColorGray1
  304. End If
  305. 'LiteLoader
  306. If Not SelectedMinecraftId.Contains("1.") OrElse Val(SelectedMinecraftId.Split(".")(1)) > 12 Then
  307. CardLiteLoader.Visibility = Visibility.Collapsed
  308. Else
  309. CardLiteLoader.Visibility = Visibility.Visible
  310. Dim LiteLoaderError As String = LoadLiteLoaderGetError()
  311. CardLiteLoader.MainSwap.Visibility = If(LiteLoaderError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  312. If LiteLoaderError IsNot Nothing Then CardLiteLoader.IsSwaped = True '例如在同时展开卡片时选择了不兼容项则强制折叠
  313. SetLiteLoaderInfoShow(CardLiteLoader.IsSwaped)
  314. If SelectedLiteLoader Is Nothing Then
  315. BtnLiteLoaderClear.Visibility = Visibility.Collapsed
  316. ImgLiteLoader.Visibility = Visibility.Collapsed
  317. LabLiteLoader.Text = If(LiteLoaderError, "点击选择")
  318. LabLiteLoader.Foreground = ColorGray4
  319. Else
  320. BtnLiteLoaderClear.Visibility = Visibility.Visible
  321. ImgLiteLoader.Visibility = Visibility.Visible
  322. LabLiteLoader.Text = SelectedLiteLoader.Inherit
  323. LabLiteLoader.Foreground = ColorGray1
  324. End If
  325. End If
  326. 'Forge
  327. Dim ForgeError As String = LoadForgeGetError()
  328. CardForge.MainSwap.Visibility = If(ForgeError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  329. If ForgeError IsNot Nothing Then CardForge.IsSwaped = True
  330. SetForgeInfoShow(CardForge.IsSwaped)
  331. If SelectedForge Is Nothing Then
  332. BtnForgeClear.Visibility = Visibility.Collapsed
  333. ImgForge.Visibility = Visibility.Collapsed
  334. LabForge.Text = If(ForgeError, "点击选择")
  335. LabForge.Foreground = ColorGray4
  336. Else
  337. BtnForgeClear.Visibility = Visibility.Visible
  338. ImgForge.Visibility = Visibility.Visible
  339. LabForge.Text = SelectedForge.VersionName
  340. LabForge.Foreground = ColorGray1
  341. End If
  342. 'NeoForge
  343. If Not SelectedMinecraftId.Contains("1.") OrElse Val(SelectedMinecraftId.Split(".")(1)) <= 19 Then
  344. CardNeoForge.Visibility = Visibility.Collapsed
  345. Else
  346. CardNeoForge.Visibility = Visibility.Visible
  347. Dim NeoForgeError As String = LoadNeoForgeGetError()
  348. CardNeoForge.MainSwap.Visibility = If(NeoForgeError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  349. If NeoForgeError IsNot Nothing Then CardNeoForge.IsSwaped = True
  350. SetNeoForgeInfoShow(CardNeoForge.IsSwaped)
  351. If SelectedNeoForge Is Nothing Then
  352. BtnNeoForgeClear.Visibility = Visibility.Collapsed
  353. ImgNeoForge.Visibility = Visibility.Collapsed
  354. LabNeoForge.Text = If(NeoForgeError, "点击选择")
  355. LabNeoForge.Foreground = ColorGray4
  356. Else
  357. BtnNeoForgeClear.Visibility = Visibility.Visible
  358. ImgNeoForge.Visibility = Visibility.Visible
  359. LabNeoForge.Text = SelectedNeoForge.VersionName
  360. LabNeoForge.Foreground = ColorGray1
  361. End If
  362. End If
  363. 'Fabric
  364. If SelectedMinecraftId.Contains("1.") AndAlso Val(SelectedMinecraftId.Split(".")(1)) <= 13 Then
  365. CardFabric.Visibility = Visibility.Collapsed
  366. Else
  367. CardFabric.Visibility = Visibility.Visible
  368. Dim FabricError As String = LoadFabricGetError()
  369. CardFabric.MainSwap.Visibility = If(FabricError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  370. If FabricError IsNot Nothing Then CardFabric.IsSwaped = True
  371. SetFabricInfoShow(CardFabric.IsSwaped)
  372. If SelectedFabric Is Nothing Then
  373. BtnFabricClear.Visibility = Visibility.Collapsed
  374. ImgFabric.Visibility = Visibility.Collapsed
  375. LabFabric.Text = If(FabricError, "点击选择")
  376. LabFabric.Foreground = ColorGray4
  377. Else
  378. BtnFabricClear.Visibility = Visibility.Visible
  379. ImgFabric.Visibility = Visibility.Visible
  380. LabFabric.Text = SelectedFabric.Replace("+build", "")
  381. LabFabric.Foreground = ColorGray1
  382. End If
  383. End If
  384. 'FabricApi
  385. If SelectedFabric Is Nothing Then
  386. CardFabricApi.Visibility = Visibility.Collapsed
  387. Else
  388. CardFabricApi.Visibility = Visibility.Visible
  389. Dim FabricApiError As String = LoadFabricApiGetError()
  390. CardFabricApi.MainSwap.Visibility = If(FabricApiError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  391. If FabricApiError IsNot Nothing OrElse SelectedFabric Is Nothing Then CardFabricApi.IsSwaped = True
  392. SetFabricApiInfoShow(CardFabricApi.IsSwaped)
  393. If SelectedFabricApi Is Nothing Then
  394. BtnFabricApiClear.Visibility = Visibility.Collapsed
  395. ImgFabricApi.Visibility = Visibility.Collapsed
  396. LabFabricApi.Text = If(FabricApiError, "点击选择")
  397. LabFabricApi.Foreground = ColorGray4
  398. Else
  399. BtnFabricApiClear.Visibility = Visibility.Visible
  400. ImgFabricApi.Visibility = Visibility.Visible
  401. LabFabricApi.Text = SelectedFabricApi.DisplayName.Split("]")(1).Replace("Fabric API ", "").Replace(" build ", ".").Split("+").First.Trim
  402. LabFabricApi.Foreground = ColorGray1
  403. End If
  404. End If
  405. 'OptiFabric
  406. If SelectedFabric Is Nothing OrElse SelectedOptiFine Is Nothing Then
  407. CardOptiFabric.Visibility = Visibility.Collapsed
  408. Else
  409. CardOptiFabric.Visibility = Visibility.Visible
  410. Dim OptiFabricError As String = LoadOptiFabricGetError()
  411. CardOptiFabric.MainSwap.Visibility = If(OptiFabricError Is Nothing, Visibility.Visible, Visibility.Collapsed)
  412. If OptiFabricError IsNot Nothing OrElse SelectedFabric Is Nothing Then CardOptiFabric.IsSwaped = True
  413. SetOptiFabricInfoShow(CardOptiFabric.IsSwaped)
  414. If SelectedOptiFabric Is Nothing Then
  415. BtnOptiFabricClear.Visibility = Visibility.Collapsed
  416. ImgOptiFabric.Visibility = Visibility.Collapsed
  417. LabOptiFabric.Text = If(OptiFabricError, "点击选择")
  418. LabOptiFabric.Foreground = ColorGray4
  419. Else
  420. BtnOptiFabricClear.Visibility = Visibility.Visible
  421. ImgOptiFabric.Visibility = Visibility.Visible
  422. LabOptiFabric.Text = SelectedOptiFabric.DisplayName.ToLower.Replace("optifabric-", "").Replace(".jar", "").Trim.TrimStart("v")
  423. LabOptiFabric.Foreground = ColorGray1
  424. End If
  425. End If
  426. '主警告
  427. If SelectedFabric IsNot Nothing AndAlso SelectedFabricApi Is Nothing Then
  428. HintFabricAPI.Visibility = Visibility.Visible
  429. Else
  430. HintFabricAPI.Visibility = Visibility.Collapsed
  431. End If
  432. If SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso SelectedOptiFabric Is Nothing Then
  433. If SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15") Then
  434. HintOptiFabric.Visibility = Visibility.Collapsed
  435. HintOptiFabricOld.Visibility = Visibility.Visible
  436. Else
  437. HintOptiFabric.Visibility = Visibility.Visible
  438. HintOptiFabricOld.Visibility = Visibility.Collapsed
  439. End If
  440. Else
  441. HintOptiFabric.Visibility = Visibility.Collapsed
  442. HintOptiFabricOld.Visibility = Visibility.Collapsed
  443. End If
  444. If SelectedMinecraftId.Contains("1.") AndAlso Val(SelectedMinecraftId.Split(".")(1)) >= 16 AndAlso SelectedOptiFine IsNot Nothing AndAlso
  445. (SelectedForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) Then
  446. HintModOptiFine.Visibility = Visibility.Visible
  447. Else
  448. HintModOptiFine.Visibility = Visibility.Collapsed
  449. End If
  450. '结束
  451. IsReloading = False
  452. End Sub
  453. ''' <summary>
  454. ''' 清空已选择的项目。
  455. ''' </summary>
  456. Private Sub SelectClear()
  457. SelectedMinecraftId = Nothing
  458. SelectedMinecraftJsonUrl = Nothing
  459. SelectedMinecraftIcon = Nothing
  460. SelectedOptiFine = Nothing
  461. SelectedLiteLoader = Nothing
  462. SelectedForge = Nothing
  463. SelectedNeoForge = Nothing
  464. SelectedFabric = Nothing
  465. SelectedFabricApi = Nothing
  466. SelectedOptiFabric = Nothing
  467. End Sub
  468. '显示信息获取
  469. ''' <summary>
  470. ''' 获取默认版本名。
  471. ''' </summary>
  472. Private Function GetSelectName() As String
  473. Dim Name As String = SelectedMinecraftId
  474. If SelectedFabric IsNot Nothing Then
  475. Name += "-Fabric " & SelectedFabric.Replace("+build", "")
  476. End If
  477. If SelectedForge IsNot Nothing Then
  478. Name += "-Forge_" & SelectedForge.VersionName
  479. End If
  480. If SelectedNeoForge IsNot Nothing Then
  481. Name += "-NeoForge_" & SelectedNeoForge.VersionName
  482. End If
  483. If SelectedLiteLoader IsNot Nothing Then
  484. Name += "-LiteLoader"
  485. End If
  486. If SelectedOptiFine IsNot Nothing Then
  487. Name += "-OptiFine_" & SelectedOptiFine.NameDisplay.Replace(SelectedMinecraftId & " ", "").Replace(" ", "_")
  488. End If
  489. Return Name
  490. End Function
  491. ''' <summary>
  492. ''' 获取版本描述信息。
  493. ''' </summary>
  494. Private Function GetSelectInfo() As String
  495. Dim Info As String = ""
  496. If SelectedFabric IsNot Nothing Then
  497. Info += ", Fabric " & SelectedFabric.Replace("+build", "")
  498. End If
  499. If SelectedForge IsNot Nothing Then
  500. Info += ", Forge " & SelectedForge.VersionName
  501. End If
  502. If SelectedNeoForge IsNot Nothing Then
  503. Info += ", NeoForge " & SelectedNeoForge.VersionName
  504. End If
  505. If SelectedLiteLoader IsNot Nothing Then
  506. Info += ", LiteLoader"
  507. End If
  508. If SelectedOptiFine IsNot Nothing Then
  509. Info += ", OptiFine " & SelectedOptiFine.NameDisplay.Replace(SelectedMinecraftId & " ", "")
  510. End If
  511. If Info = "" Then Info = ", 无附加安装"
  512. Return Info.TrimStart(", ".ToCharArray())
  513. End Function
  514. ''' <summary>
  515. ''' 获取版本图标。
  516. ''' </summary>
  517. Private Function GetSelectLogo() As String
  518. If SelectedFabric IsNot Nothing Then
  519. Return "pack://application:,,,/images/Blocks/Fabric.png"
  520. ElseIf SelectedForge IsNot Nothing Then
  521. Return "pack://application:,,,/images/Blocks/Anvil.png"
  522. ElseIf SelectedNeoForge IsNot Nothing Then
  523. Return "pack://application:,,,/images/Blocks/NeoForge.png"
  524. ElseIf SelectedLiteLoader IsNot Nothing Then
  525. Return "pack://application:,,,/images/Blocks/Egg.png"
  526. ElseIf SelectedOptiFine IsNot Nothing Then
  527. Return "pack://application:,,,/images/Blocks/GrassPath.png"
  528. Else
  529. Return SelectedMinecraftIcon
  530. End If
  531. End Function
  532. '版本名处理
  533. Private IsSelectNameEdited As Boolean = False
  534. Private IsSelectNameChanging As Boolean = False
  535. Private Sub SelectNameUpdate()
  536. If IsSelectNameEdited OrElse IsSelectNameChanging Then Exit Sub
  537. IsSelectNameChanging = True
  538. TextSelectName.Text = GetSelectName()
  539. IsSelectNameChanging = False
  540. End Sub
  541. Private Sub TextSelectName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles TextSelectName.TextChanged
  542. If IsSelectNameChanging Then Exit Sub
  543. IsSelectNameEdited = True
  544. SelectReload()
  545. End Sub
  546. Private Sub TextSelectName_ValidateChanged(sender As Object, e As EventArgs) Handles TextSelectName.ValidateChanged
  547. BtnSelectStart.IsEnabled = TextSelectName.ValidateResult = ""
  548. End Sub
  549. #End Region
  550. #Region "加载器"
  551. '结果数据化
  552. Private Sub LoadMinecraft_OnFinish()
  553. ExitSelectPage() '返回
  554. Try
  555. Dim Dict As New Dictionary(Of String, List(Of JObject)) From {
  556. {"正式版", New List(Of JObject)}, {"预览版", New List(Of JObject)}, {"远古版", New List(Of JObject)}, {"愚人节版", New List(Of JObject)}
  557. }
  558. Dim Versions As JArray = DlClientListLoader.Output.Value("versions")
  559. For Each Version As JObject In Versions
  560. '确定分类
  561. Dim Type As String = Version("type")
  562. Select Case Type
  563. Case "release"
  564. Type = "正式版"
  565. Case "snapshot"
  566. Type = "预览版"
  567. 'Mojang 误分类
  568. If Version("id").ToString.StartsWith("1.") AndAlso
  569. Not Version("id").ToString.ToLower.Contains("combat") AndAlso
  570. Not Version("id").ToString.ToLower.Contains("rc") AndAlso
  571. Not Version("id").ToString.ToLower.Contains("experimental") AndAlso
  572. Not Version("id").ToString.ToLower.Contains("pre") Then
  573. Type = "正式版"
  574. Version("type") = "release"
  575. End If
  576. '愚人节版本
  577. Select Case Version("id").ToString.ToLower
  578. Case "20w14infinite", "20w14∞"
  579. Type = "愚人节版"
  580. Version("id") = "20w14∞"
  581. Version("type") = "special"
  582. Version.Add("lore", GetMcFoolName(Version("id")))
  583. Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime", "23w13a_or_b", "24w14potato"
  584. Type = "愚人节版"
  585. Version("type") = "special"
  586. Version.Add("lore", GetMcFoolName(Version("id")))
  587. End Select
  588. '所有4月1日发布的版本视为愚人节版,但不改动版本描述
  589. Dim swedenTime As Date = Version("releaseTime").Value(Of Date).ToUniversalTime().AddHours(2)
  590. Select Case swedenTime.ToString("MM'/'dd")
  591. Case "04/01"
  592. If Not Version("type") = "special" Then
  593. Type = "愚人节版"
  594. Version("type") = "special"
  595. End If
  596. End Select
  597. Case "special"
  598. '已被处理的愚人节版
  599. Type = "愚人节版"
  600. Case Else
  601. Type = "远古版"
  602. End Select
  603. '加入辞典
  604. Dict(Type).Add(Version)
  605. Next
  606. '排序
  607. For i = 0 To Dict.Keys.Count - 1
  608. Dict(Dict.Keys(i)) = Sort(Dict.Values(i), Function(Left As JObject, Right As JObject) As Boolean
  609. Return Left("releaseTime").Value(Of Date) > Right("releaseTime").Value(Of Date)
  610. End Function)
  611. Next
  612. '清空当前
  613. PanMinecraft.Children.Clear()
  614. '添加最新版本
  615. Dim CardInfo As New MyCard With {.Title = "最新版本", .Margin = New Thickness(0, 15, 0, 15), .SwapType = 2}
  616. Dim TopestVersions As New List(Of JObject)
  617. Dim Release As JObject = Dict("正式版")(0).DeepClone()
  618. Release("lore") = "最新正式版,发布于 " & Release("releaseTime").Value(Of Date).ToString("yyyy'/'MM'/'dd HH':'mm")
  619. TopestVersions.Add(Release)
  620. If Dict("正式版")(0)("releaseTime").Value(Of Date) < Dict("预览版")(0)("releaseTime").Value(Of Date) Then
  621. Dim Snapshot As JObject = Dict("预览版")(0).DeepClone()
  622. Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").Value(Of Date).ToString("yyyy'/'MM'/'dd HH':'mm")
  623. TopestVersions.Add(Snapshot)
  624. End If
  625. Dim PanInfo As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = TopestVersions}
  626. MyCard.StackInstall(PanInfo, 7)
  627. CardInfo.Children.Add(PanInfo)
  628. PanMinecraft.Children.Insert(0, CardInfo)
  629. '添加其他版本
  630. For Each Pair As KeyValuePair(Of String, List(Of JObject)) In Dict
  631. If Not Pair.Value.Any() Then Continue For
  632. '增加卡片
  633. Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 7}
  634. 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}
  635. NewCard.Children.Add(NewStack)
  636. NewCard.SwapControl = NewStack
  637. NewCard.IsSwaped = True
  638. PanMinecraft.Children.Add(NewCard)
  639. Next
  640. '自动选择版本
  641. If McVersionWaitingForSelect Is Nothing Then Exit Try
  642. Log("[Download] 自动选择 MC 版本:" & McVersionWaitingForSelect)
  643. For Each Version As JObject In Versions
  644. If Version("id").ToString <> McVersionWaitingForSelect Then Continue For
  645. Dim Item = McDownloadListItem(Version, Sub()
  646. End Sub, False)
  647. MinecraftSelected(Item, Nothing)
  648. Next
  649. Catch ex As Exception
  650. Log(ex, "可视化安装版本列表出错", LogLevel.Feedback)
  651. End Try
  652. End Sub
  653. ''' <summary>
  654. ''' 当 MC 版本列表加载完时,立即自动选择的版本。用于外部调用。
  655. ''' </summary>
  656. Public Shared McVersionWaitingForSelect As String = Nothing
  657. #End Region
  658. #Region "OptiFine 列表"
  659. ''' <summary>
  660. ''' 获取 OptiFine 的加载异常信息。若正常则返回 Nothing。
  661. ''' </summary>
  662. Private Function LoadOptiFineGetError() As String
  663. If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
  664. If LoadOptiFine Is Nothing OrElse LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
  665. If LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFine.State, Object).Error.Message
  666. '检查 Forge 1.13 - 1.14.3:全部不兼容
  667. If SelectedForge IsNot Nothing AndAlso
  668. VersionSortInteger(SelectedMinecraftId, "1.13") >= 0 AndAlso VersionSortInteger("1.14.3", SelectedMinecraftId) >= 0 Then
  669. Return "与 Forge 不兼容"
  670. End If
  671. '检查最低 Forge 版本
  672. Dim MinimalForgeVersion As String = "9999.9999"
  673. Dim NotSuitForForge As Boolean = False
  674. For Each OptiFineVersion As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
  675. If Not OptiFineVersion.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then Continue For '不是同一个大版本
  676. If SelectedForge Is Nothing Then Return Nothing '该版本可用
  677. If IsOptiFineSuitForForge(OptiFineVersion, SelectedForge) Then
  678. Return Nothing '该版本可用
  679. Else
  680. NotSuitForForge = True
  681. If OptiFineVersion.RequiredForgeVersion IsNot Nothing Then
  682. '设置用于显示的最低允许的 Forge 版本
  683. MinimalForgeVersion = If(VersionSortBoolean(MinimalForgeVersion, OptiFineVersion.RequiredForgeVersion),
  684. OptiFineVersion.RequiredForgeVersion, MinimalForgeVersion)
  685. End If
  686. End If
  687. Next
  688. If MinimalForgeVersion = "9999.9999" Then
  689. Return If(NotSuitForForge, "与 Forge 不兼容", "没有可用版本")
  690. Else
  691. Return "需要 Forge " & If(MinimalForgeVersion.Contains("."), "", "#") & MinimalForgeVersion & " 或更高版本"
  692. End If
  693. End Function
  694. '检查某个 OptiFine 是否与某个 Forge 兼容(最低 Forge 版本是否达到需求)
  695. Private Function IsOptiFineSuitForForge(OptiFine As DlOptiFineListEntry, Forge As DlForgeVersionEntry)
  696. If Forge.Inherit <> OptiFine.Inherit Then Return False '不是同一个大版本
  697. If OptiFine.RequiredForgeVersion Is Nothing Then Return False '不兼容 Forge
  698. If String.IsNullOrWhiteSpace(OptiFine.RequiredForgeVersion) Then Return True '#4183
  699. If OptiFine.RequiredForgeVersion.Contains(".") Then 'XX.X.XXX
  700. Return VersionSortInteger(Forge.Version.ToString, OptiFine.RequiredForgeVersion) >= 0
  701. Else 'XXXX
  702. Return Forge.Version.Revision >= OptiFine.RequiredForgeVersion
  703. End If
  704. End Function
  705. '限制展开
  706. Private Sub CardOptiFine_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardOptiFine.PreviewSwap
  707. If LoadOptiFineGetError() IsNot Nothing Then e.Handled = True
  708. End Sub
  709. ''' <summary>
  710. ''' 尝试重新可视化 OptiFine 版本列表。
  711. ''' </summary>
  712. Private Sub OptiFine_Loaded() Handles LoadOptiFine.StateChanged
  713. Try
  714. If DlOptiFineListLoader.State <> LoadState.Finished Then Exit Sub
  715. '获取版本列表
  716. Dim Versions As New List(Of DlOptiFineListEntry)
  717. For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
  718. If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(Version, SelectedForge) Then Continue For
  719. If Version.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then Versions.Add(Version)
  720. Next
  721. If Not Versions.Any() Then Exit Sub
  722. '排序
  723. Versions = Sort(Versions,
  724. Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean
  725. If Not Left.IsPreview AndAlso Right.IsPreview Then Return True
  726. If Left.IsPreview AndAlso Not Right.IsPreview Then Return False
  727. Return VersionSortBoolean(Left.NameDisplay, Right.NameDisplay)
  728. End Function)
  729. '可视化
  730. PanOptiFine.Children.Clear()
  731. For Each Version In Versions
  732. PanOptiFine.Children.Add(OptiFineDownloadListItem(Version, AddressOf OptiFine_Selected, False))
  733. Next
  734. Catch ex As Exception
  735. Log(ex, "可视化 OptiFine 安装版本列表出错", LogLevel.Feedback)
  736. End Try
  737. End Sub
  738. '选择与清除
  739. Private Sub OptiFine_Selected(sender As MyListItem, e As EventArgs)
  740. SelectedOptiFine = sender.Tag
  741. If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedForge = Nothing
  742. OptiFabric_Loaded()
  743. Forge_Loaded()
  744. NeoForge_Loaded()
  745. CardOptiFine.IsSwaped = True
  746. SelectReload()
  747. End Sub
  748. Private Sub OptiFine_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnOptiFineClear.MouseLeftButtonUp
  749. SelectedOptiFine = Nothing
  750. SelectedOptiFabric = Nothing
  751. CardOptiFine.IsSwaped = True
  752. e.Handled = True
  753. Forge_Loaded()
  754. NeoForge_Loaded()
  755. SelectReload()
  756. End Sub
  757. #End Region
  758. #Region "LiteLoader 列表"
  759. ''' <summary>
  760. ''' 获取 LiteLoader 的加载异常信息。若正常则返回 Nothing。
  761. ''' </summary>
  762. Private Function LoadLiteLoaderGetError() As String
  763. If Not SelectedMinecraftId.Contains("1.") OrElse Val(SelectedMinecraftId.Split(".")(1)) > 12 Then Return "没有可用版本"
  764. If LoadLiteLoader Is Nothing OrElse LoadLiteLoader.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
  765. If LoadLiteLoader.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadLiteLoader.State, Object).Error.Message
  766. For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
  767. If Version.Inherit = SelectedMinecraftId Then Return Nothing
  768. Next
  769. Return "没有可用版本"
  770. End Function
  771. '限制展开
  772. Private Sub CardLiteLoader_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardLiteLoader.PreviewSwap
  773. If LoadLiteLoaderGetError() IsNot Nothing Then e.Handled = True
  774. End Sub
  775. ''' <summary>
  776. ''' 尝试重新可视化 LiteLoader 版本列表。
  777. ''' </summary>
  778. Private Sub LiteLoader_Loaded() Handles LoadLiteLoader.StateChanged
  779. Try
  780. If DlLiteLoaderListLoader.State <> LoadState.Finished Then Exit Sub
  781. '获取版本列表
  782. Dim Versions As New List(Of DlLiteLoaderListEntry)
  783. For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
  784. If Version.Inherit = SelectedMinecraftId Then Versions.Add(Version)
  785. Next
  786. If Not Versions.Any() Then Exit Sub
  787. '可视化
  788. PanLiteLoader.Children.Clear()
  789. For Each Version In Versions
  790. PanLiteLoader.Children.Add(LiteLoaderDownloadListItem(Version, AddressOf LiteLoader_Selected, False))
  791. Next
  792. Catch ex As Exception
  793. Log(ex, "可视化 LiteLoader 安装版本列表出错", LogLevel.Feedback)
  794. End Try
  795. End Sub
  796. '选择与清除
  797. Private Sub LiteLoader_Selected(sender As MyListItem, e As EventArgs)
  798. SelectedLiteLoader = sender.Tag
  799. CardLiteLoader.IsSwaped = True
  800. SelectReload()
  801. End Sub
  802. Private Sub LiteLoader_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnLiteLoaderClear.MouseLeftButtonUp
  803. SelectedLiteLoader = Nothing
  804. CardLiteLoader.IsSwaped = True
  805. e.Handled = True
  806. SelectReload()
  807. End Sub
  808. #End Region
  809. #Region "Forge 列表"
  810. ''' <summary>
  811. ''' 获取 Forge 的加载异常信息。若正常则返回 Nothing。
  812. ''' </summary>
  813. Private Function LoadForgeGetError() As String
  814. If Not SelectedMinecraftId.StartsWith("1.") Then Return "没有可用版本"
  815. If Not LoadForge.State.IsLoader Then Return "正在获取版本列表……"
  816. Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = LoadForge.State
  817. If SelectedMinecraftId <> Loader.Input Then Return "正在获取版本列表……"
  818. If Loader.State = LoadState.Loading Then Return "正在获取版本列表……"
  819. If Loader.State = LoadState.Failed Then
  820. Dim ErrorMessage As String = Loader.Error.Message
  821. If ErrorMessage.Contains("没有可用版本") Then
  822. Return "没有可用版本"
  823. Else
  824. Return "获取版本列表失败:" & ErrorMessage
  825. End If
  826. End If
  827. If Loader.State <> LoadState.Finished Then Return "获取版本列表失败:未知错误,状态为 " & GetStringFromEnum(Loader.State)
  828. Dim NotSuitForOptiFine As Boolean = False
  829. For Each Version In Loader.Output
  830. If Version.Category = "universal" OrElse Version.Category = "client" Then Continue For '跳过无法自动安装的版本
  831. If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
  832. If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容"
  833. If SelectedOptiFine IsNot Nothing AndAlso
  834. VersionSortInteger(SelectedMinecraftId, "1.13") >= 0 AndAlso VersionSortInteger("1.14.3", SelectedMinecraftId) >= 0 Then
  835. Return "与 OptiFine 不兼容" '1.13 ~ 1.14.3 OptiFine 检查
  836. End If
  837. If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, Version) Then
  838. NotSuitForOptiFine = True '与 OptiFine 不兼容
  839. Continue For
  840. End If
  841. Return Nothing
  842. Next
  843. Return If(NotSuitForOptiFine, "与 OptiFine 不兼容", "该版本不支持自动安装")
  844. End Function
  845. '限制展开
  846. Private Sub CardForge_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardForge.PreviewSwap
  847. If LoadForgeGetError() IsNot Nothing Then e.Handled = True
  848. End Sub
  849. ''' <summary>
  850. ''' 尝试重新可视化 Forge 版本列表。
  851. ''' </summary>
  852. Private Sub Forge_Loaded() Handles LoadForge.StateChanged
  853. Try
  854. If Not LoadForge.State.IsLoader Then Exit Sub
  855. Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = LoadForge.State
  856. If SelectedMinecraftId <> Loader.Input Then Exit Sub
  857. If Loader.State <> LoadState.Finished Then Exit Sub
  858. '获取要显示的版本
  859. Dim Versions = Loader.Output.ToList '复制数组,以免 Output 在实例化后变空
  860. If Not Loader.Output.Any() Then Exit Sub
  861. PanForge.Children.Clear()
  862. Versions = Sort(Versions, Function(a, b) a.Version > b.Version).Where(
  863. Function(v)
  864. If v.Category = "universal" OrElse v.Category = "client" Then Return False '跳过无法自动安装的版本
  865. If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, v) Then Return False
  866. Return True
  867. End Function).ToList()
  868. ForgeDownloadListItemPreload(PanForge, Versions, AddressOf Forge_Selected, False)
  869. For Each Version In Versions
  870. PanForge.Children.Add(ForgeDownloadListItem(Version, AddressOf Forge_Selected, False))
  871. Next
  872. Catch ex As Exception
  873. Log(ex, "可视化 Forge 安装版本列表出错", LogLevel.Feedback)
  874. End Try
  875. End Sub
  876. '选择与清除
  877. Private Sub Forge_Selected(sender As MyListItem, e As EventArgs)
  878. SelectedForge = sender.Tag
  879. CardForge.IsSwaped = True
  880. If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedOptiFine = Nothing
  881. OptiFine_Loaded()
  882. SelectReload()
  883. End Sub
  884. Private Sub Forge_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnForgeClear.MouseLeftButtonUp
  885. SelectedForge = Nothing
  886. CardForge.IsSwaped = True
  887. e.Handled = True
  888. OptiFine_Loaded()
  889. SelectReload()
  890. End Sub
  891. #End Region
  892. #Region "NeoForge 列表"
  893. ''' <summary>
  894. ''' 获取 NeoForge 的加载异常信息。若正常则返回 Nothing。
  895. ''' </summary>
  896. Private Function LoadNeoForgeGetError() As String
  897. If Not SelectedMinecraftId.StartsWith("1.") Then Return "没有可用版本"
  898. If SelectedOptiFine IsNot Nothing Then Return "与 OptiFine 不兼容"
  899. If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容"
  900. If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容"
  901. If LoadNeoForge Is Nothing OrElse LoadNeoForge.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
  902. If LoadNeoForge.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadNeoForge.State, Object).Error.Message
  903. If DlNeoForgeListLoader.Output.Value.Any(Function(v) v.Inherit = SelectedMinecraftId) Then
  904. Return Nothing
  905. Else
  906. Return "没有可用版本"
  907. End If
  908. End Function
  909. '限制展开
  910. Private Sub CardNeoForge_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardNeoForge.PreviewSwap
  911. If LoadNeoForgeGetError() IsNot Nothing Then e.Handled = True
  912. End Sub
  913. ''' <summary>
  914. ''' 尝试重新可视化 NeoForge 版本列表。
  915. ''' </summary>
  916. Private Sub NeoForge_Loaded() Handles LoadNeoForge.StateChanged
  917. Try
  918. '获取版本列表
  919. If DlNeoForgeListLoader.State <> LoadState.Finished Then Exit Sub
  920. Dim Versions = DlNeoForgeListLoader.Output.Value.Where(Function(v) v.Inherit = SelectedMinecraftId).ToList
  921. If Not Versions.Any() Then Exit Sub
  922. '可视化
  923. PanNeoForge.Children.Clear()
  924. NeoForgeDownloadListItemPreload(PanNeoForge, Versions, AddressOf NeoForge_Selected, False)
  925. For Each Version In Versions
  926. PanNeoForge.Children.Add(NeoForgeDownloadListItem(Version, AddressOf NeoForge_Selected, False))
  927. Next
  928. Catch ex As Exception
  929. Log(ex, "可视化 NeoForge 安装版本列表出错", LogLevel.Feedback)
  930. End Try
  931. End Sub
  932. '选择与清除
  933. Private Sub NeoForge_Selected(sender As MyListItem, e As EventArgs)
  934. SelectedNeoForge = sender.Tag
  935. CardNeoForge.IsSwaped = True
  936. OptiFine_Loaded()
  937. SelectReload()
  938. End Sub
  939. Private Sub NeoForge_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnNeoForgeClear.MouseLeftButtonUp
  940. SelectedNeoForge = Nothing
  941. CardNeoForge.IsSwaped = True
  942. e.Handled = True
  943. OptiFine_Loaded()
  944. SelectReload()
  945. End Sub
  946. #End Region
  947. #Region "Fabric 列表"
  948. ''' <summary>
  949. ''' 获取 Fabric 的加载异常信息。若正常则返回 Nothing。
  950. ''' </summary>
  951. Private Function LoadFabricGetError() As String
  952. If LoadFabric Is Nothing OrElse LoadFabric.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
  953. If LoadFabric.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadFabric.State, Object).Error.Message
  954. For Each Version As JObject In DlFabricListLoader.Output.Value("game")
  955. If Version("version").ToString = SelectedMinecraftId.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3") Then
  956. If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容"
  957. If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
  958. Return Nothing
  959. End If
  960. Next
  961. Return "没有可用版本"
  962. End Function
  963. '限制展开
  964. Private Sub CardFabric_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardFabric.PreviewSwap
  965. If LoadFabricGetError() IsNot Nothing Then e.Handled = True
  966. End Sub
  967. ''' <summary>
  968. ''' 尝试重新可视化 Fabric 版本列表。
  969. ''' </summary>
  970. Private Sub Fabric_Loaded() Handles LoadFabric.StateChanged
  971. Try
  972. If DlFabricListLoader.State <> LoadState.Finished Then Exit Sub
  973. '获取版本列表
  974. Dim Versions As JArray = DlFabricListLoader.Output.Value("loader")
  975. If Not Versions.Any() Then Exit Sub
  976. '可视化
  977. PanFabric.Children.Clear()
  978. PanFabric.Tag = Versions
  979. CardFabric.SwapControl = PanFabric
  980. CardFabric.SwapType = 12
  981. Catch ex As Exception
  982. Log(ex, "可视化 Fabric 安装版本列表出错", LogLevel.Feedback)
  983. End Try
  984. End Sub
  985. '选择与清除
  986. Public Sub Fabric_Selected(sender As MyListItem, e As EventArgs)
  987. SelectedFabric = sender.Tag("version").ToString
  988. FabricApi_Loaded()
  989. OptiFabric_Loaded()
  990. CardFabric.IsSwaped = True
  991. SelectReload()
  992. End Sub
  993. Private Sub Fabric_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnFabricClear.MouseLeftButtonUp
  994. SelectedFabric = Nothing
  995. SelectedFabricApi = Nothing
  996. SelectedOptiFabric = Nothing
  997. CardFabric.IsSwaped = True
  998. e.Handled = True
  999. SelectReload()
  1000. End Sub
  1001. #End Region
  1002. #Region "Fabric API 列表"
  1003. ''' <summary>
  1004. ''' 从显示名判断该 API 是否与某版本适配。
  1005. ''' </summary>
  1006. Public Shared Function IsSuitableFabricApi(DisplayName As String, MinecraftVersion As String) As Boolean
  1007. Try
  1008. If DisplayName Is Nothing OrElse MinecraftVersion Is Nothing Then Return False
  1009. DisplayName = DisplayName.ToLower : MinecraftVersion = MinecraftVersion.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3").ToLower
  1010. If DisplayName.StartsWith("[" & MinecraftVersion & "]") Then Return True
  1011. If Not DisplayName.Contains("/") OrElse Not DisplayName.Contains("]") Then Return False
  1012. '直接的判断(例如 1.18.1/22w03a)
  1013. For Each Part As String In DisplayName.Before("]").TrimStart("[").Split("/")
  1014. If Part = MinecraftVersion Then Return True
  1015. Next
  1016. '将版本名分割语素(例如 1.16.4/5)
  1017. Dim Lefts = RegexSearch(DisplayName.Before("]"), "[a-z/]+|[0-9/]+")
  1018. Dim Rights = RegexSearch(MinecraftVersion.Before("]"), "[a-z/]+|[0-9/]+")
  1019. '对每段进行判断
  1020. Dim i As Integer = 0
  1021. While True
  1022. '两边均缺失,感觉是一个东西
  1023. If Lefts.Count - 1 < i AndAlso Rights.Count - 1 < i Then Return True
  1024. '确定两边是否一致
  1025. Dim LeftValue As String = If(Lefts.Count - 1 < i, "-1", Lefts(i))
  1026. Dim RightValue As String = If(Rights.Count - 1 < i, "-1", Rights(i))
  1027. If Not LeftValue.Contains("/") Then
  1028. If LeftValue <> RightValue Then Return False
  1029. Else
  1030. '左边存在斜杠
  1031. If Not LeftValue.Contains(RightValue) Then Return False
  1032. End If
  1033. i += 1
  1034. End While
  1035. Return True
  1036. Catch ex As Exception
  1037. Log(ex, "判断 Fabric API 版本适配性出错(" & DisplayName & ", " & MinecraftVersion & ")")
  1038. Return False
  1039. End Try
  1040. End Function
  1041. ''' <summary>
  1042. ''' 获取 FabricApi 的加载异常信息。若正常则返回 Nothing。
  1043. ''' </summary>
  1044. Private Function LoadFabricApiGetError() As String
  1045. If LoadFabricApi Is Nothing OrElse LoadFabricApi.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
  1046. If LoadFabricApi.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadFabricApi.State, Object).Error.Message
  1047. If DlFabricApiLoader.Output Is Nothing Then
  1048. If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
  1049. Return "正在获取版本列表……"
  1050. End If
  1051. For Each Version In DlFabricApiLoader.Output
  1052. If Not IsSuitableFabricApi(Version.DisplayName, SelectedMinecraftId) Then Continue For
  1053. If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
  1054. Return Nothing
  1055. Next
  1056. Return "没有可用版本"
  1057. End Function
  1058. '限制展开
  1059. Private Sub CardFabricApi_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardFabricApi.PreviewSwap
  1060. If LoadFabricApiGetError() IsNot Nothing Then e.Handled = True
  1061. End Sub
  1062. Private AutoSelectedFabricApi As Boolean = False
  1063. ''' <summary>
  1064. ''' 尝试重新可视化 FabricApi 版本列表。
  1065. ''' </summary>
  1066. Private Sub FabricApi_Loaded() Handles LoadFabricApi.StateChanged
  1067. Try
  1068. If DlFabricApiLoader.State <> LoadState.Finished Then Exit Sub
  1069. If SelectedMinecraftId Is Nothing OrElse SelectedFabric Is Nothing Then Exit Sub
  1070. '获取版本列表
  1071. Dim Versions As New List(Of CompFile)
  1072. For Each Version In DlFabricApiLoader.Output
  1073. If IsSuitableFabricApi(Version.DisplayName, SelectedMinecraftId) Then
  1074. If Not Version.DisplayName.StartsWith("[") Then
  1075. Log("[Download] 已特判修改 Fabric API 显示名:" & Version.DisplayName, LogLevel.Debug)
  1076. Version.DisplayName = "[" & SelectedMinecraftId & "] " & Version.DisplayName
  1077. End If
  1078. Versions.Add(Version)
  1079. End If
  1080. Next
  1081. If Not Versions.Any() Then Exit Sub
  1082. Versions = Sort(Versions, Function(a, b) a.ReleaseDate > b.ReleaseDate)
  1083. '可视化
  1084. PanFabricApi.Children.Clear()
  1085. For Each Version In Versions
  1086. If Not IsSuitableFabricApi(Version.DisplayName, SelectedMinecraftId) Then Continue For
  1087. PanFabricApi.Children.Add(FabricApiDownloadListItem(Version, AddressOf FabricApi_Selected))
  1088. Next
  1089. '自动选择 Fabric API
  1090. If Not AutoSelectedFabricApi Then
  1091. AutoSelectedFabricApi = True
  1092. Log($"[Download] 已自动选择 Fabric API:{CType(PanFabricApi.Children(0), MyListItem).Title}")
  1093. FabricApi_Selected(PanFabricApi.Children(0), Nothing)
  1094. End If
  1095. Catch ex As Exception
  1096. Log(ex, "可视化 Fabric API 安装版本列表出错", LogLevel.Feedback)
  1097. End Try
  1098. End Sub
  1099. '选择与清除
  1100. Private Sub FabricApi_Selected(sender As MyListItem, e As EventArgs)
  1101. SelectedFabricApi = sender.Tag
  1102. CardFabricApi.IsSwaped = True
  1103. SelectReload()
  1104. End Sub
  1105. Private Sub FabricApi_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnFabricApiClear.MouseLeftButtonUp
  1106. SelectedFabricApi = Nothing
  1107. CardFabricApi.IsSwaped = True
  1108. e.Handled = True
  1109. SelectReload()
  1110. End Sub
  1111. #End Region
  1112. #Region "OptiFabric 列表"
  1113. ''' <summary>
  1114. ''' 从显示名判断该 Mod 是否与某版本适配。
  1115. ''' </summary>
  1116. Private Function IsSuitableOptiFabric(ModFile As CompFile, MinecraftVersion As String) As Boolean
  1117. Try
  1118. If MinecraftVersion Is Nothing Then Return False
  1119. Return ModFile.GameVersions.Contains(MinecraftVersion)
  1120. Catch ex As Exception
  1121. Log(ex, "判断 OptiFabric 版本适配性出错(" & MinecraftVersion & ")")
  1122. Return False
  1123. End Try
  1124. End Function
  1125. Private AutoSelectedOptiFabric As Boolean = False
  1126. ''' <summary>
  1127. ''' 获取 OptiFabric 的加载异常信息。若正常则返回 Nothing。
  1128. ''' </summary>
  1129. Private Function LoadOptiFabricGetError() As String
  1130. If SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15") Then Return "不兼容老版本 Fabric,请手动下载 OptiFabric Origins"
  1131. If LoadOptiFabric Is Nothing OrElse LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……"
  1132. If LoadOptiFabric.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFabric.State, Object).Error.Message
  1133. If DlOptiFabricLoader.Output Is Nothing Then
  1134. If SelectedFabric Is Nothing AndAlso SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine 与 Fabric"
  1135. If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
  1136. If SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine"
  1137. Return "正在获取版本列表……"
  1138. End If
  1139. For Each Version In DlOptiFabricLoader.Output
  1140. If Not IsSuitableOptiFabric(Version, SelectedMinecraftId) Then Continue For '2135#
  1141. If SelectedFabric Is Nothing AndAlso SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine 与 Fabric"
  1142. If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
  1143. If SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine"
  1144. Return Nothing '通过检查
  1145. Next
  1146. Return "没有可用版本"
  1147. End Function
  1148. '限制展开
  1149. Private Sub CardOptiFabric_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardOptiFabric.PreviewSwap
  1150. If LoadOptiFabricGetError() IsNot Nothing Then e.Handled = True
  1151. End Sub
  1152. ''' <summary>
  1153. ''' 尝试重新可视化 OptiFabric 版本列表。
  1154. ''' </summary>
  1155. Private Sub OptiFabric_Loaded() Handles LoadOptiFabric.StateChanged
  1156. Try
  1157. If DlOptiFabricLoader.State <> LoadState.Finished Then Exit Sub
  1158. If SelectedMinecraftId Is Nothing OrElse SelectedFabric Is Nothing OrElse SelectedOptiFine Is Nothing Then Exit Sub
  1159. '获取版本列表
  1160. Dim Versions As New List(Of CompFile)
  1161. For Each Version In DlOptiFabricLoader.Output
  1162. If IsSuitableOptiFabric(Version, SelectedMinecraftId) Then Versions.Add(Version)
  1163. Next
  1164. If Not Versions.Any() Then Exit Sub
  1165. '排序
  1166. Versions = Sort(Versions, Function(a, b) a.ReleaseDate > b.ReleaseDate)
  1167. '可视化
  1168. PanOptiFabric.Children.Clear()
  1169. For Each Version In Versions
  1170. If Not IsSuitableOptiFabric(Version, SelectedMinecraftId) Then Continue For
  1171. PanOptiFabric.Children.Add(OptiFabricDownloadListItem(Version, AddressOf OptiFabric_Selected))
  1172. Next
  1173. '自动选择 OptiFabric
  1174. If Not AutoSelectedOptiFabric AndAlso
  1175. Not (SelectedMinecraftId.StartsWith("1.14") OrElse SelectedMinecraftId.StartsWith("1.15")) Then '1.14~15 不自动选择
  1176. AutoSelectedOptiFabric = True
  1177. Log($"[Download] 已自动选择 OptiFabric:{CType(PanOptiFabric.Children(0), MyListItem).Title}")
  1178. OptiFabric_Selected(PanOptiFabric.Children(0), Nothing)
  1179. End If
  1180. Catch ex As Exception
  1181. Log(ex, "可视化 OptiFabric 安装版本列表出错", LogLevel.Feedback)
  1182. End Try
  1183. End Sub
  1184. '选择与清除
  1185. Private Sub OptiFabric_Selected(sender As MyListItem, e As EventArgs)
  1186. SelectedOptiFabric = sender.Tag
  1187. CardOptiFabric.IsSwaped = True
  1188. SelectReload()
  1189. End Sub
  1190. Private Sub OptiFabric_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnOptiFabricClear.MouseLeftButtonUp
  1191. SelectedOptiFabric = Nothing
  1192. CardOptiFabric.IsSwaped = True
  1193. e.Handled = True
  1194. SelectReload()
  1195. End Sub
  1196. #End Region
  1197. #Region "安装"
  1198. Private Sub TextSelectName_KeyDown(sender As Object, e As KeyEventArgs) Handles TextSelectName.KeyDown
  1199. If e.Key = Key.Enter AndAlso BtnSelectStart.IsEnabled Then BtnSelectStart_Click()
  1200. End Sub
  1201. Private Sub BtnSelectStart_Click() Handles BtnSelectStart.Click
  1202. '确认版本隔离
  1203. If (SelectedForge IsNot Nothing OrElse SelectedNeoForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) AndAlso
  1204. (Setup.Get("LaunchArgumentIndie") = 0 OrElse Setup.Get("LaunchArgumentIndie") = 2) Then
  1205. If MyMsgBox("你尚未开启版本隔离,这会导致多个 MC 共用同一个 Mod 文件夹。" & vbCrLf &
  1206. "因此在切换 MC 版本时,MC 会因为读取到与当前版本不符的 Mod 而崩溃。" & vbCrLf &
  1207. "PCL 推荐你在开始下载前,在 设置 → 版本隔离 中开启版本隔离选项!", "版本隔离提示", "取消下载", "继续") = 1 Then
  1208. Exit Sub
  1209. End If
  1210. End If
  1211. '提交安装申请
  1212. Dim Request As New McInstallRequest With {
  1213. .TargetVersionName = TextSelectName.Text,
  1214. .TargetVersionFolder = $"{PathMcFolder}versions\{TextSelectName.Text}\",
  1215. .MinecraftJson = SelectedMinecraftJsonUrl,
  1216. .MinecraftName = SelectedMinecraftId,
  1217. .OptiFineEntry = SelectedOptiFine,
  1218. .ForgeEntry = SelectedForge,
  1219. .NeoForgeEntry = SelectedNeoForge,
  1220. .FabricVersion = SelectedFabric,
  1221. .FabricApi = SelectedFabricApi,
  1222. .OptiFabric = SelectedOptiFabric,
  1223. .LiteLoaderEntry = SelectedLiteLoader
  1224. }
  1225. If Not McInstall(Request) Then Exit Sub
  1226. '返回,这样在再次进入安装页面时这个版本就会显示文件夹已重复
  1227. ExitSelectPage()
  1228. End Sub
  1229. #End Region
  1230. End Class