mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-24 10:33:15 +08:00
feat: add anytls support
This commit is contained in:
parent
6febb17e64
commit
be51ed3e6f
@ -141,6 +141,9 @@ set(PROJECT_SOURCES
|
|||||||
include/ui/profile/edit_trojan_vless.h
|
include/ui/profile/edit_trojan_vless.h
|
||||||
src/ui/profile/edit_trojan_vless.cpp
|
src/ui/profile/edit_trojan_vless.cpp
|
||||||
include/ui/profile/edit_trojan_vless.ui
|
include/ui/profile/edit_trojan_vless.ui
|
||||||
|
include/ui/profile/edit_anytls.h
|
||||||
|
src/ui/profile/edit_anytls.cpp
|
||||||
|
include/ui/profile/edit_anytls.ui
|
||||||
|
|
||||||
include/ui/profile/edit_quic.h
|
include/ui/profile/edit_quic.h
|
||||||
src/ui/profile/edit_quic.cpp
|
src/ui/profile/edit_quic.cpp
|
||||||
|
|||||||
@ -32,6 +32,7 @@ Apple platforms have a very strict security policy and since Throne does not hav
|
|||||||
- TUIC
|
- TUIC
|
||||||
- Hysteria
|
- Hysteria
|
||||||
- Hysteria2
|
- Hysteria2
|
||||||
|
- AnyTls
|
||||||
- Wireguard
|
- Wireguard
|
||||||
- SSH
|
- SSH
|
||||||
- Custom Outbound
|
- Custom Outbound
|
||||||
|
|||||||
35
include/configs/proxy/AnyTlsBean.hpp
Normal file
35
include/configs/proxy/AnyTlsBean.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AbstractBean.hpp"
|
||||||
|
#include "V2RayStreamSettings.hpp"
|
||||||
|
#include "Preset.hpp"
|
||||||
|
|
||||||
|
namespace Configs {
|
||||||
|
class AnyTlsBean : public AbstractBean {
|
||||||
|
public:
|
||||||
|
QString password = "";
|
||||||
|
int idle_session_check_interval = 30;
|
||||||
|
int idle_session_timeout = 30;
|
||||||
|
int min_idle_session = 0;
|
||||||
|
|
||||||
|
std::shared_ptr<V2rayStreamSettings> stream = std::make_shared<V2rayStreamSettings>();
|
||||||
|
|
||||||
|
AnyTlsBean() : AbstractBean(0) {
|
||||||
|
_add(new configItem("password", &password, itemType::string));
|
||||||
|
_add(new configItem("idle_session_check_interval", &idle_session_check_interval, itemType::integer));
|
||||||
|
_add(new configItem("idle_session_timeout", &idle_session_timeout, itemType::integer));
|
||||||
|
_add(new configItem("min_idle_session", &min_idle_session, itemType::integer));
|
||||||
|
_add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore));
|
||||||
|
};
|
||||||
|
|
||||||
|
QString DisplayType() override { return "AnyTls"; };
|
||||||
|
|
||||||
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
|
bool TryParseLink(const QString &link);
|
||||||
|
|
||||||
|
bool TryParseJson(const QJsonObject &obj);
|
||||||
|
|
||||||
|
QString ToShareLink() override;
|
||||||
|
};
|
||||||
|
} // namespace Configs
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#include "VMessBean.hpp"
|
#include "VMessBean.hpp"
|
||||||
#include "TrojanVLESSBean.hpp"
|
#include "TrojanVLESSBean.hpp"
|
||||||
#include "QUICBean.hpp"
|
#include "QUICBean.hpp"
|
||||||
|
#include "AnyTlsBean.hpp"
|
||||||
#include "WireguardBean.h"
|
#include "WireguardBean.h"
|
||||||
#include "SSHBean.h"
|
#include "SSHBean.h"
|
||||||
#include "CustomBean.hpp"
|
#include "CustomBean.hpp"
|
||||||
|
|||||||
@ -18,6 +18,8 @@ namespace Configs {
|
|||||||
|
|
||||||
class QUICBean;
|
class QUICBean;
|
||||||
|
|
||||||
|
class AnyTlsBean;
|
||||||
|
|
||||||
class WireguardBean;
|
class WireguardBean;
|
||||||
|
|
||||||
class SSHBean;
|
class SSHBean;
|
||||||
@ -76,6 +78,10 @@ namespace Configs {
|
|||||||
return (Configs::QUICBean *) bean.get();
|
return (Configs::QUICBean *) bean.get();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] Configs::AnyTlsBean *AnyTlsBean() const {
|
||||||
|
return (Configs::AnyTlsBean *) bean.get();
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] Configs::WireguardBean *WireguardBean() const {
|
[[nodiscard]] Configs::WireguardBean *WireguardBean() const {
|
||||||
return (Configs::WireguardBean *) bean.get();
|
return (Configs::WireguardBean *) bean.get();
|
||||||
};
|
};
|
||||||
|
|||||||
28
include/ui/profile/edit_anytls.h
Normal file
28
include/ui/profile/edit_anytls.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "profile_editor.h"
|
||||||
|
#include "ui_edit_anytls.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui {
|
||||||
|
class EditAnyTls;
|
||||||
|
}
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class EditAnyTls : public QWidget, public ProfileEditor {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EditAnyTls(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
~EditAnyTls() override;
|
||||||
|
|
||||||
|
void onStart(std::shared_ptr<Configs::ProxyEntity> _ent) override;
|
||||||
|
|
||||||
|
bool onEnd() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::EditAnyTls *ui;
|
||||||
|
std::shared_ptr<Configs::ProxyEntity> ent;
|
||||||
|
};
|
||||||
71
include/ui/profile/edit_anytls.ui
Normal file
71
include/ui/profile/edit_anytls.ui
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>EditAnyTls</class>
|
||||||
|
<widget class="QWidget" name="EditAnyTls">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">EditAnyTls</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Password</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="MyLineEdit" name="password"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Idle Session Check Interval</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="interval"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Idle Session Timeout</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="timeout"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Min Idle Session</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="min"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>MyLineEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>include/ui/utils/MyLineEdit.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>password</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -374,7 +374,7 @@ namespace Configs {
|
|||||||
|
|
||||||
auto stream = GetStreamSettings(ent->bean.get());
|
auto stream = GetStreamSettings(ent->bean.get());
|
||||||
if (stream != nullptr) {
|
if (stream != nullptr) {
|
||||||
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
if (stream->network == "grpc" || stream->network == "quic" || stream->network == "anytls" || (stream->network == "http" && stream->security == "tls")) {
|
||||||
needMux = false;
|
needMux = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,6 +171,24 @@ namespace Configs {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreObjOutboundBuildResult AnyTlsBean::BuildCoreObjSingBox() {
|
||||||
|
CoreObjOutboundBuildResult result;
|
||||||
|
|
||||||
|
QJsonObject outbound{
|
||||||
|
{"type", "anytls"},
|
||||||
|
{"server", serverAddress},
|
||||||
|
{"server_port", serverPort},
|
||||||
|
{"password", password},
|
||||||
|
{"idle_session_check_interval", Int2String(idle_session_check_interval)+"s"},
|
||||||
|
{"idle_session_timeout", Int2String(idle_session_timeout)+"s"},
|
||||||
|
{"min_idle_session", min_idle_session},
|
||||||
|
};
|
||||||
|
|
||||||
|
stream->BuildStreamSettingsSingBox(&outbound);
|
||||||
|
result.outbound = outbound;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
CoreObjOutboundBuildResult VMessBean::BuildCoreObjSingBox() {
|
CoreObjOutboundBuildResult VMessBean::BuildCoreObjSingBox() {
|
||||||
CoreObjOutboundBuildResult result;
|
CoreObjOutboundBuildResult result;
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,35 @@ namespace Configs {
|
|||||||
return url.toString(QUrl::FullyEncoded);
|
return url.toString(QUrl::FullyEncoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString AnyTlsBean::ToShareLink() {
|
||||||
|
QUrl url;
|
||||||
|
QUrlQuery query;
|
||||||
|
url.setScheme("anytls");
|
||||||
|
url.setUserName(password);
|
||||||
|
url.setHost(serverAddress);
|
||||||
|
url.setPort(serverPort);
|
||||||
|
if (!name.isEmpty()) url.setFragment(name);
|
||||||
|
|
||||||
|
// security
|
||||||
|
query.addQueryItem("security", stream->security == "" ? "none" : stream->security);
|
||||||
|
|
||||||
|
if (!stream->sni.isEmpty()) query.addQueryItem("sni", stream->sni);
|
||||||
|
if (!stream->alpn.isEmpty()) query.addQueryItem("alpn", stream->alpn);
|
||||||
|
if (stream->allow_insecure) query.addQueryItem("insecure", "1");
|
||||||
|
if (!stream->utlsFingerprint.isEmpty()) query.addQueryItem("fp", stream->utlsFingerprint);
|
||||||
|
if (stream->enable_tls_fragment) query.addQueryItem("fragment", "1");
|
||||||
|
if (!stream->tls_fragment_fallback_delay.isEmpty()) query.addQueryItem("fragment_fallback_delay", stream->tls_fragment_fallback_delay);
|
||||||
|
if (stream->enable_tls_record_fragment) query.addQueryItem("record_fragment", "1");
|
||||||
|
|
||||||
|
if (stream->security == "reality") {
|
||||||
|
query.addQueryItem("pbk", stream->reality_pbk);
|
||||||
|
if (!stream->reality_sid.isEmpty()) query.addQueryItem("sid", stream->reality_sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
url.setQuery(query);
|
||||||
|
return url.toString(QUrl::FullyEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
QString TrojanVLESSBean::ToShareLink() {
|
QString TrojanVLESSBean::ToShareLink() {
|
||||||
QUrl url;
|
QUrl url;
|
||||||
QUrlQuery query;
|
QUrlQuery query;
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <include/configs/proxy/SocksHttpBean.hpp>
|
#include <include/configs/proxy/SocksHttpBean.hpp>
|
||||||
#include <include/configs/proxy/TrojanVLESSBean.hpp>
|
#include <include/configs/proxy/TrojanVLESSBean.hpp>
|
||||||
#include <include/configs/proxy/VMessBean.hpp>
|
#include <include/configs/proxy/VMessBean.hpp>
|
||||||
|
#include <include/configs/proxy/AnyTlsBean.hpp>
|
||||||
#include <include/configs/proxy/WireguardBean.h>
|
#include <include/configs/proxy/WireguardBean.h>
|
||||||
|
|
||||||
#include "include/configs/proxy/ExtraCore.h"
|
#include "include/configs/proxy/ExtraCore.h"
|
||||||
@ -213,6 +214,32 @@ namespace Configs
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AnyTlsBean::TryParseJson(const QJsonObject& obj)
|
||||||
|
{
|
||||||
|
name = obj["tag"].toString();
|
||||||
|
serverAddress = obj["server"].toString();
|
||||||
|
serverPort = obj["server_port"].toInt();
|
||||||
|
password = obj["password"].toString();
|
||||||
|
idle_session_check_interval = obj["idle_session_check_interval"].toInt();
|
||||||
|
idle_session_timeout = obj["idle_session_timeout"].toInt();
|
||||||
|
min_idle_session = obj["min_idle_session"].toInt();
|
||||||
|
stream->security = obj["tls"].isObject() ? "tls" : "";
|
||||||
|
if (obj["tls"].toObject()["reality"].toObject()["enabled"].toBool())
|
||||||
|
{
|
||||||
|
stream->security = "reality";
|
||||||
|
}
|
||||||
|
stream->reality_pbk = obj["tls"].toObject()["reality"].toObject()["public_key"].toString();
|
||||||
|
stream->reality_sid = obj["tls"].toObject()["reality"].toObject()["short_id"].toString();
|
||||||
|
stream->utlsFingerprint = obj["tls"].toObject()["utls"].toObject()["fingerprint"].toString();
|
||||||
|
stream->enable_tls_fragment = obj["tls"].toObject()["fragment"].toBool();
|
||||||
|
stream->tls_fragment_fallback_delay = obj["tls"].toObject()["fragment_fallback_delay"].toString();
|
||||||
|
stream->enable_tls_record_fragment = obj["tls"].toObject()["record_fragment"].toBool();
|
||||||
|
stream->sni = obj["tls"].toObject()["server_name"].toString();
|
||||||
|
stream->alpn = obj["tls"].toObject()["alpn"].isArray() ? QJsonArray2QListString(obj["tls"].toObject()["alpn"].toArray()).join(",") : obj["tls"].toObject()["alpn"].toString();
|
||||||
|
stream->allow_insecure = obj["tls"].toObject()["insecure"].toBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool WireguardBean::TryParseJson(const QJsonObject& obj)
|
bool WireguardBean::TryParseJson(const QJsonObject& obj)
|
||||||
{
|
{
|
||||||
name = obj["tag"].toString();
|
name = obj["tag"].toString();
|
||||||
|
|||||||
@ -42,6 +42,43 @@ namespace Configs {
|
|||||||
return !serverAddress.isEmpty();
|
return !serverAddress.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AnyTlsBean::TryParseLink(const QString &link) {
|
||||||
|
auto url = QUrl(link);
|
||||||
|
if (!url.isValid()) return false;
|
||||||
|
auto query = GetQuery(url);
|
||||||
|
|
||||||
|
name = url.fragment(QUrl::FullyDecoded);
|
||||||
|
serverAddress = url.host();
|
||||||
|
serverPort = url.port();
|
||||||
|
password = url.userName();
|
||||||
|
if (serverPort == -1) serverPort = 443;
|
||||||
|
|
||||||
|
// security
|
||||||
|
|
||||||
|
stream->security = GetQueryValue(query, "security", "").replace("none", "");
|
||||||
|
auto sni1 = GetQueryValue(query, "sni");
|
||||||
|
auto sni2 = GetQueryValue(query, "peer");
|
||||||
|
if (!sni1.isEmpty()) stream->sni = sni1;
|
||||||
|
if (!sni2.isEmpty()) stream->sni = sni2;
|
||||||
|
stream->alpn = GetQueryValue(query, "alpn");
|
||||||
|
stream->allow_insecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure"));
|
||||||
|
stream->reality_pbk = GetQueryValue(query, "pbk", "");
|
||||||
|
stream->reality_sid = GetQueryValue(query, "sid", "");
|
||||||
|
stream->utlsFingerprint = GetQueryValue(query, "fp", "");
|
||||||
|
if (query.queryItemValue("fragment") == "1") stream->enable_tls_fragment = true;
|
||||||
|
stream->tls_fragment_fallback_delay = query.queryItemValue("fragment_fallback_delay");
|
||||||
|
if (query.queryItemValue("record_fragment") == "1") stream->enable_tls_record_fragment = true;
|
||||||
|
if (stream->utlsFingerprint.isEmpty()) {
|
||||||
|
stream->utlsFingerprint = dataStore->utlsFingerprint;
|
||||||
|
}
|
||||||
|
if (stream->security.isEmpty()) {
|
||||||
|
if (!sni1.isEmpty() || !sni2.isEmpty()) stream->security = "tls";
|
||||||
|
if (!stream->reality_pbk.isEmpty()) stream->security = "reality";
|
||||||
|
}
|
||||||
|
|
||||||
|
return !(password.isEmpty() || serverAddress.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
bool TrojanVLESSBean::TryParseLink(const QString &link) {
|
bool TrojanVLESSBean::TryParseLink(const QString &link) {
|
||||||
auto url = QUrl(link);
|
auto url = QUrl(link);
|
||||||
if (!url.isValid()) return false;
|
if (!url.isValid()) return false;
|
||||||
|
|||||||
@ -172,6 +172,13 @@ namespace Subscription {
|
|||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnyTls
|
||||||
|
if (str.startsWith("anytls://")) {
|
||||||
|
ent = Configs::ProfileManager::NewProxyEntity("anytls");
|
||||||
|
auto ok = ent->AnyTlsBean()->TryParseLink(str);
|
||||||
|
if (!ok) return;
|
||||||
|
}
|
||||||
|
|
||||||
// Hysteria1
|
// Hysteria1
|
||||||
if (str.startsWith("hysteria://")) {
|
if (str.startsWith("hysteria://")) {
|
||||||
needFix = false;
|
needFix = false;
|
||||||
@ -290,6 +297,13 @@ namespace Subscription {
|
|||||||
if (!ok) continue;
|
if (!ok) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnyTls
|
||||||
|
if (out["type"] == "anytls") {
|
||||||
|
ent = Configs::ProfileManager::NewProxyEntity("anytls");
|
||||||
|
auto ok = ent->AnyTlsBean()->TryParseJson(out);
|
||||||
|
if (!ok) continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Hysteria1
|
// Hysteria1
|
||||||
if (out["type"] == "hysteria") {
|
if (out["type"] == "hysteria") {
|
||||||
ent = Configs::ProfileManager::NewProxyEntity("hysteria");
|
ent = Configs::ProfileManager::NewProxyEntity("hysteria");
|
||||||
@ -526,7 +540,6 @@ namespace Subscription {
|
|||||||
if (Node2Bool(proxy["tls"])) bean->stream->security = "tls";
|
if (Node2Bool(proxy["tls"])) bean->stream->security = "tls";
|
||||||
if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true;
|
if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true;
|
||||||
bean->stream->utlsFingerprint = Node2QString(proxy["client-fingerprint"]);
|
bean->stream->utlsFingerprint = Node2QString(proxy["client-fingerprint"]);
|
||||||
bean->stream->utlsFingerprint = Node2QString(proxy["client-fingerprint"]);
|
|
||||||
if (bean->stream->utlsFingerprint.isEmpty()) {
|
if (bean->stream->utlsFingerprint.isEmpty()) {
|
||||||
bean->stream->utlsFingerprint = Configs::dataStore->utlsFingerprint;
|
bean->stream->utlsFingerprint = Configs::dataStore->utlsFingerprint;
|
||||||
}
|
}
|
||||||
@ -593,6 +606,24 @@ namespace Subscription {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (type == "anytls") {
|
||||||
|
needFix = true;
|
||||||
|
auto bean = ent->AnyTlsBean();
|
||||||
|
bean->password = Node2QString(proxy["password"]);
|
||||||
|
if (Node2Bool(proxy["tls"])) bean->stream->security = "tls";
|
||||||
|
if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true;
|
||||||
|
bean->stream->sni = FIRST_OR_SECOND(Node2QString(proxy["sni"]), Node2QString(proxy["servername"]));
|
||||||
|
bean->stream->alpn = Node2QStringList(proxy["alpn"]).join(",");
|
||||||
|
bean->stream->utlsFingerprint = Node2QString(proxy["client-fingerprint"]);
|
||||||
|
if (bean->stream->utlsFingerprint.isEmpty()) {
|
||||||
|
bean->stream->utlsFingerprint = Configs::dataStore->utlsFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reality = NodeChild(proxy, {"reality-opts"});
|
||||||
|
if (reality.is_mapping()) {
|
||||||
|
bean->stream->reality_pbk = Node2QString(reality["public-key"]);
|
||||||
|
bean->stream->reality_sid = Node2QString(reality["short-id"]);
|
||||||
|
}
|
||||||
} else if (type == "hysteria") {
|
} else if (type == "hysteria") {
|
||||||
auto bean = ent->QUICBean();
|
auto bean = ent->QUICBean();
|
||||||
|
|
||||||
|
|||||||
@ -176,6 +176,8 @@ namespace Configs {
|
|||||||
bean = new Configs::QUICBean(Configs::QUICBean::proxy_Hysteria2);
|
bean = new Configs::QUICBean(Configs::QUICBean::proxy_Hysteria2);
|
||||||
} else if (type == "tuic") {
|
} else if (type == "tuic") {
|
||||||
bean = new Configs::QUICBean(Configs::QUICBean::proxy_TUIC);
|
bean = new Configs::QUICBean(Configs::QUICBean::proxy_TUIC);
|
||||||
|
} else if (type == "anytls") {
|
||||||
|
bean = new Configs::AnyTlsBean();
|
||||||
} else if (type == "wireguard") {
|
} else if (type == "wireguard") {
|
||||||
bean = new Configs::WireguardBean(Configs::WireguardBean());
|
bean = new Configs::WireguardBean(Configs::WireguardBean());
|
||||||
} else if (type == "ssh") {
|
} else if (type == "ssh") {
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "include/ui/profile/edit_vmess.h"
|
#include "include/ui/profile/edit_vmess.h"
|
||||||
#include "include/ui/profile/edit_trojan_vless.h"
|
#include "include/ui/profile/edit_trojan_vless.h"
|
||||||
#include "include/ui/profile/edit_quic.h"
|
#include "include/ui/profile/edit_quic.h"
|
||||||
|
#include "include/ui/profile/edit_anytls.h"
|
||||||
#include "include/ui/profile/edit_wireguard.h"
|
#include "include/ui/profile/edit_wireguard.h"
|
||||||
#include "include/ui/profile/edit_ssh.h"
|
#include "include/ui/profile/edit_ssh.h"
|
||||||
#include "include/ui/profile/edit_custom.h"
|
#include "include/ui/profile/edit_custom.h"
|
||||||
@ -166,6 +167,7 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
LOAD_TYPE("hysteria")
|
LOAD_TYPE("hysteria")
|
||||||
LOAD_TYPE("hysteria2")
|
LOAD_TYPE("hysteria2")
|
||||||
LOAD_TYPE("tuic")
|
LOAD_TYPE("tuic")
|
||||||
|
LOAD_TYPE("anytls")
|
||||||
LOAD_TYPE("wireguard")
|
LOAD_TYPE("wireguard")
|
||||||
LOAD_TYPE("ssh")
|
LOAD_TYPE("ssh")
|
||||||
ui->type->addItem(tr("Custom (%1 outbound)").arg(software_core_name), "internal");
|
ui->type->addItem(tr("Custom (%1 outbound)").arg(software_core_name), "internal");
|
||||||
@ -233,6 +235,10 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
auto _innerWidget = new EditQUIC(this);
|
auto _innerWidget = new EditQUIC(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
innerEditor = _innerWidget;
|
innerEditor = _innerWidget;
|
||||||
|
} else if (type == "anytls") {
|
||||||
|
auto _innerWidget = new EditAnyTls(this);
|
||||||
|
innerWidget = _innerWidget;
|
||||||
|
innerEditor = _innerWidget;
|
||||||
} else if (type == "wireguard") {
|
} else if (type == "wireguard") {
|
||||||
auto _innerWidget = new EditWireguard(this);
|
auto _innerWidget = new EditWireguard(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
@ -375,7 +381,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
ui->network->setVisible(false);
|
ui->network->setVisible(false);
|
||||||
ui->network_box->setVisible(false);
|
ui->network_box->setVisible(false);
|
||||||
}
|
}
|
||||||
if (type == "vmess" || type == "vless" || type == "trojan" || type == "http") {
|
if (type == "vmess" || type == "vless" || type == "trojan" || type == "http" || type == "anytls") {
|
||||||
ui->security->setVisible(true);
|
ui->security->setVisible(true);
|
||||||
ui->security_l->setVisible(true);
|
ui->security_l->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
39
src/ui/profile/edit_anytls.cpp
Normal file
39
src/ui/profile/edit_anytls.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "include/ui/profile/edit_anytls.h"
|
||||||
|
|
||||||
|
#include "include/configs/proxy/AnyTlsBean.hpp"
|
||||||
|
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QRegularExpressionValidator>
|
||||||
|
#include "include/global/GuiUtils.hpp"
|
||||||
|
|
||||||
|
EditAnyTls::EditAnyTls(QWidget *parent) : QWidget(parent), ui(new Ui::EditAnyTls) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->interval->setValidator(QRegExpValidator_Number);
|
||||||
|
ui->timeout->setValidator(QRegExpValidator_Number);
|
||||||
|
ui->min->setValidator(QRegExpValidator_Number);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditAnyTls::~EditAnyTls() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditAnyTls::onStart(std::shared_ptr<Configs::ProxyEntity> _ent) {
|
||||||
|
this->ent = _ent;
|
||||||
|
auto bean = this->ent->AnyTlsBean();
|
||||||
|
|
||||||
|
ui->password->setText(bean->password);
|
||||||
|
ui->interval->setText(Int2String(bean->idle_session_check_interval));
|
||||||
|
ui->timeout->setText(Int2String(bean->idle_session_timeout));
|
||||||
|
ui->min->setText(Int2String(bean->min_idle_session));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditAnyTls::onEnd() {
|
||||||
|
auto bean = this->ent->AnyTlsBean();
|
||||||
|
|
||||||
|
bean->password = ui->password->text();
|
||||||
|
bean->idle_session_check_interval = ui->interval->text().toInt();
|
||||||
|
bean->idle_session_timeout = ui->timeout->text().toInt();
|
||||||
|
bean->min_idle_session = ui->min->text().toInt();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user