| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727 |
- ''' <summary>
- ''' 版本修改页:完整还原已安装组件后,复用安装页的选择交互。
- ''' </summary>
- Public Class PageDownloadModify
- Inherits PageDownloadInstall
- Private InitLoader As LoaderTask(Of McInstance, Object)
- Private ForgeVersionLoader As LoaderTask(Of String, List(Of DlForgeVersionEntry))
- Private InitialTarget As McComponents '进入时的组件快照
- ''' <summary>
- ''' 原版的版本号是否可靠(不是通过 json 模糊分析)。
- ''' </summary>
- Private IsVanillaVersionReliable As Boolean
- Private OriginalName As String
- Private CustomLogo As String
- ''' <summary>
- ''' 开始修改 MC 版本时,记录当前选择的组件,以在修改 MC 版本后尝试自动选中相同组件。
- ''' </summary>
- Private ReadOnly PendingComponents As New Dictionary(Of MyLoading, String)
- Private IsRestoringComponents As Boolean
- Public Overrides Sub LoaderInit() '父级 Handles Me.Initialized
- ControlInit()
- InitLoader = New LoaderTask(Of McInstance, Object)("初始化版本修改", AddressOf LoadInstance)
- PageLoaderInit(LoadMinecraft, PanLoad, PanAllBack, Nothing, InitLoader, AddressOf LoadInstanceFinished, Function() PageInstanceLeft.Instance)
- End Sub
- Public Overrides Sub Init() '父级 Handles Me.Loaded
- PanBack.ScrollToHome()
- Static IsLoad As Boolean = False
- If IsLoad Then PageLoaderRestart()
- IsLoad = True
- End Sub
- Private Sub PageUnloaded() Handles Me.Unloaded
- InitLoader.Cancel()
- End Sub
- ''' <summary>
- ''' 读取或初始化版本的安装清单。
- ''' </summary>
- Private Sub LoadInstance(Task As LoaderTask(Of McInstance, Object))
- '旧状态清理
- RunInUiWait(
- Sub()
- AniStop("FrmDownloadInstall SelectPageSwitch")
- IsSelectNameEdited = False
- ClearSelected()
- PendingComponents.Clear()
- InitialTarget = Nothing
- IsInSelectPage = False
- PanAllBack.IsHitTestVisible = False
- End Sub)
- Task.Input.Config.DiscardCache()
- '获取 Components
- Dim Manifest = Configs.McInstallManifest.Get(Task.Input.Config)
- If Manifest IsNot Nothing AndAlso Manifest.SchemaVersion > Versions.McInstallManifestVersion Then
- Logger.Warn($"安装清单由更新版本的 PCL 创建(清单版本:{Manifest.SchemaVersion},当前版本:{Versions.McInstallManifestVersion})")
- Throw New Exception($"更新 PCL 后才能修改它!点击【设置 → 其他 → 检查更新】以更新。")
- End If
- If Manifest IsNot Nothing Then
- Dim LatestManifest = Manifest.RefreshModComponents(Task.Input.PathIndie)
- If LatestManifest IsNot Manifest Then
- Manifest = LatestManifest
- Configs.McInstallManifest.Set(Manifest, Task.Input.Config)
- Task.Input.Config.Save()
- End If
- End If
- Dim Components As McComponents
- Dim OptiFineVersion As String = Nothing
- If Manifest IsNot Nothing Then
- '有清单:从清单读取
- Components = Manifest.Components
- If Components Is Nothing Then Throw New Exception("安装清单缺少组件信息,无法还原已安装组件。")
- IsVanillaVersionReliable = True
- Else
- '无清单:通过版本 JSON 获取
- Dim VersionInfo = New McInstance(Task.Input.PathVersion).Version
- If VersionInfo.VanillaName = "Unknown" Then Throw New Exception("无法确定 Minecraft 版本,无法修改")
- Dim UnknownLoaders = VersionInfo.ModLoaderVersions.
- Where(Function(Loader) String.IsNullOrWhiteSpace(Loader.Value) OrElse Loader.Value = "未知版本").
- Select(Function(Loader) Loader.Key.ToString()).ToList()
- If UnknownLoaders.Any() Then Throw New Exception($"无法确定 {UnknownLoaders.Join("、")} 的版本,无法修改")
- Components = New McComponents(VersionInfo.VanillaName, VersionInfo.ModLoaderVersions)
- OptiFineVersion = VersionInfo.OptiFine
- IsVanillaVersionReliable = VersionInfo.Reliable
- End If
- Dim MinecraftVersion = Components.MinecraftVersion
- If String.IsNullOrWhiteSpace(MinecraftVersion) Then Throw New Exception("无法确定当前 Minecraft 版本,请检查版本文件")
- '等待子列表加载器完成获取
- Dim LoaderList As New Dictionary(Of String, LoaderBase) From {
- {"Minecraft", DlClientListLoader}, {"OptiFine", DlOptiFineListLoader}, {"LiteLoader", DlLiteLoaderListLoader},
- {"NeoForge", DlNeoForgeListLoader}, {"Fabric", DlFabricListLoader}, {"Fabric API", DlFabricApiLoader}, {"OptiFabric", DlOptiFabricLoader}}
- Dim ForgeLoader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = Nothing
- If McVersion.IsStandardFormat(MinecraftVersion) Then
- ForgeLoader = New LoaderTask(Of String, List(Of DlForgeVersionEntry))("DlForgeVersion " & MinecraftVersion, AddressOf DlForgeVersionMain)
- LoaderList.Add("Forge", ForgeLoader)
- End If
- For Each Loader In LoaderList.Values
- Loader.Start(If(Loader Is ForgeLoader, MinecraftVersion, Nothing), Task.IsForceRestarting)
- Next
- Do
- If Task.IsCanceled Then Return
- For Each Pair In LoaderList
- Dim Loader = Pair.Value
- If Loader.State = LoadState.Failed Then
- If Loader Is ForgeLoader AndAlso Loader.Error.Message = "无" Then Continue For 'Forge 无版本时不报错
- Throw New Exception($"获取 {Pair.Key} 版本列表失败,请稍后再试,或使用 VPN 改善网络环境", Loader.Error)
- ElseIf Loader.State = LoadState.Canceled Then
- Throw New Exception($"获取 {Pair.Key} 版本列表被中断,请稍后再试,或使用 VPN 改善网络环境")
- End If
- Next
- If LoaderList.Values.All(Function(Loader) Loader.State = LoadState.Finished OrElse Loader.State = LoadState.Failed) Then Exit Do
- Task.Progress = 0.7 * LoaderList.Values.Average(Function(Loader) Loader.Progress)
- Thread.Sleep(10)
- Loop
- If Task.IsCanceled Then Return
- Task.Progress = 0.7
- 'Minecraft
- MinecraftVersions = CType(DlClientListLoader.Output.Value("versions").DeepClone(), JArray)
- VanillaData = MinecraftVersions.OfType(Of JObject).FirstOrDefault(
- Function(v) v("id").ToString.Replace("∞", "infinite") = MinecraftVersion.Replace("∞", "infinite"))
- If VanillaData Is Nothing Then Throw New Exception($"Minecraft 列表中没有已安装的 {MinecraftVersion}")
- VanillaData("id") = MinecraftVersion
- 'OptiFine
- If Manifest IsNot Nothing Then
- SelectedOptiFine = Components.OptiFineEntry?.ToObject(Of DlOptiFineListEntry)()
- If SelectedOptiFine IsNot Nothing AndAlso Not DlOptiFineListLoader.Output.Value.Any(Function(v) v.FileName = SelectedOptiFine.FileName) Then
- '如果 OptiFine 是 pre 版,可能只在 BMCLAPI 下有,官方源删了。如果是这种缺失数据的情况,换用 BMCLAPI 源作为输出
- If DlOptiFineListBmclapiLoader.State <> LoadState.Finished Then DlOptiFineListBmclapiLoader.WaitForExit()
- DlOptiFineListLoader.Output = DlOptiFineListBmclapiLoader.Output
- End If
- ElseIf OptiFineVersion IsNot Nothing AndAlso OptiFineVersion <> "未知版本" Then
- SelectedOptiFine = DlOptiFineListLoader.Output.Value.FirstOrDefault(
- Function(v) v.Inherit = MinecraftVersion AndAlso
- v.InstanceName.AfterLast("-OptiFine_").Replace("HD_U_", "") = OptiFineVersion.Replace("HD_U_", ""))
- If SelectedOptiFine Is Nothing Then Throw New Exception($"OptiFine 列表中没有已安装的 {OptiFineVersion}")
- End If
- 'Forge
- If Components.ModLoaderVersions.ContainsKey(ModLoaders.Forge) Then
- SelectedForge = ForgeLoader?.Output?.FirstOrDefault(
- Function(v) v.Inherit = MinecraftVersion AndAlso v.VersionName = Components.ModLoaderVersions(ModLoaders.Forge) AndAlso
- v.Category <> "universal" AndAlso v.Category <> "client" AndAlso (SelectedOptiFine Is Nothing OrElse IsOptiFineSuitForForge(SelectedOptiFine, v)))
- If SelectedForge Is Nothing Then Throw New Exception($"Forge 列表中没有已安装的 {Components.ModLoaderVersions(ModLoaders.Forge)}")
- End If
- 'NeoForge
- If Components.ModLoaderVersions.ContainsKey(ModLoaders.NeoForge) Then
- SelectedNeoForge = DlNeoForgeListLoader.Output.Value.FirstOrDefault(
- Function(v) v.Inherit = MinecraftVersion AndAlso v.VersionName = Components.ModLoaderVersions(ModLoaders.NeoForge))
- If SelectedNeoForge Is Nothing Then Throw New Exception($"NeoForge 列表中没有已安装的 {Components.ModLoaderVersions(ModLoaders.NeoForge)}")
- End If
- 'Fabric
- If Components.ModLoaderVersions.ContainsKey(ModLoaders.Fabric) Then
- Dim FabricEntry = DlFabricListLoader.Output.Value("loader").OfType(Of JObject).FirstOrDefault(
- Function(v) v("version").ToString = Components.ModLoaderVersions(ModLoaders.Fabric),
- Function(v) v("version").ToString.Replace("+build", "") = Components.ModLoaderVersions(ModLoaders.Fabric))
- If FabricEntry Is Nothing OrElse Not DlFabricListLoader.Output.Value("game").OfType(Of JObject).
- Any(Function(v) v("version").ToString = MinecraftVersion.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3")) Then
- Throw New Exception($"Fabric 列表中没有已安装的 {Components.ModLoaderVersions(ModLoaders.Fabric)}")
- End If
- SelectedFabric = FabricEntry("version").ToString
- End If
- 'LiteLoader
- If Components.ModLoaderVersions.ContainsKey(ModLoaders.LiteLoader) Then
- SelectedLiteLoader = DlLiteLoaderListLoader.Output.Value.FirstOrDefault(
- Function(v) v.Inherit = MinecraftVersion AndAlso v.JsonToken("version").ToString = Components.ModLoaderVersions(ModLoaders.LiteLoader))
- If SelectedLiteLoader Is Nothing Then Throw New Exception($"LiteLoader 列表中没有已安装的 {Components.ModLoaderVersions(ModLoaders.LiteLoader)}")
- End If
- 'Fabric API
- If Components.FabricApiVersion IsNot Nothing Then
- SelectedFabricApi = DlFabricApiLoader.Output.FirstOrDefault(
- Function(v) (v.Version = Components.FabricApiVersion OrElse v.Id = Components.FabricApiVersion OrElse
- v.Display = Components.FabricApiVersion) AndAlso IsFabricApiCompatible(v, MinecraftVersion))
- If SelectedFabricApi Is Nothing Then Throw New Exception($"Fabric API 列表中没有已安装的 {Components.FabricApiVersion}")
- End If
- 'OptiFabric
- If Components.OptiFabricVersion IsNot Nothing Then
- SelectedOptiFabric = DlOptiFabricLoader.Output.FirstOrDefault(
- Function(v) (v.Version = Components.OptiFabricVersion OrElse v.Id = Components.OptiFabricVersion OrElse
- v.Display = Components.OptiFabricVersion) AndAlso IsOptiFabricCompatible(v, MinecraftVersion))
- If SelectedOptiFabric Is Nothing Then Throw New Exception($"OptiFabric 列表中没有已安装的 {Components.OptiFabricVersion}")
- End If
- '扫描尚未识别的 Mod 组件
- Dim ManagedFiles As New List(Of McInstallManifest.ManagedFile)
- If Manifest IsNot Nothing Then ManagedFiles.AddRange(Manifest.ManagedFiles)
- #Region "从 mods 文件夹中获取以 Mod 形式安装的组件信息"
- '获取 mods 文件夹下的 jar 文件与 SHA1
- Dim Mods As New Lazy(Of List(Of (File As FileInfo, Sha1 As String)))(
- Function()
- Dim ModsFolder = Task.Input.PathIndie & "mods\"
- Dim Files = DirectoryUtils.EnumerateFiles(ModsFolder, searchPattern:="*.jar").ToList()
- If SelectedLiteLoader IsNot Nothing Then 'LiteLoader 的 OptiFine 安装目录
- Files.AddRange(DirectoryUtils.EnumerateFiles(Path.Combine(ModsFolder, MinecraftVersion), searchPattern:="*.jar"))
- End If
- Dim Entries As New List(Of (File As FileInfo, Sha1 As String))
- For Each FilePath In Files
- If Task.IsCanceled Then Return Entries
- Dim File = FileUtils.GetInfo(FilePath)
- Entries.Add((File, New LocalResourceFile(File).ModrinthHash))
- Task.Progress = 0.7 + 0.28 * Entries.Count / Files.Count
- Next
- Return Entries
- End Function)
- 'Fabric API
- If SelectedFabric IsNot Nothing AndAlso SelectedFabricApi Is Nothing Then
- Dim FabricApiList = DlFabricApiLoader.Output.Where(Function(v) IsFabricApiCompatible(v, MinecraftVersion)).ToList()
- Dim Matches As New List(Of (File As FileInfo, Sha1 As String, Version As ResourceVersion))
- For Each Entry In Mods.Value
- Dim Match = FabricApiList.FirstOrDefault(Function(v) v.Hash = Entry.Sha1)
- If Match Is Nothing Then Continue For
- Matches.Add((Entry.File, Entry.Sha1, Match))
- Next
- Dim SelectedFile = SelectMod("Fabric API", Matches)
- If SelectedFile IsNot Nothing Then
- SelectedFabricApi = SelectedFile.Value.Version
- ManagedFiles.Add(New McInstallManifest.ManagedFile("mods/" & SelectedFile.Value.File.Name.Lower(), SelectedFile.Value.Sha1, SelectedFile.Value.File.LastWriteTimeUtc, "FabricApi"))
- End If
- End If
- If Task.IsCanceled Then Return
- 'OptiFabric
- If SelectedFabric IsNot Nothing AndAlso SelectedOptiFabric Is Nothing Then
- Dim OptiFabricList = DlOptiFabricLoader.Output.Where(Function(v) IsOptiFabricCompatible(v, MinecraftVersion)).ToList()
- Dim HasMd5 = OptiFabricList.Any(Function(v) If(v.Hash, "").Length = 32) 'CurseForge 的 OptiFabric 信息可能提供 SHA1 或 MD5
- Dim Matches As New List(Of (File As FileInfo, Sha1 As String, Version As ResourceVersion))
- For Each Entry In Mods.Value
- Dim Match = OptiFabricList.FirstOrDefault(Function(v) v.Hash = Entry.Sha1)
- If Match Is Nothing AndAlso HasMd5 Then
- Dim Md5 = CryptographyUtils.ComputeFileHash(Entry.File.FullName, CryptographyUtils.HashMethod.Md5)
- Match = OptiFabricList.FirstOrDefault(Function(v) v.Hash = Md5)
- End If
- If Match Is Nothing Then Continue For
- Matches.Add((Entry.File, Entry.Sha1, Match))
- Next
- Dim SelectedFile = SelectMod("OptiFabric", Matches)
- If SelectedFile IsNot Nothing Then
- SelectedOptiFabric = SelectedFile.Value.Version
- ManagedFiles.Add(New McInstallManifest.ManagedFile("mods/" & SelectedFile.Value.File.Name.Lower(), SelectedFile.Value.Sha1, SelectedFile.Value.File.LastWriteTimeUtc, "OptiFabric"))
- End If
- End If
- If Task.IsCanceled Then Return
- 'OptiFine
- Dim OptiFineFiles As New List(Of (File As FileInfo, Sha1 As String, OriginalName As String))
- If SelectedOptiFine Is Nothing AndAlso (SelectedForge IsNot Nothing OrElse SelectedLiteLoader IsNot Nothing OrElse SelectedFabric IsNot Nothing) Then 'OptiFine 只在有 Mod 加载器时才看在不在 mods 文件夹中
- Static OptiFineHashes As JObject = FileUtils.ReadAsJson("Minecraft\OptiFineHashes.json", type:=GetType(Resource)) 'JSON 内容:{"SHA1": "原始文件名", ...}
- OptiFineFiles = Mods.Value.
- Select(Function(Entry) (Entry.File, Entry.Sha1, OriginalName:=OptiFineHashes(Entry.Sha1)?.ToString())). '用本地文件的 SHA1 匹配下载时的原始文件名,再根据原始文件名取得下载源信息
- Where(Function(Entry) Entry.OriginalName IsNot Nothing).ToList()
- Dim Matches As New List(Of (File As FileInfo, Sha1 As String, Version As DlOptiFineListEntry))
- For Each Entry In OptiFineFiles '遍历 hash 匹配到了的本地文件
- Dim Match = DlOptiFineListLoader.Output.Value.FirstOrDefault(
- Function(v) v.Inherit = MinecraftVersion AndAlso v.FileName = Entry.OriginalName AndAlso (SelectedForge Is Nothing OrElse IsOptiFineSuitForForge(v, SelectedForge)))
- If Match Is Nothing Then
- Hint($"无法从 OptiFine 列表还原 {Entry.File.Name} 对应的 {Entry.OriginalName},将跳过该文件。")
- Continue For
- End If
- Matches.Add((Entry.File, Entry.Sha1, Match))
- Next
- Dim SelectedFile = SelectMod("OptiFine", Matches)
- If SelectedFile IsNot Nothing Then
- SelectedOptiFine = SelectedFile.Value.Version
- Dim RelativePath = PathUtils.RemoveExtendedPrefix(SelectedFile.Value.File.FullName).Substring(Task.Input.PathIndie.Length).Replace("\", "/").Lower()
- ManagedFiles.Add(New McInstallManifest.ManagedFile(RelativePath, SelectedFile.Value.Sha1, SelectedFile.Value.File.LastWriteTimeUtc, "OptiFine"))
- End If
- End If
- If Task.IsCanceled Then Return
- #End Region
- '保存 Manifest
- If IsVanillaVersionReliable Then
- Components = New McComponents(MinecraftVersion, Components.ModLoaderVersions,
- If(SelectedOptiFine Is Nothing, Nothing, JObject.FromObject(SelectedOptiFine)),
- If(SelectedFabricApi?.Version, If(SelectedFabricApi?.Id, SelectedFabricApi?.Display)),
- If(SelectedOptiFabric?.Version, If(SelectedOptiFabric?.Id, SelectedOptiFabric?.Display)))
- If Manifest Is Nothing OrElse Not Components.IsEquivalentTo(Manifest.Components) OrElse Not ManagedFiles.SequenceEqual(Manifest.ManagedFiles) Then
- Configs.McInstallManifest.Set(New McInstallManifest(Versions.McInstallManifestVersion, Components, Date.UtcNow, ManagedFiles), Task.Input.Config)
- Task.Input.Config.Save()
- Logger.Info($"已为 {Task.Input.Name} 更新安装清单")
- End If
- End If
- If Task.IsCanceled Then Return
- ForgeVersionLoader = ForgeLoader
- End Sub
- Private Function SelectMod(Of T)(ComponentName As String, Matches As List(Of (File As FileInfo, Sha1 As String, Version As T))) As (File As FileInfo, Sha1 As String, Version As T)?
- If Matches.Count = 0 Then Return Nothing
- If Matches.Count = 1 Then Return Matches(0)
- Dim Choice As Integer? = Nothing
- RunInUiWait(Sub() Choice = MyMsgBoxSelect(Matches.Select(Function(Entry) CType(New MyRadioBox With {.Text = Entry.File.Name}, IMyRadio)), $"选择当前使用的 {ComponentName}"))
- If Not Choice.HasValue Then Throw New Exception($"发现了多个 {ComponentName}")
- Return Matches(Choice.Value)
- End Function
- ''' <summary>
- ''' 初始化修改页
- ''' </summary>
- Private Sub LoadInstanceFinished(Task As LoaderTask(Of McInstance, Object))
- '还原原版信息
- OriginalName = Task.Input.Name
- CustomLogo = Nothing
- If ReadIni(Task.Input.PathVersion & "PCL\Setup.ini", "LogoCustom", False) Then
- CustomLogo = If(Task.Input.Logo.EndsWithF("PCL\Logo.png"), Task.Input.PathVersion & "PCL\Logo.png", Task.Input.Logo)
- End If
- Dim Item = McDownloadListItem(VanillaData, Nothing, False).Init()
- VanillaName = Item.Title
- VanillaIcon = Item.Logo
- LabMinecraftVersion.Text = VanillaName
- TextSelectName.Text = OriginalName
- IsSelectNameEdited = Not String.Equals(OriginalName, GetSelectName(), StringComparison.Ordinal)
- TextSelectName.ValidateRules = New ObjectModel.Collection(Of Validate) From {
- New ValidateFolderName(McFolderSelected & "versions", IgnoreList:=New List(Of String) From {OriginalName})}
- '修改页 UI
- CardMinecraft.Visibility = If(RestrictMcDownload, Visibility.Collapsed, Visibility.Visible)
- BtnBack.Visibility = Visibility.Collapsed
- ImgLogo.Margin = New Thickness(15, 15, 0, 0)
- TextSelectName.Margin = New Thickness(56, 16, 16, 0)
- LabSelectName.Text = $"原名 : {OriginalName}"
- UpdateOriginalNameVisibility()
- BtnStart.Text = "开始修改"
- BtnStart.Logo = FrmInstanceLeft.ItemModify.Logo
- AutoSelectedFabricApi = SelectedFabric IsNot Nothing
- AutoSelectedOptiFabric = SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing
- If ForgeVersionLoader IsNot Nothing Then LoadForge.State = ForgeVersionLoader
- PrepareSelectPage()
- ReloadComponentLists()
- '进入动画
- PanMinecraft.Visibility = Visibility.Collapsed
- PanMinecraft.Opacity = 0
- PanMinecraft.RenderTransform = New TranslateTransform(-50, 0)
- PanSelect.Opacity = 1
- PanSelect.RenderTransform = New TranslateTransform
- PanBack.IsHitTestVisible = True
- PanAllBack.IsHitTestVisible = True
- InitialTarget = GetSelectedComponents()
- '设置原始数据
- BtnMinecraftRestore.Tag = VanillaData
- BtnOptiFineRestore.Tag = SelectedOptiFine
- BtnForgeRestore.Tag = SelectedForge
- BtnNeoForgeRestore.Tag = SelectedNeoForge
- BtnFabricRestore.Tag = SelectedFabric
- BtnFabricApiRestore.Tag = SelectedFabricApi
- BtnOptiFabricRestore.Tag = SelectedOptiFabric
- BtnLiteLoaderRestore.Tag = SelectedLiteLoader
- ImgMinecraftOld.Source = VanillaIcon
- LabMinecraftOld.Text = LabMinecraftVersion.Text
- LabOptiFineOld.Text = If(SelectedOptiFine Is Nothing, "无", LabOptiFine.Text)
- LabForgeOld.Text = If(SelectedForge Is Nothing, "无", LabForge.Text)
- LabNeoForgeOld.Text = If(SelectedNeoForge Is Nothing, "无", LabNeoForge.Text)
- LabFabricOld.Text = If(SelectedFabric Is Nothing, "无", LabFabric.Text)
- LabLiteLoaderOld.Text = If(SelectedLiteLoader Is Nothing, "无", LabLiteLoader.Text)
- LabFabricApiOld.Text = If(SelectedFabricApi Is Nothing, "无", LabFabricApi.Text)
- LabOptiFabricOld.Text = If(SelectedOptiFabric Is Nothing, "无", LabOptiFabric.Text)
- RefreshComparisons()
- End Sub
- Public Overrides Function GetSelectLogo() As String
- Return If(CustomLogo, MyBase.GetSelectLogo())
- End Function
- Public Overrides Sub ShowMinecraftVersionList()
- If IsInSelectPage Then
- '把当前已选择的组件记录到 PendingComponents
- Dim Components = GetSelectedComponents()
- For Each Component In {
- (Loader:=LoadOptiFine, Version:=Components.OptiFineVersion),
- (Loader:=LoadFabricApi, Version:=Components.FabricApiVersion),
- (Loader:=LoadOptiFabric, Version:=Components.OptiFabricVersion),
- (Loader:=LoadForge, Version:=SelectedForge?.VersionName),
- (Loader:=LoadNeoForge, Version:=SelectedNeoForge?.VersionName),
- (Loader:=LoadFabric, Version:=SelectedFabric),
- (Loader:=LoadLiteLoader, Version:=SelectedLiteLoader?.JsonToken?("version").ToString())}
- '保留尚未加载完成的组件选择
- If Component.Version IsNot Nothing Then PendingComponents(Component.Loader) = Component.Version
- Next
- End If
- MyBase.ShowMinecraftVersionList()
- End Sub
- Public Overrides Sub ReloadSelected()
- If IsRestoringComponents Then Return
- If IsInSelectPage AndAlso VanillaName IsNot Nothing AndAlso PendingComponents.Any() Then
- IsRestoringComponents = True
- Try
- Dim HasProcessed As Boolean = False
- '优先恢复 Mod 加载器,再匹配兼容的附加组件
- For Each LoadingComponent In {LoadFabric, LoadForge, LoadNeoForge, LoadLiteLoader, LoadOptiFine, LoadFabricApi, LoadOptiFabric}
- Dim Version As String = Nothing
- If Not PendingComponents.TryGetValue(LoadingComponent, Version) Then Continue For
- If Not LoadingComponent.State.IsLoader Then Continue For
- Dim Loader = DirectCast(LoadingComponent.State, LoaderBase)
- '检查前置组件
- If LoadingComponent Is LoadOptiFine Then
- If {LoadFabric, LoadForge, LoadNeoForge, LoadLiteLoader}.Any(Function(Component) PendingComponents.ContainsKey(Component)) Then Continue For
- ElseIf LoadingComponent Is LoadFabricApi Then
- If PendingComponents.ContainsKey(LoadFabric) Then Continue For
- ElseIf LoadingComponent Is LoadForge Then
- If Not McVersion.IsStandardFormat(VanillaName) Then
- PendingComponents.Remove(LoadingComponent)
- Continue For
- End If
- If DirectCast(Loader, LoaderTask(Of String, List(Of DlForgeVersionEntry))).Input <> VanillaName Then Continue For
- If Loader.State = LoadState.Failed AndAlso Loader.Error.Message = "无" Then
- PendingComponents.Remove(LoadingComponent)
- Continue For
- End If
- ElseIf LoadingComponent Is LoadOptiFabric Then
- If PendingComponents.ContainsKey(LoadFabric) OrElse PendingComponents.ContainsKey(LoadOptiFine) Then Continue For
- End If
- If Loader.State <> LoadState.Finished Then Continue For
- '移除已处理的组件
- PendingComponents.Remove(LoadingComponent)
- HasProcessed = True
- '匹配目标 MC 版本下兼容的组件
- If LoadingComponent Is LoadFabric Then
- If SelectedFabric Is Nothing AndAlso LoadFabricGetError() Is Nothing Then
- Dim Versions = DlFabricListLoader.Output.Value("loader").OfType(Of JObject)
- SelectedFabric = If(Versions.FirstOrDefault(Function(v) v("version").ToString = Version), Versions.FirstOrDefault())?("version").ToString()
- End If
- ElseIf LoadingComponent Is LoadOptiFine Then
- If SelectedOptiFine Is Nothing AndAlso LoadOptiFineGetError() Is Nothing Then
- Dim Versions = DlOptiFineListLoader.Output.Value.Where(Function(v) v.Inherit = VanillaName AndAlso
- (SelectedForge Is Nothing OrElse IsOptiFineSuitForForge(v, SelectedForge)))
- SelectedOptiFine = If(Versions.FirstOrDefault(Function(v) v.InstanceName.AfterLast("-OptiFine_") = Version),
- Versions.OrderBy(Function(v) v.IsPreview).
- ThenByDescending(Function(v) v.DisplayName, Comparer(Of String).Create(AddressOf McUtils.CompareVersion)).FirstOrDefault())
- End If
- ElseIf LoadingComponent Is LoadForge Then
- If SelectedForge Is Nothing AndAlso LoadForgeGetError() Is Nothing Then
- Dim Versions = DirectCast(Loader, LoaderTask(Of String, List(Of DlForgeVersionEntry))).Output.Where(
- Function(v) v.Inherit = VanillaName AndAlso
- v.Category <> "universal" AndAlso v.Category <> "client" AndAlso
- (SelectedOptiFine Is Nothing OrElse IsOptiFineSuitForForge(SelectedOptiFine, v)))
- SelectedForge = If(Versions.FirstOrDefault(Function(v) v.VersionName = Version), Versions.OrderByDescending(Function(v) v).FirstOrDefault())
- End If
- ElseIf LoadingComponent Is LoadNeoForge Then
- If SelectedNeoForge Is Nothing AndAlso LoadNeoForgeGetError() Is Nothing Then
- Dim Versions = DlNeoForgeListLoader.Output.Value.Where(Function(v) v.Inherit = VanillaName)
- SelectedNeoForge = If(Versions.FirstOrDefault(Function(v) v.VersionName = Version), Versions.FirstOrDefault())
- End If
- ElseIf LoadingComponent Is LoadLiteLoader Then
- If SelectedLiteLoader Is Nothing AndAlso LoadLiteLoaderGetError() Is Nothing Then
- Dim Versions = DlLiteLoaderListLoader.Output.Value.Where(Function(v) v.Inherit = VanillaName)
- SelectedLiteLoader = If(Versions.FirstOrDefault(Function(v) v.JsonToken("version").ToString = Version), Versions.FirstOrDefault())
- End If
- ElseIf LoadingComponent Is LoadFabricApi Then
- If SelectedFabricApi Is Nothing AndAlso LoadFabricApiGetError() Is Nothing Then
- Dim Versions = DlFabricApiLoader.Output.Where(Function(v) IsFabricApiCompatible(v, VanillaName))
- SelectedFabricApi = If(Versions.FirstOrDefault(Function(v) v.Version = Version OrElse v.Id = Version OrElse v.Display = Version),
- Versions.OrderByDescending(Function(v) v.ReleaseDate).FirstOrDefault())
- End If
- If SelectedFabricApi IsNot Nothing Then AutoSelectedFabricApi = True
- ElseIf LoadingComponent Is LoadOptiFabric Then
- If SelectedOptiFabric Is Nothing AndAlso LoadOptiFabricGetError() Is Nothing Then
- Dim Versions = DlOptiFabricLoader.Output.Where(Function(v) IsOptiFabricCompatible(v, VanillaName))
- SelectedOptiFabric = If(Versions.FirstOrDefault(Function(v) v.Version = Version OrElse v.Id = Version OrElse v.Display = Version),
- Versions.OrderByDescending(Function(v) v.ReleaseDate).FirstOrDefault())
- End If
- If SelectedOptiFabric IsNot Nothing Then AutoSelectedOptiFabric = True
- End If
- Next
- '更新组件列表
- If HasProcessed Then ReloadComponentLists()
- Finally
- IsRestoringComponents = False
- End Try
- End If
- '刷新当前选择与原始版本的对比
- MyBase.ReloadSelected()
- If InitialTarget IsNot Nothing Then RefreshComparisons()
- End Sub
- Private Sub RefreshComparisons()
- Dim Current = GetSelectedComponents()
- ImgMinecraftNew.Source = VanillaIcon
- 'Minecraft
- Dim IsMinecraftUnchanged = InitialTarget.MinecraftVersion = Current.MinecraftVersion
- ShowComparison(PanMinecraftCompare, PanMinecraftInfo, InitialTarget.MinecraftVersion, Current.MinecraftVersion,
- LabMinecraftVersion.Text, BtnMinecraftRestore, True)
- 'OptiFine
- Dim OriginalOptiFine = TryCast(BtnOptiFineRestore.Tag, DlOptiFineListEntry)
- ShowComparison(PanOptiFineCompare, PanOptiFineInfo, InitialTarget.OptiFineVersion, Current.OptiFineVersion,
- LabOptiFine.Text, BtnOptiFineRestore, InitialTarget.OptiFineEntry Is Nothing OrElse
- IsMinecraftUnchanged AndAlso CardOptiFine.MainSwap.Visibility = Visibility.Visible AndAlso OriginalOptiFine IsNot Nothing AndAlso
- (SelectedForge Is Nothing OrElse IsOptiFineSuitForForge(OriginalOptiFine, SelectedForge)), BtnOptiFineClear)
- 'Fabric API
- ShowComparison(PanFabricApiCompare, PanFabricApiInfo, InitialTarget.FabricApiVersion, Current.FabricApiVersion,
- LabFabricApi.Text, BtnFabricApiRestore, InitialTarget.FabricApiVersion Is Nothing OrElse
- IsMinecraftUnchanged AndAlso SelectedFabric IsNot Nothing AndAlso CardFabricApi.MainSwap.Visibility = Visibility.Visible, BtnFabricApiClear)
- 'OptiFabric
- ShowComparison(PanOptiFabricCompare, PanOptiFabricInfo, InitialTarget.OptiFabricVersion, Current.OptiFabricVersion,
- LabOptiFabric.Text, BtnOptiFabricRestore, InitialTarget.OptiFabricVersion Is Nothing OrElse
- IsMinecraftUnchanged AndAlso SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing AndAlso CardOptiFabric.MainSwap.Visibility = Visibility.Visible, BtnOptiFabricClear)
- 'Mod Loader
- For Each Loader In {
- (Kind:=ModLoaders.Forge, Card:=CardForge, ComparePanel:=PanForgeCompare, CurrentPanel:=PanForgeInfo, Label:=LabForge, RestoreButton:=BtnForgeRestore, ClearButton:=BtnForgeClear),
- (Kind:=ModLoaders.NeoForge, Card:=CardNeoForge, ComparePanel:=PanNeoForgeCompare, CurrentPanel:=PanNeoForgeInfo, Label:=LabNeoForge, RestoreButton:=BtnNeoForgeRestore, ClearButton:=BtnNeoForgeClear),
- (Kind:=ModLoaders.Fabric, Card:=CardFabric, ComparePanel:=PanFabricCompare, CurrentPanel:=PanFabricInfo, Label:=LabFabric, RestoreButton:=BtnFabricRestore, ClearButton:=BtnFabricClear),
- (Kind:=ModLoaders.LiteLoader, Card:=CardLiteLoader, ComparePanel:=PanLiteLoaderCompare, CurrentPanel:=PanLiteLoaderInfo, Label:=LabLiteLoader, RestoreButton:=BtnLiteLoaderRestore, ClearButton:=BtnLiteLoaderClear)}
- Dim OldVersion As String = Nothing, NewVersion As String = Nothing
- InitialTarget.ModLoaderVersions.TryGetValue(Loader.Kind, OldVersion)
- Current.ModLoaderVersions.TryGetValue(Loader.Kind, NewVersion)
- Dim CanRestore = OldVersion Is Nothing OrElse IsMinecraftUnchanged AndAlso
- Loader.Card.MainSwap.Visibility = Visibility.Visible AndAlso Loader.RestoreButton.Tag IsNot Nothing
- If Loader.Kind = ModLoaders.Forge AndAlso OldVersion IsNot Nothing AndAlso CanRestore Then
- CanRestore = SelectedOptiFine Is Nothing OrElse IsOptiFineSuitForForge(SelectedOptiFine, DirectCast(Loader.RestoreButton.Tag, DlForgeVersionEntry))
- End If
- If Loader.Kind = ModLoaders.Fabric AndAlso OldVersion IsNot Nothing Then
- Dim TargetVersion = VanillaName.Replace("∞", "infinite").Replace("Combat Test 7c", "1.16_combat-3")
- CanRestore = CardFabric.Visibility = Visibility.Visible AndAlso CardFabric.MainSwap.Visibility = Visibility.Visible AndAlso
- DlFabricListLoader.Output.Value("loader").OfType(Of JObject).Any(Function(v) v("version").ToString = OldVersion) AndAlso
- DlFabricListLoader.Output.Value("game").OfType(Of JObject).Any(Function(v) v("version").ToString = TargetVersion)
- End If
- ShowComparison(Loader.ComparePanel, Loader.CurrentPanel, OldVersion, NewVersion, Loader.Label.Text,
- Loader.RestoreButton, CanRestore, Loader.ClearButton)
- Next
- UpdateStartButton()
- End Sub
- Private Sub ShowComparison(ComparePanel As Grid, CurrentPanel As FrameworkElement, OldVersion As String, NewVersion As String, NewText As String,
- RestoreButton As MyIconButton, CanRestore As Boolean, Optional ClearButton As FrameworkElement = Nothing)
- '获取不可安装的原因
- Dim UnavailableReason As String = Nothing
- If NewVersion Is Nothing Then
- If RestoreButton Is BtnOptiFineRestore Then
- UnavailableReason = LoadOptiFineGetError()
- ElseIf RestoreButton Is BtnForgeRestore Then
- UnavailableReason = If(McVersion.IsStandardFormat(VanillaName), LoadForgeGetError(), "无")
- ElseIf RestoreButton Is BtnNeoForgeRestore Then
- UnavailableReason = If(CardNeoForge.Visibility = Visibility.Collapsed, "无", LoadNeoForgeGetError())
- ElseIf RestoreButton Is BtnFabricRestore Then
- UnavailableReason = If(CardFabric.Visibility = Visibility.Collapsed, "无", LoadFabricGetError())
- ElseIf RestoreButton Is BtnLiteLoaderRestore Then
- UnavailableReason = If(CardLiteLoader.Visibility = Visibility.Collapsed, "无", LoadLiteLoaderGetError())
- ElseIf RestoreButton Is BtnFabricApiRestore Then
- UnavailableReason = LoadFabricApiGetError()
- ElseIf RestoreButton Is BtnOptiFabricRestore Then
- UnavailableReason = LoadOptiFabricGetError()
- End If
- NewText = If(UnavailableReason, "可以添加")
- End If
- '修改对比
- Dim IsPending = NewVersion Is Nothing AndAlso (NewText = "获取中……" OrElse NewText.StartsWithF("获取失败:"))
- Dim IsChanged = OldVersion <> NewVersion AndAlso Not IsPending
- CanRestore = IsChanged AndAlso OldVersion IsNot Nothing AndAlso CanRestore
- ComparePanel.Visibility = If(IsChanged, Visibility.Visible, Visibility.Collapsed)
- CurrentPanel.Visibility = If(IsChanged, Visibility.Collapsed, Visibility.Visible)
- '还原与取消安装按钮
- RestoreButton.Visibility = If(CanRestore, Visibility.Visible, Visibility.Collapsed)
- If ClearButton IsNot Nothing Then ClearButton.ToolTip = If(OldVersion Is Nothing, "取消安装", "移除")
- Dim HasClearButton = ClearButton IsNot Nothing AndAlso ClearButton.Visibility = Visibility.Visible
- RestoreButton.Margin = New Thickness(0, 5, If(CanRestore AndAlso HasClearButton, 60, 32), 0)
- ComparePanel.Margin = New Thickness(ComparePanel.Margin.Left, ComparePanel.Margin.Top,
- If(CanRestore AndAlso HasClearButton, 110, 80), ComparePanel.Margin.Bottom)
- If Not IsChanged Then Return
- '显示修改前已安装组件的对比卡片
- If OldVersion IsNot Nothing Then
- Dim Card = CType(ComparePanel.Parent, MyCard)
- If Card.Visibility = Visibility.Collapsed Then
- Card.IsSwapped = True
- If Card.MainSwap IsNot Nothing Then Card.MainSwap.Visibility = Visibility.Collapsed
- Card.Visibility = Visibility.Visible
- End If
- End If
- Dim OldSide = CType(ComparePanel.Children(0), DockPanel)
- Dim NewSide = CType(ComparePanel.Children(2), DockPanel)
- OldSide.Children(0).Visibility = If(OldVersion Is Nothing, Visibility.Collapsed, Visibility.Visible)
- CType(OldSide.Children(1), TextBlock).Margin = If(OldVersion Is Nothing, New Thickness(0), New Thickness(7, 0, 0, 0))
- NewSide.Children(0).Visibility = If(NewVersion Is Nothing, Visibility.Collapsed, Visibility.Visible)
- Dim NewLabel = CType(NewSide.Children(1), TextBlock)
- NewLabel.Margin = If(NewVersion Is Nothing, New Thickness(0), New Thickness(7, 0, 0, 0))
- NewLabel.Text = If(NewVersion Is Nothing, "移除", NewText)
- If NewVersion Is Nothing AndAlso UnavailableReason IsNot Nothing Then
- NewLabel.Inlines.Add(New Run($"({If(UnavailableReason = "无", "无可用版本", UnavailableReason)})") With {.Foreground = ColorGray4})
- End If
- End Sub
- Private Sub RestoreComponent(sender As Object, e As EventArgs) Handles BtnMinecraftRestore.Click, BtnOptiFineRestore.Click, BtnForgeRestore.Click,
- BtnNeoForgeRestore.Click, BtnFabricRestore.Click, BtnFabricApiRestore.Click, BtnOptiFabricRestore.Click, BtnLiteLoaderRestore.Click
- Dim Button = DirectCast(sender, MyIconButton)
- '恢复初始选择
- If Button Is BtnMinecraftRestore Then
- IsRestoringComponents = True
- Try
- PendingComponents.Clear()
- MinecraftSelected(McDownloadListItem(DirectCast(Button.Tag, JObject), Nothing, False).Init(), Nothing)
- If ForgeVersionLoader IsNot Nothing Then LoadForge.State = ForgeVersionLoader
- '恢复初始的组件
- SelectedOptiFine = TryCast(BtnOptiFineRestore.Tag, DlOptiFineListEntry)
- SelectedForge = TryCast(BtnForgeRestore.Tag, DlForgeVersionEntry)
- SelectedNeoForge = TryCast(BtnNeoForgeRestore.Tag, DlNeoForgeListEntry)
- SelectedFabric = TryCast(BtnFabricRestore.Tag, String)
- SelectedLiteLoader = TryCast(BtnLiteLoaderRestore.Tag, DlLiteLoaderListEntry)
- SelectedFabricApi = TryCast(BtnFabricApiRestore.Tag, ResourceVersion)
- SelectedOptiFabric = TryCast(BtnOptiFabricRestore.Tag, ResourceVersion)
- AutoSelectedFabricApi = SelectedFabric IsNot Nothing
- AutoSelectedOptiFabric = SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing
- Finally
- IsRestoringComponents = False
- End Try
- ReloadComponentLists()
- Return
- ElseIf Button Is BtnOptiFineRestore Then
- SelectedOptiFine = TryCast(Button.Tag, DlOptiFineListEntry)
- AutoSelectedOptiFabric = SelectedOptiFine IsNot Nothing AndAlso SelectedFabric IsNot Nothing
- If SelectedOptiFine Is Nothing Then SelectedOptiFabric = Nothing
- ElseIf Button Is BtnForgeRestore Then
- SelectedForge = TryCast(Button.Tag, DlForgeVersionEntry)
- ElseIf Button Is BtnNeoForgeRestore Then
- SelectedNeoForge = TryCast(Button.Tag, DlNeoForgeListEntry)
- ElseIf Button Is BtnFabricRestore Then
- SelectedFabric = TryCast(Button.Tag, String)
- AutoSelectedFabricApi = SelectedFabric IsNot Nothing
- AutoSelectedOptiFabric = SelectedFabric IsNot Nothing AndAlso SelectedOptiFine IsNot Nothing
- If SelectedFabric Is Nothing Then
- SelectedFabricApi = Nothing
- SelectedOptiFabric = Nothing
- End If
- ElseIf Button Is BtnFabricApiRestore Then
- SelectedFabricApi = TryCast(Button.Tag, ResourceVersion)
- AutoSelectedFabricApi = True
- ElseIf Button Is BtnOptiFabricRestore Then
- SelectedOptiFabric = TryCast(Button.Tag, ResourceVersion)
- AutoSelectedOptiFabric = True
- ElseIf Button Is BtnLiteLoaderRestore Then
- SelectedLiteLoader = TryCast(Button.Tag, DlLiteLoaderListEntry)
- End If
- DirectCast(Button.Parent, MyCard).IsSwapped = True
- '刷新组件
- ReloadComponentLists()
- End Sub
- Private Sub CardMinecraft_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles CardMinecraft.MouseLeftButtonUp
- ShowMinecraftVersionList()
- e.Handled = True
- End Sub
- Private Sub UpdateStartButton() Handles TextSelectName.TextChanged, TextSelectName.ValidateChanged
- BtnStart.IsEnabled = TextSelectName.IsValidated AndAlso InitialTarget IsNot Nothing AndAlso
- Not PendingComponents.Any() AndAlso
- (Not IsVanillaVersionReliable OrElse Not InitialTarget.IsEquivalentTo(GetSelectedComponents()) OrElse
- Not String.Equals(TextSelectName.Text, OriginalName, StringComparison.Ordinal))
- End Sub
- Private Sub UpdateOriginalNameVisibility() Handles TextSelectName.TextChanged
- Dim IsNameChanged = Not String.Equals(TextSelectName.Text, OriginalName, StringComparison.Ordinal)
- Dim NewVisibility = If(IsNameChanged, Visibility.Visible, Visibility.Collapsed)
- If LabSelectName.Visibility = NewVisibility Then Return
- LabSelectName.Visibility = NewVisibility
- BtnOriginalNameRestore.Visibility = NewVisibility
- Dim RightMargin = If(IsNameChanged, 40, 16)
- If IsInSelectPage AndAlso AniControlEnabled = 0 Then
- AniStart(AaDouble(Sub(Delta) TextSelectName.Margin = New Thickness(56, 16, TextSelectName.Margin.Right + Delta, 0),
- RightMargin - TextSelectName.Margin.Right, 150,, New AniEaseOutFluent), "DownloadModify Name Margin")
- Else
- AniStop("DownloadModify Name Margin")
- TextSelectName.Margin = New Thickness(56, 16, RightMargin, 0)
- End If
- End Sub
- Private Sub BtnOriginalNameRestore_Click(sender As Object, e As EventArgs) Handles BtnOriginalNameRestore.Click
- TextSelectName.Text = OriginalName
- IsSelectNameEdited = Not String.Equals(OriginalName, GetSelectName(), StringComparison.Ordinal)
- End Sub
- Public Overrides Sub StartInstall(Request As McInstallRequest)
- UpdateStartButton()
- If Not BtnStart.IsEnabled Then Return
- Dim TargetInstance = InitLoader.Input
- Dim Target = Request.Components
- Dim InstanceName = Request.NewInstanceName
- Dim IsNameChanged = Not String.Equals(InstanceName, TargetInstance.Name, StringComparison.Ordinal)
- Request.NewInstanceName = If(IsNameChanged, InstanceName, Nothing)
- Request.InstanceFolder = TargetInstance.PathVersion
- '警告
- Dim Warnings As New List(Of String)
- If (SelectedForge IsNot Nothing OrElse SelectedNeoForge IsNot Nothing OrElse SelectedFabric IsNot Nothing) AndAlso
- Not PathUtils.IsSame(TargetInstance.PathIndie, TargetInstance.PathVersion) Then
- Warnings.Add("该版本尚未开启版本隔离,可能与别的 MC 版本共用同一个 Mod 和存档文件夹。" & vbCrLf &
- "修改版本后,已有的 Mod、存档等需要手动迁移到新的游戏目录。")
- End If
- Dim IsMinecraftVersionChanged = InitialTarget.MinecraftVersion <> Target.MinecraftVersion
- If Not IsVanillaVersionReliable AndAlso Not IsMinecraftVersionChanged Then
- Warnings.Add($"PCL 未能精准识别该版本,请确认它是不是 Minecraft {InitialTarget.MinecraftVersion},如果不正确,请取消并选择正确的版本!")
- End If
- If Not Configs.HintModifyInstanceWarning.Get() Then
- Warnings.Add("如果该版本安装了 PCL 不兼容的加载器,或经过第三方修改,这些改动将会丢失!")
- End If
- Dim IsModLoaderChanged As Boolean = False
- For Each Loader In InitialTarget.ModLoaderVersions.Keys.Union(Target.ModLoaderVersions.Keys)
- Dim CurrentVersion As String = Nothing, TargetVersion As String = Nothing
- Dim HasCurrent = InitialTarget.ModLoaderVersions.TryGetValue(Loader, CurrentVersion)
- Dim HasTarget = Target.ModLoaderVersions.TryGetValue(Loader, TargetVersion)
- If HasCurrent <> HasTarget OrElse CurrentVersion <> TargetVersion Then
- IsModLoaderChanged = True
- Exit For
- End If
- Next
- If (IsModLoaderChanged OrElse IsMinecraftVersionChanged) AndAlso InitialTarget.ModLoaderVersions.Any Then
- Warnings.Add("现有的 Mod、资源包等在修改后可能会不兼容!")
- End If
- If Warnings.Any() Then
- If MyMsgBox("请注意:" & vbCrLf & "• " & Warnings.Join(vbCrLf & "• "), "修改确认", "开始修改", "取消", IsWarn:=True) <> 1 Then Return
- End If
- If Not Configs.HintModifyInstanceWarning.Get() Then Configs.HintModifyInstanceWarning.Set(True)
- '开始修改
- If IsVanillaVersionReliable AndAlso InitialTarget.IsEquivalentTo(Target) Then
- '仅重命名
- Try
- Dim OldPath = TargetInstance.PathVersion
- Dim RenamedInstance = TargetInstance.Rename(InstanceName)
- If PageInstanceLeft.Instance IsNot Nothing AndAlso PathUtils.IsSame(PageInstanceLeft.Instance.PathVersion, OldPath) Then PageInstanceLeft.Instance = RenamedInstance
- If McInstanceSelected IsNot Nothing AndAlso PathUtils.IsSame(McInstanceSelected.PathVersion, OldPath) Then McInstanceSelected = RenamedInstance
- PageInstanceLeft.ReloadCurrentJava()
- Hint("重命名成功!", HintType.Green)
- LoaderFolderRun(McInstanceListLoader, McFolderSelected, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
- FrmMain.PageBack()
- Catch ex As Exception
- Logger.Error(ex, "重命名版本失败", LogBehavior.Alert)
- End Try
- Else
- '实际修改
- If McModificationStart(Request, TargetInstance) Then FrmMain.PageBack()
- End If
- End Sub
- End Class
|