added implementation of V2RayConfigurator and V2RayProtocol classes

This commit is contained in:
vladimir.kuznetsov 2023-02-10 20:07:17 +03:00
parent 8032e55d7c
commit 7d51cb7d58
24 changed files with 369 additions and 20 deletions

View file

@ -1,13 +1,70 @@
#include "v2ray_configurator.h" #include "v2ray_configurator.h"
#include <QFile>
#include <QPair>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include "core/servercontroller.h"
#include "containers/containers_defs.h"
V2RayConfigurator::V2RayConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, V2RayConfigurator::V2RayConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController,
QObject *parent) : ConfiguratorBase(settings, serverController, parent) QObject *parent) : ConfiguratorBase(settings, serverController, parent)
{ {
} }
QString V2RayConfigurator::genCloakConfig(const ServerCredentials &credentials, DockerContainer container, QString V2RayConfigurator::genV2RayConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode) const QJsonObject &containerConfig, ErrorCode *errorCode)
{ {
return ""; ErrorCode e = ErrorCode::NoError;
QString v2rayVmessClientUuid = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::v2ray::v2rayKeyPath, &e);
v2rayVmessClientUuid.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
return "";
}
QJsonObject config;
QJsonObject inboundsSocks;
inboundsSocks.insert("protocol", "socks");
inboundsSocks.insert("listen", "127.0.0.1");
inboundsSocks.insert("port", 1080); //todo
QJsonObject socksSettings;
socksSettings.insert("auth", "noauth");
socksSettings.insert("udp", true);
inboundsSocks.insert("settings", socksSettings);
QJsonArray inbounds;
inbounds.push_back(inboundsSocks);
config.insert("inbounds", inbounds);
QJsonObject outboundsVmess;
outboundsVmess.insert("protocol", "vmess");
QJsonObject vmessSettings;
QJsonObject vnext;
vnext.insert("address", credentials.hostName);
vnext.insert("port", 10086); //todo
QJsonObject users;
users.insert("id", v2rayVmessClientUuid);
vnext.insert("users", QJsonArray({users}));
vmessSettings.insert("vnext", QJsonArray({vnext}));
outboundsVmess.insert("settings", vmessSettings);
QJsonArray outbounds;
outbounds.push_back(outboundsVmess);
config.insert("outbounds", outbounds);
QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
m_serverController->genVarsForScript(credentials, container, containerConfig));
// qDebug().noquote() << textCfg;
return textCfg;
} }

View file

@ -13,7 +13,7 @@ public:
V2RayConfigurator(std::shared_ptr<Settings> settings, V2RayConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr); std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container, QString genV2RayConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
}; };

View file

@ -5,6 +5,7 @@
#include "wireguard_configurator.h" #include "wireguard_configurator.h"
#include "ikev2_configurator.h" #include "ikev2_configurator.h"
#include "ssh_configurator.h" #include "ssh_configurator.h"
#include "v2ray_configurator.h"
#include <QFile> #include <QFile>
#include <QJsonObject> #include <QJsonObject>
@ -24,6 +25,7 @@ VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings,
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, serverController, this)); wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, serverController, this));
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, serverController, this)); ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, serverController, this));
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, serverController, this)); sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, serverController, this));
v2RayConfigurator = std::shared_ptr<V2RayConfigurator>(new V2RayConfigurator(settings, serverController, this));
} }
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
@ -45,6 +47,9 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
case Proto::Ikev2: case Proto::Ikev2:
return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode); return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
case Proto::V2Ray:
return v2RayConfigurator->genV2RayConfig(credentials, container, containerConfig, errorCode);
default: default:
return ""; return "";
} }

View file

@ -13,6 +13,7 @@ class CloakConfigurator;
class WireguardConfigurator; class WireguardConfigurator;
class Ikev2Configurator; class Ikev2Configurator;
class SshConfigurator; class SshConfigurator;
class V2RayConfigurator;
// Retrieve connection settings from server // Retrieve connection settings from server
class VpnConfigurator : ConfiguratorBase class VpnConfigurator : ConfiguratorBase
@ -43,6 +44,7 @@ public:
std::shared_ptr<WireguardConfigurator> wireguardConfigurator; std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
std::shared_ptr<Ikev2Configurator> ikev2Configurator; std::shared_ptr<Ikev2Configurator> ikev2Configurator;
std::shared_ptr<SshConfigurator> sshConfigurator; std::shared_ptr<SshConfigurator> sshConfigurator;
std::shared_ptr<V2RayConfigurator> v2RayConfigurator;
}; };
#endif // VPN_CONFIGURATOR_H #endif // VPN_CONFIGURATOR_H

View file

@ -46,7 +46,7 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
return { Proto::Ikev2 /*, Protocol::L2tp */}; return { Proto::Ikev2 /*, Protocol::L2tp */};
case DockerContainer::V2Ray: case DockerContainer::V2Ray:
return { Proto::V2Ray }; return { Proto::OpenVpn, Proto::V2Ray };
case DockerContainer::Dns: case DockerContainer::Dns:
return { }; return { };

View file

@ -54,6 +54,7 @@ enum ErrorCode
ShadowSocksExecutableMissing, ShadowSocksExecutableMissing,
CloakExecutableMissing, CloakExecutableMissing,
AmneziaServiceConnectionFailed, AmneziaServiceConnectionFailed,
V2RayExecutableMissing,
ExecutableMissing, ExecutableMissing,
// VPN errors // VPN errors

View file

@ -42,6 +42,7 @@ QString errorString(ErrorCode code){
case (ShadowSocksExecutableMissing): return QObject::tr("ShadowSocks (ss-local) executable missing"); case (ShadowSocksExecutableMissing): return QObject::tr("ShadowSocks (ss-local) executable missing");
case (CloakExecutableMissing): return QObject::tr("Cloak (ck-client) executable missing"); case (CloakExecutableMissing): return QObject::tr("Cloak (ck-client) executable missing");
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error"); case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
case (V2RayExecutableMissing): return QObject::tr("V2Ray (v2ray) executable missing");
case (OpenSslFailed): return QObject::tr("OpenSSL failed"); case (OpenSslFailed): return QObject::tr("OpenSSL failed");
// VPN errors // VPN errors

View file

@ -667,6 +667,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject(); const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject(); const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject(); const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
const QJsonObject &v2RayConfig = config.value(ProtocolProps::protoToString(Proto::V2Ray)).toObject();
// //
Vars vars; Vars vars;
@ -718,6 +719,10 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }}); vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
// V2Ray vars
vars.append({{"$V2RAY_SERVER_PORT", v2RayConfig.value(config_key::port).toString(protocols::v2ray::defaultLocalPort) }});
vars.append({{"$V2RAY_LOCAL_PORT", v2RayConfig.value(config_key::local_port).toString(protocols::v2ray::defaultServerPort) }});
// IPsec vars // IPsec vars
vars.append({{"$IPSEC_VPN_L2TP_NET", "192.168.42.0/24"}}); vars.append({{"$IPSEC_VPN_L2TP_NET", "192.168.42.0/24"}});
vars.append({{"$IPSEC_VPN_L2TP_POOL", "192.168.42.10-192.168.42.250"}}); vars.append({{"$IPSEC_VPN_L2TP_POOL", "192.168.42.10-192.168.42.250"}});

View file

@ -49,9 +49,9 @@ void ManagementServer::onNewConnection()
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection()); m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
if (m_tcpServer) m_tcpServer->close(); if (m_tcpServer) m_tcpServer->close();
QObject::connect(m_socket.data(), SIGNAL(disconnected()), this, SLOT(onSocketDisconnected())); QObject::connect(m_socket.data(), &QTcpSocket::disconnected, this, &ManagementServer::onSocketDisconnected);
QObject::connect(m_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError))); QObject::connect(m_socket.data(), &QTcpSocket::errorOccurred, this, &ManagementServer::onSocketError);
QObject::connect(m_socket.data(), SIGNAL(readyRead()), this, SLOT(onReadyRead())); QObject::connect(m_socket.data(), &QTcpSocket::readyRead, this, &ManagementServer::onReadyRead);
} }
void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError) void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError)

View file

@ -116,7 +116,7 @@ int ProtocolProps::defaultPort(Proto p)
case Proto::WireGuard : return 51820; case Proto::WireGuard : return 51820;
case Proto::Ikev2 : return -1; case Proto::Ikev2 : return -1;
case Proto::L2tp : return -1; case Proto::L2tp : return -1;
case Proto::V2Ray : return -1; case Proto::V2Ray : return 10086;
case Proto::TorWebSite : return -1; case Proto::TorWebSite : return -1;
case Proto::Dns : return 53; case Proto::Dns : return 53;
@ -181,7 +181,7 @@ bool ProtocolProps::defaultTransportProtoChangeable(Proto p)
case Proto::Dns : return false; case Proto::Dns : return false;
case Proto::FileShare : return false; case Proto::FileShare : return false;
case Proto::Sftp : return false; case Proto::Sftp : return false;
default: return false; default: return false;
} }
} }

View file

@ -124,6 +124,12 @@ constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
} }
namespace v2ray {
constexpr char v2rayKeyPath[] = "/opt/amnezia/v2ray/v2ray.key";
constexpr char defaultLocalPort[] = "1080";
constexpr char defaultServerPort[] = "10086";
}
namespace sftp { namespace sftp {
constexpr char defaultUserName[] = "sftp_user"; constexpr char defaultUserName[] = "sftp_user";

View file

@ -1,33 +1,104 @@
#include "v2rayprotocol.h" #include "v2rayprotocol.h"
#include <QThread>
#include <QFileInfo>
#include <QJsonDocument>
#include "utilities.h" #include "utilities.h"
V2RayProtocol::V2RayProtocol(const QJsonObject &configuration, QObject *parent) : VpnProtocol(configuration, parent) V2RayProtocol::V2RayProtocol(const QJsonObject &configuration, QObject *parent) : OpenVpnProtocol(configuration, parent)
{ {
writeV2RayConfiguration(configuration); writeV2RayConfiguration(configuration);
} }
V2RayProtocol::~V2RayProtocol() V2RayProtocol::~V2RayProtocol()
{ {
qDebug() << "V2RayProtocol::~V2RayProtocol";
V2RayProtocol::stop();
QThread::msleep(200);
} }
ErrorCode V2RayProtocol::start() ErrorCode V2RayProtocol::start()
{ {
#ifndef Q_OS_IOS
if (!QFileInfo::exists(v2RayExecPath())) {
setLastError(ErrorCode::V2RayExecutableMissing);
return lastError();
}
if (Utils::processIsRunning(Utils::executable("v2ray", false))) {
Utils::killProcessByName(Utils::executable("v2ray", false));
}
QStringList args = QStringList() << "-c" << m_v2RayConfigFile.fileName();
qDebug().noquote() << "ShadowSocksVpnProtocol::start()"
<< v2RayExecPath() << args.join(" ");
m_v2RayProcess.setProcessChannelMode(QProcess::MergedChannels);
m_v2RayProcess.setProgram(v2RayExecPath());
m_v2RayProcess.setArguments(args);
connect(&m_v2RayProcess, &QProcess::readyReadStandardOutput, this, [this](){
qDebug().noquote() << "v2ray:" << m_v2RayProcess.readAllStandardOutput();
});
connect(&m_v2RayProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
qDebug().noquote() << "V2RayProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
setConnectionState(VpnProtocol::Disconnected);
if (exitStatus != QProcess::NormalExit){
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed); //todo
stop();
}
if (exitCode != 0 ) {
emit protocolError(amnezia::ErrorCode::InternalError);
stop();
}
});
m_v2RayProcess.start();
m_v2RayProcess.waitForStarted();
if (m_v2RayProcess.state() == QProcess::ProcessState::Running) {
setConnectionState(VpnConnectionState::Connecting);
return OpenVpnProtocol::start();
}
else return ErrorCode::ShadowSocksExecutableMissing;
#else
return ErrorCode::NotImplementedError;
#endif
return ErrorCode::NoError; return ErrorCode::NoError;
} }
void V2RayProtocol::stop() void V2RayProtocol::stop()
{ {
OpenVpnProtocol::stop();
qDebug() << "V2RayProtocol::stop()";
#ifndef Q_OS_IOS
m_v2RayProcess.terminate();
#endif
#ifdef Q_OS_WIN
Utils::signalCtrl(m_v2RayProcess.processId(), CTRL_C_EVENT);
#endif
} }
void V2RayProtocol::writeV2RayConfiguration(const QJsonObject &configuration) void V2RayProtocol::writeV2RayConfiguration(const QJsonObject &configuration)
{ {
m_v2RayConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::V2Ray)).toObject();
#ifdef QT_DEBUG
m_v2RayConfigFile.setAutoRemove(false);
#endif
m_v2RayConfigFile.open();
m_v2RayConfigFile.write(QJsonDocument(m_v2RayConfig).toJson());
m_v2RayConfigFile.close();
} }
const QString V2RayProtocol::v2rayExecPath() const const QString V2RayProtocol::v2RayExecPath() const
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return Utils::executable(QString("v2ray/v2ray"), true); return Utils::executable(QString("v2ray/v2ray"), true);

View file

@ -1,9 +1,12 @@
#ifndef V2RAYPROTOCOL_H #ifndef V2RAYPROTOCOL_H
#define V2RAYPROTOCOL_H #define V2RAYPROTOCOL_H
#include "vpnprotocol.h" #include "QProcess"
#include "QTemporaryFile"
class V2RayProtocol : public VpnProtocol #include "openvpnprotocol.h"
class V2RayProtocol : public OpenVpnProtocol
{ {
public: public:
V2RayProtocol(const QJsonObject& configuration, QObject* parent = nullptr); V2RayProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
@ -13,10 +16,15 @@ public:
void stop() override; void stop() override;
private: private:
QJsonObject m_shadowSocksConfig; QJsonObject m_v2RayConfig;
QTemporaryFile m_v2RayConfigFile;
#ifndef Q_OS_IOS
QProcess m_v2RayProcess;
#endif
void writeV2RayConfiguration(const QJsonObject &configuration); void writeV2RayConfiguration(const QJsonObject &configuration);
const QString v2rayExecPath() const; const QString v2RayExecPath() const;
}; };
#endif // V2RAYPROTOCOL_H #endif // V2RAYPROTOCOL_H

View file

@ -164,5 +164,11 @@
<file>images/svg/settings_suggest_black_24dp.svg</file> <file>images/svg/settings_suggest_black_24dp.svg</file>
<file>server_scripts/website_tor/Dockerfile</file> <file>server_scripts/website_tor/Dockerfile</file>
<file>ui/qml/Controls/PopupWithQuestion.qml</file> <file>ui/qml/Controls/PopupWithQuestion.qml</file>
<file>ui/qml/Pages/Protocols/PageProtoV2Ray.qml</file>
<file>server_scripts/openvpn_v2ray_vmess/configure_container.sh</file>
<file>server_scripts/openvpn_v2ray_vmess/Dockerfile</file>
<file>server_scripts/openvpn_v2ray_vmess/run_container.sh</file>
<file>server_scripts/openvpn_v2ray_vmess/start.sh</file>
<file>server_scripts/openvpn_v2ray_vmess/template.ovpn</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -1 +1 @@
sudo docker build -t $CONTAINER_NAME $DOCKERFILE_FOLDER --build-arg SERVER_ARCH=$(uname -m) sudo docker build --network host -t $CONTAINER_NAME $DOCKERFILE_FOLDER --build-arg SERVER_ARCH=$(uname -m)

View file

@ -26,11 +26,15 @@ $OPENVPN_TLS_AUTH
$OPENVPN_ADDITIONAL_SERVER_CONFIG $OPENVPN_ADDITIONAL_SERVER_CONFIG
EOF EOF
# V2RAY_VMESS_PORT port for v2ray listening, for example 10086. # V2RAY_SERVER_PORT port for v2ray listening, for example 10086.
# V2RAY_VMESS_CLIENT_UUID client's id and secret as UUID. # V2RAY_VMESS_CLIENT_UUID client's id and secret as UUID.
# UUID is 32 hexadecimal digits /([0-9a-f]-?){32}/ (128 bit value). # UUID is 32 hexadecimal digits /([0-9a-f]-?){32}/ (128 bit value).
mkdir -p /opt/amnezia/v2ray mkdir -p /opt/amnezia/v2ray
cd /opt/amnezia/v2ray
V2RAY_VMESS_CLIENT_UUID="b831381d-6324-4d53-ad4f-8cda48b30811" # $(openssl rand -base64 32 | tr "=" "A" | tr "+" "A" | tr "/" "A")
echo $V2RAY_VMESS_CLIENT_UUID > /opt/amnezia/v2ray/v2ray.key
cat < /opt/amnezia/v2ray/v2ray-server.json <<EOF cat < /opt/amnezia/v2ray/v2ray-server.json <<EOF
{ {
"log": { "log": {
@ -38,7 +42,7 @@ cat < /opt/amnezia/v2ray/v2ray-server.json <<EOF
}, },
"inbounds": [ "inbounds": [
{ {
"port": $V2RAY_VMESS_PORT, "port": $V2RAY_SERVER_PORT,
"protocol": "vmess", "protocol": "vmess",
"settings": { "settings": {
"clients": [ "clients": [

View file

@ -3,7 +3,7 @@ sudo docker run -d \
--log-driver none \ --log-driver none \
--restart always \ --restart always \
--cap-add=NET_ADMIN \ --cap-add=NET_ADMIN \
-p $V2RAY_VMESS_PORT:$V2RAY_VMESS_PORT/tcp \ -p $V2RAY_SERVER_PORT:$V2RAY_SERVER_PORT/tcp \
--name $CONTAINER_NAME $CONTAINER_NAME --name $CONTAINER_NAME $CONTAINER_NAME
sudo docker network connect amnezia-dns-net $CONTAINER_NAME sudo docker network connect amnezia-dns-net $CONTAINER_NAME

View file

@ -55,6 +55,7 @@ public:
friend class ShadowSocksLogic; friend class ShadowSocksLogic;
friend class CloakLogic; friend class CloakLogic;
friend class UiLogic; friend class UiLogic;
friend class V2RayLogic;
void onUpdatePage() override; void onUpdatePage() override;
ErrorCode doInstallAction(const std::function<ErrorCode()> &action); ErrorCode doInstallAction(const std::function<ErrorCode()> &action);

View file

@ -0,0 +1,127 @@
#include "V2RayLogic.h"
#include <functional>
#include "core/servercontroller.h"
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
#include "ui/uilogic.h"
using namespace amnezia;
using namespace PageEnumNS;
V2RayLogic::V2RayLogic(UiLogic *logic, QObject *parent):
PageProtocolLogicBase(logic, parent),
m_comboBoxCipherText{"chacha20-poly1305"},
m_lineEditPortText{},
m_pushButtonSaveVisible{false},
m_progressBarResetVisible{false},
m_lineEditPortEnabled{false},
m_labelInfoVisible{true},
m_labelInfoText{},
m_progressBarResetValue{0},
m_progressBarResetMaximium{100}
{
}
void V2RayLogic::updateProtocolPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData)
{
set_pageEnabled(haveAuthData);
set_pushButtonSaveVisible(haveAuthData);
set_progressBarResetVisible(haveAuthData);
set_comboBoxCipherText(ssConfig.value(config_key::cipher).
toString(protocols::shadowsocks::defaultCipher));
set_lineEditPortText(ssConfig.value(config_key::port).
toString(protocols::shadowsocks::defaultPort));
set_lineEditPortEnabled(container == DockerContainer::ShadowSocks);
}
QJsonObject V2RayLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
{
oldConfig.insert(config_key::cipher, comboBoxCipherText());
oldConfig.insert(config_key::port, lineEditPortText());
return oldConfig;
}
void V2RayLogic::onPushButtonSaveClicked()
{
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks);
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
ServerConfiguringProgressLogic::PageFunc pageFunc;
pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
set_pageEnabled(enabled);
};
ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonSaveVisible(visible);
};
ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
set_labelInfoVisible(visible);
};
waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
set_labelInfoText(text);
};
ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
set_progressBarResetVisible(visible);
};
progressBarFunc.setValueFunc = [this] (int value) -> void {
set_progressBarResetValue(value);
};
progressBarFunc.getValueFunc = [this] (void) -> int {
return progressBarResetValue();
};
progressBarFunc.getMaximiumFunc = [this] (void) -> int {
return progressBarResetMaximium();
};
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
set_progressBarTextVisible(visible);
};
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
set_progressBarText(text);
};
ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
set_labelServerBusyText(text);
};
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
set_labelServerBusyVisible(visible);
};
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonCancelVisible(visible);
};
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
uiLogic()->selectedDockerContainer,
containerConfig,
newContainerConfig);
},
pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) {
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
}
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
}
void V2RayLogic::onPushButtonCancelClicked()
{
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
}

View file

@ -0,0 +1,46 @@
#ifndef V2RAYLOGIC_H
#define V2RAYLOGIC_H
#include "PageProtocolLogicBase.h"
class UiLogic;
class V2RayLogic : public PageProtocolLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, comboBoxCipherText)
AUTO_PROPERTY(QString, lineEditPortText)
AUTO_PROPERTY(bool, pushButtonSaveVisible)
AUTO_PROPERTY(bool, progressBarResetVisible)
AUTO_PROPERTY(bool, lineEditPortEnabled)
AUTO_PROPERTY(bool, labelInfoVisible)
AUTO_PROPERTY(QString, labelInfoText)
AUTO_PROPERTY(int, progressBarResetValue)
AUTO_PROPERTY(int, progressBarResetMaximium)
AUTO_PROPERTY(bool, progressBarTextVisible)
AUTO_PROPERTY(QString, progressBarText)
AUTO_PROPERTY(bool, labelServerBusyVisible)
AUTO_PROPERTY(QString, labelServerBusyText)
AUTO_PROPERTY(bool, pushButtonCancelVisible)
public:
Q_INVOKABLE void onPushButtonSaveClicked();
Q_INVOKABLE void onPushButtonCancelClicked();
public:
explicit V2RayLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~V2RayLogic() = default;
void updateProtocolPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData) override;
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
UiLogic *m_uiLogic;
};
#endif // V2RAYLOGIC_H

View file

@ -0,0 +1,5 @@
import QtQuick
Item {
}

View file

@ -73,6 +73,7 @@
#include "pages_logic/protocols/ShadowSocksLogic.h" #include "pages_logic/protocols/ShadowSocksLogic.h"
#include "pages_logic/protocols/OtherProtocolsLogic.h" #include "pages_logic/protocols/OtherProtocolsLogic.h"
#include "pages_logic/protocols/WireGuardLogic.h" #include "pages_logic/protocols/WireGuardLogic.h"
#include "pages_logic/protocols/V2RayLogic.h"
using namespace amnezia; using namespace amnezia;
using namespace PageEnumNS; using namespace PageEnumNS;
@ -96,6 +97,7 @@ UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigur
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this)); m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this)); m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
m_protocolLogicMap.insert(Proto::WireGuard, new WireGuardLogic(this)); m_protocolLogicMap.insert(Proto::WireGuard, new WireGuardLogic(this));
m_protocolLogicMap.insert(Proto::V2Ray, new V2RayLogic(this));
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this)); m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this)); m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));

View file

@ -47,6 +47,7 @@ class PageProtocolLogicBase;
class OpenVpnLogic; class OpenVpnLogic;
class ShadowSocksLogic; class ShadowSocksLogic;
class CloakLogic; class CloakLogic;
class V2RayLogic;
class OtherProtocolsLogic; class OtherProtocolsLogic;
@ -92,6 +93,7 @@ public:
friend class OpenVpnLogic; friend class OpenVpnLogic;
friend class ShadowSocksLogic; friend class ShadowSocksLogic;
friend class CloakLogic; friend class CloakLogic;
friend class V2RayLogic;
friend class OtherProtocolsLogic; friend class OtherProtocolsLogic;

Binary file not shown.