mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-24 02:00:24 +07:00
feature: added a ui with the feature to configure goodbye dpi
- added configuration file selection - added modset selection
This commit is contained in:
+10
-4
@@ -236,8 +236,14 @@ file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/services/*.cpp
|
||||
)
|
||||
|
||||
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.h)
|
||||
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.cpp)
|
||||
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/localServices/*.h
|
||||
)
|
||||
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/localServices/*.cpp
|
||||
)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${COMMON_FILES_H}
|
||||
@@ -261,13 +267,13 @@ if(WIN32)
|
||||
)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/goodbyedpi.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/localServices/goodByeDpi.h
|
||||
)
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/goodbyedpi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/localServices/goodByeDpi.cpp
|
||||
)
|
||||
|
||||
set(RESOURCES ${RESOURCES}
|
||||
|
||||
@@ -235,6 +235,7 @@ void AmneziaApplication::registerTypes()
|
||||
|
||||
Vpn::declareQmlVpnConnectionStateEnum();
|
||||
PageLoader::declareQmlPageEnum();
|
||||
PageLoader::declareQmlFolderEnum();
|
||||
}
|
||||
|
||||
void AmneziaApplication::loadFonts()
|
||||
@@ -455,4 +456,13 @@ void AmneziaApplication::initControllers()
|
||||
|
||||
m_systemController.reset(new SystemController(m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
||||
|
||||
m_localServicesController.reset(new LocalServicesController(m_serversModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("LocalServicesController", m_localServicesController.get());
|
||||
connect(m_connectionController.get(), &ConnectionController::startLocalService, m_localServicesController.get(),
|
||||
&LocalServicesController::start);
|
||||
connect(m_connectionController.get(), &ConnectionController::stopLocalService, m_localServicesController.get(),
|
||||
&LocalServicesController::stop);
|
||||
connect(m_localServicesController.get(), &LocalServicesController::serviceStateChanged, m_connectionController.get(),
|
||||
&ConnectionController::connectionStateChanged);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ui/controllers/sitesController.h"
|
||||
#include "ui/controllers/systemController.h"
|
||||
#include "ui/controllers/appSplitTunnelingController.h"
|
||||
#include "ui/controllers/localServicesController.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/languageModel.h"
|
||||
#include "ui/models/protocols/cloakConfigModel.h"
|
||||
@@ -136,6 +137,7 @@ private:
|
||||
QScopedPointer<SitesController> m_sitesController;
|
||||
QScopedPointer<SystemController> m_systemController;
|
||||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||
QScopedPointer<LocalServicesController> m_localServicesController;
|
||||
|
||||
QNetworkAccessManager *m_nam;
|
||||
|
||||
|
||||
@@ -53,8 +53,6 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
|
||||
switch (container) {
|
||||
case DockerContainer::None: return {};
|
||||
|
||||
case DockerContainer::GoodbyeDPI: return { Proto::GoodyeDPI };
|
||||
|
||||
case DockerContainer::OpenVpn: return { Proto::OpenVpn };
|
||||
|
||||
case DockerContainer::ShadowSocks: return { Proto::OpenVpn, Proto::ShadowSocks };
|
||||
@@ -99,7 +97,6 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
||||
{ DockerContainer::Xray, "XRay" },
|
||||
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
||||
{ DockerContainer::SSXray, "Shadowsocks"},
|
||||
{ DockerContainer::GoodbyeDPI, "GoodbyeDPI"},
|
||||
|
||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
|
||||
@@ -139,9 +136,7 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
|
||||
{ DockerContainer::Sftp,
|
||||
QObject::tr("Create a file vault on your server to securely store and transfer files.") },
|
||||
{ DockerContainer::Socks5Proxy,
|
||||
QObject::tr("") } ,
|
||||
{ DockerContainer::GoodbyeDPI,
|
||||
QObject::tr("GoodbyeDPI — Deep Packet Inspection circumvention utility") }};
|
||||
QObject::tr("") } };
|
||||
}
|
||||
|
||||
QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||
@@ -250,10 +245,7 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||
"You will be able to access it using\n FileZilla or other SFTP clients, "
|
||||
"as well as mount the disk on your device to access\n it directly from your device.\n\n"
|
||||
"For more detailed information, you can\n find it in the support section under \"Create SFTP file storage.\" ") },
|
||||
{ DockerContainer::Socks5Proxy, QObject::tr("SOCKS5 proxy server") },
|
||||
{ DockerContainer::GoodbyeDPI, QObject::tr("This software designed to bypass Deep Packet Inspection systems found in many Internet Service Providers which block access to certain websites. \n"
|
||||
"It handles DPI connected using optical splitter or port mirroring (Passive DPI) which do not block any data but just replying faster than requested destination,"
|
||||
"and Active DPI connected in sequence.") }
|
||||
{ DockerContainer::Socks5Proxy, QObject::tr("SOCKS5 proxy server") } }
|
||||
|
||||
};
|
||||
}
|
||||
@@ -280,7 +272,6 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
|
||||
case DockerContainer::Dns: return Proto::Dns;
|
||||
case DockerContainer::Sftp: return Proto::Sftp;
|
||||
case DockerContainer::Socks5Proxy: return Proto::Socks5Proxy;
|
||||
case DockerContainer::GoodbyeDPI: return Proto::GoodyeDPI;
|
||||
default: return Proto::Any;
|
||||
}
|
||||
}
|
||||
@@ -387,7 +378,6 @@ bool ContainerProps::isShareable(DockerContainer container)
|
||||
case DockerContainer::Dns: return false;
|
||||
case DockerContainer::Sftp: return false;
|
||||
case DockerContainer::Socks5Proxy: return false;
|
||||
case DockerContainer::GoodbyeDPI: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
@@ -413,7 +403,6 @@ int ContainerProps::installPageOrder(DockerContainer container)
|
||||
case DockerContainer::Xray: return 3;
|
||||
case DockerContainer::Ipsec: return 7;
|
||||
case DockerContainer::SSXray: return 8;
|
||||
case DockerContainer::GoodbyeDPI: return 9;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace amnezia
|
||||
Ipsec,
|
||||
Xray,
|
||||
SSXray,
|
||||
GoodbyeDPI,
|
||||
|
||||
// non-vpn
|
||||
TorWebSite,
|
||||
|
||||
@@ -34,8 +34,7 @@ ErrorCode VpnConfigurationsController::createProtocolConfigForContainer(const Se
|
||||
{
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other ||
|
||||
container == DockerContainer::GoodbyeDPI) {
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -62,8 +61,7 @@ ErrorCode VpnConfigurationsController::createProtocolConfigString(const bool isA
|
||||
{
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other ||
|
||||
container == DockerContainer::GoodbyeDPI) {
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -84,8 +82,7 @@ QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QStr
|
||||
{
|
||||
QJsonObject vpnConfiguration {};
|
||||
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other ||
|
||||
container == DockerContainer::GoodbyeDPI) {
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
return vpnConfiguration;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ QString errorString(ErrorCode code) {
|
||||
case (ErrorCode::CloakExecutableMissing): errorMessage = QObject::tr("Cloak (ck-client) executable missing"); break;
|
||||
case (ErrorCode::AmneziaServiceConnectionFailed): errorMessage = QObject::tr("Amnezia helper service error"); break;
|
||||
case (ErrorCode::OpenSslFailed): errorMessage = QObject::tr("OpenSSL failed"); break;
|
||||
case (ErrorCode::GoodByeDPIExecutableMissing): errorMessage = QObject::tr("GoodbyeDPI executable missing"); break;
|
||||
|
||||
// VPN errors
|
||||
case (ErrorCode::OpenVpnAdaptersInUseError): errorMessage = QObject::tr("Can't connect: another VPN connection is active"); break;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "goodByeDpi.h"
|
||||
|
||||
#include "core/ipcclient.h"
|
||||
#include "utilities.h"
|
||||
|
||||
GoodByeDpi::GoodByeDpi(QObject *parent) : QObject { parent }
|
||||
{
|
||||
}
|
||||
|
||||
amnezia::ErrorCode GoodByeDpi::start(const QString &blackListFile, const int modset)
|
||||
{
|
||||
if (!QFileInfo::exists(Utils::goodbyedpiPath())) {
|
||||
return amnezia::ErrorCode::GoodByeDPIExecutableMissing;
|
||||
}
|
||||
|
||||
m_goodbyeDPIProcess = IpcClient::CreatePrivilegedProcess();
|
||||
|
||||
if (!m_goodbyeDPIProcess) {
|
||||
return amnezia::ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
|
||||
m_goodbyeDPIProcess->waitForSource(1000);
|
||||
if (!m_goodbyeDPIProcess->isInitialized()) {
|
||||
qWarning() << "IpcProcess replica is not connected!";
|
||||
return amnezia::ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
|
||||
m_goodbyeDPIProcess->setProgram(amnezia::PermittedProcess::GoodbyeDPI);
|
||||
|
||||
QStringList arguments;
|
||||
arguments << QString("-%1").arg(modset);
|
||||
arguments << QString("--blacklist %1").arg(blackListFile);
|
||||
|
||||
m_goodbyeDPIProcess->setArguments(arguments);
|
||||
qDebug() << arguments.join(" ");
|
||||
|
||||
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::errorOccurred,
|
||||
[&](QProcess::ProcessError error) { qDebug() << "PrivilegedProcess errorOccurred" << error; });
|
||||
|
||||
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::stateChanged, [&](QProcess::ProcessState newState) {
|
||||
qDebug() << "PrivilegedProcess stateChanged" << newState;
|
||||
if (newState == QProcess::Running) {
|
||||
qDebug() << "PrivilegedProcess running";
|
||||
emit serviceStateChanged(Vpn::ConnectionState::Connected);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::finished, this, [&]() {
|
||||
qDebug() << "PrivilegedProcess finished";
|
||||
emit serviceStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
|
||||
m_goodbyeDPIProcess->start();
|
||||
return amnezia::ErrorCode::NoError;
|
||||
}
|
||||
|
||||
void GoodByeDpi::stop()
|
||||
{
|
||||
if (m_goodbyeDPIProcess) {
|
||||
m_goodbyeDPIProcess->close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef GOODBYEDPI_H
|
||||
#define GOODBYEDPI_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "core/defs.h"
|
||||
#include "core/privileged_process.h"
|
||||
#include "protocols/vpnprotocol.h"
|
||||
|
||||
class GoodByeDpi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GoodByeDpi(QObject *parent = nullptr);
|
||||
|
||||
amnezia::ErrorCode start(const QString &blackListFile, const int modset);
|
||||
void stop();
|
||||
|
||||
private:
|
||||
QSharedPointer<PrivilegedProcess> m_goodbyeDPIProcess;
|
||||
signals:
|
||||
void serviceStateChanged(Vpn::ConnectionState state);
|
||||
};
|
||||
|
||||
#endif // GOODBYEDPI_H
|
||||
@@ -1,85 +0,0 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "logger.h"
|
||||
#include "goodbyedpi.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
||||
GoodbyeDPIProtocol::GoodbyeDPIProtocol(const QJsonObject &configuration, QObject* parent) :
|
||||
VpnProtocol(configuration, parent)
|
||||
{
|
||||
qDebug() << "GoodbyeDPIProtocol::GoodbyeDPIProtocol()";
|
||||
}
|
||||
|
||||
GoodbyeDPIProtocol::~GoodbyeDPIProtocol()
|
||||
{
|
||||
qDebug() << "GoodbyeDPIProtocol::~GoodbyeDPIProtocol()";
|
||||
GoodbyeDPIProtocol::stop();
|
||||
}
|
||||
|
||||
void GoodbyeDPIProtocol::stop()
|
||||
{
|
||||
if (m_goodbyeDPIProcess) {
|
||||
m_goodbyeDPIProcess->close();
|
||||
}
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
}
|
||||
|
||||
ErrorCode GoodbyeDPIProtocol::start()
|
||||
{
|
||||
qDebug() << "GoodbyeDPIProtocol::start()";
|
||||
|
||||
if (!QFileInfo::exists(Utils::goodbyedpiPath())) {
|
||||
setLastError(ErrorCode::GoodByeDPIExecutableMissing);
|
||||
return lastError();
|
||||
}
|
||||
|
||||
m_goodbyeDPIProcess = IpcClient::CreatePrivilegedProcess();
|
||||
|
||||
if (!m_goodbyeDPIProcess) {
|
||||
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
|
||||
m_goodbyeDPIProcess->waitForSource(1000);
|
||||
if (!m_goodbyeDPIProcess->isInitialized()) {
|
||||
qWarning() << "IpcProcess replica is not connected!";
|
||||
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
|
||||
m_goodbyeDPIProcess->setProgram(PermittedProcess::GoodbyeDPI);
|
||||
|
||||
QStringList arguments({"-9", "--blacklist", QCoreApplication::applicationDirPath() + "/goodbyedpi/russia-blacklist.txt",
|
||||
"--blacklist", QCoreApplication::applicationDirPath() + "/goodbyedpi/russia-youtube.txt"});
|
||||
|
||||
m_goodbyeDPIProcess->setArguments(arguments);
|
||||
qDebug() << arguments.join(" ");
|
||||
|
||||
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::errorOccurred,
|
||||
[&](QProcess::ProcessError error) { qDebug() << "PrivilegedProcess errorOccurred" << error; });
|
||||
|
||||
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::stateChanged,
|
||||
[&](QProcess::ProcessState newState) {
|
||||
qDebug() << "PrivilegedProcess stateChanged" << newState;
|
||||
if (newState == QProcess::Running)
|
||||
{
|
||||
setConnectionState(Vpn::ConnectionState::Connected);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::finished, this,
|
||||
[&]() {
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
|
||||
|
||||
m_goodbyeDPIProcess->start();
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef GOODBYEDPI_H
|
||||
#define GOODBYEDPI_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTimer>
|
||||
|
||||
#include "vpnprotocol.h"
|
||||
#include "core/ipcclient.h"
|
||||
|
||||
class GoodbyeDPIProtocol : public VpnProtocol
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GoodbyeDPIProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||
virtual ~GoodbyeDPIProtocol() override;
|
||||
|
||||
ErrorCode start() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
QSharedPointer<PrivilegedProcess> m_goodbyeDPIProcess;
|
||||
};
|
||||
|
||||
#endif // GOODBYEDPI_H
|
||||
@@ -75,7 +75,6 @@ QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
||||
{ Proto::SSXray, "Shadowsocks"},
|
||||
|
||||
|
||||
{ Proto::GoodyeDPI, "GoodbyeDPI"},
|
||||
{ Proto::TorWebSite, "Website in Tor network" },
|
||||
{ Proto::Dns, "DNS Service" },
|
||||
{ Proto::Sftp, QObject::tr("SFTP service") },
|
||||
@@ -100,7 +99,6 @@ amnezia::ServiceType ProtocolProps::protocolService(Proto p)
|
||||
case Proto::Awg: return ServiceType::Vpn;
|
||||
case Proto::Ikev2: return ServiceType::Vpn;
|
||||
case Proto::Xray: return ServiceType::Vpn;
|
||||
case Proto::GoodyeDPI: return ServiceType::Vpn;
|
||||
|
||||
case Proto::TorWebSite: return ServiceType::Other;
|
||||
case Proto::Dns: return ServiceType::Other;
|
||||
|
||||
@@ -100,6 +100,8 @@ namespace amnezia
|
||||
|
||||
constexpr char clientId[] = "clientId";
|
||||
|
||||
constexpr char isGoodbyeDpi[] = "is_goodbye_dpi";
|
||||
|
||||
}
|
||||
|
||||
namespace protocols
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include "ikev2_vpn_protocol_windows.h"
|
||||
#include "goodbyedpi.h"
|
||||
#endif
|
||||
|
||||
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
|
||||
@@ -109,7 +108,6 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
||||
switch (container) {
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
||||
case DockerContainer::GoodbyeDPI: return new GoodbyeDPIProtocol(configuration);
|
||||
#endif
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
<file>ui/qml/Pages2/PageSettingsApiLanguageList.qml</file>
|
||||
<file>images/controls/archive-restore.svg</file>
|
||||
<file>images/controls/help-circle.svg</file>
|
||||
<file>ui/qml/Pages2/LocalServices/PageGoodByeDpiSettings.qml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/countriesFlags">
|
||||
<file>images/flagKit/ZW.svg</file>
|
||||
|
||||
@@ -523,3 +523,33 @@ QString Settings::getGatewayEndpoint()
|
||||
{
|
||||
return m_gatewayEndpoint;
|
||||
}
|
||||
|
||||
void Settings::setGoodbyeDpiBlackListFile(const QString &file)
|
||||
{
|
||||
setValue("Conf/goodbyeDpiBlackListFile", file);
|
||||
}
|
||||
|
||||
QString Settings::getGoodbyeDpiBlackListFile() const
|
||||
{
|
||||
return value("Conf/goodbyeDpiBlackListFile").toString();
|
||||
}
|
||||
|
||||
void Settings::toggleGoodbyeDpi(bool enable)
|
||||
{
|
||||
setValue("Conf/isGoodbyeDpiEnabled", enable);
|
||||
}
|
||||
|
||||
bool Settings::isGoodbyeDpiEnabled() const
|
||||
{
|
||||
return value("Conf/isGoodbyeDpiEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setGoodbyeDpiModset(const int modset)
|
||||
{
|
||||
setValue("Conf/goodbyeDpiModset", modset);
|
||||
}
|
||||
|
||||
int Settings::getGoodbyeDpiModset() const
|
||||
{
|
||||
return value("Conf/goodbyeDpiModset", 9).toInt();
|
||||
}
|
||||
|
||||
+13
-1
@@ -113,7 +113,10 @@ public:
|
||||
QString routeModeString(RouteMode mode) const;
|
||||
|
||||
RouteMode routeMode() const;
|
||||
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
|
||||
void setRouteMode(RouteMode mode)
|
||||
{
|
||||
setValue("Conf/routeMode", mode);
|
||||
}
|
||||
|
||||
bool isSitesSplitTunnelingEnabled() const;
|
||||
void setSitesSplitTunnelingEnabled(bool enabled);
|
||||
@@ -219,6 +222,15 @@ public:
|
||||
void setGatewayEndpoint(const QString &endpoint);
|
||||
QString getGatewayEndpoint();
|
||||
|
||||
void setGoodbyeDpiBlackListFile(const QString &file);
|
||||
QString getGoodbyeDpiBlackListFile() const;
|
||||
|
||||
void toggleGoodbyeDpi(bool enable);
|
||||
bool isGoodbyeDpiEnabled() const;
|
||||
|
||||
void setGoodbyeDpiModset(const int modset);
|
||||
int getGoodbyeDpiModset() const;
|
||||
|
||||
signals:
|
||||
void saveLogsChanged(bool enabled);
|
||||
void screenshotsEnabledChanged(bool enabled);
|
||||
|
||||
@@ -44,6 +44,13 @@ void ConnectionController::openConnection()
|
||||
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
|
||||
const auto isGoodbyeDpi = serverConfig.value(config_key::isGoodbyeDpi).toBool(false);
|
||||
if (isGoodbyeDpi) {
|
||||
emit startLocalService();
|
||||
return;
|
||||
}
|
||||
|
||||
auto configVersion = serverConfig.value(config_key::configVersion).toInt();
|
||||
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
||||
@@ -65,6 +72,15 @@ void ConnectionController::openConnection()
|
||||
|
||||
void ConnectionController::closeConnection()
|
||||
{
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
|
||||
const auto isGoodbyeDpi = serverConfig.value(config_key::isGoodbyeDpi).toBool(false);
|
||||
if (isGoodbyeDpi) {
|
||||
emit stopLocalService();
|
||||
return;
|
||||
}
|
||||
|
||||
emit disconnectFromVpn();
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ signals:
|
||||
void updateApiConfigFromTelegram();
|
||||
void configFromApiUpdated();
|
||||
|
||||
void startLocalService();
|
||||
void stopLocalService();
|
||||
|
||||
private:
|
||||
Vpn::ConnectionState getCurrentConnectionState();
|
||||
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "localServicesController.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Logger logger("ServerController");
|
||||
}
|
||||
|
||||
LocalServicesController::LocalServicesController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
||||
{
|
||||
connect(&m_goodbyeDpiService, &GoodByeDpi::serviceStateChanged, this, &LocalServicesController::serviceStateChanged);
|
||||
}
|
||||
|
||||
LocalServicesController::~LocalServicesController()
|
||||
{
|
||||
m_goodbyeDpiService.stop();
|
||||
}
|
||||
|
||||
void LocalServicesController::toggleGoodbyeDpi(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
// auto file = getGoodbyeDpiBlackListFile();
|
||||
// auto modset = getGoodbyeDpiModset();
|
||||
// auto errorCode = ErrorCode::NoError;//m_goodbyeDpiService.start(file, modset);
|
||||
// if (errorCode != ErrorCode::NoError) {
|
||||
// emit errorOccurred(errorCode);
|
||||
// } else {
|
||||
|
||||
QJsonObject server;
|
||||
server.insert(config_key::isGoodbyeDpi, true);
|
||||
server.insert(config_key::description, "GoodbyeDPI service");
|
||||
server.insert(config_key::name, "GoodbyeDPI");
|
||||
m_serversModel->addServer(server);
|
||||
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
|
||||
|
||||
m_settings->toggleGoodbyeDpi(true);
|
||||
emit toggleGoodbyeDpiFinished(tr("GoodbyeDPI added to home page"));
|
||||
// }
|
||||
} else {
|
||||
// m_goodbyeDpiService.stop();
|
||||
|
||||
for (int i = 0; i < m_serversModel->getServersCount(); i++) {
|
||||
if (m_serversModel->getServerConfig(i).value(config_key::isGoodbyeDpi).toBool(false)) {
|
||||
m_serversModel->setProcessedServerIndex(i);
|
||||
m_serversModel->removeServer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_settings->toggleGoodbyeDpi(false);
|
||||
emit toggleGoodbyeDpiFinished("GoodbyeDPI removed from home page");
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalServicesController::isGoodbyeDpiEnabled()
|
||||
{
|
||||
return m_settings->isGoodbyeDpiEnabled();
|
||||
}
|
||||
|
||||
void LocalServicesController::setGoodbyeDpiBlackListFile(const QString &file)
|
||||
{
|
||||
m_settings->setGoodbyeDpiBlackListFile(file);
|
||||
}
|
||||
|
||||
QString LocalServicesController::getGoodbyeDpiBlackListFile()
|
||||
{
|
||||
auto file = m_settings->getGoodbyeDpiBlackListFile();
|
||||
if (file.isEmpty()) {
|
||||
return m_defaultBlackListFile;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
void LocalServicesController::resetGoodbyeDpiBlackListFile()
|
||||
{
|
||||
m_settings->setGoodbyeDpiBlackListFile(m_defaultBlackListFile);
|
||||
}
|
||||
|
||||
void LocalServicesController::setGoodbyeDpiModset(const int modset)
|
||||
{
|
||||
m_settings->setGoodbyeDpiModset(modset);
|
||||
}
|
||||
|
||||
int LocalServicesController::getGoodbyeDpiModset()
|
||||
{
|
||||
return m_settings->getGoodbyeDpiModset();
|
||||
}
|
||||
|
||||
void LocalServicesController::start()
|
||||
{
|
||||
auto errorCode = m_goodbyeDpiService.start(getGoodbyeDpiBlackListFile(), getGoodbyeDpiModset());
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalServicesController::stop()
|
||||
{
|
||||
m_goodbyeDpiService.stop();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef LOCALSERVICESCONTROLLER_H
|
||||
#define LOCALSERVICESCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "localServices/goodByeDpi.h"
|
||||
#include "protocols/vpnprotocol.h"
|
||||
#include "settings.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
class LocalServicesController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LocalServicesController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent = nullptr);
|
||||
~LocalServicesController();
|
||||
|
||||
Q_PROPERTY(bool isGoodbyeDpiEnabled READ isGoodbyeDpiEnabled NOTIFY toggleGoodbyeDpiFinished)
|
||||
|
||||
public slots:
|
||||
void toggleGoodbyeDpi(bool enable);
|
||||
bool isGoodbyeDpiEnabled();
|
||||
|
||||
void setGoodbyeDpiBlackListFile(const QString &file);
|
||||
QString getGoodbyeDpiBlackListFile();
|
||||
void resetGoodbyeDpiBlackListFile();
|
||||
|
||||
void setGoodbyeDpiModset(const int modset);
|
||||
int getGoodbyeDpiModset();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
signals:
|
||||
void errorOccurred(ErrorCode errorCode);
|
||||
void toggleGoodbyeDpiFinished(const QString &message);
|
||||
void serviceStateChanged(Vpn::ConnectionState state);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
|
||||
GoodByeDpi m_goodbyeDpiService;
|
||||
bool m_isGoodbyeDpiServiceEnabled = false;
|
||||
QString m_defaultBlackListFile = QCoreApplication::applicationDirPath() + "/goodbyedpi/blacklist.txt";
|
||||
};
|
||||
|
||||
#endif // LOCALSERVICESCONTROLLER_H
|
||||
@@ -59,11 +59,19 @@ bool PageController::isStartPageVisible()
|
||||
}
|
||||
}
|
||||
|
||||
QString PageController::getPagePath(PageLoader::PageEnum page)
|
||||
QString PageController::getPagePath(PageLoader::PageEnum page, PageLoader::FolderEnum folder)
|
||||
{
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<PageLoader::PageEnum>();
|
||||
QString pageName = metaEnum.valueToKey(static_cast<int>(page));
|
||||
return "qrc:/ui/qml/Pages2/" + pageName + ".qml";
|
||||
|
||||
metaEnum = QMetaEnum::fromType<PageLoader::FolderEnum>();
|
||||
QString folderName = "";
|
||||
if (metaEnum.value(static_cast<int>(folder)) != static_cast<int>(PageLoader::FolderEnum::Root)) {
|
||||
folderName = metaEnum.valueToKey(static_cast<int>(folder));
|
||||
folderName += "/";
|
||||
}
|
||||
|
||||
return "qrc:/ui/qml/Pages2/" + folderName + pageName + ".qml";
|
||||
}
|
||||
|
||||
void PageController::closeWindow()
|
||||
|
||||
@@ -61,7 +61,9 @@ namespace PageLoader
|
||||
|
||||
PageShareFullAccess,
|
||||
|
||||
PageDevMenu
|
||||
PageDevMenu,
|
||||
|
||||
PageGoodByeDpiSettings
|
||||
};
|
||||
Q_ENUM_NS(PageEnum)
|
||||
|
||||
@@ -69,6 +71,19 @@ namespace PageLoader
|
||||
{
|
||||
qmlRegisterUncreatableMetaObject(PageLoader::staticMetaObject, "PageEnum", 1, 0, "PageEnum", "Error: only enums");
|
||||
}
|
||||
|
||||
Q_NAMESPACE
|
||||
enum class FolderEnum {
|
||||
Root = 0,
|
||||
LocalServices
|
||||
|
||||
};
|
||||
Q_ENUM_NS(FolderEnum)
|
||||
|
||||
static void declareQmlFolderEnum()
|
||||
{
|
||||
qmlRegisterUncreatableMetaObject(PageLoader::staticMetaObject, "FolderEnum", 1, 0, "FolderEnum", "Error: only enums");
|
||||
}
|
||||
}
|
||||
|
||||
class PageController : public QObject
|
||||
@@ -80,7 +95,7 @@ public:
|
||||
|
||||
public slots:
|
||||
bool isStartPageVisible();
|
||||
QString getPagePath(PageLoader::PageEnum page);
|
||||
QString getPagePath(PageLoader::PageEnum page, PageLoader::FolderEnum folder = PageLoader::FolderEnum::Root);
|
||||
|
||||
void closeWindow();
|
||||
void hideWindow();
|
||||
@@ -103,7 +118,7 @@ public slots:
|
||||
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
||||
|
||||
signals:
|
||||
void goToPage(PageLoader::PageEnum page, bool slide = true);
|
||||
void goToPage(PageLoader::PageEnum page, PageLoader::FolderEnum folder = PageLoader::FolderEnum::Root, bool slide = true);
|
||||
void goToStartPage();
|
||||
void goToPageHome();
|
||||
void goToPageSettings();
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
SettingsController::SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<LanguageModel> &languageModel,
|
||||
const QSharedPointer<SitesModel> &sitesModel,
|
||||
const QSharedPointer<LanguageModel> &languageModel, const QSharedPointer<SitesModel> &sitesModel,
|
||||
const QSharedPointer<AppSplitTunnelingModel> &appSplitTunnelingModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
: QObject(parent),
|
||||
@@ -31,7 +30,8 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
|
||||
m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH);
|
||||
checkIfNeedDisableLogs();
|
||||
#ifdef Q_OS_ANDROID
|
||||
connect(AndroidController::instance(), &AndroidController::notificationStateChanged, this, &SettingsController::onNotificationStateChanged);
|
||||
connect(AndroidController::instance(), &AndroidController::notificationStateChanged, this,
|
||||
&SettingsController::onNotificationStateChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -131,8 +131,7 @@ void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||
bool ok = m_settings->restoreAppConfig(data);
|
||||
if (ok) {
|
||||
m_serversModel->resetModel();
|
||||
m_languageModel->changeLanguage(
|
||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
m_languageModel->changeLanguage(static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
emit restoreBackupFinished();
|
||||
} else {
|
||||
emit changeSettingsErrorOccurred(tr("Backup file is corrupted"));
|
||||
@@ -148,8 +147,7 @@ void SettingsController::clearSettings()
|
||||
{
|
||||
m_settings->clearSettings();
|
||||
m_serversModel->resetModel();
|
||||
m_languageModel->changeLanguage(
|
||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
m_languageModel->changeLanguage(static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
|
||||
m_sitesModel->setRouteMode(Settings::RouteMode::VpnOnlyForwardSites);
|
||||
m_sitesModel->toggleSplitTunneling(false);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/sites_model.h"
|
||||
#include "ui/models/appSplitTunnelingModel.h"
|
||||
#include "localServices/goodByeDpi.h"
|
||||
|
||||
class SettingsController : public QObject
|
||||
{
|
||||
@@ -112,6 +113,8 @@ private:
|
||||
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
GoodByeDpi m_goodbyeDpiService;
|
||||
|
||||
QString m_appVersion;
|
||||
|
||||
QDateTime m_loggingDisableDate;
|
||||
|
||||
@@ -37,13 +37,7 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
|
||||
case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container);
|
||||
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
|
||||
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
|
||||
case IsInstalledRole: {
|
||||
#ifdef Q_OS_WIN
|
||||
if (container == DockerContainer::GoodbyeDPI)
|
||||
return true;
|
||||
#endif
|
||||
return m_containers.contains(container);
|
||||
}
|
||||
case IsInstalledRole: return m_containers.contains(container);
|
||||
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
|
||||
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
|
||||
case IsShareableRole: return ContainerProps::isShareable(container);
|
||||
|
||||
@@ -88,9 +88,10 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
const QJsonObject server = m_servers.at(index.row()).toObject();
|
||||
const auto apiConfig = server.value(configKey::apiConfig).toObject();
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
const auto isGoodbyeDpi = server.value(config_key::isGoodbyeDpi).toBool(false);
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
if (configVersion) {
|
||||
if (configVersion || isGoodbyeDpi) {
|
||||
return server.value(config_key::name).toString();
|
||||
}
|
||||
auto name = server.value(config_key::description).toString();
|
||||
@@ -100,6 +101,10 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
return name;
|
||||
}
|
||||
case ServerDescriptionRole: {
|
||||
if (isGoodbyeDpi) {
|
||||
return server.value(config_key::description).toString();
|
||||
}
|
||||
|
||||
auto description = getServerDescription(server, index.row());
|
||||
return configVersion ? description : description + server.value(config_key::hostName).toString();
|
||||
}
|
||||
@@ -144,6 +149,9 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
QString primaryDns = server.value(config_key::dns1).toString();
|
||||
return primaryDns == protocols::dns::amneziaDnsIp;
|
||||
}
|
||||
case IsGoodByeDpiRole: {
|
||||
return isGoodbyeDpi;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -208,6 +216,12 @@ QString ServersModel::getServerDescription(const QJsonObject &server, const int
|
||||
const QString ServersModel::getDefaultServerDescriptionCollapsed()
|
||||
{
|
||||
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
|
||||
|
||||
const auto isGoodbyeDpi = server.value(config_key::isGoodbyeDpi).toBool(false);
|
||||
if (isGoodbyeDpi) {
|
||||
return server.value(config_key::description).toString();
|
||||
}
|
||||
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
auto description = getServerDescription(server, m_defaultServerIndex);
|
||||
if (configVersion) {
|
||||
@@ -222,6 +236,12 @@ const QString ServersModel::getDefaultServerDescriptionCollapsed()
|
||||
const QString ServersModel::getDefaultServerDescriptionExpanded()
|
||||
{
|
||||
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
|
||||
|
||||
const auto isGoodbyeDpi = server.value(config_key::isGoodbyeDpi).toBool(false);
|
||||
if (isGoodbyeDpi) {
|
||||
return server.value(config_key::description).toString();
|
||||
}
|
||||
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
auto description = getServerDescription(server, m_defaultServerIndex);
|
||||
if (configVersion) {
|
||||
@@ -370,6 +390,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
|
||||
roles[IsCountrySelectionAvailableRole] = "isCountrySelectionAvailable";
|
||||
roles[ApiAvailableCountriesRole] = "apiAvailableCountries";
|
||||
roles[ApiServerCountryCodeRole] = "apiServerCountryCode";
|
||||
|
||||
roles[IsGoodByeDpiRole] = "isGoodbyeDpi";
|
||||
return roles;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,9 @@ public:
|
||||
ApiAvailableCountriesRole,
|
||||
ApiServerCountryCodeRole,
|
||||
|
||||
HasAmneziaDns
|
||||
HasAmneziaDns,
|
||||
|
||||
IsGoodByeDpiRole
|
||||
};
|
||||
|
||||
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import PageEnum 1.0
|
||||
import Style 1.0
|
||||
|
||||
import "./"
|
||||
import "../../Controls2"
|
||||
import "../../Config"
|
||||
import "../../Controls2/TextTypes"
|
||||
import "../../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.height
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
property bool isGoodbyeDpiEnabled: LocalServicesController.isGoodbyeDpiEnabled
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
spacing: 16
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("GoodbyeDPI settings")
|
||||
descriptionText: qsTr("Deep Packet Inspection circumvention utility")
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Enable GoodbyeDPI")
|
||||
|
||||
checked: LocalServicesController.isGoodbyeDpiEnabled
|
||||
onCheckedChanged: {
|
||||
if (checked !== LocalServicesController.isGoodbyeDpiEnabled) {
|
||||
LocalServicesController.toggleGoodbyeDpi(checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
enabled: !content.isGoodbyeDpiEnabled
|
||||
|
||||
ListItemTitleType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: LocalServicesController.getGoodbyeDpiBlackListFile()
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
image: "qrc:/images/controls/folder-search-2.svg"
|
||||
imageColor: AmneziaStyle.color.paleGray
|
||||
|
||||
onClicked: function() {
|
||||
var fileName = SystemController.getFileName(qsTr("Open black list file"),
|
||||
qsTr("Text files (*.txt)"))
|
||||
|
||||
LocalServicesController.setGoodbyeDpiBlackListFile(fileName)
|
||||
}
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
image: "qrc:/images/controls/trash.svg"
|
||||
imageColor: AmneziaStyle.color.paleGray
|
||||
|
||||
onClicked: function() {
|
||||
LocalServicesController.resetGoodbyeDpiBlackListFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: modsetDropDown
|
||||
Layout.fillWidth: true
|
||||
|
||||
descriptionText: qsTr("Setup templates")
|
||||
headerText: qsTr("Modset")
|
||||
|
||||
drawerParent: root
|
||||
|
||||
enabled: !content.isGoodbyeDpiEnabled
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
id: modsetListView
|
||||
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : "-p -r -s -f 2 -k 2 -n -e 2" }
|
||||
ListElement { name : "-p -r -s -f 2 -k 2 -n -e 40" }
|
||||
ListElement { name : "-p -r -s -e 40" }
|
||||
ListElement { name : "-p -r -s" }
|
||||
ListElement { name : "-f 2 -e 2 --auto-ttl --reverse-frag --max-payload" }
|
||||
ListElement { name : "-f 2 -e 2 --wrong-seq --reverse-frag --max-payload" }
|
||||
ListElement { name : "-f 2 -e 2 --wrong-chksum --reverse-frag --max-payload" }
|
||||
ListElement { name : "-f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload" }
|
||||
ListElement { name : "-f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload -q" }
|
||||
}
|
||||
|
||||
clickedFunction: function() {
|
||||
modsetDropDown.text = selectedText
|
||||
LocalServicesController.setGoodbyeDpiModset(currentIndex + 1)
|
||||
modsetDropDown.close()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
modsetListView.currentIndex = (LocalServicesController.getGoodbyeDpiModset() - 1)
|
||||
modsetListView.triggerCurrentItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: detailedInstructionsButton
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: AmneziaStyle.color.transparent
|
||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
||||
pressedColor: AmneziaStyle.color.sheerWhite
|
||||
disabledColor: AmneziaStyle.color.mutedGray
|
||||
textColor: AmneziaStyle.color.goldenApricot
|
||||
|
||||
text: qsTr("Description of options")
|
||||
|
||||
clickedFunc: function() {
|
||||
Qt.openUrlExternally("https://github.com/ValdikSS/GoodbyeDPI?tab=readme-ov-file#how-to-use")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -105,6 +105,8 @@ PageType {
|
||||
buttonTextLabel.font.pixelSize: 14
|
||||
buttonTextLabel.font.weight: 500
|
||||
|
||||
visible: !ServersModel.getDefaultServerData("isGoodbyeDpi")
|
||||
|
||||
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled || AppSplitTunnelingModel.isTunnelingEnabled ||
|
||||
ServersModel.isDefaultServerDefaultContainerHasSplitTunneling
|
||||
|
||||
@@ -304,7 +306,7 @@ PageType {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
spacing: 8
|
||||
|
||||
visible: !ServersModel.isDefaultServerFromApi
|
||||
visible: !ServersModel.isDefaultServerFromApi && !ServersModel.getDefaultServerData("isGoodbyeDpi")
|
||||
|
||||
Item {
|
||||
id: focusItem1
|
||||
@@ -535,8 +537,12 @@ PageType {
|
||||
Keys.onReturnPressed: serverInfoButton.clicked()
|
||||
|
||||
onClicked: function() {
|
||||
if (ServersModel.getDefaultServerData("isGoodbyeDpi")) {
|
||||
PageController.goToPage(PageEnum.PageGoodByeDpiSettings, PageEnum.LocalServices)
|
||||
} else {
|
||||
ServersModel.processedIndex = index
|
||||
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
||||
}
|
||||
drawer.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,20 @@ PageType {
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Local bypass services")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
leftImageSource: "qrc:/images/controls/app.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageGoodByeDpiSettings, PageEnum.LocalServices)
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: backup
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -111,6 +111,8 @@ PageType {
|
||||
id: server
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: !isGoodbyeDpi
|
||||
|
||||
text: name
|
||||
parentFlickable: fl
|
||||
descriptionText: {
|
||||
|
||||
@@ -54,7 +54,7 @@ PageType {
|
||||
function onServerAlreadyExists(serverIndex) {
|
||||
PageController.goToStartPage()
|
||||
ServersModel.processedIndex = serverIndex
|
||||
PageController.goToPage(PageEnum.PageSettingsServerInfo, false)
|
||||
PageController.goToPage(PageEnum.PageSettingsServerInfo, PageEnum.LocalServices, false)
|
||||
|
||||
PageController.showErrorMessage(qsTr("The server has already been added to the application"))
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ PageType {
|
||||
tabBarStackView.pop()
|
||||
}
|
||||
|
||||
function onGoToPage(page, slide) {
|
||||
var pagePath = PageController.getPagePath(page)
|
||||
function onGoToPage(page, folder, slide) {
|
||||
var pagePath = PageController.getPagePath(page, folder)
|
||||
|
||||
if (slide) {
|
||||
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition)
|
||||
@@ -204,6 +204,14 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: LocalServicesController
|
||||
|
||||
function onErrorOccurred(error) {
|
||||
PageController.showErrorMessage(error)
|
||||
}
|
||||
}
|
||||
|
||||
StackViewType {
|
||||
id: tabBarStackView
|
||||
|
||||
|
||||
Reference in New Issue
Block a user