refactoring: replaced part of the code to work with new config classes

This commit is contained in:
vladimir.kuznetsov 2025-06-26 09:57:29 +08:00
parent 2d22a74b22
commit 65f60ab922
22 changed files with 637 additions and 595 deletions

View file

@ -7,6 +7,10 @@
using namespace amnezia;
AwgProtocolConfig::AwgProtocolConfig(const QString &protocolName) : ProtocolConfig(protocolName)
{
}
AwgProtocolConfig::AwgProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
@ -68,6 +72,12 @@ AwgProtocolConfig::AwgProtocolConfig(const QJsonObject &protocolConfigObject, co
}
}
AwgProtocolConfig::AwgProtocolConfig(const AwgProtocolConfig &other) : ProtocolConfig(other.protocolName)
{
serverProtocolConfig = other.serverProtocolConfig;
clientProtocolConfig = other.clientProtocolConfig;
}
QJsonObject AwgProtocolConfig::toJson() const
{
QJsonObject json;
@ -196,3 +206,37 @@ QJsonObject AwgProtocolConfig::toJson() const
return json;
}
bool AwgProtocolConfig::hasEqualServerSettings(const AwgProtocolConfig &other) const
{
if (serverProtocolConfig.subnetAddress != other.serverProtocolConfig.subnetAddress
|| serverProtocolConfig.port != other.serverProtocolConfig.port
|| serverProtocolConfig.awgData.junkPacketCount != other.serverProtocolConfig.awgData.junkPacketCount
|| serverProtocolConfig.awgData.junkPacketMinSize != other.serverProtocolConfig.awgData.junkPacketMinSize
|| serverProtocolConfig.awgData.junkPacketMaxSize != other.serverProtocolConfig.awgData.junkPacketMaxSize
|| serverProtocolConfig.awgData.initPacketJunkSize != other.serverProtocolConfig.awgData.initPacketJunkSize
|| serverProtocolConfig.awgData.responsePacketJunkSize != other.serverProtocolConfig.awgData.responsePacketJunkSize
|| serverProtocolConfig.awgData.initPacketMagicHeader != other.serverProtocolConfig.awgData.initPacketMagicHeader
|| serverProtocolConfig.awgData.responsePacketMagicHeader != other.serverProtocolConfig.awgData.responsePacketMagicHeader
|| serverProtocolConfig.awgData.underloadPacketMagicHeader != other.serverProtocolConfig.awgData.underloadPacketMagicHeader
|| serverProtocolConfig.awgData.transportPacketMagicHeader != other.serverProtocolConfig.awgData.transportPacketMagicHeader) {
return false;
}
return true;
}
bool AwgProtocolConfig::hasEqualClientSettings(const AwgProtocolConfig &other) const
{
if (clientProtocolConfig.wireGuardData.mtu != other.clientProtocolConfig.wireGuardData.mtu
|| clientProtocolConfig.awgData.junkPacketCount != other.clientProtocolConfig.awgData.junkPacketCount
|| clientProtocolConfig.awgData.junkPacketMinSize != other.clientProtocolConfig.awgData.junkPacketMinSize
|| clientProtocolConfig.awgData.junkPacketMaxSize != other.clientProtocolConfig.awgData.junkPacketMaxSize) {
return false;
}
return true;
}
void AwgProtocolConfig::clearClientSettings()
{
clientProtocolConfig = awg::ClientProtocolConfig();
}

View file

@ -49,15 +49,24 @@ namespace awg
QString nativeConfig;
};
const int messageInitiationSize = 148;
const int messageResponseSize = 92;
}
class AwgProtocolConfig : public ProtocolConfig
{
public:
AwgProtocolConfig(const QString &protocolName);
AwgProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
AwgProtocolConfig(const AwgProtocolConfig &other);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const AwgProtocolConfig &other) const;
bool hasEqualClientSettings(const AwgProtocolConfig &other) const;
void clearClientSettings();
awg::ServerProtocolConfig serverProtocolConfig;
awg::ClientProtocolConfig clientProtocolConfig;
};

View file

@ -1,11 +1,74 @@
#include "protocolConfig.h"
#include <QJsonObject>
#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"
using namespace amnezia;
ProtocolConfig::ProtocolConfig(const QString &protocolName) : protocolName(protocolName)
{
}
ProtocolConfigVariant ProtocolConfig::getProtocolConfigVariant(const QSharedPointer<ProtocolConfig> &protocolConfig)
{
ProtocolConfigVariant variant;
auto proto = ProtocolProps::protoFromString(protocolConfig->protocolName);
switch (proto) {
case Proto::OpenVpn: variant = qSharedPointerCast<OpenVpnProtocolConfig>(protocolConfig); break;
case Proto::WireGuard: variant = qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig); break;
case Proto::ShadowSocks: variant = qSharedPointerCast<ShadowsocksProtocolConfig>(protocolConfig); break;
case Proto::Cloak: variant = qSharedPointerCast<CloakProtocolConfig>(protocolConfig); break;
case Proto::Xray: variant = qSharedPointerCast<XrayProtocolConfig>(protocolConfig); break;
case Proto::Awg: variant = qSharedPointerCast<AwgProtocolConfig>(protocolConfig); break;
default: break;
}
return variant;
}
bool ProtocolConfig::isServerSettingsEqual(const QSharedPointer<ProtocolConfig> &other)
{
auto proto = ProtocolProps::protoFromString(protocolName);
switch (proto) {
case Proto::OpenVpn: {
auto thisConfig = qSharedPointerCast<OpenVpnProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<OpenVpnProtocolConfig>(other);
return false;
}
case Proto::WireGuard: {
auto thisConfig = qSharedPointerCast<WireGuardProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<WireGuardProtocolConfig>(other);
return false;
}
case Proto::ShadowSocks: {
auto thisConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(other);
return false;
}
case Proto::Cloak: {
auto thisConfig = qSharedPointerCast<CloakProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<CloakProtocolConfig>(other);
return false;
}
case Proto::Xray: {
auto thisConfig = qSharedPointerCast<XrayProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<XrayProtocolConfig>(other);
return false;
}
case Proto::Awg: {
auto thisConfig = qSharedPointerCast<AwgProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<AwgProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
default: return false;
}
}
QJsonObject ProtocolConfig::toJson() const
{
return QJsonObject();

View file

@ -2,15 +2,30 @@
#define PROTOCOLCONFIG_H
#include <QJsonObject>
#include <QSharedPointer>
#include <variant>
class OpenVpnProtocolConfig;
class WireGuardProtocolConfig;
class ShadowsocksProtocolConfig;
class CloakProtocolConfig;
class XrayProtocolConfig;
class AwgProtocolConfig;
using ProtocolConfigVariant =
std::variant<QSharedPointer<OpenVpnProtocolConfig>, QSharedPointer<WireGuardProtocolConfig>, QSharedPointer<ShadowsocksProtocolConfig>,
QSharedPointer<CloakProtocolConfig>, QSharedPointer<XrayProtocolConfig>, QSharedPointer<AwgProtocolConfig> >;
class ProtocolConfig
{
public:
ProtocolConfig(const QString &protocolName);
virtual QJsonObject toJson() const;
static ProtocolConfigVariant getProtocolConfigVariant(const QSharedPointer<ProtocolConfig> &protocolConfig);
bool isServerSettingsEqual(const QSharedPointer<ProtocolConfig> &protocolConfig);
QString protocolName;
virtual QJsonObject toJson() const;
};
#endif // PROTOCOLCONFIG_H

View file

@ -15,10 +15,8 @@ ApiV1ServerConfig::ApiV1ServerConfig(const QJsonObject &serverConfigObject) : Se
QJsonObject ApiV1ServerConfig::toJson() const
{
// Сначала вызываем родительскую функцию для сериализации базовых полей
QJsonObject json = ServerConfig::toJson();
// Добавляем свои поля только если они не пустые
if (!name.isEmpty()) {
json[config_key::name] = name;
}

View file

@ -38,14 +38,15 @@ ApiV2ServerConfig::ApiV2ServerConfig(const QJsonObject &serverConfigObject) : Se
apiConfig.userCountryCode = apiConfigObject.value("user_country_code").toString();
apiConfig.vpnKey = apiConfigObject.value("vpn_key").toString();
auto authDataObject = serverConfigObject.value("auth_data").toObject();
apiConfig.authData.apiKey = authDataObject.value("api_key").toString();
}
QJsonObject ApiV2ServerConfig::toJson() const
{
// Сначала вызываем родительскую функцию для сериализации базовых полей
QJsonObject json = ServerConfig::toJson();
// Добавляем свои поля только если они не пустые
if (!name.isEmpty()) {
json[config_key::name] = name;
}
@ -53,10 +54,8 @@ QJsonObject ApiV2ServerConfig::toJson() const
json[config_key::description] = description;
}
// Сериализация API конфигурации
QJsonObject apiConfigJson;
// Сериализация доступных стран только если массив не пустой
if (!apiConfig.availableCountries.isEmpty()) {
QJsonArray availableCountriesArray;
for (const auto &country : apiConfig.availableCountries) {
@ -76,21 +75,18 @@ QJsonObject ApiV2ServerConfig::toJson() const
}
}
// Сериализация подписки только если есть данные
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;
}
@ -98,7 +94,6 @@ QJsonObject ApiV2ServerConfig::toJson() const
apiConfigJson["server_country_name"] = apiConfig.serverCountryName;
}
// Сериализация информации о сервисе только если не пустая
if (!apiConfig.serviceProtocol.isEmpty()) {
apiConfigJson["service_protocol"] = apiConfig.serviceProtocol;
}
@ -106,17 +101,22 @@ QJsonObject ApiV2ServerConfig::toJson() const
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 только если есть данные
QJsonObject authDataJson;
if (!apiConfig.authData.apiKey.isEmpty()) {
authDataJson["api_key"] = apiConfig.authData.apiKey;
}
if (!authDataJson.isEmpty()) {
apiConfigJson["auth_data"] = authDataJson;
}
if (!apiConfigJson.isEmpty()) {
json["api_config"] = apiConfigJson;
}

View file

@ -20,12 +20,19 @@ namespace apiv2
QString end_date;
};
struct AuthData
{
QString apiKey;
};
struct ApiConfig {
QVector<Country> availableCountries;
Subscription subscription;
PublicKey publicKey;
AuthData authData;
QString serverCountryCode;
QString serverCountryName;

View file

@ -27,6 +27,9 @@ ServerConfig::ServerConfig(const QJsonObject &serverConfigObject)
defaultContainer = serverConfigObject.value(config_key::defaultContainer).toString();
crc = serverConfigObject.value(config_key::crc).toInt(0);
nameOverriddenByUser = serverConfigObject.value(config_key::nameOverriddenByUser).toBool(false);
auto containers = serverConfigObject.value(config_key::containers).toArray();
for (const auto &container : std::as_const(containers)) {
auto containerObject = container.toObject();
@ -98,6 +101,17 @@ QSharedPointer<ServerConfig> ServerConfig::createServerConfig(const QJsonObject
}
}
ServerConfigVariant ServerConfig::getServerConfigVariant(const QSharedPointer<ServerConfig> &serverConfig)
{
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;
}
return variant;
}
QJsonObject ServerConfig::toJson() const
{
QJsonObject json;
@ -143,3 +157,11 @@ QJsonObject ServerConfig::toJson() const
return json;
}
void ServerConfig::updateProtocolConfig(const QString &containerName, const QMap<QString, QSharedPointer<ProtocolConfig>> &protocolConfigs)
{
if (containerConfigs.contains(containerName)) {
ContainerConfig &containerConfig = containerConfigs[containerName];
containerConfig.protocolConfigs = protocolConfigs;
}
}

View file

@ -8,6 +8,13 @@
#include "core/defs.h"
#include "core/models/containers/containerConfig.h"
class SelfHostedServerConfig;
class ApiV1ServerConfig;
class ApiV2ServerConfig;
using ServerConfigVariant =
std::variant<QSharedPointer<SelfHostedServerConfig>, QSharedPointer<ApiV1ServerConfig>, QSharedPointer<ApiV2ServerConfig> >;
class ServerConfig
{
public:
@ -16,6 +23,9 @@ public:
virtual QJsonObject toJson() const;
static QSharedPointer<ServerConfig> createServerConfig(const QJsonObject &serverConfigObject);
static ServerConfigVariant getServerConfigVariant(const QSharedPointer<ServerConfig> &serverConfig);
void updateProtocolConfig(const QString &containerName, const QMap<QString, QSharedPointer<ProtocolConfig>> &protocolConfigs);
amnezia::ServerConfigType type;
@ -26,6 +36,9 @@ public:
QString defaultContainer;
bool nameOverriddenByUser;
int crc; // TODO it makes sense to add for all server types or move it to the api
QMap<QString, ContainerConfig> containerConfigs;
};