refactoring: added classes for working with server configs

This commit is contained in:
vladimir.kuznetsov 2025-06-20 22:18:47 +08:00
parent a2d30efaab
commit 2d22a74b22
34 changed files with 1441 additions and 91 deletions

View file

@ -28,7 +28,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
endif() endif()
set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON) set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE AND NOT IOS) if(APPLE AND NOT IOS)

View file

@ -116,6 +116,7 @@ file(GLOB UI_MODELS_H CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/models/services/*.h ${CLIENT_ROOT_DIR}/ui/models/services/*.h
${CLIENT_ROOT_DIR}/ui/models/api/*.h ${CLIENT_ROOT_DIR}/ui/models/api/*.h
) )
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/models/*.cpp ${CLIENT_ROOT_DIR}/ui/models/*.cpp
${CLIENT_ROOT_DIR}/ui/models/protocols/*.cpp ${CLIENT_ROOT_DIR}/ui/models/protocols/*.cpp
@ -127,17 +128,33 @@ file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/controllers/*.h ${CLIENT_ROOT_DIR}/ui/controllers/*.h
${CLIENT_ROOT_DIR}/ui/controllers/api/*.h ${CLIENT_ROOT_DIR}/ui/controllers/api/*.h
) )
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/controllers/*.cpp ${CLIENT_ROOT_DIR}/ui/controllers/*.cpp
${CLIENT_ROOT_DIR}/ui/controllers/api/*.cpp ${CLIENT_ROOT_DIR}/ui/controllers/api/*.cpp
) )
file(GLOB CORE_MODELS_H CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/core/models/*.h
${CLIENT_ROOT_DIR}/core/models/containers/*.h
${CLIENT_ROOT_DIR}/core/models/protocols/*.h
${CLIENT_ROOT_DIR}/core/models/servers/*.h
)
file(GLOB CORE_MODELS_CPP CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/core/models/*.cpp
${CLIENT_ROOT_DIR}/core/models/containers/*.cpp
${CLIENT_ROOT_DIR}/core/models/protocols/*.cpp
${CLIENT_ROOT_DIR}/core/models/servers/*.cpp
)
set(HEADERS ${HEADERS} set(HEADERS ${HEADERS}
${COMMON_FILES_H} ${COMMON_FILES_H}
${PAGE_LOGIC_H} ${PAGE_LOGIC_H}
${CONFIGURATORS_H} ${CONFIGURATORS_H}
${UI_MODELS_H} ${UI_MODELS_H}
${UI_CONTROLLERS_H} ${UI_CONTROLLERS_H}
${CORE_MODELS_H}
) )
set(SOURCES ${SOURCES} set(SOURCES ${SOURCES}
${COMMON_FILES_CPP} ${COMMON_FILES_CPP}
@ -145,6 +162,7 @@ set(SOURCES ${SOURCES}
${CONFIGURATORS_CPP} ${CONFIGURATORS_CPP}
${UI_MODELS_CPP} ${UI_MODELS_CPP}
${UI_CONTROLLERS_CPP} ${UI_CONTROLLERS_CPP}
${CORE_MODELS_CPP}
) )
if(WIN32) if(WIN32)

View file

@ -14,11 +14,6 @@ namespace apiDefs
ExternalPremium ExternalPremium
}; };
enum ConfigSource {
Telegram = 1,
AmneziaGateway
};
namespace key namespace key
{ {
constexpr QLatin1String configVersion("config_version"); constexpr QLatin1String configVersion("config_version");

View file

@ -32,8 +32,8 @@ bool apiUtils::isServerFromApi(const QJsonObject &serverConfigObject)
{ {
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt(); auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
switch (configVersion) { switch (configVersion) {
case apiDefs::ConfigSource::Telegram: return true; case amnezia::ServerConfigType::ApiV1: return true;
case apiDefs::ConfigSource::AmneziaGateway: return true; case amnezia::ServerConfigType::ApiV2: return true;
default: return false; default: return false;
} }
} }
@ -43,7 +43,7 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt(); auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
switch (configVersion) { switch (configVersion) {
case apiDefs::ConfigSource::Telegram: { case amnezia::ServerConfigType::ApiV1: {
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT); constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT); constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
@ -55,7 +55,7 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
return apiDefs::ConfigType::AmneziaFreeV2; return apiDefs::ConfigType::AmneziaFreeV2;
} }
}; };
case apiDefs::ConfigSource::AmneziaGateway: { case amnezia::ServerConfigType::ApiV2: {
constexpr QLatin1String servicePremium("amnezia-premium"); constexpr QLatin1String servicePremium("amnezia-premium");
constexpr QLatin1String serviceFree("amnezia-free"); constexpr QLatin1String serviceFree("amnezia-free");
constexpr QLatin1String serviceExternalPremium("external-premium"); constexpr QLatin1String serviceExternalPremium("external-premium");
@ -77,9 +77,9 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
}; };
} }
apiDefs::ConfigSource apiUtils::getConfigSource(const QJsonObject &serverConfigObject) amnezia::ServerConfigType apiUtils::getConfigSource(const QJsonObject &serverConfigObject)
{ {
return static_cast<apiDefs::ConfigSource>(serverConfigObject.value(apiDefs::key::configVersion).toInt()); return static_cast<amnezia::ServerConfigType>(serverConfigObject.value(apiDefs::key::configVersion).toInt());
} }
amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply) amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply)

View file

@ -16,7 +16,7 @@ namespace apiUtils
bool isPremiumServer(const QJsonObject &serverConfigObject); bool isPremiumServer(const QJsonObject &serverConfigObject);
apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject); apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject);
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject); amnezia::ServerConfigType getConfigSource(const QJsonObject &serverConfigObject);
amnezia::ErrorCode checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply); amnezia::ErrorCode checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply);

View file

@ -299,13 +299,10 @@ void CoreController::setQmlRoot()
void CoreController::initApiCountryModelUpdateHandler() void CoreController::initApiCountryModelUpdateHandler()
{ {
// TODO
connect(m_serversModel.get(), &ServersModel::updateApiCountryModel, this, [this]() { connect(m_serversModel.get(), &ServersModel::updateApiCountryModel, this, [this]() {
m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(), m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
m_serversModel->getProcessedServerData("apiServerCountryCode").toString()); m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
}); });
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
} }
void CoreController::initContainerModelUpdateHandler() void CoreController::initContainerModelUpdateHandler()

View file

@ -19,6 +19,13 @@ namespace amnezia
} }
}; };
enum ServerConfigType
{
SelfHosted,
ApiV1,
ApiV2
};
struct InstalledAppInfo { struct InstalledAppInfo {
QString appName; QString appName;
QString packageName; QString packageName;

View file

@ -0,0 +1,5 @@
#include "containerConfig.h"
ContainerConfig::ContainerConfig()
{
}

View file

@ -0,0 +1,19 @@
#ifndef CONTAINERCONFIG_H
#define CONTAINERCONFIG_H
#include <QMap>
#include <QSharedPointer>
#include <QString>
#include "core/models/protocols/protocolConfig.h"
class ContainerConfig
{
public:
ContainerConfig();
QString containerName;
QMap<QString, QSharedPointer<ProtocolConfig>> protocolConfigs;
};
#endif // CONTAINERCONFIG_H

View file

@ -0,0 +1,198 @@
#include "awgProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
AwgProtocolConfig::AwgProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString();
serverProtocolConfig.awgData.junkPacketCount = protocolConfigObject.value(config_key::junkPacketCount).toString();
serverProtocolConfig.awgData.junkPacketMinSize = protocolConfigObject.value(config_key::junkPacketMinSize).toString();
serverProtocolConfig.awgData.junkPacketMaxSize = protocolConfigObject.value(config_key::junkPacketMaxSize).toString();
serverProtocolConfig.awgData.initPacketJunkSize = protocolConfigObject.value(config_key::initPacketJunkSize).toString();
serverProtocolConfig.awgData.responsePacketJunkSize = protocolConfigObject.value(config_key::responsePacketJunkSize).toString();
serverProtocolConfig.awgData.initPacketMagicHeader = protocolConfigObject.value(config_key::initPacketMagicHeader).toString();
serverProtocolConfig.awgData.responsePacketMagicHeader = protocolConfigObject.value(config_key::responsePacketMagicHeader).toString();
serverProtocolConfig.awgData.underloadPacketMagicHeader = protocolConfigObject.value(config_key::underloadPacketMagicHeader).toString();
serverProtocolConfig.awgData.transportPacketMagicHeader = protocolConfigObject.value(config_key::transportPacketMagicHeader).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
clientProtocolConfig.awgData.junkPacketCount = clientProtocolConfigObject.value(config_key::junkPacketCount).toString();
clientProtocolConfig.awgData.junkPacketMinSize = clientProtocolConfigObject.value(config_key::junkPacketMinSize).toString();
clientProtocolConfig.awgData.junkPacketMaxSize = clientProtocolConfigObject.value(config_key::junkPacketMaxSize).toString();
clientProtocolConfig.awgData.initPacketJunkSize = clientProtocolConfigObject.value(config_key::initPacketJunkSize).toString();
clientProtocolConfig.awgData.responsePacketJunkSize = clientProtocolConfigObject.value(config_key::responsePacketJunkSize).toString();
clientProtocolConfig.awgData.initPacketMagicHeader = clientProtocolConfigObject.value(config_key::initPacketMagicHeader).toString();
clientProtocolConfig.awgData.responsePacketMagicHeader =
clientProtocolConfigObject.value(config_key::responsePacketMagicHeader).toString();
clientProtocolConfig.awgData.underloadPacketMagicHeader =
clientProtocolConfigObject.value(config_key::underloadPacketMagicHeader).toString();
clientProtocolConfig.awgData.transportPacketMagicHeader =
clientProtocolConfigObject.value(config_key::transportPacketMagicHeader).toString();
clientProtocolConfig.clientId = clientProtocolConfigObject.value(config_key::clientId).toString();
clientProtocolConfig.wireGuardData.clientIp = clientProtocolConfigObject.value(config_key::client_ip).toString();
clientProtocolConfig.wireGuardData.clientPrivateKey = clientProtocolConfigObject.value(config_key::client_priv_key).toString();
clientProtocolConfig.wireGuardData.clientPublicKey = clientProtocolConfigObject.value(config_key::client_pub_key).toString();
clientProtocolConfig.wireGuardData.persistentKeepAlive =
clientProtocolConfigObject.value(config_key::persistent_keep_alive).toString();
clientProtocolConfig.wireGuardData.pskKey = clientProtocolConfigObject.value(config_key::psk_key).toString();
clientProtocolConfig.wireGuardData.serverPubKey = clientProtocolConfigObject.value(config_key::server_pub_key).toString();
clientProtocolConfig.wireGuardData.mtu = clientProtocolConfigObject.value(config_key::mtu).toString();
clientProtocolConfig.hostname = clientProtocolConfigObject.value(config_key::hostName).toString();
clientProtocolConfig.port = clientProtocolConfigObject.value(config_key::port).toInt(0);
clientProtocolConfig.nativeConfig = clientProtocolConfigObject.value(config_key::config).toString();
if (clientProtocolConfigObject.contains(config_key::allowed_ips)
&& clientProtocolConfigObject.value(config_key::allowed_ips).isArray()) {
auto allowedIpsArray = clientProtocolConfigObject.value(config_key::allowed_ips).toArray();
for (const auto &ip : allowedIpsArray) {
clientProtocolConfig.wireGuardData.allowedIps.append(ip.toString());
}
}
}
}
QJsonObject AwgProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!serverProtocolConfig.awgData.junkPacketCount.isEmpty()) {
json[config_key::junkPacketCount] = serverProtocolConfig.awgData.junkPacketCount;
}
if (!serverProtocolConfig.awgData.junkPacketMinSize.isEmpty()) {
json[config_key::junkPacketMinSize] = serverProtocolConfig.awgData.junkPacketMinSize;
}
if (!serverProtocolConfig.awgData.junkPacketMaxSize.isEmpty()) {
json[config_key::junkPacketMaxSize] = serverProtocolConfig.awgData.junkPacketMaxSize;
}
if (!serverProtocolConfig.awgData.initPacketJunkSize.isEmpty()) {
json[config_key::initPacketJunkSize] = serverProtocolConfig.awgData.initPacketJunkSize;
}
if (!serverProtocolConfig.awgData.responsePacketJunkSize.isEmpty()) {
json[config_key::responsePacketJunkSize] = serverProtocolConfig.awgData.responsePacketJunkSize;
}
if (!serverProtocolConfig.awgData.initPacketMagicHeader.isEmpty()) {
json[config_key::initPacketMagicHeader] = serverProtocolConfig.awgData.initPacketMagicHeader;
}
if (!serverProtocolConfig.awgData.responsePacketMagicHeader.isEmpty()) {
json[config_key::responsePacketMagicHeader] = serverProtocolConfig.awgData.responsePacketMagicHeader;
}
if (!serverProtocolConfig.awgData.underloadPacketMagicHeader.isEmpty()) {
json[config_key::underloadPacketMagicHeader] = serverProtocolConfig.awgData.underloadPacketMagicHeader;
}
if (!serverProtocolConfig.awgData.transportPacketMagicHeader.isEmpty()) {
json[config_key::transportPacketMagicHeader] = serverProtocolConfig.awgData.transportPacketMagicHeader;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
if (!clientProtocolConfig.clientId.isEmpty()) {
clientConfigJson[config_key::clientId] = clientProtocolConfig.clientId;
}
if (!clientProtocolConfig.awgData.junkPacketCount.isEmpty()) {
clientConfigJson[config_key::junkPacketCount] = clientProtocolConfig.awgData.junkPacketCount;
}
if (!clientProtocolConfig.awgData.junkPacketMinSize.isEmpty()) {
clientConfigJson[config_key::junkPacketMinSize] = clientProtocolConfig.awgData.junkPacketMinSize;
}
if (!clientProtocolConfig.awgData.junkPacketMaxSize.isEmpty()) {
clientConfigJson[config_key::junkPacketMaxSize] = clientProtocolConfig.awgData.junkPacketMaxSize;
}
if (!clientProtocolConfig.awgData.initPacketJunkSize.isEmpty()) {
clientConfigJson[config_key::initPacketJunkSize] = clientProtocolConfig.awgData.initPacketJunkSize;
}
if (!clientProtocolConfig.awgData.responsePacketJunkSize.isEmpty()) {
clientConfigJson[config_key::responsePacketJunkSize] = clientProtocolConfig.awgData.responsePacketJunkSize;
}
if (!clientProtocolConfig.awgData.initPacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::initPacketMagicHeader] = clientProtocolConfig.awgData.initPacketMagicHeader;
}
if (!clientProtocolConfig.awgData.responsePacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::responsePacketMagicHeader] = clientProtocolConfig.awgData.responsePacketMagicHeader;
}
if (!clientProtocolConfig.awgData.underloadPacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::underloadPacketMagicHeader] = clientProtocolConfig.awgData.underloadPacketMagicHeader;
}
if (!clientProtocolConfig.awgData.transportPacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::transportPacketMagicHeader] = clientProtocolConfig.awgData.transportPacketMagicHeader;
}
if (!clientProtocolConfig.wireGuardData.clientIp.isEmpty()) {
clientConfigJson[config_key::client_ip] = clientProtocolConfig.wireGuardData.clientIp;
}
if (!clientProtocolConfig.wireGuardData.clientPrivateKey.isEmpty()) {
clientConfigJson[config_key::client_priv_key] = clientProtocolConfig.wireGuardData.clientPrivateKey;
}
if (!clientProtocolConfig.wireGuardData.clientPublicKey.isEmpty()) {
clientConfigJson[config_key::client_pub_key] = clientProtocolConfig.wireGuardData.clientPublicKey;
}
if (!clientProtocolConfig.wireGuardData.persistentKeepAlive.isEmpty()) {
clientConfigJson[config_key::persistent_keep_alive] = clientProtocolConfig.wireGuardData.persistentKeepAlive;
}
if (!clientProtocolConfig.wireGuardData.pskKey.isEmpty()) {
clientConfigJson[config_key::psk_key] = clientProtocolConfig.wireGuardData.pskKey;
}
if (!clientProtocolConfig.wireGuardData.serverPubKey.isEmpty()) {
clientConfigJson[config_key::server_pub_key] = clientProtocolConfig.wireGuardData.serverPubKey;
}
if (!clientProtocolConfig.wireGuardData.mtu.isEmpty()) {
clientConfigJson[config_key::mtu] = clientProtocolConfig.wireGuardData.mtu;
}
if (!clientProtocolConfig.wireGuardData.allowedIps.isEmpty()) {
QJsonArray allowedIpsArray;
for (const auto &ip : clientProtocolConfig.wireGuardData.allowedIps) {
if (!ip.isEmpty()) {
allowedIpsArray.append(ip);
}
}
if (!allowedIpsArray.isEmpty()) {
clientConfigJson[config_key::allowed_ips] = allowedIpsArray;
}
}
if (!clientProtocolConfig.hostname.isEmpty()) {
clientConfigJson[config_key::hostName] = clientProtocolConfig.hostname;
}
if (clientProtocolConfig.port) {
clientConfigJson[config_key::port] = clientProtocolConfig.port;
}
if (!clientProtocolConfig.nativeConfig.isEmpty()) {
clientConfigJson[config_key::config] = clientProtocolConfig.nativeConfig;
}
if (!clientConfigJson.isEmpty()) {
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson(QJsonDocument::Compact));
}
}
return json;
}

View file

@ -0,0 +1,65 @@
#ifndef AWGPROTOCOLCONFIG_H
#define AWGPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QStringList>
#include "protocolConfig.h"
#include "wireguardProtocolConfig.h"
namespace awg
{
struct AwgData
{
QString junkPacketCount;
QString junkPacketMinSize;
QString junkPacketMaxSize;
QString initPacketJunkSize;
QString responsePacketJunkSize;
QString initPacketMagicHeader;
QString responsePacketMagicHeader;
QString underloadPacketMagicHeader;
QString transportPacketMagicHeader;
};
struct ServerProtocolConfig
{
QString port;
QString transportProto;
QString subnetAddress;
AwgData awgData;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
wireguard::WireGuardData wireGuardData;
AwgData awgData;
QString hostname;
int port;
QString nativeConfig;
};
}
class AwgProtocolConfig : public ProtocolConfig
{
public:
AwgProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
awg::ServerProtocolConfig serverProtocolConfig;
awg::ClientProtocolConfig clientProtocolConfig;
};
#endif // AWGPROTOCOLCONFIG_H

View file

@ -0,0 +1,43 @@
#include "cloakProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
CloakProtocolConfig::CloakProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString();
serverProtocolConfig.site = protocolConfigObject.value(config_key::site).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
}
}
QJsonObject CloakProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.cipher.isEmpty()) {
json[config_key::cipher] = serverProtocolConfig.cipher;
}
if (!serverProtocolConfig.site.isEmpty()) {
json[config_key::site] = serverProtocolConfig.site;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
return json;
}

View file

@ -0,0 +1,35 @@
#ifndef CLOAKPROTOCOLCONFIG_H
#define CLOAKPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace cloak
{
struct ServerProtocolConfig
{
QString port;
QString cipher;
QString site;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
};
}
class CloakProtocolConfig : public ProtocolConfig
{
public:
CloakProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
cloak::ServerProtocolConfig serverProtocolConfig;
cloak::ClientProtocolConfig clientProtocolConfig;
};
#endif // CLOAKPROTOCOLCONFIG_H

View file

@ -0,0 +1,83 @@
#include "openvpnProtocolConfig.h"
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
OpenVpnProtocolConfig::OpenVpnProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.ncpDisable = protocolConfigObject.value(config_key::ncp_disable).toString();
serverProtocolConfig.hash = protocolConfigObject.value(config_key::hash).toString();
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString();
serverProtocolConfig.tlsAuth = protocolConfigObject.value(config_key::tls_auth).toString();
serverProtocolConfig.blockOutsideDns = protocolConfigObject.value(config_key::block_outside_dns).toString();
serverProtocolConfig.additionalClientConfig = protocolConfigObject.value(config_key::additional_client_config).toString();
serverProtocolConfig.additionalServerConfig = protocolConfigObject.value(config_key::additional_server_config).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
clientProtocolConfig.clientId = clientProtocolConfigObject.value(config_key::clientId).toString();
clientProtocolConfig.nativeConfig = clientProtocolConfigObject.value(config_key::config).toString();
}
}
QJsonObject OpenVpnProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.ncpDisable.isEmpty()) {
json[config_key::ncp_disable] = serverProtocolConfig.ncpDisable;
}
if (!serverProtocolConfig.hash.isEmpty()) {
json[config_key::hash] = serverProtocolConfig.hash;
}
if (!serverProtocolConfig.cipher.isEmpty()) {
json[config_key::cipher] = serverProtocolConfig.cipher;
}
if (!serverProtocolConfig.tlsAuth.isEmpty()) {
json[config_key::tls_auth] = serverProtocolConfig.tlsAuth;
}
if (!serverProtocolConfig.blockOutsideDns.isEmpty()) {
json[config_key::block_outside_dns] = serverProtocolConfig.blockOutsideDns;
}
if (!serverProtocolConfig.additionalClientConfig.isEmpty()) {
json[config_key::additional_client_config] = serverProtocolConfig.additionalClientConfig;
}
if (!serverProtocolConfig.additionalServerConfig.isEmpty()) {
json[config_key::additional_server_config] = serverProtocolConfig.additionalServerConfig;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
if (!clientProtocolConfig.clientId.isEmpty()) {
clientConfigJson[config_key::clientId] = clientProtocolConfig.clientId;
}
if (!clientProtocolConfig.nativeConfig.isEmpty()) {
clientConfigJson[config_key::config] = clientProtocolConfig.nativeConfig;
}
if (!clientConfigJson.isEmpty()) {
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
}
return json;
}

View file

@ -0,0 +1,46 @@
#ifndef OPENVPNPROTOCOLCONFIG_H
#define OPENVPNPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace openvpn
{
struct ServerProtocolConfig
{
QString subnetAddress;
QString transportProto;
QString port;
QString ncpDisable;
QString hash;
QString cipher;
QString tlsAuth;
QString blockOutsideDns;
QString additionalClientConfig;
QString additionalServerConfig;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
QString nativeConfig;
};
}
class OpenVpnProtocolConfig : public ProtocolConfig
{
public:
OpenVpnProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
openvpn::ServerProtocolConfig serverProtocolConfig;
openvpn::ClientProtocolConfig clientProtocolConfig;
};
#endif // OPENVPNPROTOCOLCONFIG_H

View file

@ -0,0 +1,12 @@
#include "protocolConfig.h"
#include <QJsonObject>
ProtocolConfig::ProtocolConfig(const QString &protocolName) : protocolName(protocolName)
{
}
QJsonObject ProtocolConfig::toJson() const
{
return QJsonObject();
}

View file

@ -0,0 +1,16 @@
#ifndef PROTOCOLCONFIG_H
#define PROTOCOLCONFIG_H
#include <QJsonObject>
class ProtocolConfig
{
public:
ProtocolConfig(const QString &protocolName);
QString protocolName;
virtual QJsonObject toJson() const;
};
#endif // PROTOCOLCONFIG_H

View file

@ -0,0 +1,39 @@
#include "shadowsocksProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
ShadowsocksProtocolConfig::ShadowsocksProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
}
}
QJsonObject ShadowsocksProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.cipher.isEmpty()) {
json[config_key::cipher] = serverProtocolConfig.cipher;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
return json;
}

View file

@ -0,0 +1,34 @@
#ifndef SHADOWSOCKSPROTOCOLCONFIG_H
#define SHADOWSOCKSPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace shadowsocks
{
struct ServerProtocolConfig
{
QString port;
QString cipher;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
};
}
class ShadowsocksProtocolConfig : public ProtocolConfig
{
public:
ShadowsocksProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
shadowsocks::ServerProtocolConfig serverProtocolConfig;
shadowsocks::ClientProtocolConfig clientProtocolConfig;
};
#endif // SHADOWSOCKSPROTOCOLCONFIG_H

View file

@ -0,0 +1,120 @@
#include "wireguardProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
WireGuardProtocolConfig::WireGuardProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName)
: ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
clientProtocolConfig.clientId = clientProtocolConfigObject.value(config_key::clientId).toString();
clientProtocolConfig.wireGuardData.clientIp = clientProtocolConfigObject.value(config_key::client_ip).toString();
clientProtocolConfig.wireGuardData.clientPrivateKey = clientProtocolConfigObject.value(config_key::client_priv_key).toString();
clientProtocolConfig.wireGuardData.clientPublicKey = clientProtocolConfigObject.value(config_key::client_pub_key).toString();
clientProtocolConfig.wireGuardData.persistentKeepAlive =
clientProtocolConfigObject.value(config_key::persistent_keep_alive).toString();
clientProtocolConfig.wireGuardData.pskKey = clientProtocolConfigObject.value(config_key::psk_key).toString();
clientProtocolConfig.wireGuardData.serverPubKey = clientProtocolConfigObject.value(config_key::server_pub_key).toString();
clientProtocolConfig.wireGuardData.mtu = clientProtocolConfigObject.value(config_key::mtu).toString();
clientProtocolConfig.hostname = clientProtocolConfigObject.value(config_key::hostName).toString();
clientProtocolConfig.port = clientProtocolConfigObject.value(config_key::port).toInt(0);
clientProtocolConfig.nativeConfig = clientProtocolConfigObject.value(config_key::config).toString();
if (clientProtocolConfigObject.contains(config_key::allowed_ips)
&& clientProtocolConfigObject.value(config_key::allowed_ips).isArray()) {
auto allowedIpsArray = clientProtocolConfigObject.value(config_key::allowed_ips).toArray();
for (const auto &ip : allowedIpsArray) {
clientProtocolConfig.wireGuardData.allowedIps.append(ip.toString());
}
}
}
}
QJsonObject WireGuardProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
if (!clientProtocolConfig.clientId.isEmpty()) {
clientConfigJson[config_key::clientId] = clientProtocolConfig.clientId;
}
if (!clientProtocolConfig.wireGuardData.clientIp.isEmpty()) {
clientConfigJson[config_key::client_ip] = clientProtocolConfig.wireGuardData.clientIp;
}
if (!clientProtocolConfig.wireGuardData.clientPrivateKey.isEmpty()) {
clientConfigJson[config_key::client_priv_key] = clientProtocolConfig.wireGuardData.clientPrivateKey;
}
if (!clientProtocolConfig.wireGuardData.clientPublicKey.isEmpty()) {
clientConfigJson[config_key::client_pub_key] = clientProtocolConfig.wireGuardData.clientPublicKey;
}
if (!clientProtocolConfig.wireGuardData.persistentKeepAlive.isEmpty()) {
clientConfigJson[config_key::persistent_keep_alive] = clientProtocolConfig.wireGuardData.persistentKeepAlive;
}
if (!clientProtocolConfig.wireGuardData.pskKey.isEmpty()) {
clientConfigJson[config_key::psk_key] = clientProtocolConfig.wireGuardData.pskKey;
}
if (!clientProtocolConfig.wireGuardData.serverPubKey.isEmpty()) {
clientConfigJson[config_key::server_pub_key] = clientProtocolConfig.wireGuardData.serverPubKey;
}
if (!clientProtocolConfig.wireGuardData.mtu.isEmpty()) {
clientConfigJson[config_key::mtu] = clientProtocolConfig.wireGuardData.mtu;
}
if (!clientProtocolConfig.wireGuardData.allowedIps.isEmpty()) {
QJsonArray allowedIpsArray;
for (const auto &ip : clientProtocolConfig.wireGuardData.allowedIps) {
if (!ip.isEmpty()) {
allowedIpsArray.append(ip);
}
}
if (!allowedIpsArray.isEmpty()) {
clientConfigJson[config_key::allowed_ips] = allowedIpsArray;
}
}
if (!clientProtocolConfig.hostname.isEmpty()) {
clientConfigJson[config_key::hostName] = clientProtocolConfig.hostname;
}
if (clientProtocolConfig.port) {
clientConfigJson[config_key::port] = clientProtocolConfig.port;
}
if (!clientProtocolConfig.nativeConfig.isEmpty()) {
clientConfigJson[config_key::config] = clientProtocolConfig.nativeConfig;
}
if (!clientConfigJson.isEmpty()) {
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
}
return json;
}

View file

@ -0,0 +1,58 @@
#ifndef WIREGUARDPROTOCOLCONFIG_H
#define WIREGUARDPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QStringList>
#include "protocolConfig.h"
namespace wireguard
{
struct WireGuardData
{
QStringList allowedIps;
QString clientIp;
QString clientPrivateKey;
QString clientPublicKey;
QString mtu;
QString persistentKeepAlive;
QString pskKey;
QString serverPubKey;
};
struct ServerProtocolConfig
{
QString port;
QString transportProto;
QString subnetAddress;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
WireGuardData wireGuardData;
QString hostname;
int port;
QString nativeConfig;
};
}
class WireGuardProtocolConfig : public ProtocolConfig
{
public:
WireGuardProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
wireguard::ServerProtocolConfig serverProtocolConfig;
wireguard::ClientProtocolConfig clientProtocolConfig;
};
#endif // WIREGUARDPROTOCOLCONFIG_H

View file

@ -0,0 +1,43 @@
#include "xrayProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
XrayProtocolConfig::XrayProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.site = protocolConfigObject.value(config_key::site).toString();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
}
}
QJsonObject XrayProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.site.isEmpty()) {
json[config_key::site] = serverProtocolConfig.site;
}
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
return json;
}

View file

@ -0,0 +1,35 @@
#ifndef XRAYPROTOCOLCONFIG_H
#define XRAYPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace xray
{
struct ServerProtocolConfig
{
QString site;
QString port;
QString transportProto;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
};
}
class XrayProtocolConfig : public ProtocolConfig
{
public:
XrayProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
xray::ServerProtocolConfig serverProtocolConfig;
xray::ClientProtocolConfig clientProtocolConfig;
};
#endif // XRAYPROTOCOLCONFIG_H

View file

@ -0,0 +1,30 @@
#include "apiV1ServerConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
ApiV1ServerConfig::ApiV1ServerConfig(const QJsonObject &serverConfigObject) : ServerConfig(serverConfigObject)
{
name = serverConfigObject.value(config_key::name).toString();
description = serverConfigObject.value(config_key::description).toString();
}
QJsonObject ApiV1ServerConfig::toJson() const
{
// Сначала вызываем родительскую функцию для сериализации базовых полей
QJsonObject json = ServerConfig::toJson();
// Добавляем свои поля только если они не пустые
if (!name.isEmpty()) {
json[config_key::name] = name;
}
if (!description.isEmpty()) {
json[config_key::description] = description;
}
return json;
}

View file

@ -0,0 +1,17 @@
#ifndef APIV1SERVERCONFIG_H
#define APIV1SERVERCONFIG_H
#include "serverConfig.h"
class ApiV1ServerConfig : public ServerConfig
{
public:
ApiV1ServerConfig(const QJsonObject &serverConfigObject);
QJsonObject toJson() const override;
QString name;
QString description;
};
#endif // APIV1SERVERCONFIG_H

View file

@ -0,0 +1,125 @@
#include "apiV2ServerConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
ApiV2ServerConfig::ApiV2ServerConfig(const QJsonObject &serverConfigObject) : ServerConfig(serverConfigObject)
{
name = serverConfigObject.value(config_key::name).toString();
description = serverConfigObject.value(config_key::description).toString();
auto apiConfigObject = serverConfigObject.value("api_config").toObject();
auto availableCountriesArray = apiConfigObject.value("available_countries").toArray();
for (const auto &countryValue : availableCountriesArray) {
auto countryObject = countryValue.toObject();
apiv2::Country country;
country.code = countryObject.value("server_country_code").toString();
country.name = countryObject.value("server_country_name").toString();
apiConfig.availableCountries.append(country);
}
auto subscriptionObject = apiConfigObject.value("subscription").toObject();
apiConfig.subscription.end_date = subscriptionObject.value("end_date").toString();
auto publicKeyObject = apiConfigObject.value("public_key").toObject();
apiConfig.publicKey.expiresAt = publicKeyObject.value("expires_at").toString();
apiConfig.serverCountryCode = apiConfigObject.value("server_country_code").toString();
apiConfig.serverCountryName = apiConfigObject.value("server_country_name").toString();
apiConfig.serviceProtocol = apiConfigObject.value("service_protocol").toString();
apiConfig.serviceType = apiConfigObject.value("service_type").toString();
apiConfig.userCountryCode = apiConfigObject.value("user_country_code").toString();
apiConfig.vpnKey = apiConfigObject.value("vpn_key").toString();
}
QJsonObject ApiV2ServerConfig::toJson() const
{
// Сначала вызываем родительскую функцию для сериализации базовых полей
QJsonObject json = ServerConfig::toJson();
// Добавляем свои поля только если они не пустые
if (!name.isEmpty()) {
json[config_key::name] = name;
}
if (!description.isEmpty()) {
json[config_key::description] = description;
}
// Сериализация API конфигурации
QJsonObject apiConfigJson;
// Сериализация доступных стран только если массив не пустой
if (!apiConfig.availableCountries.isEmpty()) {
QJsonArray availableCountriesArray;
for (const auto &country : apiConfig.availableCountries) {
QJsonObject countryObject;
if (!country.code.isEmpty()) {
countryObject["server_country_code"] = country.code;
}
if (!country.name.isEmpty()) {
countryObject["server_country_name"] = country.name;
}
if (!countryObject.isEmpty()) {
availableCountriesArray.append(countryObject);
}
}
if (!availableCountriesArray.isEmpty()) {
apiConfigJson["available_countries"] = availableCountriesArray;
}
}
// Сериализация подписки только если есть данные
if (!apiConfig.subscription.end_date.isEmpty()) {
QJsonObject subscriptionObject;
subscriptionObject["end_date"] = apiConfig.subscription.end_date;
apiConfigJson["subscription"] = subscriptionObject;
}
// Сериализация публичного ключа только если есть данные
if (!apiConfig.publicKey.expiresAt.isEmpty()) {
QJsonObject publicKeyObject;
publicKeyObject["expires_at"] = apiConfig.publicKey.expiresAt;
apiConfigJson["public_key"] = publicKeyObject;
}
// Сериализация информации о сервере только если не пустая
if (!apiConfig.serverCountryCode.isEmpty()) {
apiConfigJson["server_country_code"] = apiConfig.serverCountryCode;
}
if (!apiConfig.serverCountryName.isEmpty()) {
apiConfigJson["server_country_name"] = apiConfig.serverCountryName;
}
// Сериализация информации о сервисе только если не пустая
if (!apiConfig.serviceProtocol.isEmpty()) {
apiConfigJson["service_protocol"] = apiConfig.serviceProtocol;
}
if (!apiConfig.serviceType.isEmpty()) {
apiConfigJson["service_type"] = apiConfig.serviceType;
}
// Сериализация информации о пользователе только если не пустая
if (!apiConfig.userCountryCode.isEmpty()) {
apiConfigJson["user_country_code"] = apiConfig.userCountryCode;
}
// Сериализация VPN ключа только если не пустой
if (!apiConfig.vpnKey.isEmpty()) {
apiConfigJson["vpn_key"] = apiConfig.vpnKey;
}
// Добавляем API конфигурацию в основной JSON только если есть данные
if (!apiConfigJson.isEmpty()) {
json["api_config"] = apiConfigJson;
}
return json;
}

View file

@ -0,0 +1,54 @@
#ifndef APIV2SERVERCONFIG_H
#define APIV2SERVERCONFIG_H
#include "serverConfig.h"
namespace apiv2
{
struct Country {
QString code;
QString name;
};
struct PublicKey
{
QString expiresAt;
};
struct Subscription
{
QString end_date;
};
struct ApiConfig {
QVector<Country> availableCountries;
Subscription subscription;
PublicKey publicKey;
QString serverCountryCode;
QString serverCountryName;
QString serviceProtocol;
QString serviceType;
QString userCountryCode;
QString vpnKey;
};
}
class ApiV2ServerConfig : public ServerConfig
{
public:
ApiV2ServerConfig(const QJsonObject &serverConfigObject);
QJsonObject toJson() const override;
QString name;
QString description;
apiv2::ApiConfig apiConfig;
};
#endif // APIV2SERVERCONFIG_H

View file

@ -0,0 +1,48 @@
#include "selfHostedServerConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
SelfHostedServerConfig::SelfHostedServerConfig(const QJsonObject &serverConfigObject) : ServerConfig(serverConfigObject)
{
name = serverConfigObject.value(config_key::description).toString();
if (name.isEmpty()) {
name = serverConfigObject.value(config_key::hostName).toString();
}
serverCredentials.hostName = serverConfigObject.value(config_key::hostName).toString();
serverCredentials.userName = serverConfigObject.value(config_key::userName).toString();
serverCredentials.secretData = serverConfigObject.value(config_key::password).toString();
serverCredentials.port = serverConfigObject.value(config_key::port).toInt(22);
}
QJsonObject SelfHostedServerConfig::toJson() const
{
// Сначала вызываем родительскую функцию для сериализации базовых полей
QJsonObject json = ServerConfig::toJson();
// Добавляем имя только если оно не пустое
if (!name.isEmpty()) {
json[config_key::description] = name; // Используем description как в конструкторе
}
// Добавляем credentials только если они не пустые
if (!serverCredentials.hostName.isEmpty()) {
json[config_key::hostName] = serverCredentials.hostName;
}
if (!serverCredentials.userName.isEmpty()) {
json[config_key::userName] = serverCredentials.userName;
}
if (!serverCredentials.secretData.isEmpty()) {
json[config_key::password] = serverCredentials.secretData;
}
if (serverCredentials.port != 22) { // Добавляем порт только если не дефолтный
json[config_key::port] = serverCredentials.port;
}
return json;
}

View file

@ -0,0 +1,19 @@
#ifndef SELFHOSTEDSERVERCONFIG_H
#define SELFHOSTEDSERVERCONFIG_H
#include "core/defs.h"
#include "serverConfig.h"
class SelfHostedServerConfig : public ServerConfig
{
public:
SelfHostedServerConfig(const QJsonObject &serverConfigObject);
QJsonObject toJson() const override;
QString name;
amnezia::ServerCredentials serverCredentials;
};
#endif // SELFHOSTEDSERVERCONFIG_H

View file

@ -0,0 +1,145 @@
#include "serverConfig.h"
#include <QJsonArray>
#include "apiV1ServerConfig.h"
#include "apiV2ServerConfig.h"
#include "containers/containers_defs.h"
#include "core/models/protocols/awgProtocolConfig.h"
#include "core/models/protocols/cloakProtocolConfig.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
#include "core/models/protocols/protocolConfig.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
#include "core/models/protocols/xrayProtocolConfig.h"
#include "protocols/protocols_defs.h"
#include "selfHostedServerConfig.h"
using namespace amnezia;
ServerConfig::ServerConfig(const QJsonObject &serverConfigObject)
{
type = static_cast<ServerConfigType>(serverConfigObject.value(config_key::configVersion).toInt(0));
hostName = serverConfigObject.value(config_key::hostName).toString();
dns1 = serverConfigObject.value(config_key::dns1).toString();
dns2 = serverConfigObject.value(config_key::dns2).toString();
defaultContainer = serverConfigObject.value(config_key::defaultContainer).toString();
auto containers = serverConfigObject.value(config_key::containers).toArray();
for (const auto &container : std::as_const(containers)) {
auto containerObject = container.toObject();
auto containerName = containerObject.value(config_key::container).toString();
ContainerConfig containerConfig;
containerConfig.containerName = containerName;
auto protocols = ContainerProps::protocolsForContainer(ContainerProps::containerFromString(containerName));
for (const auto &protocol : protocols) {
auto protocolName = ProtocolProps::protoToString(protocol);
auto protocolConfigObject = containerObject.value(protocolName).toObject();
switch (protocol) {
case Proto::OpenVpn: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<OpenVpnProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::ShadowSocks: {
containerConfig.protocolConfigs.insert(
protocolName, QSharedPointer<ShadowsocksProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Cloak: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<CloakProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::WireGuard: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<WireGuardProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Awg: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<AwgProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Xray: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<XrayProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Ikev2: break;
case Proto::L2tp: break;
case Proto::SSXray: break;
case Proto::TorWebSite: break;
case Proto::Dns: break;
case Proto::Sftp: break;
case Proto::Socks5Proxy: break;
default: break;
}
}
containerConfigs.insert(containerName, containerConfig);
}
}
QSharedPointer<ServerConfig> ServerConfig::createServerConfig(const QJsonObject &serverConfigObject)
{
auto type = static_cast<ServerConfigType>(serverConfigObject.value(config_key::configVersion).toInt(0));
switch (type) {
case ServerConfigType::SelfHosted: return QSharedPointer<SelfHostedServerConfig>::create(serverConfigObject);
case ServerConfigType::ApiV1: return QSharedPointer<ApiV1ServerConfig>::create(serverConfigObject);
case ServerConfigType::ApiV2: return QSharedPointer<ApiV2ServerConfig>::create(serverConfigObject);
}
}
QJsonObject ServerConfig::toJson() const
{
QJsonObject json;
if (type != ServerConfigType::SelfHosted) {
json[config_key::configVersion] = static_cast<int>(type);
}
if (!hostName.isEmpty()) {
json[config_key::hostName] = hostName;
}
if (!dns1.isEmpty()) {
json[config_key::dns1] = dns1;
}
if (!dns2.isEmpty()) {
json[config_key::dns2] = dns2;
}
if (!defaultContainer.isEmpty()) {
json[config_key::defaultContainer] = defaultContainer;
}
if (!containerConfigs.isEmpty()) {
QJsonArray containersArray;
for (const auto &containerConfig : containerConfigs) {
QJsonObject containerObject;
containerObject[config_key::container] = containerConfig.containerName;
if (!containerConfig.protocolConfigs.isEmpty()) {
for (const auto &protocolConfig : containerConfig.protocolConfigs) {
QJsonObject protocolJson = protocolConfig->toJson();
if (!protocolJson.isEmpty()) {
containerObject[protocolConfig->protocolName] = protocolJson;
}
}
}
containersArray.append(containerObject);
}
if (!containersArray.isEmpty()) {
json[config_key::containers] = containersArray;
}
}
return json;
}

View file

@ -0,0 +1,32 @@
#ifndef SERVERCONFIG_H
#define SERVERCONFIG_H
#include <QJsonObject>
#include <QSharedPointer>
#include <QString>
#include "core/defs.h"
#include "core/models/containers/containerConfig.h"
class ServerConfig
{
public:
ServerConfig(const QJsonObject &serverConfigObject);
virtual QJsonObject toJson() const;
static QSharedPointer<ServerConfig> createServerConfig(const QJsonObject &serverConfigObject);
amnezia::ServerConfigType type;
QString hostName;
QString dns1;
QString dns2;
QString defaultContainer;
QMap<QString, ContainerConfig> containerConfigs;
};
#endif // SERVERCONFIG_H

View file

@ -398,16 +398,16 @@ bool ApiConfigsController::isConfigValid()
QJsonObject serverConfigObject = m_serversModel->getServerConfig(serverIndex); QJsonObject serverConfigObject = m_serversModel->getServerConfig(serverIndex);
auto configSource = apiUtils::getConfigSource(serverConfigObject); auto configSource = apiUtils::getConfigSource(serverConfigObject);
if (configSource == apiDefs::ConfigSource::Telegram if (configSource == amnezia::ServerConfigType::ApiV1
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) { && !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
m_serversModel->removeApiConfig(serverIndex); m_serversModel->removeApiConfig(serverIndex);
return updateServiceFromTelegram(serverIndex); return updateServiceFromTelegram(serverIndex);
} else if (configSource == apiDefs::ConfigSource::AmneziaGateway } else if (configSource == amnezia::ServerConfigType::ApiV2
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) { && !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
return updateServiceFromGateway(serverIndex, "", ""); return updateServiceFromGateway(serverIndex, "", "");
} else if (configSource && m_serversModel->isApiKeyExpired(serverIndex)) { } else if (configSource && m_serversModel->isApiKeyExpired(serverIndex)) {
qDebug() << "attempt to update api config by expires_at event"; qDebug() << "attempt to update api config by expires_at event";
if (configSource == apiDefs::ConfigSource::AmneziaGateway) { if (configSource == amnezia::ServerConfigType::ApiV2) {
return updateServiceFromGateway(serverIndex, "", ""); return updateServiceFromGateway(serverIndex, "", "");
} else { } else {
m_serversModel->removeApiConfig(serverIndex); m_serversModel->removeApiConfig(serverIndex);
@ -499,7 +499,7 @@ void ApiConfigsController::fillServerConfig(const QString &protocol, const ApiPa
serverConfig[config_key::containers] = newServerConfig.value(config_key::containers); serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName); serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) { if (newServerConfig.value(config_key::configVersion).toInt() == amnezia::ServerConfigType::ApiV2) {
serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion); serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
serverConfig[config_key::description] = newServerConfig.value(config_key::description); serverConfig[config_key::description] = newServerConfig.value(config_key::description);
serverConfig[config_key::name] = newServerConfig.value(config_key::name); serverConfig[config_key::name] = newServerConfig.value(config_key::name);
@ -512,7 +512,7 @@ void ApiConfigsController::fillServerConfig(const QString &protocol, const ApiPa
map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap()); map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap());
auto apiConfig = QJsonObject::fromVariantMap(map); auto apiConfig = QJsonObject::fromVariantMap(map);
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) { if (newServerConfig.value(config_key::configVersion).toInt() == amnezia::ServerConfigType::ApiV2) {
apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject()); apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject());
} }

View file

@ -2,6 +2,9 @@
#include "core/api/apiDefs.h" #include "core/api/apiDefs.h"
#include "core/controllers/serverController.h" #include "core/controllers/serverController.h"
#include "core/models/servers/apiV1ServerConfig.h"
#include "core/models/servers/apiV2ServerConfig.h"
#include "core/models/servers/selfHostedServerConfig.h"
#include "core/networkUtilities.h" #include "core/networkUtilities.h"
#ifdef Q_OS_IOS #ifdef Q_OS_IOS
@ -24,6 +27,9 @@ namespace
constexpr char publicKeyInfo[] = "public_key"; constexpr char publicKeyInfo[] = "public_key";
constexpr char expiresAt[] = "expires_at"; constexpr char expiresAt[] = "expires_at";
} }
using ServerConfigVariant =
std::variant<QSharedPointer<SelfHostedServerConfig>, QSharedPointer<ApiV1ServerConfig>, QSharedPointer<ApiV2ServerConfig> >;
} }
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent) ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent)
@ -91,29 +97,26 @@ bool ServersModel::setData(const int index, const QVariant &value, int role)
QVariant ServersModel::data(const QModelIndex &index, int role) const QVariant ServersModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers.size())) { if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers1.size())) {
return QVariant(); return QVariant();
} }
const QJsonObject server = m_servers.at(index.row()).toObject(); QSharedPointer<ServerConfig> serverConfig = m_servers1.at(index.row());
const auto apiConfig = server.value(configKey::apiConfig).toObject(); ServerConfigVariant variant;
const auto configVersion = server.value(config_key::configVersion).toInt(); switch (serverConfig->type) {
case amnezia::ServerConfigType::SelfHosted: variant = qSharedPointerCast<SelfHostedServerConfig>(serverConfig); break;
case amnezia::ServerConfigType::ApiV1: variant = qSharedPointerCast<ApiV1ServerConfig>(serverConfig); break;
case amnezia::ServerConfigType::ApiV2: variant = qSharedPointerCast<ApiV2ServerConfig>(serverConfig); break;
}
switch (role) { switch (role) {
case NameRole: { case NameRole: {
if (configVersion) { return std::visit([](const auto &ptr) -> QString { return ptr->name; }, variant);
return server.value(config_key::name).toString();
}
auto name = server.value(config_key::description).toString();
if (name.isEmpty()) {
return server.value(config_key::hostName).toString();
}
return name;
} }
case ServerDescriptionRole: { case ServerDescriptionRole: {
auto description = getServerDescription(server, index.row()); return getServerDescription(index.row());
return configVersion ? description : description + server.value(config_key::hostName).toString();
} }
case HostNameRole: return server.value(config_key::hostName).toString(); case HostNameRole: return serverConfig->hostName;
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row())); case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
case CredentialsLoginRole: return serverCredentials(index.row()).userName; case CredentialsLoginRole: return serverCredentials(index.row()).userName;
case IsDefaultRole: return index.row() == m_defaultServerIndex; case IsDefaultRole: return index.row() == m_defaultServerIndex;
@ -123,36 +126,28 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty()); return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
} }
case ContainsAmneziaDnsRole: { case ContainsAmneziaDnsRole: {
QString primaryDns = server.value(config_key::dns1).toString(); return serverConfig->dns1 == protocols::dns::amneziaDnsIp;
return primaryDns == protocols::dns::amneziaDnsIp;
} }
case DefaultContainerRole: { case DefaultContainerRole: {
return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); return ContainerProps::containerFromString(serverConfig->defaultContainer);
} }
case HasInstalledContainers: { case HasInstalledContainers: {
return serverHasInstalledContainers(index.row()); return serverHasInstalledContainers(index.row());
} }
case IsServerFromTelegramApiRole: { case IsServerFromTelegramApiRole: {
return server.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::Telegram; return serverConfig->type == amnezia::ServerConfigType::ApiV1;
} }
case IsServerFromGatewayApiRole: { case IsServerFromGatewayApiRole: {
return server.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway; return serverConfig->type == amnezia::ServerConfigType::ApiV2;
}
case ApiConfigRole: {
return apiConfig;
} }
case IsCountrySelectionAvailableRole: { case IsCountrySelectionAvailableRole: {
return !apiConfig.value(configKey::availableCountries).toArray().isEmpty(); return !qSharedPointerCast<ApiV2ServerConfig>(serverConfig)->apiConfig.availableCountries.isEmpty();
} }
case ApiAvailableCountriesRole: { case ApiAvailableCountriesRole: {
return apiConfig.value(configKey::availableCountries).toArray(); return QVariant::fromValue(qSharedPointerCast<ApiV2ServerConfig>(serverConfig)->apiConfig.availableCountries);
} }
case ApiServerCountryCodeRole: { case ApiServerCountryCodeRole: {
return apiConfig.value(configKey::serverCountryCode).toString(); return qSharedPointerCast<ApiV2ServerConfig>(serverConfig)->apiConfig.serverCountryCode;
}
case HasAmneziaDns: {
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
} }
} }
@ -171,6 +166,25 @@ void ServersModel::resetModel()
m_servers = m_settings->serversArray(); m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex(); m_defaultServerIndex = m_settings->defaultServerIndex();
m_processedServerIndex = m_defaultServerIndex; m_processedServerIndex = m_defaultServerIndex;
for (auto server : m_servers) {
auto serverConfig = ServerConfig::createServerConfig(server.toObject());
m_servers1.push_back(serverConfig);
qDebug() << "333";
qDebug() << server.toObject();
qDebug() << "333";
ServerConfigVariant variant;
switch (serverConfig->type) {
case amnezia::ServerConfigType::SelfHosted: variant = qSharedPointerCast<SelfHostedServerConfig>(serverConfig); break;
case amnezia::ServerConfigType::ApiV1: variant = qSharedPointerCast<ApiV1ServerConfig>(serverConfig); break;
case amnezia::ServerConfigType::ApiV2: variant = qSharedPointerCast<ApiV2ServerConfig>(serverConfig); break;
}
qDebug() << "123";
qDebug() << std::visit([](const auto &ptr) -> QJsonObject { return ptr->toJson(); }, variant);
qDebug() << "123";
}
endResetModel(); endResetModel();
emit defaultServerIndexChanged(m_defaultServerIndex); emit defaultServerIndexChanged(m_defaultServerIndex);
} }
@ -192,34 +206,40 @@ const QString ServersModel::getDefaultServerName()
return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole)); return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole));
} }
QString ServersModel::getServerDescription(const QJsonObject &server, const int index) const QString ServersModel::getServerDescription(const int index) const
{ {
const auto configVersion = server.value(config_key::configVersion).toInt(); auto serverConfig = m_servers1.at(index);
const auto apiConfig = server.value(configKey::apiConfig).toObject(); switch (serverConfig->type) {
case amnezia::ServerConfigType::ApiV1: return qSharedPointerCast<ApiV1ServerConfig>(serverConfig)->description;
QString description; case amnezia::ServerConfigType::ApiV2: {
auto apiV2ServerConfig = qSharedPointerCast<ApiV2ServerConfig>(serverConfig);
if (configVersion && !apiConfig.value(configKey::serverCountryCode).toString().isEmpty()) { if (apiV2ServerConfig->apiConfig.serverCountryCode.isEmpty()) {
return apiConfig.value(configKey::serverCountryName).toString(); return apiV2ServerConfig->description;
} else if (configVersion) { } else {
return server.value(config_key::description).toString(); return apiV2ServerConfig->apiConfig.serverCountryName;
} else if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
description += "Amnezia DNS | ";
}
} else {
if (data(index, HasAmneziaDns).toBool()) {
description += "Amnezia DNS | ";
} }
} }
return description; case amnezia::ServerConfigType::SelfHosted: {
QString description;
if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
description += "Amnezia DNS | " + serverConfig->hostName;
}
} else {
if (data(index, ContainsAmneziaDnsRole).toBool()) {
description += "Amnezia DNS | " + serverConfig->hostName;
}
}
return description;
}
}
} }
const QString ServersModel::getDefaultServerDescriptionCollapsed() const QString ServersModel::getDefaultServerDescriptionCollapsed()
{ {
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getServerDescription(server, m_defaultServerIndex); auto description = getServerDescription(m_defaultServerIndex);
if (configVersion) { if (configVersion) {
return description; return description;
} }
@ -233,7 +253,7 @@ const QString ServersModel::getDefaultServerDescriptionExpanded()
{ {
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getServerDescription(server, m_defaultServerIndex); auto description = getServerDescription(m_defaultServerIndex);
if (configVersion) { if (configVersion) {
return description; return description;
} }
@ -395,7 +415,6 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[IsServerFromTelegramApiRole] = "isServerFromTelegramApi"; roles[IsServerFromTelegramApiRole] = "isServerFromTelegramApi";
roles[IsServerFromGatewayApiRole] = "isServerFromGatewayApi"; roles[IsServerFromGatewayApiRole] = "isServerFromGatewayApi";
roles[ApiConfigRole] = "apiConfig";
roles[IsCountrySelectionAvailableRole] = "isCountrySelectionAvailable"; roles[IsCountrySelectionAvailableRole] = "isCountrySelectionAvailable";
roles[ApiAvailableCountriesRole] = "apiAvailableCountries"; roles[ApiAvailableCountriesRole] = "apiAvailableCountries";
roles[ApiServerCountryCodeRole] = "apiServerCountryCode"; roles[ApiServerCountryCodeRole] = "apiServerCountryCode";
@ -404,15 +423,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
ServerCredentials ServersModel::serverCredentials(int index) const ServerCredentials ServersModel::serverCredentials(int index) const
{ {
const QJsonObject &s = m_servers.at(index).toObject(); const auto serverConfig = m_servers1.at(index);
return qSharedPointerCast<SelfHostedServerConfig>(serverConfig)->serverCredentials;
ServerCredentials credentials;
credentials.hostName = s.value(config_key::hostName).toString();
credentials.userName = s.value(config_key::userName).toString();
credentials.secretData = s.value(config_key::password).toString();
credentials.port = s.value(config_key::port).toInt();
return credentials;
} }
void ServersModel::updateContainersModel() void ServersModel::updateContainersModel()
@ -670,14 +682,14 @@ bool ServersModel::isServerFromApiAlreadyExists(const QString &userCountryCode,
bool ServersModel::serverHasInstalledContainers(const int serverIndex) const bool ServersModel::serverHasInstalledContainers(const int serverIndex) const
{ {
QJsonObject server = m_servers.at(serverIndex).toObject(); auto server = m_servers1.at(serverIndex);
const auto containers = server.value(config_key::containers).toArray(); const auto containers = server->containerConfigs;
for (auto it = containers.begin(); it != containers.end(); it++) { for (const auto &container : containers) {
auto container = ContainerProps::containerFromString(it->toObject().value(config_key::container).toString()); auto dockerContainer = ContainerProps::containerFromString(container.containerName);
if (ContainerProps::containerService(container) == ServiceType::Vpn) { if (ContainerProps::containerService(dockerContainer) == ServiceType::Vpn) {
return true; return true;
} }
if (container == DockerContainer::SSXray) { if (dockerContainer == DockerContainer::SSXray) {
return true; return true;
} }
} }

View file

@ -4,6 +4,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include "core/controllers/serverController.h" #include "core/controllers/serverController.h"
#include "core/models/servers/serverConfig.h"
#include "settings.h" #include "settings.h"
class ServersModel : public QAbstractListModel class ServersModel : public QAbstractListModel
@ -36,9 +37,7 @@ public:
ApiConfigRole, ApiConfigRole,
IsCountrySelectionAvailableRole, IsCountrySelectionAvailableRole,
ApiAvailableCountriesRole, ApiAvailableCountriesRole,
ApiServerCountryCodeRole, ApiServerCountryCodeRole
HasAmneziaDns
}; };
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr); ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
@ -150,13 +149,14 @@ private:
void updateContainersModel(); void updateContainersModel();
void updateDefaultServerContainersModel(); void updateDefaultServerContainersModel();
QString getServerDescription(const QJsonObject &server, const int index) const; QString getServerDescription(const int index) const;
bool isAmneziaDnsContainerInstalled(const int serverIndex) const; bool isAmneziaDnsContainerInstalled(const int serverIndex) const;
bool serverHasInstalledContainers(const int serverIndex) const; bool serverHasInstalledContainers(const int serverIndex) const;
QJsonArray m_servers; QJsonArray m_servers;
QVector<QSharedPointer<ServerConfig>> m_servers1;
std::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;