From 06e4e8558fae214eedf4d12a8988a5c337d434a8 Mon Sep 17 00:00:00 2001 From: Big-Cake-jpg Date: Sun, 2 Nov 2025 14:29:21 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat(update):=20=E6=96=B0=E7=9A=84=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=80=9A=E9=81=93=20`Nightly`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plain Craft Launcher 2/Modules/ModSecret.vb | 115 ++++++++++-------- .../Modules/Updates/EnumUpdateChannel.vb | 1 + .../Modules/Updates/UpdatesGitHubModel.vb | 100 +++++++++++++++ .../Pages/PageSetup/PageSetupSystem.xaml | 3 +- .../Pages/PageSetup/PageSetupSystem.xaml.vb | 45 +++++-- 5 files changed, 204 insertions(+), 60 deletions(-) create mode 100644 Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb diff --git a/Plain Craft Launcher 2/Modules/ModSecret.vb b/Plain Craft Launcher 2/Modules/ModSecret.vb index 6e89ad050..b9f89dea8 100644 --- a/Plain Craft Launcher 2/Modules/ModSecret.vb +++ b/Plain Craft Launcher 2/Modules/ModSecret.vb @@ -683,6 +683,7 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 Public IsCheckingUpdates As Boolean = False Public IsUpdateWaitingRestart As Boolean = False Public RemoteServer As New UpdatesWrapperModel({ + New UpdatesGitHubModel() With {.SourceName = "GitHub Nightly"}, New UpdatesMirrorChyanModel(), New UpdatesRandomModel({ New UpdatesMinioModel("https://s3.pysio.online/pcl2-ce/", "Pysio"), @@ -690,13 +691,20 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 }), New UpdatesMinioModel("https://github.com/PCL-Community/PCL2_CE_Server/raw/main/", "GitHub") }) - Public ReadOnly Property IsUpdBetaChannel - Get - If VersionBaseName.Contains("beta") Then Return True - Return Setup.Get("SystemSystemUpdateBranch") = 1 - End Get - End Property + Public Function GetCurrentUpdateChannel() As UpdateChannel + If VersionBaseName.Contains("nightly") Then Return UpdateChannel.nightly + If VersionBaseName.Contains("beta") Then Return UpdateChannel.beta + Select Case CType(Setup.Get("SystemSystemUpdateBranch"), Integer) + Case 1 + Return UpdateChannel.beta + Case 2 + Return UpdateChannel.nightly + Case Else + Return UpdateChannel.stable + End Select + End Function + Public Sub UpdateCheckByButton() If IsCheckingUpdates Then Hint("正在检查更新中,请稍后再试……") @@ -715,7 +723,7 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 Public Function IsVerisonLatest() As Boolean Try Return RemoteServer.IsLatest( - If(IsUpdBetaChannel, UpdateChannel.beta, UpdateChannel.stable), + GetCurrentUpdateChannel(), If(IsArm64System, UpdateArch.arm64, UpdateArch.x64), SemVer.Parse(VersionBaseName), VersionCode) @@ -725,15 +733,26 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 End Try End Function Public Sub NoticeUserUpdate(Optional Silent As Boolean = False) + Dim channel = GetCurrentUpdateChannel() + If channel = UpdateChannel.nightly Then + If Not IsVerisonLatest() Then + Dim latest = RemoteServer.GetLatestVersion(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) + If MyMsgBoxMarkdown($"启动器有新版本可用({VersionBaseName} -> {latest.VersionName})。由于你选择了 Nightly 更新通道,需要立即更新才能继续使用。{vbCrLf}{vbCrLf}{latest.Changelog}", "启动器更新", "更新", "或者更新", ForceWait:=True) = 1 Or 2 Then + UpdateStart(False) + End If + Else + If Not Silent Then Hint("启动器已是最新版 " + VersionBaseName + ",无须更新啦!", HintType.Finish) + End If + Return + End If + If Not IsVerisonLatest() Then Dim latest As VersionDataModel = Nothing Dim checkUpdateEx As Exception = Nothing RunInNewThread( Sub() Try - latest = RemoteServer.GetLatestVersion( - If(IsUpdBetaChannel, UpdateChannel.beta, UpdateChannel.stable), - If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) + latest = RemoteServer.GetLatestVersion(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) Catch ex As Exception checkUpdateEx = ex End Try @@ -759,41 +778,37 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 Public Sub UpdateStart(Slient As Boolean, Optional ReceivedKey As String = Nothing, Optional ForceValidated As Boolean = False) Dim DlTargetPath As String = ExePath + "PCL\Plain Craft Launcher Community Edition.exe" RunInNewThread(Sub() - Try - Dim version = RemoteServer.GetLatestVersion( - If(IsUpdBetaChannel, UpdateChannel.beta, UpdateChannel.stable), - If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) - WriteFile($"{PathTemp}CEUpdateLog.md", version.Changelog) - '构造步骤加载器 - Dim Loaders As New List(Of LoaderBase) - '下载 - Loaders.AddRange(RemoteServer.GetDownloadLoader( - If(IsUpdBetaChannel, UpdateChannel.beta, UpdateChannel.stable), - If(IsArm64System, UpdateArch.arm64, UpdateArch.x64), DlTargetPath)) - Loaders.Add(New LoaderTask(Of Integer, Integer)("校验更新", Sub() - Dim curHash = GetFileSHA256(DlTargetPath) - If curHash <> version.SHA256 Then - Throw New Exception($"更新文件 SHA256 不正确,应该为 {version.SHA256},实际为 {curHash}") - End If - End Sub)) - If Not Slient Then - Loaders.Add(New LoaderTask(Of Integer, Integer)("安装更新", Sub() UpdateRestart(True))) - End If - '启动 - Dim Loader As New LoaderCombo(Of JObject)("启动器更新", Loaders) - Loader.Start() - If Slient Then - IsUpdateWaitingRestart = True - Else - LoaderTaskbarAdd(Loader) - FrmMain.BtnExtraDownload.ShowRefresh() - FrmMain.BtnExtraDownload.Ribble() - End If - Catch ex As Exception - Log(ex, "[Update] 下载启动器更新文件失败", LogLevel.Hint) - Hint("下载启动器更新文件失败,请检查网络连接", HintType.Critical) - End Try - End Sub) + Try + Dim channel = GetCurrentUpdateChannel() + Dim version = RemoteServer.GetLatestVersion(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) + WriteFile($"{PathTemp}CEUpdateLog.md", version.Changelog) + '构造步骤加载器 + Dim Loaders As New List(Of LoaderBase) + Loaders.AddRange(RemoteServer.GetDownloadLoader(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64), DlTargetPath)) + Loaders.Add(New LoaderTask(Of Integer, Integer)("校验更新", Sub() + Dim curHash = GetFileSHA256(DlTargetPath) + If curHash <> version.SHA256 Then + Throw New Exception($"更新文件 SHA256 不正确,应该为 {version.SHA256},实际为 {curHash}") + End If + End Sub)) + If Not Slient Then + Loaders.Add(New LoaderTask(Of Integer, Integer)("安装更新", Sub() UpdateRestart(True))) + End If + '启动 + Dim Loader As New LoaderCombo(Of JObject)("启动器更新", Loaders) + Loader.Start() + If Slient Then + IsUpdateWaitingRestart = True + Else + LoaderTaskbarAdd(Loader) + FrmMain.BtnExtraDownload.ShowRefresh() + FrmMain.BtnExtraDownload.Ribble() + End If + Catch ex As Exception + Log(ex, "[Update] 下载启动器更新文件失败", LogLevel.Hint) + Hint("下载启动器更新文件失败,请检查网络连接", HintType.Critical) + End Try + End Sub) End Sub Public Sub UpdateRestart(TriggerRestartAndByEnd As Boolean) Try @@ -906,12 +921,14 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 Dim UpdateDesire = Setup.Get("SystemSystemUpdate") Dim AnnouncementDesire = Setup.Get("SystemSystemActivity") Select Case UpdateDesire - Case 0 - If Not IsVerisonLatest() Then + Case 0, 1 + If GetCurrentUpdateChannel() = UpdateChannel.nightly Then + NoticeUserUpdate(True) ' Nightly 通道强制检查更新 + ElseIf UpdateDesire = 0 AndAlso Not IsVerisonLatest() Then UpdateStart(True) '静默更新 + ElseIf UpdateDesire = 1 Then + NoticeUserUpdate(True) End If - Case 1 - NoticeUserUpdate(True) Case 2, 3 Exit Sub End Select diff --git a/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb b/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb index 244a61a86..49cd0e264 100644 --- a/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb +++ b/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb @@ -1,6 +1,7 @@ Public Enum UpdateChannel stable beta + nightly End Enum Public Enum UpdateArch diff --git a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb new file mode 100644 index 000000000..9d5eb7a98 --- /dev/null +++ b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb @@ -0,0 +1,100 @@ +Imports System.IO.Compression +Imports Newtonsoft.Json +Imports PCL.Core.Utils + +Public Class UpdatesGitHubModel + Implements IUpdateSource + + Private Const NightlyJsonUrl As String = "https://github.com/PCL-Community/PCL2-CE/releases/download/nightly/nightly.json" + ' Private Const NightlyJsonUrl As String = "https://r2.230225.xyz/nightly.json" + Private _nightlyInfo As NightlyJsonModel + + Public Property SourceName As String Implements IUpdateSource.SourceName + + Public Function IsAvailable() As Boolean Implements IUpdateSource.IsAvailable + Return True ' Assume network is available + End Function + + Public Function RefreshCache() As Boolean Implements IUpdateSource.RefreshCache + Try + Dim jsonContent = NetGetCodeByRequestRetry(NightlyJsonUrl) + _nightlyInfo = JsonConvert.DeserializeObject(Of NightlyJsonModel)(jsonContent) + Return _nightlyInfo IsNot Nothing + Catch ex As Exception + Log(ex, "[Update] Failed to fetch nightly.json from GitHub") + Return False + End Try + End Function + + Public Function GetLatestVersion(channel As UpdateChannel, arch As UpdateArch) As VersionDataModel Implements IUpdateSource.GetLatestVersion + If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") + If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New Exception("Failed to get nightly update info.") + + Dim asset = GetAssetForArch(arch) + + Return New VersionDataModel With { + .VersionName = _nightlyInfo.version, + .VersionCode = _nightlyInfo.version_code, + .SHA256 = asset.sha256, + .Source = SourceName, + .Changelog = _nightlyInfo.changelog + } + End Function + + Public Function IsLatest(channel As UpdateChannel, arch As UpdateArch, currentVersion As SemVer, currentVersionCode As Integer) As Boolean Implements IUpdateSource.IsLatest + If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") + If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Return True ' If we can't get info, assume we're latest to avoid errors + + Return currentVersionCode >= _nightlyInfo.version_code + End Function + + Public Function GetAnnouncementList() As VersionAnnouncementDataModel Implements IUpdateSource.GetAnnouncementList + Throw New Exception("GitHub Nightly 无公告系统") + End Function + + Public Function GetDownloadLoader(channel As UpdateChannel, arch As UpdateArch, output As String) As List(Of LoaderBase) Implements IUpdateSource.GetDownloadLoader + If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") + If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New Exception("Failed to get nightly update info for download.") + + Dim asset = GetAssetForArch(arch) + Dim downloadUrl = asset.download_url + Dim tempPath = IO.Path.Combine(PathTemp, "Cache", "Update", "Download", $"{asset.sha256}.zip") + + Dim loaders As New List(Of LoaderBase) + ' 1. 下载更新包 + loaders.Add(New LoaderDownload("下载更新", New List(Of NetFile) From {New NetFile({downloadUrl}, tempPath)})) + + ' 2. 解压更新包,将 .exe 文件提取到 ModSecret 指定的 output 路径 + loaders.Add(New LoaderTask(Of String, Integer)("提取文件", Sub() + Using fs As New IO.FileStream(tempPath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) + Using zip As New ZipArchive(fs) + Dim entry = zip.Entries.FirstOrDefault(Function(x) x.Name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) + If entry Is Nothing Then Throw New Exception("在下载的更新包中找不到可执行文件。") + entry.ExtractToFile(output, True) + End Using + End Using + End Sub)) + Return loaders + End Function + + Private Function GetAssetForArch(arch As UpdateArch) As NightlyAsset + Dim archName = If(arch = UpdateArch.arm64, "arm64", "x64") + Dim asset = _nightlyInfo.assets.FirstOrDefault(Function(a) a.arch.Equals(archName, StringComparison.OrdinalIgnoreCase)) + If asset Is Nothing Then Throw New Exception($"Nightly build for architecture {archName} not found.") + Return asset + End Function + +End Class + +Public Class NightlyJsonModel + Public Property version As String + Public Property version_code As Integer + Public Property changelog As String + Public Property assets As List(Of NightlyAsset) +End Class + +Public Class NightlyAsset + Public Property arch As String + Public Property download_url As String + Public Property sha256 As String +End Class diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml index 6ba773f7a..58cb70ddc 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml @@ -144,9 +144,10 @@ + ToolTip="PCL 社区版提供了三种更新通道: Slow Ring:较为稳定,功能通常已经过测试。 Fast Ring:更新较快,但可能包含未经充分测试的功能,可能不稳定。 Nightly:每日构建,包含 dev 分支的最新更改,仅供测试使用,极不稳定。 Fast Ring 和 Nightly 仅推荐具有一定基础知识和能力的用户使用,且不适合用于制作整合包。 在升级到 Fast Ring 或 Nightly 版本后,只能手动重新下载启动器来切换回 Slow Ring。 如果你不知道你在干什么,请选择 Slow Ring。"> + diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index a7b07dcac..ad71dc11f 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -49,7 +49,7 @@ Class PageSetupSystem ComboSystemUpdate.SelectedIndex = Setup.Get("SystemSystemUpdate") Dim branch As Integer = Setup.Get("SystemSystemUpdateBranch") ComboSystemUpdateBranch.SelectedIndex = branch - If branch = 1 Then + If branch = 1 OrElse branch = 2 OrElse VersionBaseName.Contains("nightly") Then ComboSystemUpdateBranch.IsEnabled = False Else ComboSystemUpdateBranch.IsEnabled = True @@ -221,15 +221,40 @@ Class PageSetupSystem End Sub Private Sub ComboSystemUpdateBranch_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemUpdateBranch.SelectionChanged If AniControlEnabled <> 0 Then Exit Sub - If ComboSystemUpdateBranch.SelectedIndex <> 1 Then Exit Sub - If MyMsgBox("你正在切换启动器更新通道到 Fast Ring。" & vbCrLf & - "Fast Ring 可以提供下个版本更新内容的预览,但可能会包含未经充分测试的功能,稳定性欠佳。" & vbCrLf & vbCrLf & - "在升级到 Fast Ring 版本后,只能手动重新下载启动器来切换回 Slow Ring。" & vbCrLf & - "该选项仅推荐具有一定基础知识和能力的用户选择。如果你正在制作整合包,请使用 Slow Ring!", "继续之前...", "我已知晓", "取消", IsWarn:=True) = 2 Then - ComboSystemUpdateBranch.SelectedItem = e.RemovedItems(0) - Else - UpdateCheckByButton() - End If + Select Case ComboSystemUpdateBranch.SelectedIndex + Case 1 + If MyMsgBox("你正在切换启动器更新通道到 Fast Ring。" & vbCrLf & + "Fast Ring 可以提供下个版本更新内容的预览,但可能会包含未经充分测试的功能,稳定性欠佳。" & vbCrLf & vbCrLf & + "在升级到 Fast Ring 版本后,只能手动重新下载启动器来切换回 Slow Ring。" & vbCrLf & + "该选项仅推荐具有一定基础知识和能力的用户选择。如果你正在制作整合包,请使用 Slow Ring!", "继续之前...", "我已知晓", "取消", IsWarn:=True) = 2 Then + ComboSystemUpdateBranch.SelectedItem = e.RemovedItems(0) + Else + UpdateCheckByButton() + End If + Case 2 + If MyMsgBox("你正在切换启动器更新通道到 Nightly。" & vbCrLf & + "该通道可第一时间获取基于最新代码构建的开发版本,但可能极不稳定,甚至直接无法启动。" & vbCrLf & vbCrLf & + "在升级到 Nightly 版本后,只能手动重新下载启动器来切换回 Slow Ring。" & vbCrLf & + "该选项仅推荐高级用户选择。如果你正在制作整合包,请使用 Slow Ring!", "继续之前...", "我已知晓", "取消", IsWarn:=True) = 2 Then + ComboSystemUpdateBranch.SelectedItem = e.RemovedItems(0) + Return + End If + Dim ret = MyMsgBoxInput("最终确认", "你确定要切换到 Nightly 通道吗?" & vbCrLf & + "Nightly 版本可能存在严重问题,甚至无法启动!" & vbCrLf & + "在升级到 Nightly 版本后,将无法切换回其他任何更新通道,只能手动重新下载启动器来切换回 Slow Ring 或 Fast Ring。" & vbCrLf & vbCrLf & + "该选项仅推荐高级用户选择。如果你正在制作整合包,请使用 Slow Ring!" & vbCrLf & + "请输入 '我确认切换到此分支并已知晓风险' 以确认切换到 Nightly 通道。", Button1 := "提交", Button2 := "取消", IsWarn:=True) + If ret Is Nothing Then + ComboSystemUpdateBranch.SelectedItem = e.RemovedItems(0) + Return + End If + If ret = "我确认切换到此分支并已知晓风险" Then + UpdateCheckByButton() + Else + Hint("你输入了错误的内容...") + ComboSystemUpdateBranch.SelectedItem = e.RemovedItems(0) + End If + End Select End Sub Private Sub BtnSystemUpdate_Click(sender As Object, e As EventArgs) Handles BtnSystemUpdate.Click UpdateCheckByButton() From 64d9adc752953150cd1bece803b6404cb6fba805 Mon Sep 17 00:00:00 2001 From: Big-Cake-jpg Date: Tue, 4 Nov 2025 00:23:21 +0800 Subject: [PATCH 2/7] =?UTF-8?q?ref(update):=20=E7=A7=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E9=80=BB=E8=BE=91=EF=BC=8C=E6=8D=A2=E7=94=A8=E8=AF=AD?= =?UTF-8?q?=E4=B9=89=E6=98=8E=E7=A1=AE=E7=9A=84=20Exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plain Craft Launcher 2/Modules/ModSecret.vb | 16 ++-------------- .../Modules/Updates/UpdatesGitHubModel.vb | 8 ++++---- .../Pages/PageSetup/PageSetupSystem.xaml.vb | 2 +- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/Plain Craft Launcher 2/Modules/ModSecret.vb b/Plain Craft Launcher 2/Modules/ModSecret.vb index effa5785f..949af9f46 100644 --- a/Plain Craft Launcher 2/Modules/ModSecret.vb +++ b/Plain Craft Launcher 2/Modules/ModSecret.vb @@ -2,6 +2,7 @@ Imports System.ComponentModel Imports System.Management Imports System.Net.Http Imports System.Runtime.InteropServices +Imports System.Security Imports System.Security.Cryptography Imports PCL.Core.IO Imports PCL.Core.UI @@ -692,8 +693,6 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 }) Public Function GetCurrentUpdateChannel() As UpdateChannel - If VersionBaseName.Contains("nightly") Then Return UpdateChannel.nightly - If VersionBaseName.Contains("beta") Then Return UpdateChannel.beta Select Case CType(Setup.Get("SystemSystemUpdateBranch"), Integer) Case 1 Return UpdateChannel.beta @@ -733,17 +732,6 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 End Function Public Sub NoticeUserUpdate(Optional Silent As Boolean = False) Dim channel = GetCurrentUpdateChannel() - If channel = UpdateChannel.nightly Then - If Not IsVerisonLatest() Then - Dim latest = RemoteServer.GetLatestVersion(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) - If MyMsgBoxMarkdown($"启动器有新版本可用({VersionBaseName} -> {latest.VersionName})。由于你选择了 Nightly 更新通道,需要立即更新才能继续使用。{vbCrLf}{vbCrLf}{latest.Changelog}", "启动器更新", "更新", "或者更新", ForceWait:=True) = 1 Or 2 Then - UpdateStart(False) - End If - Else - If Not Silent Then Hint("启动器已是最新版 " + VersionBaseName + ",无须更新啦!", HintType.Finish) - End If - Return - End If If Not IsVerisonLatest() Then Dim latest As VersionDataModel = Nothing @@ -787,7 +775,7 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 Loaders.Add(New LoaderTask(Of Integer, Integer)("校验更新", Sub() Dim curHash = GetFileSHA256(DlTargetPath) If curHash <> version.SHA256 Then - Throw New Exception($"更新文件 SHA256 不正确,应该为 {version.SHA256},实际为 {curHash}") + Throw New SecurityException($"更新文件 SHA256 不正确,应该为 {version.SHA256},实际为 {curHash}") End If End Sub)) If Not Slient Then diff --git a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb index 9d5eb7a98..2f4265e7f 100644 --- a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb +++ b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb @@ -28,7 +28,7 @@ Public Class UpdatesGitHubModel Public Function GetLatestVersion(channel As UpdateChannel, arch As UpdateArch) As VersionDataModel Implements IUpdateSource.GetLatestVersion If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") - If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New Exception("Failed to get nightly update info.") + If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New InvalidOperationException("Failed to get nightly update info.") Dim asset = GetAssetForArch(arch) @@ -54,7 +54,7 @@ Public Class UpdatesGitHubModel Public Function GetDownloadLoader(channel As UpdateChannel, arch As UpdateArch, output As String) As List(Of LoaderBase) Implements IUpdateSource.GetDownloadLoader If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") - If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New Exception("Failed to get nightly update info for download.") + If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New InvalidOperationException("Failed to get nightly update info for download.") Dim asset = GetAssetForArch(arch) Dim downloadUrl = asset.download_url @@ -69,7 +69,7 @@ Public Class UpdatesGitHubModel Using fs As New IO.FileStream(tempPath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) Using zip As New ZipArchive(fs) Dim entry = zip.Entries.FirstOrDefault(Function(x) x.Name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) - If entry Is Nothing Then Throw New Exception("在下载的更新包中找不到可执行文件。") + If entry Is Nothing Then Throw New InvalidOperationException("在下载的更新包中找不到可执行文件。") entry.ExtractToFile(output, True) End Using End Using @@ -80,7 +80,7 @@ Public Class UpdatesGitHubModel Private Function GetAssetForArch(arch As UpdateArch) As NightlyAsset Dim archName = If(arch = UpdateArch.arm64, "arm64", "x64") Dim asset = _nightlyInfo.assets.FirstOrDefault(Function(a) a.arch.Equals(archName, StringComparison.OrdinalIgnoreCase)) - If asset Is Nothing Then Throw New Exception($"Nightly build for architecture {archName} not found.") + If asset Is Nothing Then Throw New InvalidOperationException($"Nightly build for architecture {archName} not found.") Return asset End Function diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index ad71dc11f..ad62931e5 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -49,7 +49,7 @@ Class PageSetupSystem ComboSystemUpdate.SelectedIndex = Setup.Get("SystemSystemUpdate") Dim branch As Integer = Setup.Get("SystemSystemUpdateBranch") ComboSystemUpdateBranch.SelectedIndex = branch - If branch = 1 OrElse branch = 2 OrElse VersionBaseName.Contains("nightly") Then + If branch = 1 OrElse branch = 2 Then ComboSystemUpdateBranch.IsEnabled = False Else ComboSystemUpdateBranch.IsEnabled = True From 9556bcef956da04818c59a710d4b509be341d6ed Mon Sep 17 00:00:00 2001 From: Big-Cake-jpg Date: Tue, 4 Nov 2025 00:26:21 +0800 Subject: [PATCH 3/7] =?UTF-8?q?fix(update):=20=E6=AC=B8=E6=88=91=E8=8D=89?= =?UTF-8?q?=E7=9C=BC=E7=9E=8E=E5=BF=98=E4=BF=AE=E4=B8=80=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb index 2f4265e7f..85dc3c9e5 100644 --- a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb +++ b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb @@ -49,7 +49,7 @@ Public Class UpdatesGitHubModel End Function Public Function GetAnnouncementList() As VersionAnnouncementDataModel Implements IUpdateSource.GetAnnouncementList - Throw New Exception("GitHub Nightly 无公告系统") + Throw New InvalidOperationException("GitHub Nightly 无公告系统") End Function Public Function GetDownloadLoader(channel As UpdateChannel, arch As UpdateArch, output As String) As List(Of LoaderBase) Implements IUpdateSource.GetDownloadLoader From bf18aa5a07d187308614e33cbf87ff343b8d1088 Mon Sep 17 00:00:00 2001 From: Big-Cake-jpg Date: Wed, 5 Nov 2025 23:31:31 +0800 Subject: [PATCH 4/7] =?UTF-8?q?ref(update):=20=E4=BC=98=E5=8C=96=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=80=9A=E9=81=93=E4=B8=8B=E6=8B=89=E6=A1=86=E7=9A=84?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pages/PageSetup/PageSetupSystem.xaml.vb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index ad62931e5..285b05f50 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -49,11 +49,7 @@ Class PageSetupSystem ComboSystemUpdate.SelectedIndex = Setup.Get("SystemSystemUpdate") Dim branch As Integer = Setup.Get("SystemSystemUpdateBranch") ComboSystemUpdateBranch.SelectedIndex = branch - If branch = 1 OrElse branch = 2 Then - ComboSystemUpdateBranch.IsEnabled = False - Else - ComboSystemUpdateBranch.IsEnabled = True - End If + ComboSystemUpdateBranch.IsEnabled = (branch = 0) ComboSystemActivity.SelectedIndex = Setup.Get("SystemSystemActivity") TextSystemCache.Text = Setup.Get("SystemSystemCache") CheckSystemDisableHardwareAcceleration.Checked = Setup.Get("SystemDisableHardwareAcceleration") From 53bd78db58903dfdd1c68ad689acf1890467c1dd Mon Sep 17 00:00:00 2001 From: Big-Cake-jpg Date: Wed, 5 Nov 2025 23:45:05 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix(update):=20=E4=BC=9A=E9=94=99=E6=84=8F?= =?UTF-8?q?=E4=BA=86=20=E6=8A=8A=E6=9B=B4=E6=96=B0=E7=9A=84=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E8=A1=A5=E5=9B=9E=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plain Craft Launcher 2/Modules/ModSecret.vb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Plain Craft Launcher 2/Modules/ModSecret.vb b/Plain Craft Launcher 2/Modules/ModSecret.vb index 949af9f46..8efd99410 100644 --- a/Plain Craft Launcher 2/Modules/ModSecret.vb +++ b/Plain Craft Launcher 2/Modules/ModSecret.vb @@ -732,7 +732,17 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 End Function Public Sub NoticeUserUpdate(Optional Silent As Boolean = False) Dim channel = GetCurrentUpdateChannel() - + If channel = UpdateChannel.nightly Then + If Not IsVerisonLatest() Then + Dim latest = RemoteServer.GetLatestVersion(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) + If MyMsgBoxMarkdown($"启动器有新版本可用({VersionBaseName} -> {latest.VersionName})。由于你选择了 Nightly 更新通道,需要立即更新才能继续使用。{vbCrLf}{vbCrLf}{latest.Changelog}", "启动器更新", "更新", "或者更新", ForceWait:=True) + UpdateStart(False) + End If + Else + If Not Silent Then Hint("启动器已是最新版 " + VersionBaseName + ",无须更新啦!", HintType.Finish) + End If + Return + End If If Not IsVerisonLatest() Then Dim latest As VersionDataModel = Nothing Dim checkUpdateEx As Exception = Nothing From 151f1db04d17bec505049b91e9fe8abc022ff42f Mon Sep 17 00:00:00 2001 From: Big_Cake Date: Fri, 7 Nov 2025 22:41:03 +0800 Subject: [PATCH 6/7] =?UTF-8?q?ref(update):=20=E6=89=94=E6=8E=89=20if=20?= =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 若琳酱 --- Plain Craft Launcher 2/Modules/ModSecret.vb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Plain Craft Launcher 2/Modules/ModSecret.vb b/Plain Craft Launcher 2/Modules/ModSecret.vb index 8efd99410..7fbd01282 100644 --- a/Plain Craft Launcher 2/Modules/ModSecret.vb +++ b/Plain Craft Launcher 2/Modules/ModSecret.vb @@ -735,9 +735,8 @@ PCL-Community 及其成员与龙腾猫跃无从属关系,且均不会为您的 If channel = UpdateChannel.nightly Then If Not IsVerisonLatest() Then Dim latest = RemoteServer.GetLatestVersion(channel, If(IsArm64System, UpdateArch.arm64, UpdateArch.x64)) - If MyMsgBoxMarkdown($"启动器有新版本可用({VersionBaseName} -> {latest.VersionName})。由于你选择了 Nightly 更新通道,需要立即更新才能继续使用。{vbCrLf}{vbCrLf}{latest.Changelog}", "启动器更新", "更新", "或者更新", ForceWait:=True) - UpdateStart(False) - End If + MyMsgBoxMarkdown($"启动器有新版本可用({VersionBaseName} -> {latest.VersionName})。由于你选择了 Nightly 更新通道,需要立即更新才能继续使用。{vbCrLf}{vbCrLf}{latest.Changelog}", "启动器更新", "更新", "或者更新", ForceWait:=True) + UpdateStart(False) Else If Not Silent Then Hint("启动器已是最新版 " + VersionBaseName + ",无须更新啦!", HintType.Finish) End If From ef99eeeac02517796f2fbbafad53ae478741afc4 Mon Sep 17 00:00:00 2001 From: Big-Cake-jpg Date: Sun, 1 Feb 2026 12:18:43 +0800 Subject: [PATCH 7/7] =?UTF-8?q?ref(update):=20=E9=87=8D=E6=9E=84=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E7=89=88=E7=9A=84=E7=8E=B0=E6=9C=89=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E9=80=82=E9=85=8D=E6=96=B0=E4=BB=93=E5=BA=93=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modules/Updates/EnumUpdateChannel.vb | 2 +- .../Modules/Updates/UpdatesGitHubModel.vb | 100 ------------------ .../Modules/Updates/UpdatesMinioModel.vb | 2 + .../Pages/PageSetup/PageSetupUpdate.xaml | 10 +- 4 files changed, 12 insertions(+), 102 deletions(-) delete mode 100644 Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb diff --git a/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb b/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb index 49cd0e264..868a9e516 100644 --- a/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb +++ b/Plain Craft Launcher 2/Modules/Updates/EnumUpdateChannel.vb @@ -1,7 +1,7 @@ Public Enum UpdateChannel stable beta - nightly + dev End Enum Public Enum UpdateArch diff --git a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb b/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb deleted file mode 100644 index 85dc3c9e5..000000000 --- a/Plain Craft Launcher 2/Modules/Updates/UpdatesGitHubModel.vb +++ /dev/null @@ -1,100 +0,0 @@ -Imports System.IO.Compression -Imports Newtonsoft.Json -Imports PCL.Core.Utils - -Public Class UpdatesGitHubModel - Implements IUpdateSource - - Private Const NightlyJsonUrl As String = "https://github.com/PCL-Community/PCL2-CE/releases/download/nightly/nightly.json" - ' Private Const NightlyJsonUrl As String = "https://r2.230225.xyz/nightly.json" - Private _nightlyInfo As NightlyJsonModel - - Public Property SourceName As String Implements IUpdateSource.SourceName - - Public Function IsAvailable() As Boolean Implements IUpdateSource.IsAvailable - Return True ' Assume network is available - End Function - - Public Function RefreshCache() As Boolean Implements IUpdateSource.RefreshCache - Try - Dim jsonContent = NetGetCodeByRequestRetry(NightlyJsonUrl) - _nightlyInfo = JsonConvert.DeserializeObject(Of NightlyJsonModel)(jsonContent) - Return _nightlyInfo IsNot Nothing - Catch ex As Exception - Log(ex, "[Update] Failed to fetch nightly.json from GitHub") - Return False - End Try - End Function - - Public Function GetLatestVersion(channel As UpdateChannel, arch As UpdateArch) As VersionDataModel Implements IUpdateSource.GetLatestVersion - If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") - If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New InvalidOperationException("Failed to get nightly update info.") - - Dim asset = GetAssetForArch(arch) - - Return New VersionDataModel With { - .VersionName = _nightlyInfo.version, - .VersionCode = _nightlyInfo.version_code, - .SHA256 = asset.sha256, - .Source = SourceName, - .Changelog = _nightlyInfo.changelog - } - End Function - - Public Function IsLatest(channel As UpdateChannel, arch As UpdateArch, currentVersion As SemVer, currentVersionCode As Integer) As Boolean Implements IUpdateSource.IsLatest - If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") - If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Return True ' If we can't get info, assume we're latest to avoid errors - - Return currentVersionCode >= _nightlyInfo.version_code - End Function - - Public Function GetAnnouncementList() As VersionAnnouncementDataModel Implements IUpdateSource.GetAnnouncementList - Throw New InvalidOperationException("GitHub Nightly 无公告系统") - End Function - - Public Function GetDownloadLoader(channel As UpdateChannel, arch As UpdateArch, output As String) As List(Of LoaderBase) Implements IUpdateSource.GetDownloadLoader - If channel <> UpdateChannel.nightly Then Throw New NotSupportedException("UpdatesGitHubModel only supports the Nightly channel.") - If _nightlyInfo Is Nothing AndAlso Not RefreshCache() Then Throw New InvalidOperationException("Failed to get nightly update info for download.") - - Dim asset = GetAssetForArch(arch) - Dim downloadUrl = asset.download_url - Dim tempPath = IO.Path.Combine(PathTemp, "Cache", "Update", "Download", $"{asset.sha256}.zip") - - Dim loaders As New List(Of LoaderBase) - ' 1. 下载更新包 - loaders.Add(New LoaderDownload("下载更新", New List(Of NetFile) From {New NetFile({downloadUrl}, tempPath)})) - - ' 2. 解压更新包,将 .exe 文件提取到 ModSecret 指定的 output 路径 - loaders.Add(New LoaderTask(Of String, Integer)("提取文件", Sub() - Using fs As New IO.FileStream(tempPath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) - Using zip As New ZipArchive(fs) - Dim entry = zip.Entries.FirstOrDefault(Function(x) x.Name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) - If entry Is Nothing Then Throw New InvalidOperationException("在下载的更新包中找不到可执行文件。") - entry.ExtractToFile(output, True) - End Using - End Using - End Sub)) - Return loaders - End Function - - Private Function GetAssetForArch(arch As UpdateArch) As NightlyAsset - Dim archName = If(arch = UpdateArch.arm64, "arm64", "x64") - Dim asset = _nightlyInfo.assets.FirstOrDefault(Function(a) a.arch.Equals(archName, StringComparison.OrdinalIgnoreCase)) - If asset Is Nothing Then Throw New InvalidOperationException($"Nightly build for architecture {archName} not found.") - Return asset - End Function - -End Class - -Public Class NightlyJsonModel - Public Property version As String - Public Property version_code As Integer - Public Property changelog As String - Public Property assets As List(Of NightlyAsset) -End Class - -Public Class NightlyAsset - Public Property arch As String - Public Property download_url As String - Public Property sha256 As String -End Class diff --git a/Plain Craft Launcher 2/Modules/Updates/UpdatesMinioModel.vb b/Plain Craft Launcher 2/Modules/Updates/UpdatesMinioModel.vb index f526a5ebb..638c743a9 100644 --- a/Plain Craft Launcher 2/Modules/Updates/UpdatesMinioModel.vb +++ b/Plain Craft Launcher 2/Modules/Updates/UpdatesMinioModel.vb @@ -91,6 +91,8 @@ Public Class UpdatesMinioModel '社区自己的更新系统格式 ChannelName += "sr" Case UpdateChannel.beta ChannelName += "fr" + Case UpdateChannel.dev + ChannelName += "dev" Case Else ChannelName += "sr" End Select diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUpdate.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUpdate.xaml index 0ef5d2344..a77feab8c 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUpdate.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUpdate.xaml @@ -23,12 +23,16 @@ + - + @@ -40,6 +44,10 @@ +