| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199 |
- Public Class PageDownloadInstall
- Public Sub ControlInit()
- DisabledPageAnimControls.Add(BtnStart)
- LoadOptiFine.State = DlOptiFineListLoader
- LoadLiteLoader.State = DlLiteLoaderListLoader
- LoadFabric.State = DlFabricListLoader
- LoadFabricApi.State = DlFabricApiLoader
- LoadNeoForge.State = DlNeoForgeListLoader
- LoadOptiFabric.State = DlOptiFabricLoader
- McDownloadForgeRecommendedRefresh()
- End Sub
- Public Overridable Sub LoaderInit() Handles Me.Initialized
- ControlInit()
- If RestrictMcDownload Then
- PageLoaderInit(LoadMinecraft, PanLoad, PanAllBack, Nothing, New LoaderTask(Of String, DlClientListResult)("关闭下载", Sub() Throw New Exception("为遵守相关法律法规,PCL 暂时不再提供 MC 下载功能,非常抱歉 qwq……")), AddressOf LoadMinecraft_OnFinish)
- Else
- PageLoaderInit(LoadMinecraft, PanLoad, PanAllBack, Nothing, DlClientListLoader, AddressOf LoadMinecraft_OnFinish)
- End If
- End Sub
- Private IsLoad As Boolean = False
- Public Overridable Sub Init() Handles Me.Loaded
- If IsLoad Then
- IsSelectNameEdited = False
- ExitSelectPage()
- If DlClientListLoader.State = LoadState.Finished Then TrySelectWaitingVersion()
- End If
- IsLoad = True
- PanBack.ScrollToHome()
- DlOptiFineListLoader.Start()
- DlLiteLoaderListLoader.Start()
- DlFabricListLoader.Start()
- DlNeoForgeListLoader.Start()
- '重载预览
- TextSelectName.ValidateRules = New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(McFolderSelected & "versions")}
- TextSelectName.Validate()
- ReloadSelected()
- End Sub
- #Region "页面切换"
- '页面切换动画
- Public IsInSelectPage As Boolean = False
- ''' <summary>
- ''' 选择页面 UI 初始化。
- ''' </summary>
- Public Sub PrepareSelectPage()
- IsInSelectPage = True
- PanInner.Margin = New Thickness(25, 10, 25, 40)
- PanSelect.Visibility = Visibility.Visible
- PanSelect.IsHitTestVisible = True
- PanMinecraft.IsHitTestVisible = False
- PanBack.IsHitTestVisible = False
- PanBack.ScrollToHome()
- DisabledPageAnimControls.Remove(BtnStart)
- BtnStart.Show = True
- For Each Card In {CardOptiFine, CardLiteLoader, CardForge, CardNeoForge, CardFabric, CardFabricApi, CardOptiFabric}
- Card.IsSwapped = True
- Next
- '如果在选择页面按了刷新键,选择页的东西可能会由于动画被隐藏,但不会由于加载结束而再次显示,因此这里需要手动恢复
- For Each Control In GetAllAnimControls(PanSelect)
- Control.Opacity = 1
- If Control.RenderTransform Is Nothing OrElse TypeOf Control.RenderTransform Is TranslateTransform Then
- Control.RenderTransform = New TranslateTransform
- End If
- Next
- End Sub
- Private Sub EnterSelectPage()
- If IsInSelectPage Then Return
- AutoSelectedFabricApi = False
- AutoSelectedOptiFabric = False
- PrepareSelectPage()
- '启动 Forge 加载
- If McVersion.IsStandardFormat(VanillaName) Then
- Dim ForgeLoader = New LoaderTask(Of String, List(Of DlForgeVersionEntry))("DlForgeVersion " & VanillaName, AddressOf DlForgeVersionMain)
- LoadForge.State = ForgeLoader
- ForgeLoader.Start(VanillaName)
- End If
- '启动 Fabric API、OptiFabric 加载
- DlFabricApiLoader.Start()
- DlOptiFabricLoader.Start()
- AniStart({
- AaOpacity(PanMinecraft, -PanMinecraft.Opacity, 70, 10),
- AaTranslateX(PanMinecraft, -50 - CType(PanMinecraft.RenderTransform, TranslateTransform).X, 90, 10),
- AaCode(
- Sub()
- PanBack.ScrollToHome()
- ReloadComponentLists()
- PanMinecraft.Visibility = Visibility.Collapsed
- End Sub, After:=True),
- AaOpacity(PanSelect, 1 - PanSelect.Opacity, 70, 100),
- AaTranslateX(PanSelect, -CType(PanSelect.RenderTransform, TranslateTransform).X, 160, 100, Ease:=New AniEaseOutFluent(AniEasePower.ExtraStrong)),
- AaCode(Sub() PanBack.IsHitTestVisible = True,, True)
- }, "FrmDownloadInstall SelectPageSwitch", True)
- End Sub
- Public Sub ReloadComponentLists()
- TextSelectName.Validate()
- OptiFine_Loaded()
- LiteLoader_Loaded()
- Forge_Loaded()
- NeoForge_Loaded()
- Fabric_Loaded()
- FabricApi_Loaded()
- OptiFabric_Loaded()
- ReloadSelected()
- End Sub
- Public Sub ExitSelectPage() Handles BtnBack.Click
- If Not IsInSelectPage Then Return
- IsInSelectPage = False
- PanInner.Margin = New Thickness(25, 10, 25, 25)
- DisabledPageAnimControls.Add(BtnStart)
- BtnStart.Show = False
- ClearSelected() '清除已选择项
- PanMinecraft.Visibility = Visibility.Visible
- PanSelect.IsHitTestVisible = False
- PanMinecraft.IsHitTestVisible = True
- PanBack.IsHitTestVisible = False
- PanBack.ScrollToHome()
- AniStart({
- AaOpacity(PanSelect, -PanSelect.Opacity, 70, 10),
- AaTranslateX(PanSelect, 50 - CType(PanSelect.RenderTransform, TranslateTransform).X, 90, 10),
- AaCode(Sub() PanBack.ScrollToHome(), After:=True),
- AaOpacity(PanMinecraft, 1 - PanMinecraft.Opacity, 70, 100),
- AaTranslateX(PanMinecraft, -CType(PanMinecraft.RenderTransform, TranslateTransform).X, 160, 100, Ease:=New AniEaseOutFluent(AniEasePower.ExtraStrong)),
- AaCode(
- Sub()
- PanSelect.Visibility = Visibility.Collapsed
- PanBack.IsHitTestVisible = True
- End Sub,, True)
- }, "FrmDownloadInstall SelectPageSwitch")
- End Sub
- Public Overridable Sub MinecraftSelected(sender As MyListItem, e As MouseButtonEventArgs)
- VanillaName = sender.Title
- VanillaData = sender.Tag
- VanillaIcon = sender.Logo
- LabMinecraftVersion.Text = VanillaName
- EnterSelectPage()
- End Sub
- #End Region
- #Region "选择"
- 'Minecraft
- Public VanillaName As String
- Public VanillaData As JObject
- Public VanillaIcon As String
- Private ReadOnly Property VanillaDrop As Integer
- Get
- Return McVersion.VersionToDrop(VanillaName)
- End Get
- End Property
- '附加组件
- Public SelectedOptiFine As DlOptiFineListEntry = Nothing
- Public SelectedLiteLoader As DlLiteLoaderListEntry = Nothing
- Public SelectedForge As DlForgeVersionEntry = Nothing
- Public SelectedNeoForge As DlNeoForgeListEntry = Nothing
- Public SelectedFabric As String = Nothing
- Public SelectedFabricApi As ResourceVersion = Nothing
- Public SelectedOptiFabric As ResourceVersion = Nothing
- ''' <summary>
- ''' 重载已选择的项目的显示。
- ''' </summary>
- Public Overridable Sub ReloadSelected() 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
- Static Ongoing As Boolean = False '#3742 中,LoadOptiFineGetError 会初始化 LoadOptiFine,触发事件 LoadOptiFine.StateChanged,导致再次调用 SelectReload
- If VanillaName Is Nothing OrElse Ongoing Then Return
- Ongoing = True
- '主预览
- SelectNameUpdate()
- ImgLogo.Source = GetSelectLogo()
- ImgMinecraft.Source = VanillaIcon
- 'OptiFine
- Dim OptiFineError As String = LoadOptiFineGetError()
- CardOptiFine.MainSwap.Visibility = If(OptiFineError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If OptiFineError IsNot Nothing Then CardOptiFine.IsSwapped = True '例如在同时展开卡片时选择了不兼容项则强制折叠
- SetPanelVisibility(PanOptiFineInfo, CardOptiFine.IsSwapped)
- If SelectedOptiFine Is Nothing Then
- BtnOptiFineClear.Visibility = Visibility.Collapsed
- ImgOptiFine.Visibility = Visibility.Collapsed
- LabOptiFine.Text = If(OptiFineError, "可以添加")
- LabOptiFine.Foreground = ColorGray4
- Else
- BtnOptiFineClear.Visibility = Visibility.Visible
- ImgOptiFine.Visibility = Visibility.Visible
- LabOptiFine.Text = SelectedOptiFine.DisplayName.Replace(VanillaName & " ", "")
- LabOptiFine.Foreground = ColorGray1
- End If
- 'LiteLoader
- If VanillaDrop >= 130 Then
- CardLiteLoader.Visibility = Visibility.Collapsed
- Else
- CardLiteLoader.Visibility = Visibility.Visible
- Dim LiteLoaderError As String = LoadLiteLoaderGetError()
- CardLiteLoader.MainSwap.Visibility = If(LiteLoaderError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If LiteLoaderError IsNot Nothing Then CardLiteLoader.IsSwapped = True '例如在同时展开卡片时选择了不兼容项则强制折叠
- SetPanelVisibility(PanLiteLoaderInfo, CardLiteLoader.IsSwapped)
- If SelectedLiteLoader Is Nothing Then
- BtnLiteLoaderClear.Visibility = Visibility.Collapsed
- ImgLiteLoader.Visibility = Visibility.Collapsed
- LabLiteLoader.Text = If(LiteLoaderError, "可以添加")
- LabLiteLoader.Foreground = ColorGray4
- Else
- BtnLiteLoaderClear.Visibility = Visibility.Visible
- ImgLiteLoader.Visibility = Visibility.Visible
- LabLiteLoader.Text = SelectedLiteLoader.Inherit
- LabLiteLoader.Foreground = ColorGray1
- End If
- End If
- 'Forge
- If Not McVersion.IsStandardFormat(VanillaName) Then
- CardForge.Visibility = Visibility.Collapsed
- Else
- CardForge.Visibility = Visibility.Visible
- Dim ForgeError As String = LoadForgeGetError()
- CardForge.MainSwap.Visibility = If(ForgeError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If ForgeError IsNot Nothing Then CardForge.IsSwapped = True
- SetPanelVisibility(PanForgeInfo, CardForge.IsSwapped)
- If SelectedForge Is Nothing Then
- BtnForgeClear.Visibility = Visibility.Collapsed
- ImgForge.Visibility = Visibility.Collapsed
- LabForge.Text = If(ForgeError, "可以添加")
- LabForge.Foreground = ColorGray4
- Else
- BtnForgeClear.Visibility = Visibility.Visible
- ImgForge.Visibility = Visibility.Visible
- LabForge.Text = SelectedForge.VersionName
- LabForge.Foreground = ColorGray1
- End If
- End If
- 'NeoForge
- If VanillaData("releaseTime").ToObject(Of Date) < New Date(2023, 6, 11) Then '匹配 1.20.1+ 与一些愚人节版本
- CardNeoForge.Visibility = Visibility.Collapsed
- Else
- CardNeoForge.Visibility = Visibility.Visible
- Dim NeoForgeError As String = LoadNeoForgeGetError()
- CardNeoForge.MainSwap.Visibility = If(NeoForgeError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If NeoForgeError IsNot Nothing Then CardNeoForge.IsSwapped = True
- SetPanelVisibility(PanNeoForgeInfo, CardNeoForge.IsSwapped)
- If SelectedNeoForge Is Nothing Then
- BtnNeoForgeClear.Visibility = Visibility.Collapsed
- ImgNeoForge.Visibility = Visibility.Collapsed
- LabNeoForge.Text = If(NeoForgeError, "可以添加")
- LabNeoForge.Foreground = ColorGray4
- Else
- BtnNeoForgeClear.Visibility = Visibility.Visible
- ImgNeoForge.Visibility = Visibility.Visible
- LabNeoForge.Text = SelectedNeoForge.VersionName
- LabNeoForge.Foreground = ColorGray1
- End If
- End If
- 'Fabric
- If VanillaDrop <= 130 Then
- CardFabric.Visibility = Visibility.Collapsed
- Else
- CardFabric.Visibility = Visibility.Visible
- Dim FabricError As String = LoadFabricGetError()
- CardFabric.MainSwap.Visibility = If(FabricError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If FabricError IsNot Nothing Then CardFabric.IsSwapped = True
- SetPanelVisibility(PanFabricInfo, CardFabric.IsSwapped)
- If SelectedFabric Is Nothing Then
- BtnFabricClear.Visibility = Visibility.Collapsed
- ImgFabric.Visibility = Visibility.Collapsed
- LabFabric.Text = If(FabricError, "可以添加")
- LabFabric.Foreground = ColorGray4
- Else
- BtnFabricClear.Visibility = Visibility.Visible
- ImgFabric.Visibility = Visibility.Visible
- LabFabric.Text = SelectedFabric.Replace("+build", "")
- LabFabric.Foreground = ColorGray1
- End If
- End If
- 'FabricApi
- If SelectedFabric Is Nothing Then
- CardFabricApi.Visibility = Visibility.Collapsed
- Else
- CardFabricApi.Visibility = Visibility.Visible
- Dim FabricApiError As String = LoadFabricApiGetError()
- CardFabricApi.MainSwap.Visibility = If(FabricApiError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If FabricApiError IsNot Nothing OrElse SelectedFabric Is Nothing Then CardFabricApi.IsSwapped = True
- SetPanelVisibility(PanFabricApiInfo, CardFabricApi.IsSwapped)
- If SelectedFabricApi Is Nothing Then
- BtnFabricApiClear.Visibility = Visibility.Collapsed
- ImgFabricApi.Visibility = Visibility.Collapsed
- LabFabricApi.Text = If(FabricApiError, "可以添加")
- LabFabricApi.Foreground = ColorGray4
- Else
- BtnFabricApiClear.Visibility = Visibility.Visible
- ImgFabricApi.Visibility = Visibility.Visible
- LabFabricApi.Text = SelectedFabricApi.Display.Split("]")(1).Replace("Fabric API ", "").Replace(" build ", ".").Split("+").First.Trim
- LabFabricApi.Foreground = ColorGray1
- End If
- End If
- 'OptiFabric
- If SelectedFabric Is Nothing OrElse SelectedOptiFine Is Nothing Then
- CardOptiFabric.Visibility = Visibility.Collapsed
- Else
- CardOptiFabric.Visibility = Visibility.Visible
- Dim OptiFabricError As String = LoadOptiFabricGetError()
- CardOptiFabric.MainSwap.Visibility = If(OptiFabricError Is Nothing, Visibility.Visible, Visibility.Collapsed)
- If OptiFabricError IsNot Nothing OrElse SelectedFabric Is Nothing Then CardOptiFabric.IsSwapped = True
- SetPanelVisibility(PanOptiFabricInfo, CardOptiFabric.IsSwapped)
- If SelectedOptiFabric Is Nothing Then
- BtnOptiFabricClear.Visibility = Visibility.Collapsed
- ImgOptiFabric.Visibility = Visibility.Collapsed
- LabOptiFabric.Text = If(OptiFabricError, "可以添加")
- LabOptiFabric.Foreground = ColorGray4
- Else
- BtnOptiFabricClear.Visibility = Visibility.Visible
- ImgOptiFabric.Visibility = Visibility.Visible
- LabOptiFabric.Text = SelectedOptiFabric.Display.Lower.Replace("optifabric-", "").Replace(".jar", "").Trim.TrimStart("v")
- LabOptiFabric.Foreground = ColorGray1
- End If
- End If
- '主警告
- If SelectedFabric IsNot Nothing AndAlso SelectedFabricApi Is Nothing Then
- HintFabricAPI.Visibility = Visibility.Visible
- Else
- HintFabricAPI.Visibility = Visibility.Collapsed
- End If
- If SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso SelectedOptiFabric Is Nothing Then
- If VanillaDrop >= 140 AndAlso VanillaDrop <= 150 Then
- HintOptiFabric.Visibility = Visibility.Collapsed
- HintOptiFabricOld.Visibility = Visibility.Visible
- Else
- HintOptiFabric.Visibility = Visibility.Visible
- HintOptiFabricOld.Visibility = Visibility.Collapsed
- End If
- Else
- HintOptiFabric.Visibility = Visibility.Collapsed
- HintOptiFabricOld.Visibility = Visibility.Collapsed
- End If
- If VanillaDrop >= 160 AndAlso SelectedOptiFine IsNot Nothing AndAlso
- (SelectedForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) Then
- HintModOptiFine.Visibility = Visibility.Visible
- Else
- HintModOptiFine.Visibility = Visibility.Collapsed
- End If
- '结束
- Ongoing = False
- End Sub
- ''' <summary>
- ''' 清空已选择的项目。
- ''' </summary>
- Public Sub ClearSelected()
- VanillaName = Nothing
- VanillaData = Nothing
- VanillaIcon = Nothing
- SelectedOptiFine = Nothing
- SelectedLiteLoader = Nothing
- SelectedForge = Nothing
- SelectedNeoForge = Nothing
- SelectedFabric = Nothing
- SelectedFabricApi = Nothing
- SelectedOptiFabric = Nothing
- For Each ClearButton In {BtnOptiFineClear, BtnLiteLoaderClear, BtnForgeClear, BtnNeoForgeClear,
- BtnFabricClear, BtnFabricApiClear, BtnOptiFabricClear}
- ClearButton.Visibility = Visibility.Collapsed
- Next
- End Sub
- '信息栏动画
- Private Sub SetPanelVisibility(Panel As Grid, IsVisible As Boolean)
- If Panel.Tag = IsVisible.ToString Then Return
- Panel.Tag = IsVisible.ToString
- If IsVisible Then
- AniStart({
- AaTranslateY(Panel, -CType(Panel.RenderTransform, TranslateTransform).Y, 150, Ease:=New AniEaseOutFluent),
- AaOpacity(Panel, 1 - Panel.Opacity, 60)
- }, "PageDownloadInstall Visibility " & Panel.Name)
- Else
- AniStart({
- AaTranslateY(Panel, 6 - CType(Panel.RenderTransform, TranslateTransform).Y, 60),
- AaOpacity(Panel, -Panel.Opacity, 60)
- }, "PageDownloadInstall Visibility " & Panel.Name)
- End If
- End Sub
- ''' <summary>
- ''' 获取版本图标。
- ''' </summary>
- Public Overridable Function GetSelectLogo() As String
- If SelectedFabric IsNot Nothing Then
- Return "pack://application:,,,/images/Blocks/Fabric.png"
- ElseIf SelectedForge IsNot Nothing Then
- Return "pack://application:,,,/images/Blocks/Anvil.png"
- ElseIf SelectedNeoForge IsNot Nothing Then
- Return "pack://application:,,,/images/Blocks/NeoForge.png"
- ElseIf SelectedLiteLoader IsNot Nothing Then
- Return "pack://application:,,,/images/Blocks/Egg.png"
- ElseIf SelectedOptiFine IsNot Nothing Then
- Return "pack://application:,,,/images/Blocks/GrassPath.png"
- Else
- Return VanillaIcon
- End If
- End Function
- '版本名处理
- ''' <summary>
- ''' 获取默认版本名。
- ''' </summary>
- Public Function GetSelectName() As String
- Dim Name As String = VanillaName
- If SelectedFabric IsNot Nothing Then Name += "-Fabric " & SelectedFabric.BeforeFirst("+")
- If SelectedForge IsNot Nothing Then Name += "-Forge_" & SelectedForge.VersionName
- If SelectedNeoForge IsNot Nothing Then Name += "-NeoForge_" & SelectedNeoForge.VersionName.BeforeFirst("+")
- If SelectedLiteLoader IsNot Nothing Then Name += "-LiteLoader"
- If SelectedOptiFine IsNot Nothing Then Name += "-OptiFine_" & SelectedOptiFine.DisplayName.Replace(VanillaName & " ", "").Replace(" ", "_")
- Return Name
- End Function
- Public IsSelectNameEdited As Boolean = False
- Private Sub SelectNameUpdate()
- If IsSelectNameEdited Then Return
- TextSelectName.Text = GetSelectName()
- IsSelectNameEdited = False
- End Sub
- Private Sub TextSelectName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles TextSelectName.TextChanged
- IsSelectNameEdited = True
- End Sub
- Private Sub TextSelectName_ValidateChanged(sender As Object, e As EventArgs) Handles TextSelectName.ValidateChanged
- BtnStart.IsEnabled = TextSelectName.IsValidated
- HintSelectName.Text = TextSelectName.ValidateResult
- HintSelectName.Visibility = If(TextSelectName.IsValidated, Visibility.Collapsed, Visibility.Visible)
- End Sub
- #End Region
- #Region "加载器"
- Public MinecraftVersions As JArray
- Private Sub LoadMinecraft_OnFinish()
- MinecraftVersions = CType(DlClientListLoader.Output.Value("versions").DeepClone(), JArray)
- ShowMinecraftVersionList()
- TrySelectWaitingVersion() '自动选择版本
- End Sub
- '结果数据化
- Public Overridable Sub ShowMinecraftVersionList()
- ExitSelectPage() '返回
- Try
- Dim Dict As New Dictionary(Of String, List(Of JObject)) From {
- {"正式版", New List(Of JObject)}, {"预览版", New List(Of JObject)}, {"远古版", New List(Of JObject)}, {"愚人节版", New List(Of JObject)}
- }
- For Each Version As JObject In MinecraftVersions
- '确定分类
- Dim Type As String = Version("type")
- Select Case Type
- Case "release"
- Type = "正式版"
- Case "snapshot"
- Type = "预览版"
- 'Mojang 误分类
- If Version("id").ToString.StartsWithF("1.") AndAlso
- Not Version("id").ToString.Lower.Contains("combat") AndAlso
- Not Version("id").ToString.Lower.Contains("rc") AndAlso
- Not Version("id").ToString.Lower.Contains("experimental") AndAlso
- Not Version("id").ToString.Lower.Contains("pre") Then
- Type = "正式版"
- Version("type") = "release"
- End If
- '愚人节版本
- Select Case Version("id").ToString.Lower
- Case "20w14infinite", "20w14∞"
- Type = "愚人节版"
- Version("id") = "20w14∞"
- Version("type") = "special"
- Version.Add("lore", GetMcFoolName(Version("id")))
- Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime", "23w13a_or_b", "24w14potato", "25w14craftmine", "26w14a"
- Type = "愚人节版"
- Version("type") = "special"
- Version.Add("lore", GetMcFoolName(Version("id")))
- Case Else '4/1 自动视作愚人节版
- Dim ReleaseDate = Version("releaseTime").Value(Of Date).ToUniversalTime().AddHours(2)
- If ReleaseDate.Month = 4 AndAlso ReleaseDate.Day = 1 Then
- Type = "愚人节版"
- Version("type") = "special"
- End If
- End Select
- Case "special"
- '已被处理的愚人节版
- Type = "愚人节版"
- Case Else
- Type = "远古版"
- End Select
- '加入辞典
- Dict(Type).Add(Version)
- Next
- '排序
- For Each Pair In Dict.ToList
- Dict(Pair.Key) = Pair.Value.OrderByDescending(Function(j) j("releaseTime").Value(Of Date)).ToList
- Next
- '清空当前
- PanMinecraft.Children.Clear()
- '添加最新版本
- Dim CardInfo As New MyCard With {.Title = "最新版本", .Margin = New Thickness(0, 15, 0, 15)}
- Dim PinnedVersions As New List(Of JObject)
- Dim Release As JObject = Dict("正式版")(0).DeepClone()
- Release("lore") = "最新正式版,发布于 " & Release("releaseTime").Value(Of Date).ToString("yyyy'/'MM'/'dd HH':'mm")
- PinnedVersions.Add(Release)
- If Dict("正式版")(0)("releaseTime").Value(Of Date) < Dict("预览版")(0)("releaseTime").Value(Of Date) Then
- Dim Snapshot As JObject = Dict("预览版")(0).DeepClone()
- Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").Value(Of Date).ToString("yyyy'/'MM'/'dd HH':'mm")
- PinnedVersions.Add(Snapshot)
- End If
- Dim PanInfo As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0)}
- CardInfo.Children.Add(PanInfo)
- CardInfo.SwapControl = PanInfo
- CardInfo.SetContentBuilder(PinnedVersions, '使用 Lambda 转发点击事件,避免 #535
- Function(Version) McDownloadListItem(Version, Sub(sender, e) MinecraftSelected(sender, e), False))
- CardInfo.BuildContent()
- PanMinecraft.Children.Insert(0, CardInfo)
- '添加其他版本
- For Each Pair As KeyValuePair(Of String, List(Of JObject)) In Dict
- If Not Pair.Value.Any() Then Continue For
- '增加卡片
- Dim NewCard As New MyCard With {.Title = Pair.Key, .Margin = New Thickness(0, 0, 0, 15)}
- Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0)}
- NewCard.Children.Add(NewStack)
- NewCard.SwapControl = NewStack
- NewCard.SetContentBuilder(Pair.Value,
- Function(Version) McDownloadListItem(Version, Sub(sender, e) MinecraftSelected(sender, e), False))
- NewCard.IsSwapped = True
- PanMinecraft.Children.Add(NewCard)
- Next
- Catch ex As Exception
- Logger.Error(ex, "可视化安装版本列表出错")
- End Try
- End Sub
- Private Sub TrySelectWaitingVersion()
- If VersionWaitingSelect Is Nothing Then Return
- For Each Version As JObject In MinecraftVersions
- If Version("id").ToString <> VersionWaitingSelect Then Continue For
- Logger.Info($"自动选择 MC 版本:{VersionWaitingSelect}")
- MinecraftSelected(McDownloadListItem(Version, Nothing, False).Init(), Nothing)
- VersionWaitingSelect = Nothing
- Return
- Next
- End Sub
- ''' <summary>
- ''' 当 MC 版本列表加载完时,立即自动选择的版本。用于外部调用。
- ''' </summary>
- Public Shared VersionWaitingSelect As String = Nothing
- #End Region
- #Region "OptiFine 列表"
- ''' <summary>
- ''' 获取 OptiFine 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadOptiFineGetError() As String
- If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
- '检查 Forge 1.13 - 1.14.3:全部不兼容
- If SelectedForge IsNot Nothing AndAlso
- McUtils.CompareVersionGE(VanillaName, "1.13") AndAlso McUtils.CompareVersionGE("1.14.3", VanillaName) Then
- Return "与 Forge 不兼容"
- End If
- '检查 Fabric 1.20.5+:全部不兼容
- If SelectedFabric IsNot Nothing AndAlso
- McUtils.CompareVersion(VanillaName, "1.20.4") > 0 Then
- Return "与 Fabric 不兼容"
- End If
- '检查 Loader
- If GetLoaderError(LoadOptiFine) IsNot Nothing Then Return GetLoaderError(LoadOptiFine)
- '检查 Forge 版本
- Dim HasAny As Boolean = False
- Dim HasRequiredVersion As Boolean = False
- For Each OptiFineVersion As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
- If Not OptiFineVersion.DisplayName.StartsWithF(VanillaName & " ") Then Continue For '不是同一个大版本
- HasAny = True
- If SelectedForge Is Nothing Then Return Nothing '未选择 Forge
- If IsOptiFineSuitForForge(OptiFineVersion, SelectedForge) Then Return Nothing '该版本可用
- If OptiFineVersion.RequiredForgeVersion IsNot Nothing Then HasRequiredVersion = True
- Next
- If Not HasAny Then
- Return "无"
- ElseIf HasRequiredVersion Then
- Return "仅兼容特定版本的 Forge"
- Else
- Return "与 Forge 不兼容"
- End If
- End Function
- '检查某个 OptiFine 是否与某个 Forge 兼容
- Public Shared Function IsOptiFineSuitForForge(OptiFine As DlOptiFineListEntry, Forge As DlForgeVersionEntry) As Boolean
- If Forge.Inherit <> OptiFine.Inherit Then Return False '不是同一个大版本
- If OptiFine.RequiredForgeVersion Is Nothing Then Return False '不兼容 Forge
- If String.IsNullOrWhiteSpace(OptiFine.RequiredForgeVersion) Then Return True '#4183
- If OptiFine.RequiredForgeVersion.Contains(".") Then 'XX.X.XXX
- Return McUtils.CompareVersion(Forge.Version.ToString, OptiFine.RequiredForgeVersion) = 0
- Else 'XXXX
- Return Forge.Version.Revision = OptiFine.RequiredForgeVersion
- End If
- End Function
- '限制展开
- Private Sub CardOptiFine_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardOptiFine.PreviewSwap
- If LoadOptiFineGetError() IsNot Nothing Then e.Handled = True
- End Sub
- ''' <summary>
- ''' 尝试重新可视化 OptiFine 版本列表。
- ''' </summary>
- Private Sub OptiFine_Loaded() Handles LoadOptiFine.StateChanged
- Try
- If DlOptiFineListLoader.State <> LoadState.Finished Then Return
- '获取版本列表
- Dim Versions As New List(Of DlOptiFineListEntry)
- For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
- If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(Version, SelectedForge) Then Continue For
- If Version.DisplayName.StartsWithF(VanillaName & " ") Then Versions.Add(Version)
- Next
- If Not Versions.Any() Then Return
- '排序
- Versions = Versions.SortByComparison(
- Function(Left As DlOptiFineListEntry, Right As DlOptiFineListEntry) As Boolean
- If Not Left.IsPreview AndAlso Right.IsPreview Then Return True
- If Left.IsPreview AndAlso Not Right.IsPreview Then Return False
- Return McUtils.CompareVersionGE(Left.DisplayName, Right.DisplayName)
- End Function)
- '可视化
- PanOptiFine.Children.Clear()
- For Each Version In Versions
- PanOptiFine.Children.Add(OptiFineDownloadListItem(Version, AddressOf OptiFine_Selected, False))
- Next
- Catch ex As Exception
- Logger.Error(ex, "可视化 OptiFine 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Private Sub OptiFine_Selected(sender As MyListItem, e As EventArgs)
- SelectedOptiFine = sender.Tag
- If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedForge = Nothing
- OptiFabric_Loaded()
- Forge_Loaded()
- NeoForge_Loaded()
- CardOptiFine.IsSwapped = True
- ReloadSelected()
- End Sub
- Private Sub OptiFine_Clear(sender As Object, e As EventArgs) Handles BtnOptiFineClear.Click
- SelectedOptiFine = Nothing
- SelectedOptiFabric = Nothing
- BtnOptiFabricClear.Visibility = Visibility.Collapsed
- AutoSelectedOptiFabric = False
- CardOptiFine.IsSwapped = True
- Forge_Loaded()
- NeoForge_Loaded()
- ReloadSelected()
- End Sub
- #End Region
- #Region "LiteLoader 列表"
- ''' <summary>
- ''' 获取 LiteLoader 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadLiteLoaderGetError() As String
- '检查 Loader
- If GetLoaderError(LoadLiteLoader) IsNot Nothing Then Return GetLoaderError(LoadLiteLoader)
- '检查版本
- Return If(DlLiteLoaderListLoader.Output.Value.Any(Function(v) v.Inherit = VanillaName), Nothing, "无")
- End Function
- '限制展开
- Private Sub CardLiteLoader_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardLiteLoader.PreviewSwap
- If LoadLiteLoaderGetError() IsNot Nothing Then e.Handled = True
- End Sub
- ''' <summary>
- ''' 尝试重新可视化 LiteLoader 版本列表。
- ''' </summary>
- Private Sub LiteLoader_Loaded() Handles LoadLiteLoader.StateChanged
- Try
- If DlLiteLoaderListLoader.State <> LoadState.Finished Then Return
- '获取版本列表
- Dim Versions As New List(Of DlLiteLoaderListEntry)
- For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
- If Version.Inherit = VanillaName Then Versions.Add(Version)
- Next
- If Not Versions.Any() Then Return
- '可视化
- PanLiteLoader.Children.Clear()
- For Each Version In Versions
- PanLiteLoader.Children.Add(LiteLoaderDownloadListItem(Version, AddressOf LiteLoader_Selected, False))
- Next
- Catch ex As Exception
- Logger.Error(ex, "可视化 LiteLoader 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Private Sub LiteLoader_Selected(sender As MyListItem, e As EventArgs)
- SelectedLiteLoader = sender.Tag
- CardLiteLoader.IsSwapped = True
- ReloadSelected()
- End Sub
- Private Sub LiteLoader_Clear(sender As Object, e As EventArgs) Handles BtnLiteLoaderClear.Click
- SelectedLiteLoader = Nothing
- CardLiteLoader.IsSwapped = True
- ReloadSelected()
- End Sub
- #End Region
- #Region "Forge 列表"
- ''' <summary>
- ''' 获取 Forge 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadForgeGetError() As String
- If McUtils.CompareVersionGE("1.5.1", VanillaName) AndAlso McUtils.CompareVersionGE(VanillaName, "1.1") Then Return "无"
- '检查 Loader
- If GetLoaderError(LoadForge) IsNot Nothing Then Return GetLoaderError(LoadForge)
- Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = LoadForge.State
- If VanillaName <> Loader.Input Then Return "获取中……"
- '检查版本
- For Each Version In Loader.Output
- If Version.Category = "universal" OrElse Version.Category = "client" Then Continue For '跳过无法自动安装的版本
- If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
- If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容"
- If SelectedOptiFine IsNot Nothing AndAlso
- McUtils.CompareVersionGE(VanillaName, "1.13") AndAlso McUtils.CompareVersionGE("1.14.3", VanillaName) Then
- Return "与 OptiFine 不兼容" '1.13 ~ 1.14.3 OptiFine 检查
- End If
- If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, Version) Then Continue For
- Return Nothing
- Next
- Return "与 OptiFine 不兼容"
- End Function
- '限制展开
- Private Sub CardForge_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardForge.PreviewSwap
- If LoadForgeGetError() IsNot Nothing Then e.Handled = True
- End Sub
- ''' <summary>
- ''' 尝试重新可视化 Forge 版本列表。
- ''' </summary>
- Private Sub Forge_Loaded() Handles LoadForge.StateChanged
- Try
- If Not LoadForge.State.IsLoader Then Return
- Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = LoadForge.State
- If VanillaName <> Loader.Input Then Return
- If Loader.State <> LoadState.Finished Then Return
- '获取要显示的版本
- Dim Versions = Loader.Output.ToList '复制数组,以免 Output 在实例化后变空
- If Not Loader.Output.Any() Then Return
- PanForge.Children.Clear()
- Versions = Versions.Where(
- Function(v)
- If v.Category = "universal" OrElse v.Category = "client" Then Return False '跳过无法自动安装的版本
- If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, v) Then Return False
- Return True
- End Function).OrderByDescending(Function(v) v).ToList()
- ForgeDownloadListItemPreload(PanForge, Versions, AddressOf Forge_Selected, False)
- For Each Version In Versions
- PanForge.Children.Add(ForgeDownloadListItem(Version, AddressOf Forge_Selected, False))
- Next
- Catch ex As Exception
- Logger.Error(ex, "可视化 Forge 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Private Sub Forge_Selected(sender As MyListItem, e As EventArgs)
- SelectedForge = sender.Tag
- CardForge.IsSwapped = True
- If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedOptiFine = Nothing
- OptiFine_Loaded()
- ReloadSelected()
- End Sub
- Private Sub Forge_Clear(sender As Object, e As EventArgs) Handles BtnForgeClear.Click
- SelectedForge = Nothing
- CardForge.IsSwapped = True
- OptiFine_Loaded()
- ReloadSelected()
- End Sub
- #End Region
- #Region "NeoForge 列表"
- ''' <summary>
- ''' 获取 NeoForge 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadNeoForgeGetError() As String
- If SelectedOptiFine IsNot Nothing Then Return "与 OptiFine 不兼容"
- If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容"
- If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容"
- '检查 Loader
- If GetLoaderError(LoadNeoForge) IsNot Nothing Then Return GetLoaderError(LoadNeoForge)
- '检查版本
- Return If(DlNeoForgeListLoader.Output.Value.Any(Function(v) v.Inherit = VanillaName), Nothing, "无")
- End Function
- '限制展开
- Private Sub CardNeoForge_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardNeoForge.PreviewSwap
- If LoadNeoForgeGetError() IsNot Nothing Then e.Handled = True
- End Sub
- ''' <summary>
- ''' 尝试重新可视化 NeoForge 版本列表。
- ''' </summary>
- Private Sub NeoForge_Loaded() Handles LoadNeoForge.StateChanged
- Try
- '获取版本列表
- If DlNeoForgeListLoader.State <> LoadState.Finished Then Return
- Dim Versions = DlNeoForgeListLoader.Output.Value.Where(Function(v) v.Inherit = VanillaName).ToList
- If Not Versions.Any() Then Return
- '可视化
- PanNeoForge.Children.Clear()
- NeoForgeDownloadListItemPreload(PanNeoForge, Versions, AddressOf NeoForge_Selected, False)
- For Each Version In Versions
- PanNeoForge.Children.Add(NeoForgeDownloadListItem(Version, AddressOf NeoForge_Selected, False))
- Next
- Catch ex As Exception
- Logger.Error(ex, "可视化 NeoForge 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Private Sub NeoForge_Selected(sender As MyListItem, e As EventArgs)
- SelectedNeoForge = sender.Tag
- CardNeoForge.IsSwapped = True
- OptiFine_Loaded()
- ReloadSelected()
- End Sub
- Private Sub NeoForge_Clear(sender As Object, e As EventArgs) Handles BtnNeoForgeClear.Click
- SelectedNeoForge = Nothing
- CardNeoForge.IsSwapped = True
- OptiFine_Loaded()
- ReloadSelected()
- End Sub
- #End Region
- #Region "Fabric 列表"
- ''' <summary>
- ''' 获取 Fabric 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadFabricGetError() As String
- '检查 OptiFine 1.20.5+:没有 OptiFabric 故全部不兼容
- If SelectedOptiFine IsNot Nothing AndAlso McUtils.CompareVersionGE(VanillaName, "1.20.5") Then Return "与 OptiFine 不兼容"
- '检查 Loader
- If GetLoaderError(LoadFabric) IsNot Nothing Then Return GetLoaderError(LoadFabric)
- '检查版本
- For Each Version As JObject In DlFabricListLoader.Output.Value("game")
- If Version("version").ToString = VanillaName.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3") Then
- If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容"
- If SelectedNeoForge IsNot Nothing Then Return "与 NeoForge 不兼容"
- Return Nothing
- End If
- Next
- Return "无"
- End Function
- '限制展开
- Private Sub CardFabric_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardFabric.PreviewSwap
- If LoadFabricGetError() IsNot Nothing Then e.Handled = True
- End Sub
- ''' <summary>
- ''' 尝试重新可视化 Fabric 版本列表。
- ''' </summary>
- Private Sub Fabric_Loaded() Handles LoadFabric.StateChanged
- Try
- If DlFabricListLoader.State <> LoadState.Finished Then Return
- '获取版本列表
- Dim Versions As JArray = DlFabricListLoader.Output.Value("loader")
- If Not Versions.Any() Then Return
- '可视化
- PanFabric.Children.Clear()
- CardFabric.SwapControl = PanFabric
- CardFabric.SetContentBuilder(Versions.OfType(Of JObject),
- Function(Version) FabricDownloadListItem(Version, AddressOf Fabric_Selected))
- If Not CardFabric.IsSwapped Then CardFabric.BuildContent()
- Catch ex As Exception
- Logger.Error(ex, "可视化 Fabric 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Public Sub Fabric_Selected(sender As MyListItem, e As EventArgs)
- SelectedFabric = sender.Tag("version").ToString
- FabricApi_Loaded()
- OptiFabric_Loaded()
- CardFabric.IsSwapped = True
- ReloadSelected()
- End Sub
- Private Sub Fabric_Clear(sender As Object, e As EventArgs) Handles BtnFabricClear.Click
- SelectedFabric = Nothing
- SelectedFabricApi = Nothing
- BtnFabricApiClear.Visibility = Visibility.Collapsed
- AutoSelectedFabricApi = False
- SelectedOptiFabric = Nothing
- BtnOptiFabricClear.Visibility = Visibility.Collapsed
- AutoSelectedOptiFabric = False
- CardFabric.IsSwapped = True
- ReloadSelected()
- End Sub
- #End Region
- #Region "Fabric API 列表"
- ''' <summary>
- ''' 判断某 Fabric API 是否适配指定的原版版本。
- ''' </summary>
- Public Shared Function IsFabricApiCompatible(FabricApi As ResourceVersion, MinecraftVersion As String) As Boolean
- Dim FabricApiName = FabricApi.Display
- Try
- If FabricApiName Is Nothing OrElse MinecraftVersion Is Nothing Then Return False
- FabricApiName = FabricApiName.Lower
- Dim TargetName = MinecraftVersion.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3").Lower
- If FabricApiName.StartsWithF("[" & TargetName & "]") Then Return True
- If Not FabricApiName.Contains("/") OrElse Not FabricApiName.Contains("]") Then Return False
- '直接的判断(例如 1.18.1/22w03a)
- For Each Part As String In FabricApiName.BeforeFirst("]").TrimStart("[").Split("/")
- If Part = TargetName Then Return True
- Next
- '将版本名分割语素(例如 1.16.4/5)
- Dim Lefts = FabricApiName.BeforeFirst("]").RegexSearch("[a-z/]+|[0-9/]+").ToList
- Dim Rights = TargetName.BeforeFirst("]").RegexSearch("[a-z/]+|[0-9/]+").ToList
- '对每段进行判断
- Dim i As Integer = 0
- While True
- '两边均缺失,感觉是一个东西
- If Lefts.Count - 1 < i AndAlso Rights.Count - 1 < i Then Return True
- '确定两边是否一致
- Dim LeftValue As String = If(Lefts.Count - 1 < i, "-1", Lefts(i))
- Dim RightValue As String = If(Rights.Count - 1 < i, "-1", Rights(i))
- If Not LeftValue.Contains("/") Then
- If LeftValue <> RightValue Then Return False
- Else
- '左边存在斜杠
- If Not LeftValue.Contains(RightValue) Then Return False
- End If
- i += 1
- End While
- Return True
- Catch ex As Exception
- Logger.Warn(ex, $"判断 Fabric API 版本适配性出错({FabricApiName}, {MinecraftVersion})")
- Return False
- End Try
- End Function
- ''' <summary>
- ''' 获取 FabricApi 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadFabricApiGetError() As String
- '检查 Loader
- If GetLoaderError(LoadFabricApi) IsNot Nothing Then Return GetLoaderError(LoadFabricApi)
- If DlFabricApiLoader.Output Is Nothing Then Return If(SelectedFabric Is Nothing, "需要安装 Fabric", "获取中……")
- '检查版本
- If DlFabricApiLoader.Output.Any(Function(f) IsFabricApiCompatible(f, VanillaName)) Then
- Return If(SelectedFabric Is Nothing, "需要安装 Fabric", Nothing)
- Else
- Return "无"
- End If
- End Function
- '限制展开
- Private Sub CardFabricApi_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardFabricApi.PreviewSwap
- If LoadFabricApiGetError() IsNot Nothing Then e.Handled = True
- End Sub
- Public AutoSelectedFabricApi As Boolean = False
- ''' <summary>
- ''' 尝试重新可视化 FabricApi 版本列表。
- ''' </summary>
- Private Sub FabricApi_Loaded() Handles LoadFabricApi.StateChanged
- Try
- If DlFabricApiLoader.State <> LoadState.Finished Then Return
- If VanillaName Is Nothing OrElse SelectedFabric Is Nothing Then Return
- '获取版本列表
- Dim Versions As New List(Of ResourceVersion)
- For Each Version In DlFabricApiLoader.Output
- If IsFabricApiCompatible(Version, VanillaName) Then
- If Not Version.Display.StartsWithF("[") Then
- Logger.Warn($"已特判修改 Fabric API 显示名:{Version.Display}")
- Version.Display = "[" & VanillaName & "] " & Version.Display
- End If
- Versions.Add(Version)
- End If
- Next
- If Not Versions.Any() Then Return
- Versions = Versions.OrderByDescending(Function(v) v.ReleaseDate).ToList
- '可视化
- PanFabricApi.Children.Clear()
- For Each Version In Versions
- PanFabricApi.Children.Add(FabricApiDownloadListItem(Version, AddressOf FabricApi_Selected))
- Next
- '自动选择 Fabric API
- If Not AutoSelectedFabricApi Then
- AutoSelectedFabricApi = True
- Dim Item As MyListItem = MyVirtualizingElement.TryInit(PanFabricApi.Children(0))
- Logger.Info($"已自动选择 Fabric API:{Item.Title}")
- FabricApi_Selected(Item, Nothing)
- End If
- Catch ex As Exception
- Logger.Error(ex, "可视化 Fabric API 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Private Sub FabricApi_Selected(sender As MyListItem, e As EventArgs)
- SelectedFabricApi = sender.Tag
- CardFabricApi.IsSwapped = True
- ReloadSelected()
- End Sub
- Private Sub FabricApi_Clear(sender As Object, e As EventArgs) Handles BtnFabricApiClear.Click
- SelectedFabricApi = Nothing
- CardFabricApi.IsSwapped = True
- ReloadSelected()
- End Sub
- #End Region
- #Region "OptiFabric 列表"
- ''' <summary>
- ''' 判断某 OptiFabric 是否适配指定的原版版本。
- ''' </summary>
- Public Shared Function IsOptiFabricCompatible(ModFile As ResourceVersion, MinecraftVersion As String) As Boolean
- Try
- If MinecraftVersion Is Nothing Then Return False
- Return ModFile.GameVersions.Contains(MinecraftVersion)
- Catch ex As Exception
- Logger.Warn(ex, $"判断 OptiFabric 版本适配性出错({MinecraftVersion})")
- Return False
- End Try
- End Function
- Public AutoSelectedOptiFabric As Boolean = False
- ''' <summary>
- ''' 获取 OptiFabric 的加载异常信息。若正常则返回 Nothing。
- ''' </summary>
- Public Function LoadOptiFabricGetError() As String
- If VanillaDrop >= 140 AndAlso VanillaDrop <= 150 Then Return "不兼容老版本 Fabric,请手动下载 OptiFabric Origins"
- '检查 Loader
- If GetLoaderError(LoadOptiFabric) IsNot Nothing Then Return GetLoaderError(LoadOptiFabric)
- '检查版本
- If DlOptiFabricLoader.Output Is Nothing Then
- If SelectedFabric Is Nothing AndAlso SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine 与 Fabric"
- If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
- If SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine"
- Return "获取中……"
- End If
- For Each Version In DlOptiFabricLoader.Output
- If Not IsOptiFabricCompatible(Version, VanillaName) Then Continue For '2135#
- If SelectedFabric Is Nothing AndAlso SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine 与 Fabric"
- If SelectedFabric Is Nothing Then Return "需要安装 Fabric"
- If SelectedOptiFine Is Nothing Then Return "需要安装 OptiFine"
- Return Nothing '通过检查
- Next
- Return "无"
- End Function
- '限制展开
- Private Sub CardOptiFabric_PreviewSwap(sender As Object, e As RouteEventArgs) Handles CardOptiFabric.PreviewSwap
- If LoadOptiFabricGetError() IsNot Nothing Then e.Handled = True
- End Sub
- ''' <summary>
- ''' 尝试重新可视化 OptiFabric 版本列表。
- ''' </summary>
- Private Sub OptiFabric_Loaded() Handles LoadOptiFabric.StateChanged
- Try
- If DlOptiFabricLoader.State <> LoadState.Finished Then Return
- If VanillaName Is Nothing OrElse SelectedFabric Is Nothing OrElse SelectedOptiFine Is Nothing Then Return
- '获取版本列表
- Dim Versions As New List(Of ResourceVersion)
- For Each Version In DlOptiFabricLoader.Output
- If IsOptiFabricCompatible(Version, VanillaName) Then Versions.Add(Version)
- Next
- If Not Versions.Any() Then Return
- '排序
- Versions = Versions.OrderByDescending(Function(v) v.ReleaseDate).ToList
- '可视化
- PanOptiFabric.Children.Clear()
- For Each Version In Versions
- PanOptiFabric.Children.Add(OptiFabricDownloadListItem(Version, AddressOf OptiFabric_Selected))
- Next
- '自动选择 OptiFabric
- If AutoSelectedOptiFabric OrElse VanillaDrop >= 140 AndAlso VanillaDrop <= 150 Then Return '1.14~15 不自动选择
- AutoSelectedOptiFabric = True
- Dim Item As MyListItem = MyVirtualizingElement.TryInit(PanOptiFabric.Children(0))
- Logger.Info($"已自动选择 OptiFabric:{Item.Title}")
- OptiFabric_Selected(Item, Nothing)
- Catch ex As Exception
- Logger.Error(ex, "可视化 OptiFabric 安装版本列表出错")
- End Try
- End Sub
- '选择与清除
- Private Sub OptiFabric_Selected(sender As MyListItem, e As EventArgs)
- SelectedOptiFabric = sender.Tag
- CardOptiFabric.IsSwapped = True
- ReloadSelected()
- End Sub
- Private Sub OptiFabric_Clear(sender As Object, e As EventArgs) Handles BtnOptiFabricClear.Click
- SelectedOptiFabric = Nothing
- CardOptiFabric.IsSwapped = True
- ReloadSelected()
- End Sub
- #End Region
- #Region "安装"
- ''' <summary>
- ''' 获取当前选择的组件信息。
- ''' </summary>
- Public Function GetSelectedComponents() As McComponents
- Return New McComponents(
- minecraftVersion:=VanillaName,
- optiFineEntry:=If(SelectedOptiFine Is Nothing, Nothing, JObject.FromObject(SelectedOptiFine)),
- forgeVersion:=SelectedForge?.VersionName,
- neoForgeVersion:=SelectedNeoForge?.VersionName,
- fabricVersion:=SelectedFabric,
- fabricApiVersion:=If(SelectedFabricApi?.Version, If(SelectedFabricApi?.Id, SelectedFabricApi?.Display)),
- optiFabricVersion:=If(SelectedOptiFabric?.Version, If(SelectedOptiFabric?.Id, SelectedOptiFabric?.Display)),
- liteLoaderVersion:=SelectedLiteLoader?.JsonToken?("version").ToString())
- End Function
- Private Sub TextSelectName_KeyDown(sender As Object, e As KeyEventArgs) Handles TextSelectName.KeyDown
- If e.Key = Key.Enter AndAlso IsInSelectPage AndAlso BtnStart.IsEnabled Then BtnStart_Click()
- End Sub
- Private Sub BtnStart_Click() Handles BtnStart.Click
- '提交安装申请
- Dim InstanceName As String = TextSelectName.Text
- Dim Request As New McInstallRequest With {
- .NewInstanceName = InstanceName,
- .InstanceFolder = $"{McFolderSelected}versions\{InstanceName}\",
- .Components = GetSelectedComponents(),
- .MinecraftJson = VanillaData("url").ToString,
- .ForgeEntry = SelectedForge,
- .NeoForgeEntry = SelectedNeoForge,
- .FabricApi = SelectedFabricApi,
- .OptiFabric = SelectedOptiFabric,
- .LiteLoaderEntry = SelectedLiteLoader
- }
- StartInstall(Request)
- End Sub
- Public Overridable Sub StartInstall(Request As McInstallRequest)
- '确认版本隔离
- If (SelectedForge IsNot Nothing OrElse SelectedNeoForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) AndAlso
- (Settings.Get(Of Integer)("LaunchArgumentIndieV2") = 0 OrElse Settings.Get(Of Integer)("LaunchArgumentIndieV2") = 2) Then
- If MyMsgBox("你尚未开启版本隔离,多个 MC 版本会共用同一个 Mod 文件夹。" & vbCrLf &
- "因此,游戏可能会因为读取到与当前版本不符的 Mod 而崩溃。" & vbCrLf &
- "推荐先在 设置 → 启动选项 → 默认版本隔离 中开启版本隔离!", "版本隔离提示", "取消下载", "继续") = 1 Then
- Return
- End If
- End If
- If Not McInstallStart(Request) Then Return
- '返回,这样在再次进入安装页面时这个版本就会显示文件夹已重复
- ExitSelectPage()
- End Sub
- #End Region
- Private Function GetLoaderError(Loader As MyLoading) As String
- If Loader Is Nothing Then Return "获取中……"
- If Not Loader.State.IsLoader Then Return "获取中……"
- Select Case Loader.State.LoadingState
- Case MyLoading.MyLoadingState.Run
- Return "获取中……"
- Case MyLoading.MyLoadingState.Error
- Dim Message As String = CType(Loader.State, LoaderBase).Error.Message
- Return If(Message = "无", "无", "获取失败:" & Message)
- Case MyLoading.MyLoadingState.Unloaded
- Return "未知错误,状态为 Unloaded"
- Case Else
- Return Nothing
- End Select
- End Function
- End Class
|