mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 10:50:23 +08:00
refactor: more refactors 2
This commit is contained in:
parent
09ef7cea3a
commit
0289f72ecf
@ -1 +1 @@
|
||||
5584
|
||||
5585
|
||||
|
@ -3,7 +3,14 @@
|
||||
#include "base/Qv2rayBase.hpp"
|
||||
#include "common/QvHelpers.hpp"
|
||||
#include "common/QvTranslator.hpp"
|
||||
#include "core/handler/ConfigHandler.hpp"
|
||||
#include "core/handler/RouteHandler.hpp"
|
||||
#include "core/settings/SettingsBackend.hpp"
|
||||
#include "ui/styles/StyleManager.hpp"
|
||||
#include "ui/windows/w_MainWindow.hpp"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
namespace Qv2ray
|
||||
{
|
||||
@ -47,14 +54,38 @@ namespace Qv2ray
|
||||
{
|
||||
case Qv2rayProcessArguments::EXIT: ExitQv2ray(); break;
|
||||
case Qv2rayProcessArguments::NORMAL:
|
||||
{
|
||||
mainWindow->show();
|
||||
mainWindow->raise();
|
||||
mainWindow->activateWindow();
|
||||
break;
|
||||
}
|
||||
case Qv2rayProcessArguments::RECONNECT:
|
||||
{
|
||||
ConnectionManager->RestartConnection();
|
||||
break;
|
||||
}
|
||||
case Qv2rayProcessArguments::DISCONNECT:
|
||||
case Qv2rayProcessArguments::QV2RAY_LINK: break;
|
||||
{
|
||||
ConnectionManager->StopConnection();
|
||||
break;
|
||||
}
|
||||
case Qv2rayProcessArguments::QV2RAY_LINK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Qv2rayApplication::InitilizeConfigurations()
|
||||
int Qv2rayApplication::RunQv2ray()
|
||||
{
|
||||
// Show MainWindow
|
||||
mainWindow = new MainWindow();
|
||||
return exec();
|
||||
}
|
||||
|
||||
bool Qv2rayApplication::FindAndCreateInitialConfiguration()
|
||||
{
|
||||
if (initilized)
|
||||
{
|
||||
@ -71,7 +102,6 @@ namespace Qv2ray
|
||||
//
|
||||
//
|
||||
// Some built-in search paths for Qv2ray to find configs. (load the first one if possible).
|
||||
//
|
||||
QStringList configFilePaths;
|
||||
const auto useManualConfigPath = qEnvironmentVariableIsSet(QV2RAY_CONFIG_PATH_ENV_NAME);
|
||||
const auto manualConfigPath = qEnvironmentVariable(QV2RAY_CONFIG_PATH_ENV_NAME);
|
||||
@ -199,78 +229,73 @@ namespace Qv2ray
|
||||
QDir().mkdir(QV2RAY_GENERATED_DIR);
|
||||
LOG(MODULE_INIT, "Created config generation dir at: " + QV2RAY_GENERATED_DIR)
|
||||
}
|
||||
|
||||
return true;
|
||||
} // namespace Qv2ray
|
||||
}
|
||||
|
||||
bool Qv2rayApplication::CheckSettingsPathAvailability(const QString &_path, bool checkExistingConfig)
|
||||
bool Qv2rayApplication::LoadConfiguration()
|
||||
{
|
||||
auto path = _path;
|
||||
|
||||
if (!path.endsWith("/"))
|
||||
path.append("/");
|
||||
|
||||
// Does not exist.
|
||||
if (!QDir(path).exists())
|
||||
return false;
|
||||
// Load the config for upgrade, but do not parse it to the struct.
|
||||
auto conf = JsonFromString(StringFromFile(QV2RAY_CONFIG_FILE));
|
||||
const auto configVersion = conf["config_version"].toInt();
|
||||
|
||||
if (configVersion > QV2RAY_CONFIG_VERSION)
|
||||
{
|
||||
// A temp file used to test file permissions in that folder.
|
||||
QFile testFile(path + ".qv2ray_test_file" + QSTRN(QTime::currentTime().msecsSinceStartOfDay()));
|
||||
|
||||
if (!testFile.open(QFile::OpenModeFlag::ReadWrite))
|
||||
{
|
||||
LOG(MODULE_SETTINGS, "Directory at: " + path + " cannot be used as a valid config file path.")
|
||||
LOG(MODULE_SETTINGS, "---> Cannot create a new file or open a file for writing.")
|
||||
return false;
|
||||
}
|
||||
|
||||
testFile.write("Qv2ray test file, feel free to remove.");
|
||||
testFile.flush();
|
||||
testFile.close();
|
||||
|
||||
if (!testFile.remove())
|
||||
{
|
||||
// This is rare, as we can create a file but failed to remove it.
|
||||
LOG(MODULE_SETTINGS, "Directory at: " + path + " cannot be used as a valid config file path.")
|
||||
LOG(MODULE_SETTINGS, "---> Cannot remove a file.")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkExistingConfig)
|
||||
{
|
||||
// Just pass the test
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if an existing config is found.
|
||||
QFile configFile(path + "Qv2ray.conf");
|
||||
|
||||
// No such config file.
|
||||
if (!configFile.exists())
|
||||
return false;
|
||||
|
||||
if (!configFile.open(QIODevice::ReadWrite))
|
||||
{
|
||||
LOG(MODULE_SETTINGS, "File: " + configFile.fileName() + " cannot be opened!")
|
||||
// Config version is larger than the current version...
|
||||
// This is rare but it may happen....
|
||||
QvMessageBoxWarn(nullptr, tr("Qv2ray Cannot Continue"), //
|
||||
tr("You are running a lower version of Qv2ray compared to the current config file.") + NEWLINE + //
|
||||
tr("Please check if there's an issue explaining about it.") + NEWLINE + //
|
||||
tr("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE + //
|
||||
tr("Qv2ray will now exit."));
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto err = VerifyJsonString(StringFromFile(configFile));
|
||||
if (!err.isEmpty())
|
||||
if (configVersion < QV2RAY_CONFIG_VERSION)
|
||||
{
|
||||
LOG(MODULE_INIT, "Json parse returns: " + err)
|
||||
return false;
|
||||
// That is, config file needs to be upgraded.
|
||||
conf = Qv2ray::UpgradeSettingsVersion(configVersion, QV2RAY_CONFIG_VERSION, conf);
|
||||
}
|
||||
|
||||
// If the file format is valid.
|
||||
const auto conf = JsonFromString(StringFromFile(configFile));
|
||||
LOG(MODULE_SETTINGS, "Found a config file, v=" + conf["config_version"].toString() + " path=" + path)
|
||||
configFile.close();
|
||||
// Load config object from upgraded config QJsonObject
|
||||
auto confObject = Qv2rayConfigObject::fromJson(conf);
|
||||
|
||||
if (confObject.uiConfig.language.isEmpty())
|
||||
{
|
||||
// Prevent empty.
|
||||
LOG(MODULE_UI, "Setting default UI language to system locale.")
|
||||
confObject.uiConfig.language = QLocale::system().name();
|
||||
}
|
||||
|
||||
if (!Qv2rayTranslator->InstallTranslation(confObject.uiConfig.language))
|
||||
{
|
||||
QvMessageBoxWarn(nullptr, "Translation Failed",
|
||||
"Cannot load translation for " + confObject.uiConfig.language + NEWLINE + //
|
||||
"English is now used." + NEWLINE + NEWLINE + //
|
||||
"Please go to Preferences Window to change language or open an Issue");
|
||||
}
|
||||
|
||||
// Let's save the config.
|
||||
SaveGlobalSettings(confObject);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Qv2rayApplication::InitilizeGlobalVariables()
|
||||
{
|
||||
StyleManager = new QvStyleManager();
|
||||
PluginHost = new QvPluginHost();
|
||||
RouteManager = new RouteHandler();
|
||||
ConnectionManager = new QvConfigHandler();
|
||||
StyleManager->ApplyStyle(GlobalConfig.uiConfig.theme);
|
||||
}
|
||||
|
||||
void Qv2rayApplication::DeallocateGlobalVariables()
|
||||
{
|
||||
delete ConnectionManager;
|
||||
delete RouteManager;
|
||||
delete PluginHost;
|
||||
delete StyleManager;
|
||||
}
|
||||
|
||||
bool Qv2rayApplication::PreInitilize(int argc, char *argv[])
|
||||
{
|
||||
QString errorMessage;
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include <SingleApplication>
|
||||
|
||||
class MainWindow;
|
||||
|
||||
namespace Qv2ray
|
||||
{
|
||||
struct Qv2rayProcessArguments
|
||||
@ -39,15 +41,18 @@ namespace Qv2ray
|
||||
public:
|
||||
static bool PreInitilize(int argc, char *argv[]);
|
||||
explicit Qv2rayApplication(int &argc, char *argv[]);
|
||||
//
|
||||
bool SetupQv2ray();
|
||||
bool InitilizeConfigurations();
|
||||
bool CheckSettingsPathAvailability(const QString &_path, bool checkExistingConfig);
|
||||
bool FindAndCreateInitialConfiguration();
|
||||
bool LoadConfiguration();
|
||||
void InitilizeGlobalVariables();
|
||||
int RunQv2ray();
|
||||
void DeallocateGlobalVariables();
|
||||
|
||||
private slots:
|
||||
void onMessageReceived(quint32 clientID, QByteArray msg);
|
||||
|
||||
private:
|
||||
MainWindow *mainWindow;
|
||||
static commandline_status ParseCommandLine(QString *errorMessage);
|
||||
bool initilized = false;
|
||||
};
|
||||
|
@ -26,6 +26,74 @@ namespace Qv2ray::core::config
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckSettingsPathAvailability(const QString &_path, bool checkExistingConfig)
|
||||
{
|
||||
auto path = _path;
|
||||
|
||||
if (!path.endsWith("/"))
|
||||
path.append("/");
|
||||
|
||||
// Does not exist.
|
||||
if (!QDir(path).exists())
|
||||
return false;
|
||||
|
||||
{
|
||||
// A temp file used to test file permissions in that folder.
|
||||
QFile testFile(path + ".qv2ray_test_file" + QSTRN(QTime::currentTime().msecsSinceStartOfDay()));
|
||||
|
||||
if (!testFile.open(QFile::OpenModeFlag::ReadWrite))
|
||||
{
|
||||
LOG(MODULE_SETTINGS, "Directory at: " + path + " cannot be used as a valid config file path.")
|
||||
LOG(MODULE_SETTINGS, "---> Cannot create a new file or open a file for writing.")
|
||||
return false;
|
||||
}
|
||||
|
||||
testFile.write("Qv2ray test file, feel free to remove.");
|
||||
testFile.flush();
|
||||
testFile.close();
|
||||
|
||||
if (!testFile.remove())
|
||||
{
|
||||
// This is rare, as we can create a file but failed to remove it.
|
||||
LOG(MODULE_SETTINGS, "Directory at: " + path + " cannot be used as a valid config file path.")
|
||||
LOG(MODULE_SETTINGS, "---> Cannot remove a file.")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkExistingConfig)
|
||||
{
|
||||
// Just pass the test
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if an existing config is found.
|
||||
QFile configFile(path + "Qv2ray.conf");
|
||||
|
||||
// No such config file.
|
||||
if (!configFile.exists())
|
||||
return false;
|
||||
|
||||
if (!configFile.open(QIODevice::ReadWrite))
|
||||
{
|
||||
LOG(MODULE_SETTINGS, "File: " + configFile.fileName() + " cannot be opened!")
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto err = VerifyJsonString(StringFromFile(configFile));
|
||||
if (!err.isEmpty())
|
||||
{
|
||||
LOG(MODULE_INIT, "Json parse returns: " + err)
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the file format is valid.
|
||||
const auto conf = JsonFromString(StringFromFile(configFile));
|
||||
LOG(MODULE_SETTINGS, "Found a config file, v=" + conf["config_version"].toString() + " path=" + path)
|
||||
configFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Qv2ray::core::config
|
||||
|
||||
using namespace Qv2ray::core::config;
|
||||
|
@ -6,6 +6,7 @@ namespace Qv2ray::core::config
|
||||
void SaveGlobalSettings();
|
||||
void SaveGlobalSettings(const Qv2rayConfigObject &conf);
|
||||
void SetConfigDirPath(const QString &path);
|
||||
bool CheckSettingsPathAvailability(const QString &_path, bool checkExistingConfig);
|
||||
} // namespace Qv2ray::core::config
|
||||
|
||||
namespace Qv2ray
|
||||
|
105
src/main.cpp
105
src/main.cpp
@ -1,19 +1,14 @@
|
||||
#include "Qv2rayApplication.hpp"
|
||||
#include "common/QvHelpers.hpp"
|
||||
#include "common/QvTranslator.hpp"
|
||||
#include "components/plugins/QvPluginHost.hpp"
|
||||
#include "core/handler/ConfigHandler.hpp"
|
||||
#include "core/handler/RouteHandler.hpp"
|
||||
#include "core/settings/SettingsBackend.hpp"
|
||||
#include "ui/styles/StyleManager.hpp"
|
||||
#include "ui/windows/w_MainWindow.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QLocale>
|
||||
#include <QObject>
|
||||
#include <QSslSocket>
|
||||
#include <QStandardPaths>
|
||||
#include <QTranslator>
|
||||
#include <csignal>
|
||||
#include <memory>
|
||||
|
||||
@ -82,57 +77,17 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
//
|
||||
// Qv2ray Initialize, find possible config paths and verify them.
|
||||
if (!app.InitilizeConfigurations())
|
||||
if (!app.FindAndCreateInitialConfiguration())
|
||||
{
|
||||
LOG(MODULE_INIT, "Failed to initialise Qv2ray, exiting.")
|
||||
LOG(MODULE_INIT, "Cannot find or create initial configuration file.")
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load the config for upgrade, but do not parse it to the struct.
|
||||
auto conf = JsonFromString(StringFromFile(QV2RAY_CONFIG_FILE));
|
||||
const auto configVersion = conf["config_version"].toInt();
|
||||
|
||||
if (configVersion > QV2RAY_CONFIG_VERSION)
|
||||
if (!app.LoadConfiguration())
|
||||
{
|
||||
// Config version is larger than the current version...
|
||||
// This is rare but it may happen....
|
||||
QvMessageBoxWarn(nullptr, QObject::tr("Qv2ray Cannot Continue"),
|
||||
QObject::tr("You are running a lower version of Qv2ray compared to the current config file.") + NEWLINE +
|
||||
QObject::tr("Please check if there's an issue explaining about it.") + NEWLINE +
|
||||
QObject::tr("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE +
|
||||
QObject::tr("Qv2ray will now exit."));
|
||||
LOG(MODULE_INIT, "Cannot load existing configuration file.")
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (configVersion < QV2RAY_CONFIG_VERSION)
|
||||
{
|
||||
// That is, config file needs to be upgraded.
|
||||
conf = Qv2ray::UpgradeSettingsVersion(configVersion, QV2RAY_CONFIG_VERSION, conf);
|
||||
}
|
||||
|
||||
{
|
||||
// Load config object from upgraded config QJsonObject
|
||||
auto confObject = Qv2rayConfigObject::fromJson(conf);
|
||||
|
||||
if (confObject.uiConfig.language.isEmpty())
|
||||
{
|
||||
// Prevent empty.
|
||||
LOG(MODULE_UI, "Setting default UI language to system locale.")
|
||||
confObject.uiConfig.language = QLocale::system().name();
|
||||
}
|
||||
|
||||
if (!Qv2rayTranslator->InstallTranslation(confObject.uiConfig.language))
|
||||
{
|
||||
QvMessageBoxWarn(nullptr, "Translation Failed",
|
||||
"Cannot load translation for " + confObject.uiConfig.language + NEWLINE + //
|
||||
"English is now used." + NEWLINE + NEWLINE + //
|
||||
"Please go to Preferences Window to change language or open an Issue");
|
||||
}
|
||||
|
||||
// Let's save the config.
|
||||
SaveGlobalSettings(confObject);
|
||||
}
|
||||
//
|
||||
// Check OpenSSL version for auto-update and subscriptions
|
||||
auto osslReqVersion = QSslSocket::sslLibraryBuildVersionString();
|
||||
auto osslCurVersion = QSslSocket::sslLibraryVersionString();
|
||||
@ -151,6 +106,8 @@ int main(int argc, char *argv[])
|
||||
return -3;
|
||||
}
|
||||
|
||||
app.InitilizeGlobalVariables();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Set special font in Windows
|
||||
QFont font;
|
||||
@ -158,48 +115,20 @@ int main(int argc, char *argv[])
|
||||
font.setFamily("Microsoft YaHei");
|
||||
app.setFont(font);
|
||||
#endif
|
||||
StyleManager = new QvStyleManager(qvApp);
|
||||
StyleManager->ApplyStyle(GlobalConfig.uiConfig.theme);
|
||||
|
||||
try
|
||||
{
|
||||
// Initialise Connection Handler
|
||||
PluginHost = new QvPluginHost();
|
||||
ConnectionManager = new QvConfigHandler();
|
||||
RouteManager = new RouteHandler();
|
||||
#ifndef Q_OS_WIN
|
||||
signal(SIGUSR1, [](int) { ConnectionManager->RestartConnection(); });
|
||||
signal(SIGUSR2, [](int) { ConnectionManager->StopConnection(); });
|
||||
signal(SIGUSR1, [](int) { ConnectionManager->RestartConnection(); });
|
||||
signal(SIGUSR2, [](int) { ConnectionManager->StopConnection(); });
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
qvApp->setFallbackSessionManagementEnabled(false);
|
||||
QObject::connect(qvApp, &QGuiApplication::commitDataRequest, [] {
|
||||
ConnectionManager->SaveConnectionConfig();
|
||||
LOG(MODULE_INIT, "Quit triggered by session manager.")
|
||||
});
|
||||
qvApp->setFallbackSessionManagementEnabled(false);
|
||||
QObject::connect(qvApp, &QGuiApplication::commitDataRequest, [] {
|
||||
ConnectionManager->SaveConnectionConfig();
|
||||
LOG(MODULE_INIT, "Quit triggered by session manager.")
|
||||
});
|
||||
#endif
|
||||
|
||||
// Show MainWindow
|
||||
MainWindow w;
|
||||
QObject::connect(qvApp, &SingleApplication::receivedMessage, [&](quint32, QByteArray) {
|
||||
// When a second instance is connected, show the mainwindow.
|
||||
w.show();
|
||||
w.raise();
|
||||
w.activateWindow();
|
||||
});
|
||||
|
||||
auto rcode = app.exec();
|
||||
delete ConnectionManager;
|
||||
delete RouteManager;
|
||||
delete PluginHost;
|
||||
LOG(MODULE_INIT, "Quitting normally")
|
||||
return rcode;
|
||||
}
|
||||
catch (std::exception e)
|
||||
{
|
||||
QvMessageBoxWarn(nullptr, "ERROR", "There's something wrong happened and Qv2ray will quit now.");
|
||||
LOG(MODULE_INIT, "EXCEPTION THROWN: " + QString(e.what()))
|
||||
return -99;
|
||||
}
|
||||
auto rcode = app.RunQv2ray();
|
||||
app.DeallocateGlobalVariables();
|
||||
return rcode;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ class MainWindow
|
||||
void StartConnection() const;
|
||||
void StopConnection() const;
|
||||
void RestartConnection() const;
|
||||
void ProcessCommand(const QStringList &command, const QMap<QString, QString> &args);
|
||||
|
||||
private:
|
||||
QvMessageBusSlotDecl;
|
||||
|
Loading…
Reference in New Issue
Block a user