mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 02:40:20 +08:00
refactor: more refactors, fixed previously introduced SingleApplication bug
This commit is contained in:
parent
4cd00df503
commit
6dbf9968e1
@ -1 +1 @@
|
||||
6001
|
||||
6002
|
||||
|
@ -21,9 +21,8 @@ namespace Qv2ray
|
||||
EXIT_NORMAL = 0,
|
||||
EXIT_NEW_VERSION_TRIGGER = EXIT_NORMAL,
|
||||
EXIT_SECONDARY_INSTANCE = EXIT_NORMAL,
|
||||
EXIT_PREINITIALIZATION_FAILED = -1,
|
||||
EXIT_INITIALIZATION_FAILED = -1,
|
||||
EXIT_PRECONDITION_FAILED = -2,
|
||||
EXIT_CRASHED = -9,
|
||||
};
|
||||
|
||||
struct Qv2rayStartupArguments
|
||||
@ -58,7 +57,6 @@ namespace Qv2ray
|
||||
public:
|
||||
Qv2ray::base::config::Qv2rayConfigObject *ConfigObject;
|
||||
QString ConfigPath;
|
||||
Qv2rayExitReason ExitReason;
|
||||
Qv2rayStartupArguments StartupArguments;
|
||||
|
||||
public:
|
||||
@ -68,9 +66,6 @@ namespace Qv2ray
|
||||
public:
|
||||
virtual QStringList GetAssetsPaths(const QString &dirName) const final;
|
||||
//
|
||||
virtual bool Initialize() = 0;
|
||||
virtual Qv2rayExitReason RunQv2ray() = 0;
|
||||
//
|
||||
virtual void MessageBoxWarn(QWidget *parent, const QString &title, const QString &text, MessageOpt button) = 0;
|
||||
virtual void MessageBoxInfo(QWidget *parent, const QString &title, const QString &text, MessageOpt button) = 0;
|
||||
virtual MessageOpt MessageBoxAsk(QWidget *parent, const QString &title, const QString &text, const QList<MessageOpt> &buttons) = 0;
|
||||
|
@ -212,8 +212,8 @@ namespace Qv2ray::core::config
|
||||
return false;
|
||||
}
|
||||
|
||||
GlobalConfig.kernelConfig.KernelPath(QString(QV2RAY_DEFAULT_VCORE_PATH));
|
||||
GlobalConfig.kernelConfig.AssetsPath(QString(QV2RAY_DEFAULT_VASSETS_PATH));
|
||||
GlobalConfig.kernelConfig.KernelPath(QV2RAY_DEFAULT_VCORE_PATH);
|
||||
GlobalConfig.kernelConfig.AssetsPath(QV2RAY_DEFAULT_VASSETS_PATH);
|
||||
GlobalConfig.logLevel = 3;
|
||||
GlobalConfig.uiConfig.language = QLocale::system().name();
|
||||
GlobalConfig.defaultRouteConfig.dnsConfig.servers.append({ "1.1.1.1" });
|
||||
|
61
src/main.cpp
61
src/main.cpp
@ -15,7 +15,6 @@
|
||||
|
||||
#include "utils/QvHelpers.hpp"
|
||||
|
||||
#include <QSslSocket>
|
||||
#include <csignal>
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
@ -180,30 +179,6 @@ LONG WINAPI TopLevelExceptionHandler(PEXCEPTION_POINTERS)
|
||||
}
|
||||
#endif
|
||||
|
||||
void ProcessExitReason(Qv2rayExitReason reason)
|
||||
{ // app.MessageBoxWarn(nullptr, app.tr("Cannot start Qv2ray"), app.tr("Qv2ray early initialization failed."));
|
||||
// return QVEXIT_EARLY_SETUP_FAIL;
|
||||
switch (reason)
|
||||
{
|
||||
case EXIT_CRASHED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case EXIT_NORMAL:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case EXIT_PREINITIALIZATION_FAILED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case EXIT_PRECONDITION_FAILED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
globalArgc = argc;
|
||||
@ -258,31 +233,22 @@ int main(int argc, char *argv[])
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
|
||||
#endif
|
||||
|
||||
// Check OpenSSL version for auto-update and subscriptions
|
||||
auto osslReqVersion = QSslSocket::sslLibraryBuildVersionString();
|
||||
auto osslCurVersion = QSslSocket::sslLibraryVersionString();
|
||||
LOG("Current OpenSSL version: " + osslCurVersion);
|
||||
|
||||
if (!QSslSocket::supportsSsl())
|
||||
Qv2rayApplication app(argc, argv);
|
||||
if (const auto list = app.CheckPrerequisites(); !list.isEmpty())
|
||||
{
|
||||
LOG("Required OpenSSL version: " + osslReqVersion);
|
||||
LOG("OpenSSL library MISSING, Quitting.");
|
||||
BootstrapMessageBox(QObject::tr("Dependency Missing"),
|
||||
QObject::tr("Cannot find openssl libs") + NEWLINE +
|
||||
QObject::tr("This could be caused by a missing of `openssl` package in your system.") + NEWLINE +
|
||||
QObject::tr("If you are using an AppImage from Github Action, please report a bug.") + NEWLINE + //
|
||||
NEWLINE + QObject::tr("Technical Details") + NEWLINE + //
|
||||
"OSsl.Rq.V=" + osslReqVersion + NEWLINE + //
|
||||
"OSsl.Cr.V=" + osslCurVersion);
|
||||
BootstrapMessageBox(QObject::tr("Cannot start Qv2ray"), QObject::tr("Cannot start Qv2ray without OpenSSL"));
|
||||
return -1;
|
||||
BootstrapMessageBox("Qv2ray Prerequisites Check Failed", list.join(NEWLINE));
|
||||
return Qv2rayExitReason::EXIT_PRECONDITION_FAILED;
|
||||
}
|
||||
|
||||
Qv2rayApplication app(argc, argv);
|
||||
if (!app.Initialize())
|
||||
{
|
||||
LOG("Qv2ray initialization failed:", app.ExitReason);
|
||||
ProcessExitReason(app.ExitReason);
|
||||
const auto reason = app.GetExitReason();
|
||||
if (reason == EXIT_INITIALIZATION_FAILED)
|
||||
{
|
||||
BootstrapMessageBox("Qv2ray Initialization Failed", "PreInitialization Failed." NEWLINE "For more information, please see the log.");
|
||||
LOG("Qv2ray initialization failed:", reason);
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
@ -291,10 +257,11 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
app.RunQv2ray();
|
||||
if (app.ExitReason == EXIT_NEW_VERSION_TRIGGER)
|
||||
const auto reason = app.GetExitReason();
|
||||
if (reason == EXIT_NEW_VERSION_TRIGGER)
|
||||
{
|
||||
LOG("Starting new version of Qv2ray: " + app.StartupArguments._qvNewVersionPath);
|
||||
QProcess::startDetached(app.StartupArguments._qvNewVersionPath, {});
|
||||
}
|
||||
return app.ExitReason;
|
||||
return reason;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "Qv2rayPlatformApplication.hpp"
|
||||
|
||||
#include "core/settings/SettingsBackend.hpp"
|
||||
|
||||
#include <QSslSocket>
|
||||
#define QV_MODULE_NAME "PlatformApplication"
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
@ -9,13 +11,42 @@ const static inline QString QV2RAY_URL_SCHEME = "qv2ray-debug";
|
||||
const static inline QString QV2RAY_URL_SCHEME = "qv2ray";
|
||||
#endif
|
||||
|
||||
bool Qv2rayPlatformApplication::initializeInternal()
|
||||
QStringList Qv2rayPlatformApplication::CheckPrerequisites()
|
||||
{
|
||||
QStringList errors;
|
||||
if (!QSslSocket::supportsSsl())
|
||||
{
|
||||
// Check OpenSSL version for auto-update and subscriptions
|
||||
const auto osslReqVersion = QSslSocket::sslLibraryBuildVersionString();
|
||||
const auto osslCurVersion = QSslSocket::sslLibraryVersionString();
|
||||
LOG("Current OpenSSL version: " + osslCurVersion);
|
||||
LOG("Required OpenSSL version: " + osslReqVersion);
|
||||
errors << "Qv2ray cannot run without OpenSSL.";
|
||||
errors << "This is usually caused by using the wrong version of OpenSSL";
|
||||
errors << "Required=" + osslReqVersion + "Current=" + osslCurVersion;
|
||||
}
|
||||
return errors + checkPrerequisitesInternal();
|
||||
}
|
||||
|
||||
bool Qv2rayPlatformApplication::Initialize()
|
||||
{
|
||||
QString errorMessage;
|
||||
bool canContinue;
|
||||
auto hasError = parseCommandLine(&errorMessage, &canContinue);
|
||||
if (hasError && !canContinue)
|
||||
return false;
|
||||
const auto hasError = parseCommandLine(&errorMessage, &canContinue);
|
||||
if (hasError)
|
||||
{
|
||||
LOG("Command line:" A(errorMessage));
|
||||
if (!canContinue)
|
||||
{
|
||||
LOG("Fatal, Qv2ray cannot continue.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Non-fatal error, continue starting up.");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
const auto appPath = QDir::toNativeSeparators(applicationFilePath());
|
||||
const auto regPath = "HKEY_CURRENT_USER\\Software\\Classes\\" + QV2RAY_URL_SCHEME;
|
||||
@ -37,15 +68,18 @@ bool Qv2rayPlatformApplication::initializeInternal()
|
||||
if (isSecondary())
|
||||
{
|
||||
StartupArguments.version = QV2RAY_VERSION_STRING;
|
||||
StartupArguments.buildVersion = QV2RAY_VERSION_BUILD;
|
||||
StartupArguments.fullArgs = arguments();
|
||||
if (StartupArguments.arguments.isEmpty())
|
||||
StartupArguments.arguments << Qv2rayStartupArguments::NORMAL;
|
||||
bool status = sendMessage(JsonToString(StartupArguments.toJson(), QJsonDocument::Compact).toUtf8());
|
||||
if (!status)
|
||||
LOG("Cannot send message.");
|
||||
return true;
|
||||
SetExitReason(EXIT_SECONDARY_INSTANCE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef QV2RAY_GUI
|
||||
#ifdef Q_OS_LINUX
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
@ -58,6 +92,7 @@ bool Qv2rayPlatformApplication::initializeInternal()
|
||||
SaveGlobalSettings();
|
||||
});
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
SetCurrentDirectory(applicationDirPath().toStdWString().c_str());
|
||||
// Set special font in Windows
|
||||
@ -71,12 +106,10 @@ bool Qv2rayPlatformApplication::initializeInternal()
|
||||
// Install a default translater. From the OS/DE
|
||||
Qv2rayTranslator = std::make_unique<QvTranslator>();
|
||||
Qv2rayTranslator->InstallTranslation(QLocale::system().name());
|
||||
//
|
||||
//
|
||||
LocateConfiguration();
|
||||
//
|
||||
const auto allTranslations = Qv2rayTranslator->GetAvailableLanguages();
|
||||
const auto osLanguage = QLocale::system().name();
|
||||
//
|
||||
LocateConfiguration();
|
||||
if (!allTranslations.contains(GlobalConfig.uiConfig.language))
|
||||
{
|
||||
// If we need to reset the language.
|
||||
@ -102,12 +135,12 @@ bool Qv2rayPlatformApplication::initializeInternal()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Qv2rayPlatformApplication::runInternal()
|
||||
Qv2rayExitReason Qv2rayPlatformApplication::RunQv2ray()
|
||||
{
|
||||
PluginHost = new QvPluginHost();
|
||||
RouteManager = new RouteHandler();
|
||||
ConnectionManager = new QvConfigHandler();
|
||||
return true;
|
||||
return runQv2rayInternal();
|
||||
}
|
||||
|
||||
void Qv2rayPlatformApplication::quitInternal()
|
||||
@ -118,7 +151,7 @@ void Qv2rayPlatformApplication::quitInternal()
|
||||
ConnectionManager->SaveConnectionConfig();
|
||||
PluginHost->SavePluginSettings();
|
||||
SaveGlobalSettings();
|
||||
TerminateUI();
|
||||
terminateUIInternal();
|
||||
delete ConnectionManager;
|
||||
delete RouteManager;
|
||||
delete PluginHost;
|
||||
|
@ -51,21 +51,30 @@ class Qv2rayPlatformApplication
|
||||
public:
|
||||
Qv2rayPlatformApplication(int &argc, char *argv[]) : QVBASEAPPLICATION(QVBASEAPPLICATION_CTORARGS), Qv2rayApplicationInterface(){};
|
||||
virtual ~Qv2rayPlatformApplication(){};
|
||||
inline void QuitApplication(int retCode = 0)
|
||||
virtual Qv2rayExitReason GetExitReason() const final
|
||||
{
|
||||
QCoreApplication::exit(retCode);
|
||||
return _exitReason;
|
||||
}
|
||||
|
||||
virtual QStringList CheckPrerequisites() final;
|
||||
virtual bool Initialize() final;
|
||||
virtual Qv2rayExitReason RunQv2ray() final;
|
||||
|
||||
protected:
|
||||
bool initializeInternal();
|
||||
bool runInternal();
|
||||
void quitInternal();
|
||||
virtual void TerminateUI() = 0;
|
||||
virtual QStringList checkPrerequisitesInternal() = 0;
|
||||
virtual Qv2rayExitReason runQv2rayInternal() = 0;
|
||||
virtual void terminateUIInternal() = 0;
|
||||
virtual void SetExitReason(Qv2rayExitReason r) final
|
||||
{
|
||||
_exitReason = r;
|
||||
}
|
||||
|
||||
#ifndef QV2RAY_NO_SINGLEAPPLICATON
|
||||
virtual void onMessageReceived(quint32 clientId, QByteArray msg) = 0;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void quitInternal();
|
||||
Qv2rayExitReason _exitReason;
|
||||
bool parseCommandLine(QString *errorMessage, bool *canContinue);
|
||||
};
|
||||
|
@ -25,17 +25,12 @@ Qv2rayWidgetApplication::Qv2rayWidgetApplication(int &argc, char *argv[]) : Qv2r
|
||||
{
|
||||
}
|
||||
|
||||
bool Qv2rayWidgetApplication::Initialize()
|
||||
QStringList Qv2rayWidgetApplication::checkPrerequisitesInternal()
|
||||
{
|
||||
const auto result = initializeInternal();
|
||||
if (!result)
|
||||
return false;
|
||||
setQuitOnLastWindowClosed(false);
|
||||
hTray = new QSystemTrayIcon();
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
void Qv2rayWidgetApplication::TerminateUI()
|
||||
void Qv2rayWidgetApplication::terminateUIInternal()
|
||||
{
|
||||
delete mainWindow;
|
||||
delete hTray;
|
||||
@ -73,7 +68,7 @@ void Qv2rayWidgetApplication::onMessageReceived(quint32 clientId, QByteArray _ms
|
||||
if (result == Yes)
|
||||
{
|
||||
StartupArguments._qvNewVersionPath = newPath;
|
||||
QuitApplication(EXIT_NEW_VERSION_TRIGGER);
|
||||
SetExitReason(EXIT_NEW_VERSION_TRIGGER);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +78,8 @@ void Qv2rayWidgetApplication::onMessageReceived(quint32 clientId, QByteArray _ms
|
||||
{
|
||||
case Qv2rayStartupArguments::EXIT:
|
||||
{
|
||||
QuitApplication();
|
||||
SetExitReason(EXIT_NORMAL);
|
||||
quit();
|
||||
break;
|
||||
}
|
||||
case Qv2rayStartupArguments::NORMAL:
|
||||
@ -128,9 +124,10 @@ void Qv2rayWidgetApplication::onMessageReceived(quint32 clientId, QByteArray _ms
|
||||
}
|
||||
#endif
|
||||
|
||||
Qv2rayExitReason Qv2rayWidgetApplication::RunQv2ray()
|
||||
Qv2rayExitReason Qv2rayWidgetApplication::runQv2rayInternal()
|
||||
{
|
||||
runInternal();
|
||||
setQuitOnLastWindowClosed(false);
|
||||
hTray = new QSystemTrayIcon();
|
||||
StyleManager = new QvStyleManager();
|
||||
StyleManager->ApplyStyle(GlobalConfig.uiConfig.theme);
|
||||
// Show MainWindow
|
||||
|
@ -13,8 +13,6 @@ namespace Qv2ray
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Qv2rayWidgetApplication(int &argc, char *argv[]);
|
||||
bool Initialize() override;
|
||||
Qv2rayExitReason RunQv2ray() override;
|
||||
QJsonObject UIStates;
|
||||
|
||||
public:
|
||||
@ -31,8 +29,10 @@ namespace Qv2ray
|
||||
}
|
||||
|
||||
private:
|
||||
QStringList checkPrerequisitesInternal() override;
|
||||
Qv2rayExitReason runQv2rayInternal() override;
|
||||
bool isInitialized;
|
||||
void TerminateUI() override;
|
||||
void terminateUIInternal() override;
|
||||
#ifndef QV2RAY_NO_SINGLEAPPLICATON
|
||||
void onMessageReceived(quint32 clientID, QByteArray msg) override;
|
||||
#endif
|
||||
|
@ -484,7 +484,7 @@ void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason)
|
||||
void MainWindow::Action_Exit()
|
||||
{
|
||||
ConnectionManager->StopConnection();
|
||||
QvWidgetApplication->QuitApplication();
|
||||
QvWidgetApplication->quit();
|
||||
}
|
||||
|
||||
void MainWindow::on_preferencesBtn_clicked()
|
||||
|
@ -12,14 +12,6 @@ class QvTestApplication
|
||||
{
|
||||
public:
|
||||
explicit QvTestApplication() : QCoreApplication(fakeArgc, fakeArgv), Qv2rayApplicationInterface(){};
|
||||
virtual bool Initialize() override
|
||||
{
|
||||
return true;
|
||||
};
|
||||
virtual Qv2rayExitReason RunQv2ray() override
|
||||
{
|
||||
return {};
|
||||
};
|
||||
virtual void MessageBoxWarn(QWidget *, const QString &, const QString &, MessageOpt) override{};
|
||||
virtual void MessageBoxInfo(QWidget *, const QString &, const QString &, MessageOpt) override{};
|
||||
virtual MessageOpt MessageBoxAsk(QWidget *, const QString &, const QString &, const QList<MessageOpt> &) override
|
||||
|
Loading…
Reference in New Issue
Block a user