refactor: more refactors, fixed previously introduced SingleApplication bug

This commit is contained in:
QxQ 2020-10-14 22:59:39 +08:00
parent 4cd00df503
commit 6dbf9968e1
10 changed files with 91 additions and 98 deletions

View File

@ -1 +1 @@
6001
6002

View File

@ -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;

View File

@ -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" });

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
};

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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