feat: core check update

This commit is contained in:
Chenx Dust
2025-03-25 15:39:33 +08:00
parent e08f14fb9c
commit 4095299226
8 changed files with 148 additions and 33 deletions

View File

@@ -39,6 +39,7 @@ set(SOURCE_FILES
loginwindow/loginwindow.cpp
utils/utils.cpp
utils/proxysettings.cpp
utils/coreversion.cpp
resource.qrc
)

View File

@@ -47,9 +47,12 @@ MainWindow::MainWindow(QWidget *parent) :
)));
ui->applicationNameLabel->setText(QApplication::applicationDisplayName());
ui->versionLabel->setText(
"当前版本v" + QApplication::applicationVersion() + "\n正在检查更新……\n"
);
versionInfo.ui_version = QApplication::applicationVersion();
versionInfo.ui_latest = "正在检查";
versionInfo.core_version = "未知";
versionInfo.core_latest = "正在检查";
updateVersionInfo();
// 系统托盘
trayIcon = new QSystemTrayIcon(this);
@@ -175,9 +178,9 @@ MainWindow::MainWindow(QWidget *parent) :
this, [&](QNetworkReply* reply) {
if (reply->error() != QNetworkReply::NoError)
{
addLog("检查更新失败。原因是:" + reply->errorString());
addLog("检查 UI 更新失败。原因是:" + reply->errorString());
ui->versionLabel->setText(
"当前版本:" + QApplication::applicationVersion() + "\n检查更新失败\n"
"当前版本:" + QApplication::applicationVersion() + "\n检查 UI 更新失败\n"
);
reply->deleteLater();
return;
@@ -194,11 +197,9 @@ MainWindow::MainWindow(QWidget *parent) :
{
latestVersion = latestVersion.mid(1);
}
addLog("检查更新成功。最新版本:" + latestVersion);
ui->versionLabel->setText(
"当前版本:" + nowVersion + "\n"
"最新版本:" + latestVersion + "\n"
);
addLog("检查 UI 更新成功。最新版本:" + latestVersion);
versionInfo.ui_latest = latestVersion;
updateVersionInfo();
qsizetype nowVersionSuffix, latestVersionSuffix;
auto nowVersionQ = QVersionNumber::fromString(nowVersion, &nowVersionSuffix);
@@ -208,8 +209,8 @@ MainWindow::MainWindow(QWidget *parent) :
(latestVersionQ == nowVersionQ && latestVersion.right(latestVersionSuffix) != nowVersion.right(nowVersionSuffix)))
{
QMessageBox msgBox;
msgBox.setText("版本更新");
msgBox.setInformativeText("存在版本更新:" + latestVersion + "\n"
msgBox.setText("UI 版本更新");
msgBox.setInformativeText("存在 UI 版本更新:" + latestVersion + "\n"
"是否前往 Github 发布页面查看?");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
@@ -222,18 +223,59 @@ MainWindow::MainWindow(QWidget *parent) :
}
});
// 检查核心更新
checkCoreUpdateNAM = new QNetworkAccessManager(this);
connect(checkCoreUpdateNAM, &QNetworkAccessManager::finished,
this, [&](QNetworkReply* reply) {
if (reply->error() != QNetworkReply::NoError)
{
addLog("检查核心更新失败。原因是:" + reply->errorString());
ui->versionLabel->setText(
"当前版本:" + QApplication::applicationVersion() + "\n检查核心更新失败\n"
);
reply->deleteLater();
return;
}
QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
reply->deleteLater();
QString nowVersion = versionInfo.core_version;
QString latestVersion = json["tag_name"].toString();
// 移除开头的 'v'
if (latestVersion.startsWith('v'))
{
latestVersion = latestVersion.mid(1);
}
addLog("检查核心更新成功。最新版本:" + latestVersion);
versionInfo.core_latest = latestVersion;
updateVersionInfo();
qsizetype nowVersionSuffix, latestVersionSuffix;
auto nowVersionQ = QVersionNumber::fromString(nowVersion, &nowVersionSuffix);
auto latestVersionQ = QVersionNumber::fromString(latestVersion, &latestVersionSuffix);
if (latestVersionQ > nowVersionQ ||
(latestVersionQ == nowVersionQ && latestVersion.right(latestVersionSuffix) != nowVersion.right(nowVersionSuffix)))
{
addLog("核心版本存在更新,可手动更新或通知开发者更新。");
}
});
initZjuConnect();
if (settings->value("Common/CheckUpdateAfterStart", true).toBool())
{
checkUpdate();
}
else
{
ui->versionLabel->setText(
"当前版本:" + QApplication::applicationVersion() + "\n自动检查更新已禁用\n"
);
versionInfo.ui_latest = "已禁用";
versionInfo.core_latest = "已禁用";
updateVersionInfo();
}
initZjuConnect();
}
void MainWindow::closeEvent(QCloseEvent *event)
@@ -259,8 +301,20 @@ void MainWindow::clearLog()
void MainWindow::checkUpdate()
{
try
{
versionInfo.core_version = Utils::checkCoreVersion(this);
addLog("检查核心版本成功:" + versionInfo.core_version);
}
catch (const std::runtime_error& e)
{
addLog("检查核心版本失败:" + QString(e.what()));
versionInfo.core_version = "错误";
}
QNetworkRequest request(QUrl("https://api.github.com/repos/" + Utils::REPO_NAME + "/releases/latest"));
checkUpdateNAM->get(request);
QNetworkRequest request_c(QUrl("https://api.github.com/repos/" + Utils::CORE_REPO_NAME + "/releases/latest"));
checkCoreUpdateNAM->get(request_c);
}
void MainWindow::upgradeSettings()
@@ -291,6 +345,14 @@ void MainWindow::upgradeSettings()
settings->sync();
}
void MainWindow::updateVersionInfo()
{
ui->versionLabel->setText(
"UI 版本:" + versionInfo.ui_version + " 最新:" + versionInfo.ui_latest + "\n"
"核心版本:" + versionInfo.core_version + " 最新:" + versionInfo.core_latest + "\n"
);
}
void MainWindow::showNotification(const QString &title, const QString &content, QSystemTrayIcon::MessageIcon icon)
{
disconnect(trayIcon, &QSystemTrayIcon::messageClicked, nullptr, nullptr);

View File

@@ -55,6 +55,13 @@ private:
void initZjuConnect();
void updateVersionInfo();
struct {
QString ui_version, ui_latest;
QString core_version, core_latest;
} versionInfo;
Ui::MainWindow *ui;
QSystemTrayIcon *trayIcon;
QMenu *trayMenu;
@@ -62,6 +69,7 @@ private:
QAction *trayCloseAction;
ZjuConnectController *zjuConnectController;
QNetworkAccessManager *checkUpdateNAM;
QNetworkAccessManager *checkCoreUpdateNAM;
QSettings *settings;
QProcess *process;
QProcess *processForL2tp;

View File

@@ -26,7 +26,7 @@
</font>
</property>
<property name="toolTip">
<string>关注 OSA 谢谢喵n(*≧▽≦*)n</string>
<string>关注 HITSZ OSA 谢谢喵n(*≧▽≦*)n</string>
</property>
<property name="text">
<string>EZ4Connect</string>

52
utils/coreversion.cpp Normal file
View File

@@ -0,0 +1,52 @@
#include <QProcess>
#include <QCoreApplication>
#include <QFileInfo>
#include "utils.h"
namespace Utils {
QString getCorePath()
{
QString program_filename;
if (QSysInfo::productType() == "windows")
{
program_filename = "zju-connect.exe";
}
else
{
program_filename = "zju-connect";
}
return QCoreApplication::applicationDirPath() + "/" + program_filename;
}
QString checkCoreVersion(QObject* parent)
{
QProcess process(parent);
process.start(Utils::getCorePath(), { "-version" });
if (!process.waitForStarted()) {
throw std::runtime_error("核心无法启动");
}
if (!process.waitForFinished()) {
throw std::runtime_error("核心运行超时");
}
// 获取错误输出
QByteArray errorOutput = process.readAllStandardError();
if (!errorOutput.isEmpty()) {
throw std::runtime_error(errorOutput);
}
// 获取标准输出
QString output = process.readAllStandardOutput();
const QString prefix("ZJU Connect v");
if (!output.startsWith(prefix)) {
throw std::runtime_error("无法解析核心版本号");
}
return output.mid(prefix.size()).trimmed();
}
}

View File

@@ -1,6 +1,3 @@
#ifndef PROXYSETTINGS_H
#define PROXYSETTINGS_H
#include <QProcess>
#include <QMessageBox>
#include <QSettings>
@@ -524,5 +521,3 @@ void Utils::clearSystemProxy()
linuxClearSystemProxy();
#endif
}
#endif // PROXYSETTINGS_H

View File

@@ -3,12 +3,14 @@
#include <QString>
#include <QByteArray>
#include <QNetworkReply>
#include <QWidget>
#include <QSettings>
namespace Utils
{
const inline QString REPO_NAME("PageChen04/EZ4Connect");
const inline QString CORE_REPO_NAME("Mythologyli/zju-connect");
const inline QString APP_NAME("EZ4Connect");
@@ -33,6 +35,10 @@ namespace Utils
bool credentialCheck(const QString &username, const QString &password);
void resetDefaultSettings(QSettings &settings);
QString getCorePath();
QString checkCoreVersion(QObject *parent);
}
#endif //UTILS_H

View File

@@ -115,16 +115,7 @@ void MainWindow::initZjuConnect()
QString password_ = QByteArray::fromBase64(settings->value("Credential/Password", "").toString().toUtf8());
auto startZjuConnect = [this](const QString &username, const QString &password) {
QString program_filename;
if (QSysInfo::productType() == "windows")
{
program_filename = "zju-connect.exe";
}
else
{
program_filename = "zju-connect";
}
QString program_path = QCoreApplication::applicationDirPath() + "/" + program_filename;
QString program_path = Utils::getCorePath();
QString bind_prefix = settings->value("ZJUConnect/OutsideAccess", false).toBool() ? "[::]:" : "[::1]:";
isZjuConnectLinked = true;