From 4b1a0c078874822dbfb5d40cd9dfdbb074d84f6c Mon Sep 17 00:00:00 2001 From: dranik Date: Thu, 30 Apr 2026 16:53:17 +0300 Subject: [PATCH] fixed changes --- .../core/configurators/xrayConfigurator.cpp | 50 +++++++----- .../models/protocols/xrayProtocolConfig.cpp | 81 ++++++++++++------- .../models/protocols/xrayProtocolConfig.h | 16 ++-- .../ui/models/protocols/xrayConfigModel.cpp | 16 +++- .../qml/Pages2/PageProtocolXraySettings.qml | 24 +++--- 5 files changed, 113 insertions(+), 74 deletions(-) diff --git a/client/core/configurators/xrayConfigurator.cpp b/client/core/configurators/xrayConfigurator.cpp index e50110067..1d6e2240a 100644 --- a/client/core/configurators/xrayConfigurator.cpp +++ b/client/core/configurators/xrayConfigurator.cpp @@ -1,29 +1,28 @@ #include "xrayConfigurator.h" -#include "logger.h" #include -#include #include #include +#include #include +#include "logger.h" -#include "core/models/containerConfig.h" -#include "core/models/protocolConfig.h" -#include "core/models/protocols/xrayProtocolConfig.h" -#include "core/protocols/protocolUtils.h" -#include "core/utils/constants/configKeys.h" -#include "core/utils/constants/protocolConstants.h" #include "core/utils/containerEnum.h" #include "core/utils/containers/containerUtils.h" #include "core/utils/protocolEnum.h" -#include "core/utils/selfhosted/scriptsRegistry.h" #include "core/utils/selfhosted/sshSession.h" +#include "core/utils/selfhosted/scriptsRegistry.h" +#include "core/utils/protocolEnum.h" +#include "core/protocols/protocolUtils.h" +#include "core/utils/constants/configKeys.h" +#include "core/utils/constants/protocolConstants.h" +#include "core/models/containerConfig.h" +#include "core/models/protocols/xrayProtocolConfig.h" -namespace -{ +namespace { Logger logger("XrayConfigurator"); - QString normalizeXhttpMode(const QString &m) - { + + QString normalizeXhttpMode(const QString &m) { const QString t = m.trimmed(); if (t.isEmpty() || t.compare(QLatin1String("Auto"), Qt::CaseInsensitive) == 0) { return QStringLiteral("auto"); @@ -416,9 +415,9 @@ QJsonObject XrayConfigurator::buildStreamSettings(const XrayServerConfig &srv, c } ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, - const ContainerConfig &containerConfig, - const DnsSettings &dnsSettings, - ErrorCode &errorCode) + const ContainerConfig &containerConfig, + const DnsSettings &dnsSettings, + ErrorCode &errorCode) { const XrayServerConfig *serverConfig = nullptr; if (const auto *xrayCfg = containerConfig.protocolConfig.as()) { @@ -428,7 +427,7 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia if (!serverConfig) { logger.error() << "No XrayProtocolConfig found"; errorCode = ErrorCode::InternalError; - return XrayProtocolConfig {}; + return XrayProtocolConfig{}; } const XrayServerConfig &srv = *serverConfig; @@ -436,7 +435,10 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia QString xrayClientId = prepareServerConfig(credentials, container, containerConfig, dnsSettings, errorCode); if (errorCode != ErrorCode::NoError || xrayClientId.isEmpty()) { logger.error() << "Failed to prepare server config"; - return XrayProtocolConfig {}; + if (errorCode == ErrorCode::NoError) { + errorCode = ErrorCode::InternalError; + } + return XrayProtocolConfig{}; } // Fetch server keys (Reality only) @@ -448,7 +450,10 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia amnezia::protocols::xray::PublicKeyPath, errorCode); if (errorCode != ErrorCode::NoError || xrayPublicKey.isEmpty()) { logger.error() << "Failed to get public key"; - return XrayProtocolConfig {}; + if (errorCode == ErrorCode::NoError) { + errorCode = ErrorCode::InternalError; + } + return XrayProtocolConfig{}; } xrayPublicKey.replace("\n", ""); @@ -456,7 +461,10 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia amnezia::protocols::xray::shortidPath, errorCode); if (errorCode != ErrorCode::NoError || xrayShortId.isEmpty()) { logger.error() << "Failed to get short ID"; - return XrayProtocolConfig {}; + if (errorCode == ErrorCode::NoError) { + errorCode = ErrorCode::InternalError; + } + return XrayProtocolConfig{}; } xrayShortId.replace("\n", ""); } @@ -522,4 +530,4 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia protocolConfig.setClientConfig(clientConfig); return protocolConfig; -} +} \ No newline at end of file diff --git a/client/core/models/protocols/xrayProtocolConfig.cpp b/client/core/models/protocols/xrayProtocolConfig.cpp index 194559e90..78ce75892 100644 --- a/client/core/models/protocols/xrayProtocolConfig.cpp +++ b/client/core/models/protocols/xrayProtocolConfig.cpp @@ -170,23 +170,46 @@ QJsonObject XrayServerConfig::toJson() const QJsonObject obj; // Existing fields - if (!port.isEmpty()) obj[configKey::port] = port; - if (!transportProto.isEmpty()) obj[configKey::transportProto] = transportProto; - if (!subnetAddress.isEmpty()) obj[configKey::subnetAddress] = subnetAddress; - if (!site.isEmpty()) obj[configKey::site] = site; - if (isThirdPartyConfig) obj[configKey::isThirdPartyConfig] = isThirdPartyConfig; + if (!port.isEmpty()) { + obj[configKey::port] = port; + } + if (!transportProto.isEmpty()) { + obj[configKey::transportProto] = transportProto; + } + if (!subnetAddress.isEmpty()) { + obj[configKey::subnetAddress] = subnetAddress; + } + if (!site.isEmpty()) { + obj[configKey::site] = site; + } + + if (isThirdPartyConfig) { + obj[configKey::isThirdPartyConfig] = isThirdPartyConfig; + } // New: Security - if (!security.isEmpty()) obj[configKey::xraySecurity] = security; - if (!flow.isEmpty()) obj[configKey::xrayFlow] = flow; - if (!fingerprint.isEmpty()) obj[configKey::xrayFingerprint] = fingerprint; - if (!sni.isEmpty()) obj[configKey::xraySni] = sni; - if (!alpn.isEmpty()) obj[configKey::xrayAlpn] = alpn; + if (!security.isEmpty()) { + obj[configKey::xraySecurity] = security; + } + if (!flow.isEmpty()) { + obj[configKey::xrayFlow] = flow; + } + if (!fingerprint.isEmpty()) { + obj[configKey::xrayFingerprint] = fingerprint; + } + if (!sni.isEmpty()) { + obj[configKey::xraySni] = sni; + } + if (!alpn.isEmpty()) { + obj[configKey::xrayAlpn] = alpn; + } // New: Transport - if (!transport.isEmpty()) obj[configKey::xrayTransport] = transport; + if (!transport.isEmpty()) { + obj[configKey::xrayTransport] = transport; + } obj["xhttp"] = xhttp.toJson(); - obj["mkcp"] = mkcp.toJson(); + obj["mkcp"] = mkcp.toJson(); return obj; } @@ -196,39 +219,39 @@ XrayServerConfig XrayServerConfig::fromJson(const QJsonObject &json) XrayServerConfig c; // Existing fields - c.port = json.value(configKey::port).toString(); - c.transportProto = json.value(configKey::transportProto).toString(); - c.subnetAddress = json.value(configKey::subnetAddress).toString(); - c.site = json.value(configKey::site).toString(); + c.port = json.value(configKey::port).toString(); + c.transportProto = json.value(configKey::transportProto).toString(); + c.subnetAddress = json.value(configKey::subnetAddress).toString(); + c.site = json.value(configKey::site).toString(); c.isThirdPartyConfig = json.value(configKey::isThirdPartyConfig).toBool(false); // New: Security - c.security = json.value(configKey::xraySecurity).toString(protocols::xray::defaultSecurity); - c.flow = json.value(configKey::xrayFlow).toString(protocols::xray::defaultFlow); + c.security = json.value(configKey::xraySecurity).toString(protocols::xray::defaultSecurity); + c.flow = json.value(configKey::xrayFlow).toString(protocols::xray::defaultFlow); c.fingerprint = json.value(configKey::xrayFingerprint).toString(protocols::xray::defaultFingerprint); if (c.fingerprint.contains(QLatin1String("Mozilla/5.0"), Qt::CaseInsensitive)) { c.fingerprint = QString::fromLatin1(protocols::xray::defaultFingerprint); } - c.sni = json.value(configKey::xraySni).toString(protocols::xray::defaultSni); - c.alpn = json.value(configKey::xrayAlpn).toString(protocols::xray::defaultAlpn); + c.sni = json.value(configKey::xraySni).toString(protocols::xray::defaultSni); + c.alpn = json.value(configKey::xrayAlpn).toString(protocols::xray::defaultAlpn); // New: Transport c.transport = json.value(configKey::xrayTransport).toString(protocols::xray::defaultTransport); - c.xhttp = XrayXhttpConfig::fromJson(json.value("xhttp").toObject()); - c.mkcp = XrayMkcpConfig::fromJson(json.value("mkcp").toObject()); + c.xhttp = XrayXhttpConfig::fromJson(json.value("xhttp").toObject()); + c.mkcp = XrayMkcpConfig::fromJson(json.value("mkcp").toObject()); return c; } bool XrayServerConfig::hasEqualServerSettings(const XrayServerConfig &other) const { - return port == other.port - && site == other.site - && security == other.security - && flow == other.flow - && transport == other.transport - && fingerprint == other.fingerprint - && sni == other.sni; + return port == other.port + && site == other.site + && security == other.security + && flow == other.flow + && transport == other.transport + && fingerprint == other.fingerprint + && sni == other.sni; } QJsonObject XrayClientConfig::toJson() const diff --git a/client/core/models/protocols/xrayProtocolConfig.h b/client/core/models/protocols/xrayProtocolConfig.h index 73c160bc7..eaf9abfd2 100644 --- a/client/core/models/protocols/xrayProtocolConfig.h +++ b/client/core/models/protocols/xrayProtocolConfig.h @@ -93,26 +93,26 @@ struct XrayMkcpConfig { // ── Server config (settings editable by user) ───────────────────────────────── struct XrayServerConfig { - // Existing fields QString port; QString transportProto; QString subnetAddress; QString site; - bool isThirdPartyConfig = false; + bool isThirdPartyConfig = false; // New: Security - QString security = protocols::xray::defaultSecurity; - QString flow = protocols::xray::defaultFlow; + QString security = protocols::xray::defaultSecurity; + QString flow = protocols::xray::defaultFlow; QString fingerprint = protocols::xray::defaultFingerprint; - QString sni = protocols::xray::defaultSni; - QString alpn = protocols::xray::defaultAlpn; + QString sni = protocols::xray::defaultSni; + QString alpn = protocols::xray::defaultAlpn; // New: Transport QString transport = protocols::xray::defaultTransport; XrayXhttpConfig xhttp; - XrayMkcpConfig mkcp; + XrayMkcpConfig mkcp; QJsonObject toJson() const; + static XrayServerConfig fromJson(const QJsonObject &json); bool hasEqualServerSettings(const XrayServerConfig &other) const; @@ -130,7 +130,7 @@ struct XrayClientConfig { // ── Top-level protocol config ────────────────────────────────────────────────── struct XrayProtocolConfig { - XrayServerConfig serverConfig; + XrayServerConfig serverConfig; std::optional clientConfig; QJsonObject toJson() const; diff --git a/client/ui/models/protocols/xrayConfigModel.cpp b/client/ui/models/protocols/xrayConfigModel.cpp index 6e215afcf..e81c7d76c 100644 --- a/client/ui/models/protocols/xrayConfigModel.cpp +++ b/client/ui/models/protocols/xrayConfigModel.cpp @@ -167,8 +167,7 @@ bool XrayConfigModel::setData(const QModelIndex& index, const QVariant& value, i QVariant XrayConfigModel::data(const QModelIndex& index, int role) const { - if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) - { + if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) { return QVariant(); } @@ -252,14 +251,18 @@ QVariant XrayConfigModel::data(const QModelIndex& index, int role) const return QVariant(); } -void XrayConfigModel::updateModel(amnezia::DockerContainer container, - const amnezia::XrayProtocolConfig& protocolConfig) +void XrayConfigModel::updateModel(amnezia::DockerContainer container, const amnezia::XrayProtocolConfig& protocolConfig) { beginResetModel(); + m_container = container; + m_protocolConfig = protocolConfig; + applyDefaultsToServerConfig(m_protocolConfig.serverConfig); + m_originalProtocolConfig = m_protocolConfig; + endResetModel(); } @@ -269,6 +272,11 @@ void XrayConfigModel::applyDefaultsToServerConfig(amnezia::XrayServerConfig &con config.port = protocols::xray::defaultPort; } + if (config.transportProto.isEmpty()) { + config.transportProto = ProtocolUtils::transportProtoToString( + ProtocolUtils::defaultTransportProto(amnezia::Proto::Xray), amnezia::Proto::Xray); + } + if (config.site.isEmpty()) { config.site = protocols::xray::defaultSite; } diff --git a/client/ui/qml/Pages2/PageProtocolXraySettings.qml b/client/ui/qml/Pages2/PageProtocolXraySettings.qml index b0188b7fb..39509fc04 100644 --- a/client/ui/qml/Pages2/PageProtocolXraySettings.qml +++ b/client/ui/qml/Pages2/PageProtocolXraySettings.qml @@ -46,7 +46,7 @@ PageType { delegate: ColumnLayout { width: listView.width - property alias focusItemId: portTextField.textField + property alias focusItemId: textFieldWithHeaderType.textField spacing: 0 @@ -87,7 +87,7 @@ PageType { } TextFieldWithHeaderType { - id: portTextField + id: textFieldWithHeaderType Layout.fillWidth: true Layout.topMargin: 32 Layout.leftMargin: 16 @@ -112,7 +112,7 @@ PageType { descriptionText: transport rightImageSource: "qrc:/images/controls/chevron-right.svg" enabled: listView.enabled - clickedFunction: function () { + clickedFunction: function() { PageController.goToPage(PageEnum.PageProtocolXrayTransportSettings) } } @@ -126,7 +126,7 @@ PageType { descriptionText: security rightImageSource: "qrc:/images/controls/chevron-right.svg" enabled: listView.enabled - clickedFunction: function () { + clickedFunction: function() { PageController.goToPage(PageEnum.PageProtocolXraySecuritySettings) } } @@ -140,7 +140,7 @@ PageType { descriptionText: flow rightImageSource: "qrc:/images/controls/chevron-right.svg" enabled: listView.enabled - clickedFunction: function () { + clickedFunction: function() { PageController.goToPage(PageEnum.PageProtocolXrayFlowSettings) } } @@ -158,15 +158,15 @@ PageType { Layout.bottomMargin: 8 Layout.leftMargin: 16 Layout.rightMargin: 16 - enabled: portTextField.errorText === "" + enabled: textFieldWithHeaderType.errorText === "" text: qsTr("Save") - onClicked: function () { + onClicked: function() { forceActiveFocus() var headerText = qsTr("Save settings?") var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.") var yesButtonText = qsTr("Continue") var noButtonText = qsTr("Cancel") - var yesButtonFunction = function () { + var yesButtonFunction = function() { if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) { PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) return @@ -174,7 +174,7 @@ PageType { PageController.goToPage(PageEnum.PageSetupWizardInstalling) InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) } - var noButtonFunction = function () { + var noButtonFunction = function() { if (!GC.isMobile()) saveButton.forceActiveFocus() } showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) @@ -188,12 +188,12 @@ PageType { text: qsTr("Reset settings") textColor: AmneziaStyle.color.vibrantRed visible: listView.enabled - clickedFunction: function () { - var yesButtonFunction = function () { + clickedFunction: function() { + var yesButtonFunction = function() { XrayConfigModel.resetToDefaults() } showQuestionDrawer(qsTr("Reset settings?"), qsTr("All XRay settings will be restored to defaults."), - qsTr("Reset"), qsTr("Cancel"), yesButtonFunction, function () { + qsTr("Reset"), qsTr("Cancel"), yesButtonFunction, function() { }) } }