From fce84ece23e23b0c7e37d667b8edfb9dce3fc5eb Mon Sep 17 00:00:00 2001 From: Qv2ray-dev <59914293+Qv2ray-dev@users.noreply.github.com> Date: Sat, 13 Jun 2020 21:51:28 +0800 Subject: [PATCH] refactor: main.cpp refactor --- cmake/components/qv2ray-lib.cmake | 2 - makespec/BUILDVERSION | 2 +- src/Qv2rayApplication.cpp | 168 +++++++++++++++++++++------- src/Qv2rayApplication.hpp | 25 ++++- src/base/models/QvStartupConfig.hpp | 40 ++++--- src/common/CommandArgs.cpp | 75 ------------- src/common/CommandArgs.hpp | 37 ------ src/main.cpp | 59 +--------- 8 files changed, 170 insertions(+), 238 deletions(-) delete mode 100644 src/common/CommandArgs.cpp delete mode 100644 src/common/CommandArgs.hpp diff --git a/cmake/components/qv2ray-lib.cmake b/cmake/components/qv2ray-lib.cmake index 53a9b3d5..90d59fd2 100644 --- a/cmake/components/qv2ray-lib.cmake +++ b/cmake/components/qv2ray-lib.cmake @@ -15,8 +15,6 @@ set(QV2RAY_BASE_HEADERS set(QV2RAY_LIB_SOURCES # headers ${CMAKE_SOURCE_DIR}/src/base/Qv2rayLog.cpp - ${CMAKE_SOURCE_DIR}/src/common/CommandArgs.cpp - ${CMAKE_SOURCE_DIR}/src/common/CommandArgs.hpp ${CMAKE_SOURCE_DIR}/src/common/HTTPRequestHelper.cpp ${CMAKE_SOURCE_DIR}/src/common/HTTPRequestHelper.hpp ${CMAKE_SOURCE_DIR}/src/common/QJsonModel.cpp diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION index 9274a034..a9842242 100644 --- a/makespec/BUILDVERSION +++ b/makespec/BUILDVERSION @@ -1 +1 @@ -5578 +5579 diff --git a/src/Qv2rayApplication.cpp b/src/Qv2rayApplication.cpp index 894136e1..ed201803 100644 --- a/src/Qv2rayApplication.cpp +++ b/src/Qv2rayApplication.cpp @@ -9,11 +9,11 @@ namespace Qv2ray Qv2rayApplication::Qv2rayApplication(int &argc, char *argv[]) : SingleApplication(argc, argv, true, User | ExcludeAppPath | ExcludeAppVersion) { - LOG("QV2RAY_BUILD_INFO", QV2RAY_BUILD_INFO) - LOG("QV2RAY_BUILD_EXTRA_INFO", QV2RAY_BUILD_EXTRA_INFO) - LOG("QV2RAY_BUILD_NUMBER", QSTRN(QV2RAY_VERSION_BUILD)) - LOG(MODULE_INIT, "Qv2ray " QV2RAY_VERSION_STRING " on " + QSysInfo::prettyProductName() + " " + QSysInfo::currentCpuArchitecture()) LOG(MODULE_INIT, "Qv2ray Start Time: " + QSTRN(QTime::currentTime().msecsSinceStartOfDay())) + LOG(MODULE_INIT, "Qv2ray " QV2RAY_VERSION_STRING " on " + QSysInfo::prettyProductName() + " " + QSysInfo::currentCpuArchitecture()) + DEBUG("QV2RAY_BUILD_INFO", QV2RAY_BUILD_INFO) + DEBUG("QV2RAY_BUILD_EXTRA_INFO", QV2RAY_BUILD_EXTRA_INFO) + DEBUG("QV2RAY_BUILD_NUMBER", QSTRN(QV2RAY_VERSION_BUILD)) } bool Qv2rayApplication::SetupQv2ray() @@ -21,8 +21,7 @@ namespace Qv2ray connect(this, &SingleApplication::receivedMessage, this, &Qv2rayApplication::onMessageReceived); if (isSecondary()) { - const auto argument = arguments().join(' '); - sendMessage(argument.toUtf8()); + sendMessage(JsonToString(Qv2rayProcessArgument.toJson()).toUtf8()); return true; } return false; @@ -31,25 +30,7 @@ namespace Qv2ray void Qv2rayApplication::onMessageReceived(quint32 clientId, QByteArray msg) { LOG(MODULE_INIT, "Client ID: " + QSTRN(clientId) + " message received.") - const auto args = Qv2rayInterProcessArguments::fromJson(JsonFromString(msg)); - } - - void Qv2rayApplication::SetHiDPIEnableState(bool enabled) - { - if (enabled) - { - LOG(MODULE_INIT, "High DPI scaling is enabled.") - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); -#endif - } - else - { - LOG(MODULE_INIT, "Force set QT_SCALE_FACTOR to 1.") - LOG(MODULE_UI, "Original QT_SCALE_FACTOR was: " + qEnvironmentVariable("QT_SCALE_FACTOR")) - qputenv("QT_SCALE_FACTOR", "1"); - } + const auto args = Qv2rayProcessArguments::fromJson(JsonFromString(msg)); } bool Qv2rayApplication::InitilizeConfigurations() @@ -122,17 +103,16 @@ namespace Qv2ray // Check if the dirs are write-able if (!hasPossibleNewLocation) { - // // None of the path above can be used as a dir for storing config. // Even the last folder failed to pass the check. LOG(MODULE_INIT, "FATAL") LOG(MODULE_INIT, " ---> CANNOT find a proper place to store Qv2ray config files.") - QvMessageBoxWarn(nullptr, QObject::tr("Cannot Start Qv2ray"), - QObject::tr("Cannot find a place to store config files.") + NEWLINE + - QObject::tr("Qv2ray has searched these paths below:") + NEWLINE + NEWLINE + // - configFilePaths.join(NEWLINE) + NEWLINE + - QObject::tr("It usually means you don't have the write permission to all of those locations.") + - QObject::tr("Qv2ray will now exit.")); + QvMessageBoxWarn(nullptr, tr("Cannot Start Qv2ray"), + tr("Cannot find a place to store config files.") + NEWLINE + // + tr("Qv2ray has searched these paths below:") + NEWLINE + NEWLINE + // + configFilePaths.join(NEWLINE) + NEWLINE + // + tr("It usually means you don't have the write permission to all of those locations.") + NEWLINE + // + tr("Qv2ray will now exit.")); // return false; } // Found a valid config dir, with write permission, but assume no config is located in it. @@ -151,13 +131,13 @@ namespace Qv2ray // Otherwise Qv2ray would have loaded this config already instead of notifying to create a new config in this folder. // LOG(MODULE_INIT, "This should not occur: Qv2ray config exists but failed to load.") - QvMessageBoxWarn(nullptr, QObject::tr("Failed to initialise Qv2ray"), - QObject::tr("Failed to determine the location of config file:") + NEWLINE + // - QObject::tr("Qv2ray has found a config file, but it failed to be loaded due to some errors.") + NEWLINE + // - QObject::tr("A workaround is to remove the this file and restart Qv2ray:") + NEWLINE + // - QV2RAY_CONFIG_FILE + NEWLINE + // - QObject::tr("Qv2ray will now exit.") + NEWLINE + // - QObject::tr("Please report if you think it's a bug.")); // + QvMessageBoxWarn(nullptr, tr("Failed to initialise Qv2ray"), + tr("Failed to determine the location of config file:") + NEWLINE + // + tr("Qv2ray has found a config file, but it failed to be loaded due to some errors.") + NEWLINE + // + tr("A workaround is to remove the this file and restart Qv2ray:") + NEWLINE + // + QV2RAY_CONFIG_FILE + NEWLINE + // + tr("Qv2ray will now exit.") + NEWLINE + // + tr("Please report if you think it's a bug.")); // return false; } @@ -272,8 +252,7 @@ namespace Qv2ray { LOG(MODULE_SETTINGS, "Exception raised when checking config: " + configFile.fileName()) // LOG(INIT, e->what()) - QvMessageBoxWarn(nullptr, QObject::tr("Warning"), - QObject::tr("Qv2ray cannot load the config file from here:") + NEWLINE + configFile.fileName()); + QvMessageBoxWarn(nullptr, tr("Warning"), tr("Qv2ray cannot load the config file from here:") + NEWLINE + configFile.fileName()); return false; } } @@ -282,4 +261,111 @@ namespace Qv2ray return true; } } + + bool Qv2rayApplication::PreInitilize(int argc, char *argv[]) + { + QCoreApplication consoleApp(argc, argv); + QString errorMessage; + + const auto &args = consoleApp.arguments(); + Qv2rayProcessArgument.path = args.first(); + Qv2rayProcessArgument.version = QV2RAY_VERSION_STRING; + Qv2rayProcessArgument.data = args.join(" "); + switch (ParseCommandLine(&errorMessage)) + { + case QUIT: + { + return false; + } + case ERROR: + { + LOG(MODULE_INIT, errorMessage) + return false; + } + case CONTINUE: + { + break; + } + } + // noScaleFactors = disable HiDPI + if (StartupOption.noScaleFactor) + { + LOG(MODULE_INIT, "Force set QT_SCALE_FACTOR to 1.") + LOG(MODULE_UI, "Original QT_SCALE_FACTOR was: " + qEnvironmentVariable("QT_SCALE_FACTOR")) + qputenv("QT_SCALE_FACTOR", "1"); + } + else + { + LOG(MODULE_INIT, "High DPI scaling is enabled.") + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); +#endif + } + return true; + } + + Qv2rayApplication::commandline_status Qv2rayApplication::ParseCommandLine(QString *errorMessage) + { + QCommandLineParser parser; + QCommandLineOption noAPIOption("noAPI", tr("Disable gRPC API subsystem.")); + QCommandLineOption noPluginsOption("noPlugin", tr("Disable plugins feature")); + QCommandLineOption noScaleFactorOption("noScaleFactor", tr("Disable Qt UI scale factor")); + QCommandLineOption debugOption("debug", tr("Enable debug output")); + + parser.setApplicationDescription(tr("Qv2ray - A cross-platform Qt frontend for V2ray.")); + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + // + parser.addOption(noAPIOption); + parser.addOption(noPluginsOption); + parser.addOption(noScaleFactorOption); + parser.addOption(debugOption); + auto helpOption = parser.addHelpOption(); + auto versionOption = parser.addVersionOption(); + + if (!parser.parse(arguments())) + { + *errorMessage = parser.errorText(); + return ERROR; + } + + if (parser.isSet(versionOption)) + { + parser.showVersion(); + return QUIT; + } + + if (parser.isSet(helpOption)) + { + parser.showHelp(); + return QUIT; + } + + if (parser.isSet(noAPIOption)) + { + DEBUG(MODULE_INIT, "noAPIOption is set.") + StartupOption.noAPI = true; + } + + if (parser.isSet(debugOption)) + { + DEBUG(MODULE_INIT, "debugOption is set.") + StartupOption.debugLog = true; + } + + if (parser.isSet(noScaleFactorOption)) + { + DEBUG(MODULE_INIT, "noScaleFactorOption is set.") + StartupOption.noScaleFactor = true; + } + + if (parser.isSet(noPluginsOption)) + { + DEBUG(MODULE_INIT, "noPluginOption is set.") + StartupOption.noPlugins = true; + } + + return CONTINUE; + } + } // namespace Qv2ray diff --git a/src/Qv2rayApplication.hpp b/src/Qv2rayApplication.hpp index fb980de7..e59e0a34 100644 --- a/src/Qv2rayApplication.hpp +++ b/src/Qv2rayApplication.hpp @@ -6,33 +6,46 @@ namespace Qv2ray { - struct Qv2rayInterProcessArguments + struct Qv2rayProcessArguments { enum Argument { - SHOWWINDOW = 0, - PROTOCOLHANDLER = 1, - EXITQV2RAY = 2, + NORMAL = 0, + QV2RAY_LINK = 1, + EXIT = 2 }; Argument argument; + QString version; + QString path; QString data; - JSONSTRUCT_REGISTER(Qv2rayInterProcessArguments, F(argument, data)) + JSONSTRUCT_REGISTER(Qv2rayProcessArguments, F(argument, version, path, data)) }; + + inline Qv2rayProcessArguments Qv2rayProcessArgument; + class Qv2rayApplication : public SingleApplication { + enum commandline_status + { + ERROR, + QUIT, + CONTINUE + }; Q_OBJECT public: + static bool PreInitilize(int argc, char *argv[]); explicit Qv2rayApplication(int &argc, char *argv[]); + // bool SetupQv2ray(); bool InitilizeConfigurations(); - static void SetHiDPIEnableState(bool enabled); bool CheckSettingsPathAvailability(const QString &_path, bool checkExistingConfig); private slots: void onMessageReceived(quint32 clientID, QByteArray msg); private: + static commandline_status ParseCommandLine(QString *errorMessage); bool initilized = false; }; } // namespace Qv2ray diff --git a/src/base/models/QvStartupConfig.hpp b/src/base/models/QvStartupConfig.hpp index a10d0570..6c0e4839 100644 --- a/src/base/models/QvStartupConfig.hpp +++ b/src/base/models/QvStartupConfig.hpp @@ -1,22 +1,26 @@ #pragma once -namespace Qv2ray +namespace Qv2ray::base { - namespace base + struct QvStartupOptions { - struct QvStartupOptions - { - /// No API subsystem - bool noAPI; - /// Explicitly run as root user. - bool forceRunAsRootUser; - /// Enable Debug Log. - bool debugLog; - /// Disable Qt scale factors support. - bool noScaleFactors; - /// Disable all plugin features. - bool noPlugins; - }; - } // namespace base - inline base::QvStartupOptions StartupOption = base::QvStartupOptions(); -} // namespace Qv2ray + /// No API subsystem + bool noAPI; + + /// Enable Debug Log. + bool debugLog; + + /// Disable Qt scale factors support. + bool noScaleFactor; + + /// Disable all plugin features. + bool noPlugins; + + /// Exit existing Qv2ray instance + bool exitQv2ray; + + /// + }; +} // namespace Qv2ray::base + +inline Qv2ray::base::QvStartupOptions StartupOption = Qv2ray::base::QvStartupOptions(); diff --git a/src/common/CommandArgs.cpp b/src/common/CommandArgs.cpp deleted file mode 100644 index f4f7d88f..00000000 --- a/src/common/CommandArgs.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "CommandArgs.hpp" - -#include "base/Qv2rayBase.hpp" - -namespace Qv2ray::common -{ - QvCommandArgParser::QvCommandArgParser() - : QObject(), noAPIOption("noAPI", tr("Disable gRPC API subsystems.")), // - runAsRootOption("I-just-wanna-run-with-root", tr("Explicitly run Qv2ray as root.")), // - debugOption("debug", tr("Enable Debug Output")), // - noScaleFactorOption("noScaleFactor", tr("Disable manually set QT_SCALE_FACTOR")), // - noPluginsOption("noPlugin", tr("Disable plugin feature")), // - // - helpOption("FAKE"), versionOption("FAKE") - { - parser.setApplicationDescription(QObject::tr("Qv2ray - A cross-platform Qt frontend for V2ray.")); - parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); - // - parser.addOption(noAPIOption); - parser.addOption(runAsRootOption); - parser.addOption(debugOption); - parser.addOption(noScaleFactorOption); - parser.addOption(noPluginsOption); - helpOption = parser.addHelpOption(); - versionOption = parser.addVersionOption(); - } - - CommandLineParseResult QvCommandArgParser::ParseCommandLine(QString *errorMessage) - { - if (!parser.parse(QCoreApplication::arguments())) - { - *errorMessage = parser.errorText(); - return CommandLineError; - } - - if (parser.isSet(versionOption)) - return CommandLineVersionRequested; - - if (parser.isSet(helpOption)) - return CommandLineHelpRequested; - - if (parser.isSet(noAPIOption)) - { - DEBUG(MODULE_INIT, "noAPIOption is set.") - StartupOption.noAPI = true; - } - - if (parser.isSet(runAsRootOption)) - { - DEBUG(MODULE_INIT, "runAsRootOption is set.") - StartupOption.forceRunAsRootUser = true; - } - - if (parser.isSet(debugOption)) - { - DEBUG(MODULE_INIT, "debugOption is set.") - StartupOption.debugLog = true; - } - - if (parser.isSet(noScaleFactorOption)) - { - DEBUG(MODULE_INIT, "noScaleFactorOption is set.") - StartupOption.noScaleFactors = true; - } - - if (parser.isSet(noPluginsOption)) - { - DEBUG(MODULE_INIT, "noPluginOption is set.") - StartupOption.noPlugins = true; - } - - return CommandLineOk; - } - -} // namespace Qv2ray::common diff --git a/src/common/CommandArgs.hpp b/src/common/CommandArgs.hpp deleted file mode 100644 index e0217401..00000000 --- a/src/common/CommandArgs.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include - -namespace Qv2ray::common -{ - enum CommandLineParseResult - { - CommandLineOk, - CommandLineError, - CommandLineVersionRequested, - CommandLineHelpRequested - }; - class QvCommandArgParser : public QObject - { - Q_OBJECT - public: - QvCommandArgParser(); - CommandLineParseResult ParseCommandLine(QString *errorMessage); - const QCommandLineParser *Parser() - { - return &parser; - } - - private: - QCommandLineParser parser; - QCommandLineOption noAPIOption; - QCommandLineOption runAsRootOption; - QCommandLineOption debugOption; - QCommandLineOption noScaleFactorOption; - QCommandLineOption noPluginsOption; - QCommandLineOption helpOption; - QCommandLineOption versionOption; - }; -} // namespace Qv2ray::common - -using namespace Qv2ray::common; diff --git a/src/main.cpp b/src/main.cpp index bd696d75..165e673a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,4 @@ #include "Qv2rayApplication.hpp" -#include "common/CommandArgs.hpp" #include "common/QvHelpers.hpp" #include "common/QvTranslator.hpp" #include "components/plugins/QvPluginHost.hpp" @@ -18,11 +17,6 @@ #include #include -#ifdef Q_OS_UNIX - // For unix root user check - #include "unistd.h" -#endif - void signalHandler(int signum) { std::cout << "Qv2ray: Interrupt signal (" << signum << ") received." << std::endl; @@ -53,58 +47,7 @@ int main(int argc, char *argv[]) #endif // // parse the command line before starting as a Qt application - { - std::unique_ptr consoleApp(new QCoreApplication(argc, argv)); - // - // Install a default translator. From the OS/DE - Qv2rayTranslator = std::make_unique(); - Qv2rayTranslator->InstallTranslation(QLocale::system().name()); - QvCommandArgParser parser; - QString errorMessage; - - switch (parser.ParseCommandLine(&errorMessage)) - { - case CommandLineOk: break; - - case CommandLineError: - std::cout << "Invalid command line arguments" << std::endl; - std::cout << errorMessage.toStdString() << std::endl; - std::cout << parser.Parser()->helpText().toStdString() << std::endl; - break; - - case CommandLineVersionRequested: - LOG("Qv2ray", QV2RAY_VERSION_STRING) - LOG("QV2RAY_BUILD_INFO", QV2RAY_BUILD_INFO) - LOG("QV2RAY_BUILD_EXTRA_INFO", QV2RAY_BUILD_EXTRA_INFO) - return 0; - - case CommandLineHelpRequested: - { - std::cout << parser.Parser()->helpText().toStdString() << std::endl; - return 0; - } - } - } - // - // finished: command line parsing - // - -#ifdef Q_OS_UNIX - // Unix OS root user check. - // Do not use getuid() here since it's installed as owned by the root, - // someone may accidently setuid to it. - if (!StartupOption.forceRunAsRootUser && geteuid() == 0) - { - LOG("ERROR", QObject::tr("You cannot run Qv2ray as root, please use --I-just-wanna-run-with-root if you REALLY want to do so.")) - LOG("ERROR", QObject::tr(" --> USE IT AT YOUR OWN RISK!")) - return 1; - } -#endif - // - // Early initialisation - // noScaleFactors = disable HiDPI - Qv2rayApplication::SetHiDPIEnableState(!StartupOption.noScaleFactors); - // + Qv2rayApplication::PreInitilize(argc, argv); Qv2rayApplication app(argc, argv); if (app.SetupQv2ray()) {