Files
MRCC/launcher/PCL-CE/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUpdate.xaml.cs
T
xyou f70b061d1a
CI / Go Backend (push) Canceled after 0s
feat: 项目初始化 + 3D方块世界原型 + AI助搭系统
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器

HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块

Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚

AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
2026-08-08 14:07:56 +08:00

285 lines
10 KiB
C#

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<UpdateStatus> 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("<summary>", "</summary>");
if (!updateInfo.Changelog.Contains("<summary>") || 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
}
}