using System.Windows; using System.Windows.Controls; using System.Windows.Input; using PCL.Core.App; using PCL.Core.Utils; using PCL.Core.App.Localization; using PCL.Core.Utils.OS; namespace PCL; public partial class PageSetupUpdate { public VersionDataModel updateInfo; public PageSetupUpdate() { InitializeComponent(); Loaded += (_, _) => Init(); } private void Init() { ModAnimation.AniControlEnabled += 1; TextMirrorCDK.Password = Config.Update.MirrorChyanKey; ComboSystemUpdateChannel.SelectedIndex = (int)Config.Update.UpdateChannel; ComboSystemUpdateMode.SelectedIndex = (int)Config.Update.UpdateMode; TextCurrentVersion.Text = "PCL CE " + VersionNameFormat(ModBase.versionBaseName); ModAnimation.AniControlEnabled -= 1; CheckUpdate(); } private async Task IsLatestAsync() { try { // 修复:使用 dynamic 绕过命名空间重名导致的编译期类型冲突, // 或者你可以尝试替换为 PCL.Core.App.SemVer.Parse(ModBase.versionBaseName) if (await UpdateManager.remoteServer.IsLatestAsync( UpdateManager.IsCurrentVersionBeta ? UpdateChannel.beta : UpdateChannel.stable, SystemInfo.IsArm64System ? UpdateArch.arm64 : UpdateArch.x64, SemVer.Parse(ModBase.versionBaseName), ModBase.versionCode)) { ModBase.Log("[Update] 已是最新版本"); return UpdateStatus.Latest; } ModBase.Log("[Update] 有可用的新版本"); return UpdateStatus.Available; } catch (Exception ex) { ModBase.Log( ex, Lang.Text("Setup.Update.Error.NetworkFailed"), ModBase.LogLevel.Hint, userSummary: Lang.Text("Setup.Update.Error.NetworkFailed")); return UpdateStatus.Error; } } public async void CheckUpdate() { ModBase.Log("[Update] 开始检查更新"); CardUpdate.Visibility = Visibility.Collapsed; CardCheck.Visibility = Visibility.Visible; TextCurrentDesc.Text = Lang.Text("Setup.Update.Checking"); BtnCheckAgain.IsEnabled = false; switch (await IsLatestAsync()) { case UpdateStatus.Available: { Exception checkUpdateEx = null; try { updateInfo = UpdateManager.remoteServer.GetLatestVersion( UpdateManager.IsCurrentVersionBeta ? UpdateChannel.beta : UpdateChannel.stable, SystemInfo.IsArm64System ? UpdateArch.arm64 : UpdateArch.x64); TextUpdateName.Text = "PCL CE " + VersionNameFormat(updateInfo.VersionName); var summary = updateInfo.Changelog.Between("", ""); if (!updateInfo.Changelog.Contains("") || string.IsNullOrWhiteSpace(summary.Trim())) TextChangelog.Text = Lang.Text("Setup.Update.Changelog.Empty"); else TextChangelog.Text = summary; } catch (Exception ex) { checkUpdateEx = ex; } BtnCheckAgain.IsEnabled = true; if (updateInfo is null) { TextCurrentDesc.Text = Lang.Text("Setup.Update.CheckFailed"); if (checkUpdateEx is not null) ModBase.Log( checkUpdateEx, "[Update] 检查更新失败", ModBase.LogLevel.Msgbox, userSummary: Lang.Text("Update.Check.Failed")); else ModBase.Log( "[Update] 检查更新失败", ModBase.LogLevel.Msgbox, userSummary: Lang.Text("Update.Check.Failed")); return; } if (UpdateManager.updateLoader is not null && UpdateManager.updateLoader.State == ModBase.LoadState.Loading) { BtnUpdate_Timer(); BtnUpdate.IsEnabled = false; } else if (UpdateManager.isUpdateWaitingRestart) { BtnUpdate.Text = Lang.Text("Setup.Update.RestartInstall"); BtnUpdate.IsEnabled = true; } else { BtnUpdate.Text = Lang.Text("Setup.Update.Install"); BtnUpdate.IsEnabled = true; } CardUpdate.Visibility = Visibility.Visible; CardCheck.Visibility = Visibility.Collapsed; break; } case UpdateStatus.Latest: { CardUpdate.Visibility = Visibility.Collapsed; CardCheck.Visibility = Visibility.Visible; BtnCheckAgain.IsEnabled = true; TextCurrentDesc.Text = Lang.Text("Setup.Update.Latest"); break; } case UpdateStatus.Error: { CardUpdate.Visibility = Visibility.Collapsed; CardCheck.Visibility = Visibility.Visible; BtnCheckAgain.IsEnabled = true; TextCurrentDesc.Text = Lang.Text("Setup.Update.CheckFailed"); break; } } } public void BtnUpdate_Timer() { while (UpdateManager.updateLoader is not null && UpdateManager.updateLoader.State == ModBase.LoadState.Loading) { ModBase.RunInUi(() => BtnUpdate.Text = Lang.Number(UpdateManager.updateLoader.Progress, "P2")); Thread.Sleep(200); } } private void BtnUpdate_Click(object sender, MouseButtonEventArgs e) { if (UpdateManager.isUpdateWaitingRestart) UpdateManager.UpdateRestart(true); // 开始更新流程 UpdateManager.UpdateStart(UpdateEnums.UpdateType.UpdateNow); } private void BtnChangelogDetail_Click(object sender, EventArgs e) { if (updateInfo is null) ModMain.MyMsgBox(Lang.Text("Setup.Update.Changelog.Unavailable"), Lang.Text("Setup.Update.Changelog.Title")); else ModMain.MyMsgBoxMarkdown(updateInfo.Changelog, Lang.Text("Setup.Update.Changelog.Title")); } private void ComboSystemUpdateMode_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ModAnimation.AniControlEnabled == 0) Config.Update.UpdateMode = (LauncherAutoUpdateBehavior)ComboSystemUpdateMode.SelectedIndex; } private void ComboSystemUpdateBranch_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ModAnimation.AniControlEnabled != 0) return; var isCancelled = false; switch (ComboSystemUpdateChannel.SelectedIndex) { case 0: { break; } case 1: { if (ModMain.MyMsgBox(Lang.Text("Setup.Update.Channel.Beta.Warning.Message"), Lang.Text("Setup.Update.Channel.Common.Warning.Title"), Lang.Text("Setup.Update.Channel.Common.Warning.Confirm"), Lang.Text("Common.Action.Cancel"), isWarn: true) == 2) isCancelled = true; else CheckUpdate(); break; } case 2: { if (ModMain.MyMsgBox(Lang.Text("Setup.Update.Channel.Dev.Warning.Message"), Lang.Text("Setup.Update.Channel.Common.Warning.Title"), Lang.Text("Setup.Update.Channel.Common.Warning.Confirm"), Lang.Text("Common.Action.Cancel"), isWarn: true) == 2) { isCancelled = true; break; } var confirmText = Lang.Text("Setup.Update.Channel.Dev.FinalConfirm.ExpectedInput"); var ret = ModMain.MyMsgBoxInput( Lang.Text("Setup.Update.Channel.Dev.FinalConfirm.Title"), Lang.Text("Setup.Update.Channel.Dev.FinalConfirm.Message", confirmText), button1: Lang.Text("Setup.Update.Channel.Dev.FinalConfirm.Submit"), button2: Lang.Text("Common.Action.Cancel"), isWarn: true); if (ret == confirmText) { CheckUpdate(); } else { HintService.Hint(Lang.Text("Setup.Update.Channel.Dev.FinalConfirm.WrongInput")); isCancelled = true; } break; } } if (isCancelled) { ModAnimation.AniControlEnabled += 1; ComboSystemUpdateChannel.SelectedItem = e.RemovedItems[0]; ModAnimation.AniControlEnabled -= 1; } else { Config.Update.UpdateChannel = (Core.App.UpdateChannel)ComboSystemUpdateChannel.SelectedIndex; } } private void TextMirrorCDK_PasswordChanged(object sender, EventArgs e) { Config.Update.MirrorChyanKey = TextMirrorCDK.Password; } private void BtnGetMirrorCDK_Click(object sender, MouseButtonEventArgs e) { ModBase.OpenWebsite("https://mirrorchyan.com/"); } private void BtnChangelog_Click(object sender, MouseButtonEventArgs e) { ModBase.OpenWebsite("https://github.com/PCL-Community/PCL2-CE/releases/v" + ModBase.versionBaseName); } public string VersionNameFormat(string str) { str = str.Replace("v", ""); if (!str.Contains("-")) return str; var add = str.AfterLast("-"); str = str.BeforeLast("-"); return $"{str} {add.Replace(".", " ").Replace("beta", "Beta").Replace("rc", "RC")}"; } private void BtnCheckAgain_OnClick(object sender, MouseButtonEventArgs e) { CheckUpdate(); } private enum UpdateStatus { Checking = 0, Available = 1, Error = 2, Latest = 3 } }