mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
feat: fix auto switch
This commit is contained in:
@@ -44,8 +44,6 @@ public:
|
||||
QQmlApplicationEngine *qmlEngine() const;
|
||||
QNetworkAccessManager *networkManager();
|
||||
QClipboard *getClipboard();
|
||||
CoreController *coreController() const { return m_coreController.data(); }
|
||||
|
||||
|
||||
public slots:
|
||||
void forceQuit();
|
||||
|
||||
@@ -125,6 +125,15 @@ void CoreController::initControllers()
|
||||
connect(m_installController.get(), &InstallController::profileCleared,
|
||||
m_protocolsModel.get(), &ProtocolsModel::updateModel);
|
||||
|
||||
connect(m_connectionController.get(), &ConnectionController::requestSetCurrentProtocol,
|
||||
m_apiConfigsController.get(), &ApiConfigsController::setCurrentProtocol, Qt::QueuedConnection);
|
||||
connect(m_connectionController.get(), &ConnectionController::requestUpdateServiceFromGateway,
|
||||
m_apiConfigsController.get(), &ApiConfigsController::updateServiceFromGateway, Qt::QueuedConnection);
|
||||
|
||||
connect(m_apiConfigsController.get(), &ApiConfigsController::updateServiceFromGatewayCompleted,
|
||||
m_connectionController.get(), &ConnectionController::onUpdateServiceFromGatewayCompleted,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||
|
||||
|
||||
@@ -62,9 +62,6 @@ public:
|
||||
QQmlApplicationEngine *engine, QObject *parent = nullptr);
|
||||
|
||||
QSharedPointer<PageController> pageController() const;
|
||||
QSharedPointer<ServersModel> serversModel() const { return m_serversModel; }
|
||||
ConnectionController *connectionController() const { return m_connectionController.get(); }
|
||||
ApiConfigsController *apiConfigsController() const { return m_apiConfigsController.data(); }
|
||||
void setQmlRoot();
|
||||
|
||||
void openConnectionByIndex(int serverIndex);
|
||||
|
||||
@@ -709,9 +709,11 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const
|
||||
} else {
|
||||
emit changeApiCountryFinished(tr("Successfully changed the country of connection to %1").arg(newCountryName));
|
||||
}
|
||||
emit updateServiceFromGatewayCompleted(true, serverIndex);
|
||||
return true;
|
||||
} else {
|
||||
emit errorOccurred(errorCode);
|
||||
emit updateServiceFromGatewayCompleted(false, serverIndex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ signals:
|
||||
void changeApiCountryFinished(const QString &message);
|
||||
void reloadServerFromApiFinished(const QString &message);
|
||||
void updateServerFromApiFinished();
|
||||
void updateServiceFromGatewayCompleted(bool success, int serverIndex);
|
||||
|
||||
void vpnKeyExportReady();
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#endif
|
||||
|
||||
#include "utilities.h"
|
||||
#include "amnezia_application.h"
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/api/apiUtils.h"
|
||||
#include "containers/containers_defs.h"
|
||||
@@ -194,63 +193,21 @@ void ConnectionController::onAwgStateTimeout()
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
qDebug().noquote()
|
||||
<< "AWG connect timeout: trying to switch API protocol to VLESS"
|
||||
<< "and reload config from gateway for premium server index" << serverIndex;
|
||||
|
||||
bool apiSwitched = false;
|
||||
bool hasXray = false;
|
||||
// Store state for async operation
|
||||
m_pendingApiServerIndex = serverIndex;
|
||||
m_apiSwitched = false;
|
||||
m_waitingForApiUpdate = true;
|
||||
|
||||
if (auto app = amnApp) {
|
||||
if (auto core = app->coreController()) {
|
||||
if (auto api = core->apiConfigsController()) {
|
||||
qDebug().noquote()
|
||||
<< "AWG connect timeout: trying to switch API protocol to VLESS"
|
||||
<< "and reload config from gateway for premium server index" << serverIndex;
|
||||
|
||||
m_serversModel->setProcessedServerIndex(serverIndex);
|
||||
api->setCurrentProtocol(QStringLiteral("vless"));
|
||||
apiSwitched = api->updateServiceFromGateway(serverIndex, QString(), QString(), true);
|
||||
|
||||
if (apiSwitched) {
|
||||
const QJsonObject newServerConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
const QJsonArray newContainers = newServerConfig.value(config_key::containers).toArray();
|
||||
for (const QJsonValue &value : newContainers) {
|
||||
const QJsonObject obj = value.toObject();
|
||||
const DockerContainer c =
|
||||
ContainerProps::containerFromString(obj.value(config_key::container).toString());
|
||||
if (c == DockerContainer::Xray) {
|
||||
hasXray = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasXray) {
|
||||
qDebug().noquote()
|
||||
<< "AWG connect timeout: no XRay available for server index" << serverIndex
|
||||
<< "(API switch attempt success =" << (apiSwitched ? "YES" : "NO") << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug().noquote() << "AWG connect timeout (10s), switching default container to XRay for server index"
|
||||
<< serverIndex << "and reconnecting";
|
||||
|
||||
m_serversModel->setDefaultContainer(serverIndex, static_cast<int>(DockerContainer::Xray));
|
||||
|
||||
if (auto app = amnApp) {
|
||||
if (auto core = app->coreController()) {
|
||||
if (auto api = core->apiConfigsController()) {
|
||||
m_serversModel->setProcessedServerIndex(serverIndex);
|
||||
api->setCurrentProtocol(QStringLiteral("vless"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_isConnected && !m_isConnectionInProgress) {
|
||||
emit prepareConfig();
|
||||
}
|
||||
m_serversModel->setProcessedServerIndex(serverIndex);
|
||||
|
||||
emit requestSetCurrentProtocol(QStringLiteral("vless"));
|
||||
emit requestUpdateServiceFromGateway(serverIndex, QString(), QString(), true);
|
||||
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -306,6 +263,53 @@ bool ConnectionController::isConnected() const
|
||||
return m_isConnected;
|
||||
}
|
||||
|
||||
void ConnectionController::onUpdateServiceFromGatewayCompleted(bool success, int serverIndex)
|
||||
{
|
||||
if (!m_waitingForApiUpdate || m_pendingApiServerIndex != serverIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_waitingForApiUpdate = false;
|
||||
m_apiSwitched = success;
|
||||
bool hasXray = false;
|
||||
|
||||
if (success) {
|
||||
const QJsonObject newServerConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
const QJsonArray newContainers = newServerConfig.value(config_key::containers).toArray();
|
||||
for (const QJsonValue &value : newContainers) {
|
||||
const QJsonObject obj = value.toObject();
|
||||
const DockerContainer c =
|
||||
ContainerProps::containerFromString(obj.value(config_key::container).toString());
|
||||
if (c == DockerContainer::Xray) {
|
||||
hasXray = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasXray) {
|
||||
qDebug().noquote()
|
||||
<< "AWG connect timeout: no XRay available for server index" << serverIndex
|
||||
<< "(API switch attempt success =" << (m_apiSwitched ? "YES" : "NO") << ")";
|
||||
m_pendingApiServerIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug().noquote() << "AWG connect timeout (10s), switching default container to XRay for server index"
|
||||
<< serverIndex << "and reconnecting";
|
||||
|
||||
m_serversModel->setDefaultContainer(serverIndex, static_cast<int>(DockerContainer::Xray));
|
||||
|
||||
m_serversModel->setProcessedServerIndex(serverIndex);
|
||||
emit requestSetCurrentProtocol(QStringLiteral("vless"));
|
||||
|
||||
m_pendingApiServerIndex = -1;
|
||||
|
||||
if (!m_isConnected && !m_isConnectionInProgress) {
|
||||
emit prepareConfig();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionController::checkAndStartAwgStateTimer()
|
||||
{
|
||||
const int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
|
||||
@@ -41,6 +41,7 @@ public slots:
|
||||
void onTranslationsUpdated();
|
||||
|
||||
void checkAndStartAwgStateTimer();
|
||||
void onUpdateServiceFromGatewayCompleted(bool success, int serverIndex);
|
||||
|
||||
private slots:
|
||||
void onAwgStateTimeout();
|
||||
@@ -57,6 +58,9 @@ signals:
|
||||
void preparingConfig();
|
||||
void prepareConfig();
|
||||
|
||||
void requestSetCurrentProtocol(const QString &protocolName);
|
||||
void requestUpdateServiceFromGateway(int serverIndex, const QString &newCountryCode, const QString &newCountryName, bool reloadServiceConfig);
|
||||
|
||||
private:
|
||||
Vpn::ConnectionState getCurrentConnectionState();
|
||||
|
||||
@@ -76,6 +80,11 @@ private:
|
||||
QString m_connectionStateText = tr("Connect");
|
||||
|
||||
Vpn::ConnectionState m_state;
|
||||
|
||||
// State for async API operations
|
||||
int m_pendingApiServerIndex = -1;
|
||||
bool m_apiSwitched = false;
|
||||
bool m_waitingForApiUpdate = false;
|
||||
};
|
||||
|
||||
#endif // CONNECTIONCONTROLLER_H
|
||||
|
||||
Reference in New Issue
Block a user