From 15a5deeb6e0df41d6e464e06066a9763b1300f08 Mon Sep 17 00:00:00 2001 From: Nova Date: Thu, 30 Oct 2025 20:56:44 +0330 Subject: [PATCH 1/9] Implement new classes --- CMakeLists.txt | 25 ++++++ include/configs/baseConfig.h | 11 ++- include/configs/common/DialFields.h | 7 ++ include/configs/common/Outbound.h | 8 ++ include/configs/common/TLS.h | 28 ++++++ include/configs/common/multiplex.h | 16 +++- include/configs/common/transport.h | 7 ++ include/configs/common/utils.h | 10 +++ include/configs/generate.h | 10 +++ include/configs/outbounds/anyTLS.h | 14 +++ include/configs/outbounds/http.h | 14 +++ include/configs/outbounds/hysteria.h | 14 +++ include/configs/outbounds/hysteria2.h | 14 +++ include/configs/outbounds/shadowsocks.h | 14 +++ include/configs/outbounds/socks.h | 14 +++ include/configs/outbounds/ssh.h | 14 +++ include/configs/outbounds/tailscale.h | 56 ++++++++++++ include/configs/outbounds/trojan.h | 14 +++ include/configs/outbounds/tuic.h | 14 +++ include/configs/outbounds/vless.h | 14 +++ include/configs/outbounds/vmess.h | 14 +++ include/configs/outbounds/wireguard.h | 99 +++++++++++++++++++++ src/configs/common/DialFields.cpp | 56 ++++++++++++ src/configs/common/Outbound.cpp | 11 +++ src/configs/common/TLS.cpp | 29 +++++++ src/configs/common/multiplex.cpp | 109 ++++++++++++++++++++++++ src/configs/common/transport.cpp | 11 +++ src/configs/common/utils.cpp | 21 +++++ src/configs/outbounds/anyTLS.cpp | 17 ++++ src/configs/outbounds/http.cpp | 17 ++++ src/configs/outbounds/hysteria.cpp | 17 ++++ src/configs/outbounds/hysteria2.cpp | 17 ++++ src/configs/outbounds/shadowsocks.cpp | 17 ++++ src/configs/outbounds/socks.cpp | 17 ++++ src/configs/outbounds/ssh.cpp | 17 ++++ src/configs/outbounds/tailscale.cpp | 17 ++++ src/configs/outbounds/trojan.cpp | 17 ++++ src/configs/outbounds/tuic.cpp | 17 ++++ src/configs/outbounds/vless.cpp | 17 ++++ src/configs/outbounds/vmess.cpp | 17 ++++ src/configs/outbounds/wireguard.cpp | 23 +++++ 41 files changed, 890 insertions(+), 5 deletions(-) create mode 100644 include/configs/common/utils.h create mode 100644 include/configs/generate.h create mode 100644 include/configs/outbounds/tailscale.h create mode 100644 include/configs/outbounds/wireguard.h create mode 100644 src/configs/common/DialFields.cpp create mode 100644 src/configs/common/Outbound.cpp create mode 100644 src/configs/common/TLS.cpp create mode 100644 src/configs/common/multiplex.cpp create mode 100644 src/configs/common/transport.cpp create mode 100644 src/configs/common/utils.cpp create mode 100644 src/configs/outbounds/anyTLS.cpp create mode 100644 src/configs/outbounds/http.cpp create mode 100644 src/configs/outbounds/hysteria.cpp create mode 100644 src/configs/outbounds/hysteria2.cpp create mode 100644 src/configs/outbounds/shadowsocks.cpp create mode 100644 src/configs/outbounds/socks.cpp create mode 100644 src/configs/outbounds/ssh.cpp create mode 100644 src/configs/outbounds/tailscale.cpp create mode 100644 src/configs/outbounds/trojan.cpp create mode 100644 src/configs/outbounds/tuic.cpp create mode 100644 src/configs/outbounds/vless.cpp create mode 100644 src/configs/outbounds/vmess.cpp create mode 100644 src/configs/outbounds/wireguard.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f889a0..5c7e8e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,6 +227,13 @@ set(PROJECT_SOURCES include/configs/common/multiplex.h include/configs/common/transport.h include/configs/common/Outbound.h + + # common impl + src/configs/common/DialFields.cpp + src/configs/common/TLS.cpp + src/configs/common/multiplex.cpp + src/configs/common/transport.cpp + src/configs/common/Outbound.cpp include/configs/outbounds/socks.h include/configs/outbounds/http.h include/configs/outbounds/shadowsocks.h @@ -238,6 +245,24 @@ set(PROJECT_SOURCES include/configs/outbounds/hysteria2.h include/configs/outbounds/anyTLS.h include/configs/outbounds/ssh.h + + # outbounds impl + src/configs/outbounds/anyTLS.cpp + src/configs/outbounds/http.cpp + src/configs/outbounds/hysteria.cpp + src/configs/outbounds/hysteria2.cpp + src/configs/outbounds/shadowsocks.cpp + src/configs/outbounds/socks.cpp + src/configs/outbounds/ssh.cpp + src/configs/outbounds/tailscale.cpp + src/configs/outbounds/trojan.cpp + src/configs/outbounds/tuic.cpp + src/configs/outbounds/vless.cpp + src/configs/outbounds/vmess.cpp + src/configs/outbounds/wireguard.cpp + include/configs/generate.h + include/configs/common/utils.h + src/configs/common/utils.cpp ) if (NOT APPLE AND Qt6_VERSION VERSION_GREATER_EQUAL 6.9.0) diff --git a/include/configs/baseConfig.h b/include/configs/baseConfig.h index f153341..817ac57 100644 --- a/include/configs/baseConfig.h +++ b/include/configs/baseConfig.h @@ -1,7 +1,8 @@ #pragma once -#include #include + +#include "generate.h" #include "include/global/ConfigItem.hpp" namespace Configs @@ -9,20 +10,22 @@ namespace Configs class baseConfig : public JsonStore { public: - virtual bool ParseFromLink(QString link); + virtual bool ParseFromLink(const QString& link); - virtual bool ParseFromJson(QJsonObject object); + virtual bool ParseFromJson(const QJsonObject& object); virtual QString ExportToLink(); virtual QJsonObject ExportToJson(); - virtual QJsonObject Build(); + virtual BuildResult Build(); }; class outboundMeta { public: + virtual ~outboundMeta() = default; + void ResolveDomainToIP(const std::function &onFinished); virtual QString DisplayAddress(); diff --git a/include/configs/common/DialFields.h b/include/configs/common/DialFields.h index b58d987..5cc47f1 100644 --- a/include/configs/common/DialFields.h +++ b/include/configs/common/DialFields.h @@ -20,5 +20,12 @@ namespace Configs _add(new configItem("tcp_multi_path", &tcp_multi_path, itemType::boolean)); _add(new configItem("udp_fragment", &udp_fragment, itemType::boolean)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; } diff --git a/include/configs/common/Outbound.h b/include/configs/common/Outbound.h index 2f2e588..574ccc6 100644 --- a/include/configs/common/Outbound.h +++ b/include/configs/common/Outbound.h @@ -1,4 +1,5 @@ #pragma once +#include "DialFields.h" #include "include/configs/baseConfig.h" namespace Configs @@ -22,5 +23,12 @@ namespace Configs _add(new configItem("server_port", &server_port, integer)); _add(new configItem("dial_fields", dynamic_cast(dialFields.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; } diff --git a/include/configs/common/TLS.h b/include/configs/common/TLS.h index bcdd5e0..3e41b69 100644 --- a/include/configs/common/TLS.h +++ b/include/configs/common/TLS.h @@ -17,6 +17,13 @@ namespace Configs _add(new configItem("enabled", &enabled, boolean)); _add(new configItem("fingerprint", &fingerPrint, string)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; class ECH : public baseConfig @@ -32,6 +39,13 @@ namespace Configs _add(new configItem("config", &config, stringList)); _add(new configItem("config_path", &config_path, string)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; class Reality : public baseConfig @@ -47,6 +61,13 @@ namespace Configs _add(new configItem("public_key", &public_key, string)); _add(new configItem("short_id", &short_id, string)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; class TLS : public baseConfig @@ -100,5 +121,12 @@ namespace Configs _add(new configItem("utls", dynamic_cast(utls.get()), jsonStore)); _add(new configItem("reality", dynamic_cast(reality.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; } diff --git a/include/configs/common/multiplex.h b/include/configs/common/multiplex.h index 9179081..a8f1dbd 100644 --- a/include/configs/common/multiplex.h +++ b/include/configs/common/multiplex.h @@ -3,7 +3,7 @@ namespace Configs { - inline QStringLists muxProtocols = {"smux", "yamux", "h2mux"}; + inline QStringList muxProtocols = {"smux", "yamux", "h2mux"}; class TcpBrutal : public baseConfig { @@ -18,6 +18,13 @@ namespace Configs _add(new configItem("up_mbps", &up_mbps, integer)); _add(new configItem("down_mbps", &down_mbps, integer)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; class Multiplex : public baseConfig @@ -41,5 +48,12 @@ namespace Configs _add(new configItem("padding", &padding, boolean)); _add(new configItem("brutal", dynamic_cast(brutal.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; } diff --git a/include/configs/common/transport.h b/include/configs/common/transport.h index b26b676..3f95e9c 100644 --- a/include/configs/common/transport.h +++ b/include/configs/common/transport.h @@ -36,5 +36,12 @@ namespace Configs _add(new configItem("early_data_header_name", &early_data_header_name, string)); _add(new configItem("service_name", &service_name, string)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; }; } diff --git a/include/configs/common/utils.h b/include/configs/common/utils.h new file mode 100644 index 0000000..b37ec29 --- /dev/null +++ b/include/configs/common/utils.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include + +namespace Configs +{ + void mergeUrlQuery(QUrlQuery& baseQuery, const QString& strQuery); + + void mergeJsonObjects(QJsonObject& baseObject, const QJsonObject& obj); +} diff --git a/include/configs/generate.h b/include/configs/generate.h new file mode 100644 index 0000000..8c921c4 --- /dev/null +++ b/include/configs/generate.h @@ -0,0 +1,10 @@ +#pragma once +#include + +namespace Configs +{ + struct BuildResult { + QJsonObject object; + QString error; + }; +} diff --git a/include/configs/outbounds/anyTLS.h b/include/configs/outbounds/anyTLS.h index 14d8a55..c2d1793 100644 --- a/include/configs/outbounds/anyTLS.h +++ b/include/configs/outbounds/anyTLS.h @@ -24,5 +24,19 @@ namespace Configs _add(new configItem("min_idle_session", &min_idle_session, integer)); _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/http.h b/include/configs/outbounds/http.h index 0ab7601..e6205f2 100644 --- a/include/configs/outbounds/http.h +++ b/include/configs/outbounds/http.h @@ -25,5 +25,19 @@ namespace Configs _add(new configItem("headers", &headers, stringList)); _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/hysteria.h b/include/configs/outbounds/hysteria.h index f51d5e5..5c5dc0d 100644 --- a/include/configs/outbounds/hysteria.h +++ b/include/configs/outbounds/hysteria.h @@ -36,5 +36,19 @@ namespace Configs _add(new configItem("disable_mtu_discovery", &disable_mtu_discovery, boolean)); _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/hysteria2.h b/include/configs/outbounds/hysteria2.h index ef42313..8a01976 100644 --- a/include/configs/outbounds/hysteria2.h +++ b/include/configs/outbounds/hysteria2.h @@ -30,5 +30,19 @@ namespace Configs _add(new configItem("password", &password, string)); _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/shadowsocks.h b/include/configs/outbounds/shadowsocks.h index a0a0073..dca2bfe 100644 --- a/include/configs/outbounds/shadowsocks.h +++ b/include/configs/outbounds/shadowsocks.h @@ -32,5 +32,19 @@ namespace Configs _add(new configItem("uot", &uot, itemType::boolean)); _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/socks.h b/include/configs/outbounds/socks.h index 1991400..764bd88 100644 --- a/include/configs/outbounds/socks.h +++ b/include/configs/outbounds/socks.h @@ -20,5 +20,19 @@ namespace Configs _add(new configItem("password", &password, string)); _add(new configItem("uot", &uot, boolean)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/ssh.h b/include/configs/outbounds/ssh.h index b20f8d9..104d0f1 100644 --- a/include/configs/outbounds/ssh.h +++ b/include/configs/outbounds/ssh.h @@ -29,5 +29,19 @@ namespace Configs _add(new configItem("host_key_algorithms", &host_key_algorithms, stringList)); _add(new configItem("client_version", &client_version, string)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/tailscale.h b/include/configs/outbounds/tailscale.h new file mode 100644 index 0000000..1c99d07 --- /dev/null +++ b/include/configs/outbounds/tailscale.h @@ -0,0 +1,56 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" + +namespace Configs +{ + class tailscale : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + + QString state_directory = "$HOME/.tailscale"; + QString auth_key; + QString control_url = "https://controlplane.tailscale.com"; + bool ephemeral = false; + QString hostname; + bool accept_routes = false; + QString exit_node; + bool exit_node_allow_lan_access = false; + QStringList advertise_routes; + bool advertise_exit_node = false; + bool globalDNS = false; + + tailscale() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("state_directory", &state_directory, itemType::string)); + _add(new configItem("auth_key", &auth_key, itemType::string)); + _add(new configItem("control_url", &control_url, itemType::string)); + _add(new configItem("ephemeral", &ephemeral, itemType::boolean)); + _add(new configItem("hostname", &hostname, itemType::string)); + _add(new configItem("accept_routes", &accept_routes, itemType::boolean)); + _add(new configItem("exit_node", &exit_node, itemType::string)); + _add(new configItem("exit_node_allow_lan_access", &exit_node_allow_lan_access, itemType::boolean)); + _add(new configItem("advertise_routes", &advertise_routes, itemType::stringList)); + _add(new configItem("advertise_exit_node", &advertise_exit_node, itemType::boolean)); + _add(new configItem("globalDNS", &globalDNS, itemType::boolean)); + } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; + }; +} + + diff --git a/include/configs/outbounds/trojan.h b/include/configs/outbounds/trojan.h index 2e7c2f9..448aa8d 100644 --- a/include/configs/outbounds/trojan.h +++ b/include/configs/outbounds/trojan.h @@ -25,5 +25,19 @@ namespace Configs _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); _add(new configItem("transport", dynamic_cast(transport.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/tuic.h b/include/configs/outbounds/tuic.h index 4658285..b4dc2d1 100644 --- a/include/configs/outbounds/tuic.h +++ b/include/configs/outbounds/tuic.h @@ -34,5 +34,19 @@ namespace Configs _add(new configItem("heartbeat", &heartbeat, string)); _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/vless.h b/include/configs/outbounds/vless.h index 3c87ff6..86dd6d9 100644 --- a/include/configs/outbounds/vless.h +++ b/include/configs/outbounds/vless.h @@ -30,5 +30,19 @@ namespace Configs _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); _add(new configItem("transport", dynamic_cast(transport.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/vmess.h b/include/configs/outbounds/vmess.h index b42dc0a..2b56392 100644 --- a/include/configs/outbounds/vmess.h +++ b/include/configs/outbounds/vmess.h @@ -39,5 +39,19 @@ namespace Configs _add(new configItem("transport", dynamic_cast(transport.get()), jsonStore)); _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; }; } diff --git a/include/configs/outbounds/wireguard.h b/include/configs/outbounds/wireguard.h new file mode 100644 index 0000000..e843c05 --- /dev/null +++ b/include/configs/outbounds/wireguard.h @@ -0,0 +1,99 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" + +namespace Configs +{ + class Peer : public baseConfig + { + public: + QString address; + int port = 0; + QString public_key; + QString pre_shared_key; + QList reserved; + int persistent_keepalive = 0; + + Peer() + { + _add(new configItem("address", &address, string)); + _add(new configItem("port", &port, integer)); + _add(new configItem("public_key", &public_key, itemType::string)); + _add(new configItem("pre_shared_key", &pre_shared_key, itemType::string)); + _add(new configItem("reserved", &reserved, itemType::integerList)); + _add(new configItem("persistent_keepalive", &persistent_keepalive, itemType::integer)); + } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + }; + + class wireguard : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString private_key; + std::shared_ptr peer = std::make_shared(); + QStringList address; + int mtu = 1420; + bool system = false; + int worker_count = 0; + QString udp_timeout; + + // Amnezia options + bool enable_amnezia = false; + int junk_packet_count = 0; + int junk_packet_min_size = 0; + int junk_packet_max_size = 0; + int init_packet_junk_size = 0; + int response_packet_junk_size = 0; + int init_packet_magic_header = 0; + int response_packet_magic_header = 0; + int underload_packet_magic_header = 0; + int transport_packet_magic_header = 0; + + wireguard() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + + _add(new configItem("private_key", &private_key, itemType::string)); + _add(new configItem("peer", dynamic_cast(peer.get()), jsonStore)); + _add(new configItem("address", &address, itemType::stringList)); + _add(new configItem("mtu", &mtu, itemType::integer)); + _add(new configItem("system", &system, itemType::boolean)); + _add(new configItem("worker_count", &worker_count, itemType::integer)); + _add(new configItem("udp_timeout", &udp_timeout, itemType::string)); + + _add(new configItem("enable_amnezia", &enable_amnezia, itemType::boolean)); + _add(new configItem("junk_packet_count", &junk_packet_count, itemType::integer)); + _add(new configItem("junk_packet_min_size", &junk_packet_min_size, itemType::integer)); + _add(new configItem("junk_packet_max_size", &junk_packet_max_size, itemType::integer)); + _add(new configItem("init_packet_junk_size", &init_packet_junk_size, itemType::integer)); + _add(new configItem("response_packet_junk_size", &response_packet_junk_size, itemType::integer)); + _add(new configItem("init_packet_magic_header", &init_packet_magic_header, itemType::integer)); + _add(new configItem("response_packet_magic_header", &response_packet_magic_header, itemType::integer)); + _add(new configItem("underload_packet_magic_header", &underload_packet_magic_header, itemType::integer)); + _add(new configItem("transport_packet_magic_header", &transport_packet_magic_header, itemType::integer)); + } + + // baseConfig overrides + bool ParseFromLink(const QString& link) override; + bool ParseFromJson(const QJsonObject& object) override; + QString ExportToLink() override; + QJsonObject ExportToJson() override; + BuildResult Build() override; + + // outboundMeta overrides + QString DisplayAddress() override; + QString DisplayName() override; + QString DisplayType() override; + QString DisplayTypeAndName() override; + bool IsEndpoint() override; + }; +} + + diff --git a/src/configs/common/DialFields.cpp b/src/configs/common/DialFields.cpp new file mode 100644 index 0000000..7fadff8 --- /dev/null +++ b/src/configs/common/DialFields.cpp @@ -0,0 +1,56 @@ +#include "include/configs/common/DialFields.h" + +#include + +namespace Configs { + bool DialFields::ParseFromLink(const QString& link) + { + auto url = QUrl(link); + if (!url.isValid()) return false; + auto query = QUrlQuery(url.query(QUrl::ComponentFormattingOption::FullyDecoded)); + + if (query.hasQueryItem("reuse_addr")) reuse_addr = query.queryItemValue("reuse_addr") == "true"; + if (query.hasQueryItem("connect_timeout")) connect_timeout = query.queryItemValue("connect_timeout"); + if (query.hasQueryItem("tcp_fast_open")) tcp_fast_open = query.queryItemValue("tcp_fast_open") == "true"; + if (query.hasQueryItem("tcp_multi_path")) tcp_multi_path = query.queryItemValue("tcp_multi_path") == "true"; + if (query.hasQueryItem("udp_fragment")) udp_fragment = query.queryItemValue("udp_fragment") == "true"; + return true; + } + bool DialFields::ParseFromJson(const QJsonObject& object) + { + if (object == nullptr) return false; + + if (object.contains("reuse_addr")) reuse_addr = object["reuse_addr"].toBool(); + if (object.contains("connect_timeout")) connect_timeout = object["connect_timeout"].toString(); + if (object.contains("tcp_fast_open")) tcp_fast_open = object["tcp_fast_open"].toBool(); + if (object.contains("tcp_multi_path")) tcp_multi_path = object["tcp_multi_path"].toBool(); + if (object.contains("udp_fragment")) udp_fragment = object["udp_fragment"].toBool(); + return true; + } + QString DialFields::ExportToLink() + { + QUrlQuery query; + if (reuse_addr) query.addQueryItem("reuse_addr", "true"); + if (!connect_timeout.isEmpty()) query.addQueryItem("connect_timeout", connect_timeout); + if (tcp_fast_open) query.addQueryItem("tcp_fast_open", "true"); + if (tcp_multi_path) query.addQueryItem("tcp_multi_path", "true"); + if (udp_fragment) query.addQueryItem("udp_fragment", "true"); + return query.toString(); + } + QJsonObject DialFields::ExportToJson() + { + QJsonObject object; + if (reuse_addr) object["reuse_addr"] = reuse_addr; + if (!connect_timeout.isEmpty()) object["connect_timeout"] = connect_timeout; + if (tcp_fast_open) object["tcp_fast_open"] = tcp_fast_open; + if (tcp_multi_path) object["tcp_multi_path"] = tcp_multi_path; + if (udp_fragment) object["udp_fragment"] = udp_fragment; + return object; + } + BuildResult DialFields::Build() + { + return {ExportToJson(), ""}; + } +} + + diff --git a/src/configs/common/Outbound.cpp b/src/configs/common/Outbound.cpp new file mode 100644 index 0000000..ede4927 --- /dev/null +++ b/src/configs/common/Outbound.cpp @@ -0,0 +1,11 @@ +#include "include/configs/common/Outbound.h" + +namespace Configs { + bool OutboundCommons::ParseFromLink(const QString& link) { return false; } + bool OutboundCommons::ParseFromJson(const QJsonObject& object) { return false; } + QString OutboundCommons::ExportToLink() { return {}; } + QJsonObject OutboundCommons::ExportToJson() { return {}; } + BuildResult OutboundCommons::Build() { return {}; } +} + + diff --git a/src/configs/common/TLS.cpp b/src/configs/common/TLS.cpp new file mode 100644 index 0000000..547f1de --- /dev/null +++ b/src/configs/common/TLS.cpp @@ -0,0 +1,29 @@ +#include "include/configs/common/TLS.h" + +namespace Configs { + bool uTLS::ParseFromLink(const QString& link) { return false; } + bool uTLS::ParseFromJson(const QJsonObject& object) { return false; } + QString uTLS::ExportToLink() { return {}; } + QJsonObject uTLS::ExportToJson() { return {}; } + BuildResult uTLS::Build() { return {}; } + + bool ECH::ParseFromLink(const QString& link) { return false; } + bool ECH::ParseFromJson(const QJsonObject& object) { return false; } + QString ECH::ExportToLink() { return {}; } + QJsonObject ECH::ExportToJson() { return {}; } + BuildResult ECH::Build() { return {}; } + + bool Reality::ParseFromLink(const QString& link) { return false; } + bool Reality::ParseFromJson(const QJsonObject& object) { return false; } + QString Reality::ExportToLink() { return {}; } + QJsonObject Reality::ExportToJson() { return {}; } + BuildResult Reality::Build() { return {}; } + + bool TLS::ParseFromLink(const QString& link) { return false; } + bool TLS::ParseFromJson(const QJsonObject& object) { return false; } + QString TLS::ExportToLink() { return {}; } + QJsonObject TLS::ExportToJson() { return {}; } + BuildResult TLS::Build() { return {}; } +} + + diff --git a/src/configs/common/multiplex.cpp b/src/configs/common/multiplex.cpp new file mode 100644 index 0000000..cc2edc6 --- /dev/null +++ b/src/configs/common/multiplex.cpp @@ -0,0 +1,109 @@ +#include "include/configs/common/multiplex.h" + +#include + +#include "include/configs/common/utils.h" + +namespace Configs { + bool TcpBrutal::ParseFromLink(const QString& link) + { + auto url = QUrl(link); + if (!url.isValid()) return false; + auto query = QUrlQuery(url.query(QUrl::ComponentFormattingOption::FullyDecoded)); + + if (query.hasQueryItem("brutal_enabled")) enabled = query.queryItemValue("brutal_enabled") == "true"; + if (query.hasQueryItem("brutal_up_mbps")) up_mbps = query.queryItemValue("brutal_up_mbps").toInt(); + if (query.hasQueryItem("brutal_down_mbps")) down_mbps = query.queryItemValue("brutal_down_mbps").toInt(); + return true; + } + bool TcpBrutal::ParseFromJson(const QJsonObject& object) + { + if (object == nullptr) return false; + if (object.contains("enabled")) enabled = object["enabled"].toBool(); + if (object.contains("up_mbps")) up_mbps = object["up_mbps"].toInt(); + if (object.contains("down_mbps")) down_mbps = object["down_mbps"].toInt(); + return true; + } + QString TcpBrutal::ExportToLink() + { + QUrlQuery query; + if (!enabled) return ""; + query.addQueryItem("brutal_enabled", "true"); + if (up_mbps > 0) query.addQueryItem("brutal_up_mbps", QString::number(up_mbps)); + if (down_mbps > 0) query.addQueryItem("brutal_down_mbps", QString::number(down_mbps)); + return QUrlQuery(query).toString(); + } + QJsonObject TcpBrutal::ExportToJson() + { + QJsonObject object; + if (!enabled) return object; + object["enabled"] = enabled; + if (up_mbps > 0) object["up_mbps"] = up_mbps; + if (down_mbps > 0) object["down_mbps"] = down_mbps; + return object; + } + BuildResult TcpBrutal::Build() + { + return {ExportToJson(), ""}; + } + + bool Multiplex::ParseFromLink(const QString& link) + { + auto url = QUrl(link); + if (!url.isValid()) return false; + auto query = QUrlQuery(url.query(QUrl::ComponentFormattingOption::FullyDecoded)); + + if (query.hasQueryItem("mux")) enabled = query.queryItemValue("mux") == "true"; + protocol = query.hasQueryItem("mux_protocol") ? query.queryItemValue("mux_protocol") : "smux"; + if (query.hasQueryItem("mux_max_connections")) max_connections = query.queryItemValue("mux_max_connections").toInt(); + if (query.hasQueryItem("mux_min_streams")) min_streams = query.queryItemValue("mux_min_streams").toInt(); + if (query.hasQueryItem("mux_max_streams")) max_streams = query.queryItemValue("mux_max_streams").toInt(); + if (query.hasQueryItem("mux_padding")) padding = query.queryItemValue("mux_padding") == "true"; + brutal->ParseFromLink(link); + return true; + } + bool Multiplex::ParseFromJson(const QJsonObject& object) + { + if (object == nullptr) return false; + if (object.contains("enabled")) enabled = object["enabled"].toBool(); + if (object.contains("protocol")) protocol = object["protocol"].toString(); + if (object.contains("max_connections")) max_connections = object["max_connections"].toInt(); + if (object.contains("min_streams")) min_streams = object["min_streams"].toInt(); + if (object.contains("max_streams")) max_streams = object["max_streams"].toInt(); + if (object.contains("padding")) padding = object["padding"].toBool(); + if (object.contains("brutal")) brutal->ParseFromJson(object["brutal"].toObject()); + return true; + } + QString Multiplex::ExportToLink() + { + QUrlQuery query; + if (!enabled) return ""; + query.addQueryItem("mux", "true"); + if (!protocol.isEmpty()) query.addQueryItem("mux_protocol", protocol); + if (max_connections > 0) query.addQueryItem("mux_max_connections", QString::number(max_connections)); + if (min_streams > 0) query.addQueryItem("mux_min_streams", QString::number(min_streams)); + if (max_streams > 0) query.addQueryItem("mux_max_streams", QString::number(max_streams)); + if (padding) query.addQueryItem("mux_padding", "true"); + mergeUrlQuery(query, brutal->ExportToLink()); + return query.toString(); + } + QJsonObject Multiplex::ExportToJson() + { + QJsonObject object; + if (!enabled) return object; + object["enabled"] = enabled; + if (!protocol.isEmpty()) object["protocol"] = protocol; + if (max_connections > 0) object["max_connections"] = max_connections; + if (min_streams > 0) object["min_streams"] = min_streams; + if (max_streams > 0) object["max_streams"] = max_streams; + if (padding) object["padding"] = padding; + if (brutal->enabled) object["brutal"] = brutal->ExportToJson(); + return object; + } + BuildResult Multiplex::Build() + { + return {ExportToJson(), ""}; + } +} + + diff --git a/src/configs/common/transport.cpp b/src/configs/common/transport.cpp new file mode 100644 index 0000000..c2f5aff --- /dev/null +++ b/src/configs/common/transport.cpp @@ -0,0 +1,11 @@ +#include "include/configs/common/transport.h" + +namespace Configs { + bool Transport::ParseFromLink(const QString& link) { return false; } + bool Transport::ParseFromJson(const QJsonObject& object) { return false; } + QString Transport::ExportToLink() { return {}; } + QJsonObject Transport::ExportToJson() { return {}; } + BuildResult Transport::Build() { return {}; } +} + + diff --git a/src/configs/common/utils.cpp b/src/configs/common/utils.cpp new file mode 100644 index 0000000..e373cef --- /dev/null +++ b/src/configs/common/utils.cpp @@ -0,0 +1,21 @@ +#include "include/configs/common/utils.h" + +namespace Configs +{ + void mergeUrlQuery(QUrlQuery& baseQuery, const QString& strQuery) + { + QUrlQuery query = QUrlQuery(strQuery); + for (const auto& item : query.queryItems()) + { + baseQuery.addQueryItem(item.first, item.second); + } + } + + void mergeJsonObjects(QJsonObject& baseObject, const QJsonObject& obj) + { + for (const auto& key : obj.keys()) + { + baseObject[key] = obj[key]; + } + } +} \ No newline at end of file diff --git a/src/configs/outbounds/anyTLS.cpp b/src/configs/outbounds/anyTLS.cpp new file mode 100644 index 0000000..f521602 --- /dev/null +++ b/src/configs/outbounds/anyTLS.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/anyTLS.h" + +namespace Configs { + bool anyTLS::ParseFromLink(const QString& link) { return false; } + bool anyTLS::ParseFromJson(const QJsonObject& object) { return false; } + QString anyTLS::ExportToLink() { return {}; } + QJsonObject anyTLS::ExportToJson() { return {}; } + BuildResult anyTLS::Build() { return {}; } + + QString anyTLS::DisplayAddress() { return {}; } + QString anyTLS::DisplayName() { return {}; } + QString anyTLS::DisplayType() { return {}; } + QString anyTLS::DisplayTypeAndName() { return {}; } + bool anyTLS::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/http.cpp b/src/configs/outbounds/http.cpp new file mode 100644 index 0000000..8b55341 --- /dev/null +++ b/src/configs/outbounds/http.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/http.h" + +namespace Configs { + bool http::ParseFromLink(const QString& link) { return false; } + bool http::ParseFromJson(const QJsonObject& object) { return false; } + QString http::ExportToLink() { return {}; } + QJsonObject http::ExportToJson() { return {}; } + BuildResult http::Build() { return {}; } + + QString http::DisplayAddress() { return {}; } + QString http::DisplayName() { return {}; } + QString http::DisplayType() { return {}; } + QString http::DisplayTypeAndName() { return {}; } + bool http::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/hysteria.cpp b/src/configs/outbounds/hysteria.cpp new file mode 100644 index 0000000..0eb0ea3 --- /dev/null +++ b/src/configs/outbounds/hysteria.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/hysteria.h" + +namespace Configs { + bool hysteria::ParseFromLink(const QString& link) { return false; } + bool hysteria::ParseFromJson(const QJsonObject& object) { return false; } + QString hysteria::ExportToLink() { return {}; } + QJsonObject hysteria::ExportToJson() { return {}; } + BuildResult hysteria::Build() { return {}; } + + QString hysteria::DisplayAddress() { return {}; } + QString hysteria::DisplayName() { return {}; } + QString hysteria::DisplayType() { return {}; } + QString hysteria::DisplayTypeAndName() { return {}; } + bool hysteria::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/hysteria2.cpp b/src/configs/outbounds/hysteria2.cpp new file mode 100644 index 0000000..574869d --- /dev/null +++ b/src/configs/outbounds/hysteria2.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/hysteria2.h" + +namespace Configs { + bool hysteria2::ParseFromLink(const QString& link) { return false; } + bool hysteria2::ParseFromJson(const QJsonObject& object) { return false; } + QString hysteria2::ExportToLink() { return {}; } + QJsonObject hysteria2::ExportToJson() { return {}; } + BuildResult hysteria2::Build() { return {}; } + + QString hysteria2::DisplayAddress() { return {}; } + QString hysteria2::DisplayName() { return {}; } + QString hysteria2::DisplayType() { return {}; } + QString hysteria2::DisplayTypeAndName() { return {}; } + bool hysteria2::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/shadowsocks.cpp b/src/configs/outbounds/shadowsocks.cpp new file mode 100644 index 0000000..0056497 --- /dev/null +++ b/src/configs/outbounds/shadowsocks.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/shadowsocks.h" + +namespace Configs { + bool shadowsocks::ParseFromLink(const QString& link) { return false; } + bool shadowsocks::ParseFromJson(const QJsonObject& object) { return false; } + QString shadowsocks::ExportToLink() { return {}; } + QJsonObject shadowsocks::ExportToJson() { return {}; } + BuildResult shadowsocks::Build() { return {}; } + + QString shadowsocks::DisplayAddress() { return {}; } + QString shadowsocks::DisplayName() { return {}; } + QString shadowsocks::DisplayType() { return {}; } + QString shadowsocks::DisplayTypeAndName() { return {}; } + bool shadowsocks::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/socks.cpp b/src/configs/outbounds/socks.cpp new file mode 100644 index 0000000..d4c9546 --- /dev/null +++ b/src/configs/outbounds/socks.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/socks.h" + +namespace Configs { + bool socks::ParseFromLink(const QString& link) { return false; } + bool socks::ParseFromJson(const QJsonObject& object) { return false; } + QString socks::ExportToLink() { return {}; } + QJsonObject socks::ExportToJson() { return {}; } + BuildResult socks::Build() { return {}; } + + QString socks::DisplayAddress() { return {}; } + QString socks::DisplayName() { return {}; } + QString socks::DisplayType() { return {}; } + QString socks::DisplayTypeAndName() { return {}; } + bool socks::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/ssh.cpp b/src/configs/outbounds/ssh.cpp new file mode 100644 index 0000000..9c1126d --- /dev/null +++ b/src/configs/outbounds/ssh.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/ssh.h" + +namespace Configs { + bool ssh::ParseFromLink(const QString& link) { return false; } + bool ssh::ParseFromJson(const QJsonObject& object) { return false; } + QString ssh::ExportToLink() { return {}; } + QJsonObject ssh::ExportToJson() { return {}; } + BuildResult ssh::Build() { return {}; } + + QString ssh::DisplayAddress() { return {}; } + QString ssh::DisplayName() { return {}; } + QString ssh::DisplayType() { return {}; } + QString ssh::DisplayTypeAndName() { return {}; } + bool ssh::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/tailscale.cpp b/src/configs/outbounds/tailscale.cpp new file mode 100644 index 0000000..1c1e1e8 --- /dev/null +++ b/src/configs/outbounds/tailscale.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/tailscale.h" + +namespace Configs { + bool tailscale::ParseFromLink(const QString& link) { return false; } + bool tailscale::ParseFromJson(const QJsonObject& object) { return false; } + QString tailscale::ExportToLink() { return {}; } + QJsonObject tailscale::ExportToJson() { return {}; } + BuildResult tailscale::Build() { return {}; } + + QString tailscale::DisplayAddress() { return {}; } + QString tailscale::DisplayName() { return {}; } + QString tailscale::DisplayType() { return {}; } + QString tailscale::DisplayTypeAndName() { return {}; } + bool tailscale::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/trojan.cpp b/src/configs/outbounds/trojan.cpp new file mode 100644 index 0000000..b7978e2 --- /dev/null +++ b/src/configs/outbounds/trojan.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/trojan.h" + +namespace Configs { + bool Trojan::ParseFromLink(const QString& link) { return false; } + bool Trojan::ParseFromJson(const QJsonObject& object) { return false; } + QString Trojan::ExportToLink() { return {}; } + QJsonObject Trojan::ExportToJson() { return {}; } + BuildResult Trojan::Build() { return {}; } + + QString Trojan::DisplayAddress() { return {}; } + QString Trojan::DisplayName() { return {}; } + QString Trojan::DisplayType() { return {}; } + QString Trojan::DisplayTypeAndName() { return {}; } + bool Trojan::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/tuic.cpp b/src/configs/outbounds/tuic.cpp new file mode 100644 index 0000000..a75f4ed --- /dev/null +++ b/src/configs/outbounds/tuic.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/tuic.h" + +namespace Configs { + bool tuic::ParseFromLink(const QString& link) { return false; } + bool tuic::ParseFromJson(const QJsonObject& object) { return false; } + QString tuic::ExportToLink() { return {}; } + QJsonObject tuic::ExportToJson() { return {}; } + BuildResult tuic::Build() { return {}; } + + QString tuic::DisplayAddress() { return {}; } + QString tuic::DisplayName() { return {}; } + QString tuic::DisplayType() { return {}; } + QString tuic::DisplayTypeAndName() { return {}; } + bool tuic::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/vless.cpp b/src/configs/outbounds/vless.cpp new file mode 100644 index 0000000..df1f5cc --- /dev/null +++ b/src/configs/outbounds/vless.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/vless.h" + +namespace Configs { + bool vless::ParseFromLink(const QString& link) { return false; } + bool vless::ParseFromJson(const QJsonObject& object) { return false; } + QString vless::ExportToLink() { return {}; } + QJsonObject vless::ExportToJson() { return {}; } + BuildResult vless::Build() { return {}; } + + QString vless::DisplayAddress() { return {}; } + QString vless::DisplayName() { return {}; } + QString vless::DisplayType() { return {}; } + QString vless::DisplayTypeAndName() { return {}; } + bool vless::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/vmess.cpp b/src/configs/outbounds/vmess.cpp new file mode 100644 index 0000000..da72d69 --- /dev/null +++ b/src/configs/outbounds/vmess.cpp @@ -0,0 +1,17 @@ +#include "include/configs/outbounds/vmess.h" + +namespace Configs { + bool vmess::ParseFromLink(const QString& link) { return false; } + bool vmess::ParseFromJson(const QJsonObject& object) { return false; } + QString vmess::ExportToLink() { return {}; } + QJsonObject vmess::ExportToJson() { return {}; } + BuildResult vmess::Build() { return {}; } + + QString vmess::DisplayAddress() { return {}; } + QString vmess::DisplayName() { return {}; } + QString vmess::DisplayType() { return {}; } + QString vmess::DisplayTypeAndName() { return {}; } + bool vmess::IsEndpoint() { return false; } +} + + diff --git a/src/configs/outbounds/wireguard.cpp b/src/configs/outbounds/wireguard.cpp new file mode 100644 index 0000000..9426374 --- /dev/null +++ b/src/configs/outbounds/wireguard.cpp @@ -0,0 +1,23 @@ +#include "include/configs/outbounds/wireguard.h" + +namespace Configs { + bool Peer::ParseFromLink(const QString& link) { return false; } + bool Peer::ParseFromJson(const QJsonObject& object) { return false; } + QString Peer::ExportToLink() { return {}; } + QJsonObject Peer::ExportToJson() { return {}; } + BuildResult Peer::Build() { return {}; } + + bool wireguard::ParseFromLink(const QString& link) { return false; } + bool wireguard::ParseFromJson(const QJsonObject& object) { return false; } + QString wireguard::ExportToLink() { return {}; } + QJsonObject wireguard::ExportToJson() { return {}; } + BuildResult wireguard::Build() { return {}; } + + QString wireguard::DisplayAddress() { return {}; } + QString wireguard::DisplayName() { return {}; } + QString wireguard::DisplayType() { return {}; } + QString wireguard::DisplayTypeAndName() { return {}; } + bool wireguard::IsEndpoint() { return false; } +} + + From ddcf35c01380c22297ecd74cb651035ab1093fe8 Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Fri, 31 Oct 2025 22:54:23 +0300 Subject: [PATCH 2/9] Created russian readme Full russian translation with hyperlinks to English and Chinese versions of the readme. --- README_ru.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 README_ru.md diff --git a/README_ru.md b/README_ru.md new file mode 100644 index 0000000..8599a13 --- /dev/null +++ b/README_ru.md @@ -0,0 +1,79 @@ +:uk: [English](README.md) + +:cn: [中文](README_zh.md) + +# Throne (бывш. Nekoray) +Кросс-платформенный компьютерный прокси-клиент с графическим интерфейсом на базе Qt, преемник [Sing-box](https://github.com/SagerNet/sing-box). + +Поддерживает Windows 11/10/8/7 / Linux / MacOS "из коробки". + +image + +### Примечание для MacOS +Экосистема Apple имеет строгую политику безопасности, и так как Throne не имеет подписанного сертификата, вам нужно избавиться от карантина, используя `xattr -d com.apple.quarantine /path/to/throne.app`. Также, чтобы встроенная функция повышения полномочий работала, у `Terminal` должен быть доступ к `Full Disk`. + +### GitHub установки (Portable ZIP) + +[![GitHub All Releases](https://img.shields.io/github/downloads/Mahdi-zarei/nekoray/total?label=downloads-total&logo=github&style=flat-square)](https://github.com/throneproj/Throne/releases) + +### AUR пакеты +- [source](https://aur.archlinux.org/packages/throne) +- [git](https://aur.archlinux.org/packages/throne-git) +- [bin](https://aur.archlinux.org/packages/throne-bin) + +### RPM репозиторий +[Репозиторий Throne RPM](https://parhelia512.github.io/) для Fedora/RHEL и openSUSE/SLE. + +## Поддерживаемые протоколы + +- SOCKS +- HTTP(S) +- Shadowsocks +- Trojan +- VMess +- VLESS +- TUIC +- Hysteria +- Hysteria2 +- AnyTLS +- Wireguard +- SSH +- Custom Outbound +- Custom Config +- Chaining outbounds +- Extra Core + +## Форматы подписок (Subscription) + +Полностью поддерживаются различные форматы, включая share links, JSON array of outbounds и v2rayN link, и в ограниченном режиме поддерживаются Shadowsocks и Clash. + +## Отдельная благодарность + +- [SagerNet/sing-box](https://github.com/SagerNet/sing-box) +- [Qv2ray](https://github.com/Qv2ray/Qv2ray) +- [Qt](https://www.qt.io/) +- [simple-protobuf](https://github.com/tonda-kriz/simple-protobuf) +- [fkYAML](https://github.com/fktn-k/fkYAML) +- [quirc](https://github.com/dlbeer/quirc) +- [QHotkey](https://github.com/Skycoder42/QHotkey) + +## FAQ +**Как этот проект отличается от оригинального Nekoray?**
+Разработчик Nekoray частично забросил проект ещё в декабре 2023, и хоть некоторые обновления ещё выпускались, сейчас проект официально заархивирован. Throne создан чтобы продолжить путь оригинального проекта, улучшая существующее, добавляя новое и удаляя пережитки. + +**Почему мой антивирус детектит Throne / его ядро как вредносное ПО?**
+Встроенная функция автообновления Throne удаляет старые файлы и создаёт на их месте новые, что несколько схоже с вирусами-шифровальщиками, которые заменяют ваши оригинальные файлы на зашифрованные копии. +Также, функция `Системный DNS` изменяет настройки DNS на вашей системе, что тоже считается опасным действием и является флагом для некоторых антивирусов. + +**Нужна ли настройка `SUID` на Linux?**
+Чтобы создавать и управлять системными интерфейсами TUN, Throne необходимы root-права, ведь иначе вам вручную придётся выдавать ядру некоторые важые права `Cap_xxx_admin` и вводить ваш пароль 3-4 раза каждый раз при запуске TUN. Вы можете отключить автоматическую выдачу root-прав в `Основные настройки`->`Безопасность`, но в таком случае функции, требующие прав администратора, не смогут продолжать работать до тех пор, пока вы самостоятельно не выдадите необходимые права. + +**Почему мой интернет перестаёт работать после принудительного выключения Throne?**
+Если Throne был выключен принудительно пока включен `Системный прокси`, процесс завершится моментально и Throne не сможет сбросить прокси. + +Решение: +- Всегда завершайте Throne нормально. +- Если вы случайно принудительно выключили Throne, откройте его снова, включите `Системный прокси` и выключите его — это сбросит настройки. + +**Откуда загружаются профили/наборы правил маршрутизации?**
+Они расположены в репозитории [routeprofiles](https://github.com/throneproj/routeprofiles). From 90e20088fad50eecce8dd3e9219fd91e7cd6975a Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Fri, 31 Oct 2025 22:55:43 +0300 Subject: [PATCH 3/9] Added hyperlinks to Chinese/Russian docs --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 1b4c36e..f61753e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +:cn: [中文](README_zh.md) + +:ru: [Русский](README_ru.md) + # Throne (Formerly Nekoray) Qt based Desktop cross-platform GUI proxy utility, empowered by [Sing-box](https://github.com/SagerNet/sing-box) From e06fa1e1b0f650da9788db59bde9aa7a38d4ac80 Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Fri, 31 Oct 2025 22:57:07 +0300 Subject: [PATCH 4/9] Added hyperlinks to English/Russian docs --- README_zh.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README_zh.md b/README_zh.md index 44bb16e..e69c753 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,3 +1,7 @@ +:uk: [English](README.md) + +:ru: [Русский](README_ru.md) + # Throne (原先的 Nekoray) 基于 Qt 的跨平台的桌面 GUI 代理客户端,授权自 [Sing-box](https://github.com/SagerNet/sing-box) From 7d2301b3a540cedcbf02dd71475da6082f1debd2 Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Fri, 31 Oct 2025 23:02:32 +0300 Subject: [PATCH 5/9] Russian screenshot --- README_ru.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README_ru.md b/README_ru.md index 8599a13..1acb341 100644 --- a/README_ru.md +++ b/README_ru.md @@ -5,9 +5,10 @@ # Throne (бывш. Nekoray) Кросс-платформенный компьютерный прокси-клиент с графическим интерфейсом на базе Qt, преемник [Sing-box](https://github.com/SagerNet/sing-box). + Поддерживает Windows 11/10/8/7 / Linux / MacOS "из коробки". -image +image ### Примечание для MacOS Экосистема Apple имеет строгую политику безопасности, и так как Throne не имеет подписанного сертификата, вам нужно избавиться от карантина, используя `xattr -d com.apple.quarantine /path/to/throne.app`. Также, чтобы встроенная функция повышения полномочий работала, у `Terminal` должен быть доступ к `Full Disk`. From 2b0bf0ebf1cf12ebc198c0a95e4fb5950251214d Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:20:46 +0300 Subject: [PATCH 6/9] New SVG flags instead of emoji one's --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f61753e..0a7b16e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -:cn: [中文](README_zh.md) + :cn: [中文](README_zh.md) -:ru: [Русский](README_ru.md) + [Русский](README_ru.md) # Throne (Formerly Nekoray) From 99637bb0eeba9ccf43ebac49e75f0ec085308db0 Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:21:25 +0300 Subject: [PATCH 7/9] SVG icons for russian readme --- README_ru.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_ru.md b/README_ru.md index 1acb341..09d58a6 100644 --- a/README_ru.md +++ b/README_ru.md @@ -1,6 +1,6 @@ -:uk: [English](README.md) + [English](README.md) -:cn: [中文](README_zh.md) + [中文](README_zh.md) # Throne (бывш. Nekoray) Кросс-платформенный компьютерный прокси-клиент с графическим интерфейсом на базе Qt, преемник [Sing-box](https://github.com/SagerNet/sing-box). From 8c353be4bdbff7bb382ad07e421e109d23b8b909 Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:22:00 +0300 Subject: [PATCH 8/9] SVG icons for Chinese readme --- README_zh.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_zh.md b/README_zh.md index e69c753..e1efcfc 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,6 +1,6 @@ -:uk: [English](README.md) + [English](README.md) -:ru: [Русский](README_ru.md) + [Русский](README_ru.md) # Throne (原先的 Nekoray) From d0e595a1c31a6a5c232aa87b2b5cf05038c50a83 Mon Sep 17 00:00:00 2001 From: justiamtgm <128042664+justiamtgm@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:22:20 +0300 Subject: [PATCH 9/9] Fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a7b16e..caa4497 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - :cn: [中文](README_zh.md) + [中文](README_zh.md) [Русский](README_ru.md)