mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 05:30:06 +08:00
Fix lots of bugs
This commit is contained in:
parent
fa25de7b74
commit
6bacd1c7a3
@ -274,8 +274,8 @@ set(PROJECT_SOURCES
|
|||||||
src/configs/generate.cpp
|
src/configs/generate.cpp
|
||||||
include/configs/common/utils.h
|
include/configs/common/utils.h
|
||||||
src/configs/common/utils.cpp
|
src/configs/common/utils.cpp
|
||||||
include/configs/outbounds/Custom.h
|
include/configs/outbounds/custom.h
|
||||||
include/configs/outbounds/Chain.h
|
include/configs/outbounds/chain.h
|
||||||
include/configs/outbounds/extracore.h
|
include/configs/outbounds/extracore.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <QHostInfo>
|
||||||
#include "DialFields.h"
|
#include "DialFields.h"
|
||||||
#include "multiplex.h"
|
#include "multiplex.h"
|
||||||
#include "TLS.h"
|
#include "TLS.h"
|
||||||
@ -13,6 +14,7 @@ namespace Configs
|
|||||||
QString name;
|
QString name;
|
||||||
QString server;
|
QString server;
|
||||||
int server_port = 0;
|
int server_port = 0;
|
||||||
|
bool invalid = false;
|
||||||
std::shared_ptr<DialFields> dialFields = std::make_shared<DialFields>();
|
std::shared_ptr<DialFields> dialFields = std::make_shared<DialFields>();
|
||||||
|
|
||||||
outbound()
|
outbound()
|
||||||
@ -23,7 +25,19 @@ namespace Configs
|
|||||||
_add(new configItem("dial_fields", dynamic_cast<JsonStore *>(dialFields.get()), jsonStore));
|
_add(new configItem("dial_fields", dynamic_cast<JsonStore *>(dialFields.get()), jsonStore));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResolveDomainToIP(const std::function<void()> &onFinished);
|
void ResolveDomainToIP(const std::function<void()> &onFinished) {
|
||||||
|
bool noResolve = false;
|
||||||
|
if (IsIpAddress(server) || server.isEmpty()) noResolve = true;
|
||||||
|
if (noResolve) {
|
||||||
|
onFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QHostInfo::lookupHost(server, QApplication::instance(), [=, this](const QHostInfo &host) {
|
||||||
|
auto addrs = host.addresses();
|
||||||
|
if (!addrs.isEmpty()) server = addrs.first().toString();
|
||||||
|
onFinished();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
virtual QString GetAddress()
|
virtual QString GetAddress()
|
||||||
{
|
{
|
||||||
@ -56,6 +70,8 @@ namespace Configs
|
|||||||
|
|
||||||
virtual bool HasTLS() { return false; }
|
virtual bool HasTLS() { return false; }
|
||||||
|
|
||||||
|
virtual bool MustTLS() { return false; }
|
||||||
|
|
||||||
virtual std::shared_ptr<TLS> GetTLS() { return std::make_shared<TLS>(); }
|
virtual std::shared_ptr<TLS> GetTLS() { return std::make_shared<TLS>(); }
|
||||||
|
|
||||||
virtual std::shared_ptr<Transport> GetTransport() { return std::make_shared<Transport>(); }
|
virtual std::shared_ptr<Transport> GetTransport() { return std::make_shared<Transport>(); }
|
||||||
@ -64,6 +80,17 @@ namespace Configs
|
|||||||
|
|
||||||
virtual bool IsEndpoint() { return false; };
|
virtual bool IsEndpoint() { return false; };
|
||||||
|
|
||||||
|
QString ExportJsonLink() {
|
||||||
|
auto json = ExportToJson();
|
||||||
|
QUrl url;
|
||||||
|
url.setScheme("json");
|
||||||
|
url.setHost("throne");
|
||||||
|
url.setFragment(QJsonObject2QString(json, true)
|
||||||
|
.toUtf8()
|
||||||
|
.toBase64(QByteArray::Base64UrlEncoding));
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// baseConfig overrides
|
// baseConfig overrides
|
||||||
bool ParseFromLink(const QString& link) override;
|
bool ParseFromLink(const QString& link) override;
|
||||||
bool ParseFromJson(const QJsonObject& object) override;
|
bool ParseFromJson(const QJsonObject& object) override;
|
||||||
|
|||||||
@ -58,7 +58,10 @@ namespace Configs
|
|||||||
}
|
}
|
||||||
|
|
||||||
void saveMuxState(int state) {
|
void saveMuxState(int state) {
|
||||||
if (state == 1) enabled = true;
|
if (state == 1) {
|
||||||
|
enabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
enabled = false;
|
enabled = false;
|
||||||
if (state == 0) unspecified = true;
|
if (state == 0) unspecified = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,10 @@ namespace Configs
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MustTLS() override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<TLS> GetTLS() override {
|
std::shared_ptr<TLS> GetTLS() override {
|
||||||
return tls;
|
return tls;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "include/configs/common/Outbound.h"
|
#include "include/configs/common/Outbound.h"
|
||||||
|
#include "QJsonArray"
|
||||||
|
|
||||||
namespace Configs
|
namespace Configs
|
||||||
{
|
{
|
||||||
@ -17,6 +18,21 @@ namespace Configs
|
|||||||
|
|
||||||
QString DisplayAddress() override { return ""; };
|
QString DisplayAddress() override { return ""; };
|
||||||
|
|
||||||
|
bool ParseFromJson(const QJsonObject &object) override {
|
||||||
|
if (object.isEmpty()) return false;
|
||||||
|
if (object.contains("name")) name = object["name"].toString();
|
||||||
|
if (object.contains("list")) list = QJsonArray2QListInt(object["list"].toArray());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject ExportToJson() override {
|
||||||
|
QJsonObject object;
|
||||||
|
object["name"] = name;
|
||||||
|
object["type"] = "chain";
|
||||||
|
object["list"] = QListInt2QJsonArray(list);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
BuildResult Build() override
|
BuildResult Build() override
|
||||||
{
|
{
|
||||||
return {{}, "Cannot call Build on chain config"};
|
return {{}, "Cannot call Build on chain config"};
|
||||||
|
|||||||
@ -15,6 +15,23 @@ namespace Configs
|
|||||||
_add(new configItem("type", &type, string));
|
_add(new configItem("type", &type, string));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ParseFromJson(const QJsonObject &object) override {
|
||||||
|
if (object.isEmpty()) return false;
|
||||||
|
if (object.contains("name")) name = object["name"].toString();
|
||||||
|
if (object.contains("subtype")) type = object["subtype"].toString();
|
||||||
|
if (object.contains("config")) config = object["config"].toString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject ExportToJson() override {
|
||||||
|
QJsonObject object;
|
||||||
|
object["name"] = name;
|
||||||
|
object["type"] = "custom";
|
||||||
|
object["subtype"] = type;
|
||||||
|
object["config"] = config;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
QString GetAddress() override
|
QString GetAddress() override
|
||||||
{
|
{
|
||||||
if (type == "outbound") {
|
if (type == "outbound") {
|
||||||
|
|||||||
@ -21,6 +21,31 @@ namespace Configs
|
|||||||
_add(new configItem("no_logs", &noLogs, itemType::boolean));
|
_add(new configItem("no_logs", &noLogs, itemType::boolean));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool ParseFromJson(const QJsonObject &object) override {
|
||||||
|
if (object.isEmpty()) return false;
|
||||||
|
if (object.contains("name")) name = object["name"].toString();
|
||||||
|
if (object.contains("socks_address")) socksAddress = object["socks_address"].toString();
|
||||||
|
if (object.contains("socks_port")) socksPort = object["socks_port"].toInt();
|
||||||
|
if (object.contains("extra_core_path")) extraCorePath = object["extra_core_path"].toString();
|
||||||
|
if (object.contains("extra_core_args")) extraCoreArgs = object["extra_core_args"].toString();
|
||||||
|
if (object.contains("extra_core_conf")) extraCoreConf = object["extra_core_conf"].toString();
|
||||||
|
if (object.contains("no_logs")) noLogs = object["no_logs"].toBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject ExportToJson() override {
|
||||||
|
QJsonObject object;
|
||||||
|
object["name"] = name;
|
||||||
|
object["type"] = "extracore";
|
||||||
|
object["socks_address"] = socksAddress;
|
||||||
|
object["socks_port"] = socksPort;
|
||||||
|
object["extra_core_path"] = extraCorePath;
|
||||||
|
object["extra_core_args"] = extraCoreArgs;
|
||||||
|
object["extra_core_conf"] = extraCoreConf;
|
||||||
|
object["no_logs"] = noLogs;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
QString DisplayType() override { return "ExtraCore"; };
|
QString DisplayType() override { return "ExtraCore"; };
|
||||||
|
|
||||||
BuildResult Build() override
|
BuildResult Build() override
|
||||||
|
|||||||
@ -38,6 +38,10 @@ namespace Configs
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MustTLS() override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<TLS> GetTLS() override {
|
std::shared_ptr<TLS> GetTLS() override {
|
||||||
return tls;
|
return tls;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,10 @@ namespace Configs
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MustTLS() override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<TLS> GetTLS() override {
|
std::shared_ptr<TLS> GetTLS() override {
|
||||||
return tls;
|
return tls;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,10 @@ namespace Configs
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MustTLS() override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<TLS> GetTLS() override {
|
std::shared_ptr<TLS> GetTLS() override {
|
||||||
return tls;
|
return tls;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -878,7 +878,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="menu_copy_links_nkr">
|
<action name="menu_copy_links_nkr">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Copy links of selected (Custom Links)</string>
|
<string>Copy links of selected (Json Links)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string notr="true">Ctrl+Alt+C</string>
|
<string notr="true">Ctrl+Alt+C</string>
|
||||||
|
|||||||
@ -40,7 +40,11 @@ namespace Configs {
|
|||||||
}
|
}
|
||||||
BuildResult outbound::Build()
|
BuildResult outbound::Build()
|
||||||
{
|
{
|
||||||
return {ExportToJson(), ""};
|
QJsonObject object;
|
||||||
|
if (!server.isEmpty()) object["server"] = server;
|
||||||
|
if (server_port > 0) object["server_port"] = server_port;
|
||||||
|
mergeJsonObjects(object, dialFields->Build().object);
|
||||||
|
return {object, ""};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -152,7 +152,13 @@ namespace Configs {
|
|||||||
if (!url.isValid()) return false;
|
if (!url.isValid()) return false;
|
||||||
auto query = QUrlQuery(url.query(QUrl::ComponentFormattingOption::FullyDecoded));
|
auto query = QUrlQuery(url.query(QUrl::ComponentFormattingOption::FullyDecoded));
|
||||||
|
|
||||||
if (query.hasQueryItem("security")) enabled = query.queryItemValue("security").replace("reality", "tls").replace("none", "") == "tls";
|
if (query.hasQueryItem("security")) enabled = query.queryItemValue("security")
|
||||||
|
.replace("reality", "tls")
|
||||||
|
.replace("none", "")
|
||||||
|
.replace("0", "")
|
||||||
|
.replace("false", "tls")
|
||||||
|
.replace("1", "tls")
|
||||||
|
.replace("true", "tls") == "tls";
|
||||||
if (query.hasQueryItem("disable_sni")) disable_sni = query.queryItemValue("disable_sni").replace("1", "true") == "true";
|
if (query.hasQueryItem("disable_sni")) disable_sni = query.queryItemValue("disable_sni").replace("1", "true") == "true";
|
||||||
if (query.hasQueryItem("sni")) server_name = query.queryItemValue("sni");
|
if (query.hasQueryItem("sni")) server_name = query.queryItemValue("sni");
|
||||||
if (query.hasQueryItem("peer")) server_name = query.queryItemValue("peer");
|
if (query.hasQueryItem("peer")) server_name = query.queryItemValue("peer");
|
||||||
|
|||||||
@ -67,7 +67,10 @@ namespace Configs {
|
|||||||
if (query.hasQueryItem("type"))
|
if (query.hasQueryItem("type"))
|
||||||
{
|
{
|
||||||
type = query.queryItemValue("type");
|
type = query.queryItemValue("type");
|
||||||
if ((type == "tcp" && query.queryItemValue("headerType") == "http") || type == "h2") type = "http";
|
if ((type == "tcp" && query.queryItemValue("headerType") == "http") || type == "h2") {
|
||||||
|
type = "http";
|
||||||
|
method = "GET";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (query.hasQueryItem("host")) host = query.queryItemValue("host");
|
if (query.hasQueryItem("host")) host = query.queryItemValue("host");
|
||||||
if (query.hasQueryItem("path")) path = query.queryItemValue("path");
|
if (query.hasQueryItem("path")) path = query.queryItemValue("path");
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "3rdparty/fkYAML/node.hpp"
|
#include "3rdparty/fkYAML/node.hpp"
|
||||||
|
|
||||||
@ -13,22 +14,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
GroupUpdater *groupUpdater = new GroupUpdater;
|
GroupUpdater *groupUpdater = new GroupUpdater;
|
||||||
|
|
||||||
void RawUpdater_FixEnt(const std::shared_ptr<Configs::ProxyEntity> &ent) {
|
|
||||||
if (ent == nullptr) return;
|
|
||||||
auto stream = Configs::GetStreamSettings(ent->bean.get());
|
|
||||||
if (stream == nullptr) return;
|
|
||||||
// 1. "security"
|
|
||||||
if (stream->security == "none" || stream->security == "0" || stream->security == "false") {
|
|
||||||
stream->security = "";
|
|
||||||
} else if (stream->security == "1" || stream->security == "true") {
|
|
||||||
stream->security = "tls";
|
|
||||||
}
|
|
||||||
// 2. TLS SNI: v2rayN config builder generate sni like this, so set sni here for their format.
|
|
||||||
if (stream->security == "tls" && IsIpAddress(ent->bean->serverAddress) && (!stream->host.isEmpty()) && stream->sni.isEmpty()) {
|
|
||||||
stream->sni = stream->host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int JsonEndIdx(const QString &str, int begin) {
|
int JsonEndIdx(const QString &str, int begin) {
|
||||||
int sz = str.length();
|
int sz = str.length();
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
@ -106,18 +91,18 @@ namespace Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Configs::ProxyEntity> ent;
|
std::shared_ptr<Configs::ProxyEntity> ent;
|
||||||
bool needFix = true;
|
|
||||||
|
|
||||||
// Nekoray format
|
// Json base64 link format
|
||||||
if (str.startsWith("nekoray://")) {
|
if (str.startsWith("json://")) {
|
||||||
needFix = false;
|
|
||||||
auto link = QUrl(str);
|
auto link = QUrl(str);
|
||||||
if (!link.isValid()) return;
|
if (!link.isValid()) return;
|
||||||
ent = Configs::ProfileManager::NewProxyEntity(link.host());
|
auto dataBytes = DecodeB64IfValid(link.fragment().toUtf8(), QByteArray::Base64UrlEncoding);
|
||||||
if (ent->bean->version == -114514) return;
|
if (dataBytes.isEmpty()) return;
|
||||||
auto j = DecodeB64IfValid(link.fragment().toUtf8(), QByteArray::Base64UrlEncoding);
|
auto data = QJsonDocument::fromJson(dataBytes).object();
|
||||||
if (j.isEmpty()) return;
|
if (data.isEmpty()) return;
|
||||||
ent->bean->FromJsonBytes(j);
|
ent = Configs::ProfileManager::NewProxyEntity(data["type"].toString());
|
||||||
|
if (ent->outbound->invalid) return;
|
||||||
|
ent->outbound->ParseFromJson(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Json
|
// Json
|
||||||
@ -188,7 +173,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
// Hysteria1
|
// Hysteria1
|
||||||
if (str.startsWith("hysteria://")) {
|
if (str.startsWith("hysteria://")) {
|
||||||
needFix = false;
|
|
||||||
ent = Configs::ProfileManager::NewProxyEntity("hysteria");
|
ent = Configs::ProfileManager::NewProxyEntity("hysteria");
|
||||||
auto ok = ent->Hysteria()->ParseFromLink(str);
|
auto ok = ent->Hysteria()->ParseFromLink(str);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@ -196,7 +180,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
// Hysteria2
|
// Hysteria2
|
||||||
if (str.startsWith("hysteria2://") || str.startsWith("hy2://")) {
|
if (str.startsWith("hysteria2://") || str.startsWith("hy2://")) {
|
||||||
needFix = false;
|
|
||||||
ent = Configs::ProfileManager::NewProxyEntity("hysteria2");
|
ent = Configs::ProfileManager::NewProxyEntity("hysteria2");
|
||||||
auto ok = ent->Hysteria2()->ParseFromLink(str);
|
auto ok = ent->Hysteria2()->ParseFromLink(str);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@ -204,7 +187,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
// TUIC
|
// TUIC
|
||||||
if (str.startsWith("tuic://")) {
|
if (str.startsWith("tuic://")) {
|
||||||
needFix = false;
|
|
||||||
ent = Configs::ProfileManager::NewProxyEntity("tuic");
|
ent = Configs::ProfileManager::NewProxyEntity("tuic");
|
||||||
auto ok = ent->TUIC()->ParseFromLink(str);
|
auto ok = ent->TUIC()->ParseFromLink(str);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@ -212,7 +194,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
// Wireguard
|
// Wireguard
|
||||||
if (str.startsWith("wg://")) {
|
if (str.startsWith("wg://")) {
|
||||||
needFix = false;
|
|
||||||
ent = Configs::ProfileManager::NewProxyEntity("wireguard");
|
ent = Configs::ProfileManager::NewProxyEntity("wireguard");
|
||||||
auto ok = ent->Wireguard()->ParseFromLink(str);
|
auto ok = ent->Wireguard()->ParseFromLink(str);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@ -220,7 +201,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
// SSH
|
// SSH
|
||||||
if (str.startsWith("ssh://")) {
|
if (str.startsWith("ssh://")) {
|
||||||
needFix = false;
|
|
||||||
ent = Configs::ProfileManager::NewProxyEntity("ssh");
|
ent = Configs::ProfileManager::NewProxyEntity("ssh");
|
||||||
auto ok = ent->SSH()->ParseFromLink(str);
|
auto ok = ent->SSH()->ParseFromLink(str);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@ -228,9 +208,6 @@ namespace Subscription {
|
|||||||
|
|
||||||
if (ent == nullptr) return;
|
if (ent == nullptr) return;
|
||||||
|
|
||||||
// Fix
|
|
||||||
if (needFix) RawUpdater_FixEnt(ent);
|
|
||||||
|
|
||||||
// End
|
// End
|
||||||
updated_order += ent;
|
updated_order += ent;
|
||||||
}
|
}
|
||||||
@ -817,7 +794,7 @@ namespace Subscription {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needFix) RawUpdater_FixEnt(ent);
|
// if (needFix) RawUpdater_FixEnt(ent); TODO
|
||||||
updated_order += ent;
|
updated_order += ent;
|
||||||
}
|
}
|
||||||
} catch (const fkyaml::exception &ex) {
|
} catch (const fkyaml::exception &ex) {
|
||||||
@ -927,7 +904,7 @@ namespace Subscription {
|
|||||||
if (Configs::dataStore->sub_clear) {
|
if (Configs::dataStore->sub_clear) {
|
||||||
// all is new profile
|
// all is new profile
|
||||||
for (const auto &ent: out_all) {
|
for (const auto &ent: out_all) {
|
||||||
change_text += "[+] " + ent->bean->DisplayTypeAndName() + "\n";
|
change_text += "[+] " + ent->outbound->DisplayTypeAndName() + "\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// find and delete not updated profile by ProfileFilter
|
// find and delete not updated profile by ProfileFilter
|
||||||
@ -940,7 +917,7 @@ namespace Subscription {
|
|||||||
if (only_out.size() < 1000)
|
if (only_out.size() < 1000)
|
||||||
{
|
{
|
||||||
for (const auto &ent: only_out) {
|
for (const auto &ent: only_out) {
|
||||||
notice_added += "[+] " + ent->bean->DisplayTypeAndName() + "\n";
|
notice_added += "[+] " + ent->outbound->DisplayTypeAndName() + "\n";
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@ -949,7 +926,7 @@ namespace Subscription {
|
|||||||
if (only_in.size() < 1000)
|
if (only_in.size() < 1000)
|
||||||
{
|
{
|
||||||
for (const auto &ent: only_in) {
|
for (const auto &ent: only_in) {
|
||||||
notice_deleted += "[-] " + ent->bean->DisplayTypeAndName() + "\n";
|
notice_deleted += "[-] " + ent->outbound->DisplayTypeAndName() + "\n";
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -283,6 +283,7 @@ namespace Configs {
|
|||||||
} else {
|
} else {
|
||||||
bean = new Configs::AbstractBean(-114514);
|
bean = new Configs::AbstractBean(-114514);
|
||||||
outbound = new Configs::outbound();
|
outbound = new Configs::outbound();
|
||||||
|
outbound->invalid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ent = std::make_shared<ProxyEntity>(outbound, bean, type);
|
auto ent = std::make_shared<ProxyEntity>(outbound, bean, type);
|
||||||
|
|||||||
@ -191,7 +191,7 @@ namespace Configs {
|
|||||||
MW_show_log("The outbound described in the rule chain is missing, maybe your data is corrupted");
|
MW_show_log("The outbound described in the rule chain is missing, maybe your data is corrupted");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
obj["outbound"] = prof->bean->DisplayName();
|
obj["outbound"] = prof->outbound->DisplayName();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!outboundTag.isEmpty()) obj["outbound"] = outboundTag;
|
if (!outboundTag.isEmpty()) obj["outbound"] = outboundTag;
|
||||||
@ -511,7 +511,7 @@ namespace Configs {
|
|||||||
if (name == "proxy") return -1;
|
if (name == "proxy") return -1;
|
||||||
if (name == "direct") return -2;
|
if (name == "direct") return -2;
|
||||||
for (const auto& item: profileManager->profiles) {
|
for (const auto& item: profileManager->profiles) {
|
||||||
if (item.second->bean->name == name) return item.first;
|
if (item.second->outbound->name == name) return item.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INVALID_ID;
|
return INVALID_ID;
|
||||||
|
|||||||
@ -77,7 +77,7 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr<Configs::Group> &ent, QWi
|
|||||||
QStringList links;
|
QStringList links;
|
||||||
for (const auto &[_, profile]: Configs::profileManager->profiles) {
|
for (const auto &[_, profile]: Configs::profileManager->profiles) {
|
||||||
if (profile->gid != ent->id) continue;
|
if (profile->gid != ent->id) continue;
|
||||||
links += profile->bean->ToShareLink();
|
links += profile->outbound->ExportToLink();
|
||||||
}
|
}
|
||||||
QApplication::clipboard()->setText(links.join("\n"));
|
QApplication::clipboard()->setText(links.join("\n"));
|
||||||
MessageBoxInfo(software_name, tr("Copied"));
|
MessageBoxInfo(software_name, tr("Copied"));
|
||||||
@ -86,7 +86,7 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr<Configs::Group> &ent, QWi
|
|||||||
QStringList links;
|
QStringList links;
|
||||||
for (const auto &[_, profile]: Configs::profileManager->profiles) {
|
for (const auto &[_, profile]: Configs::profileManager->profiles) {
|
||||||
if (profile->gid != ent->id) continue;
|
if (profile->gid != ent->id) continue;
|
||||||
links += profile->bean->ToNekorayShareLink(profile->type);
|
links += profile->outbound->ExportToLink(); // TODO FIX neko link
|
||||||
}
|
}
|
||||||
QApplication::clipboard()->setText(links.join("\n"));
|
QApplication::clipboard()->setText(links.join("\n"));
|
||||||
MessageBoxInfo(software_name, tr("Copied"));
|
MessageBoxInfo(software_name, tr("Copied"));
|
||||||
@ -122,7 +122,7 @@ QStringList DialogEditGroup::load_proxy_items() {
|
|||||||
QStringList res = QStringList();
|
QStringList res = QStringList();
|
||||||
auto profiles = Configs::profileManager->profiles;
|
auto profiles = Configs::profileManager->profiles;
|
||||||
for (const auto &item: profiles) {
|
for (const auto &item: profiles) {
|
||||||
res.push_back(item.second->bean->DisplayName());
|
res.push_back(item.second->outbound->DisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -131,7 +131,7 @@ QStringList DialogEditGroup::load_proxy_items() {
|
|||||||
int DialogEditGroup::get_proxy_id(QString name) {
|
int DialogEditGroup::get_proxy_id(QString name) {
|
||||||
auto profiles = Configs::profileManager->profiles;
|
auto profiles = Configs::profileManager->profiles;
|
||||||
for (const auto &item: profiles) {
|
for (const auto &item: profiles) {
|
||||||
if (item.second->bean->DisplayName() == name) return item.first;
|
if (item.second->outbound->DisplayName() == name) return item.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -139,5 +139,5 @@ int DialogEditGroup::get_proxy_id(QString name) {
|
|||||||
|
|
||||||
QString DialogEditGroup::get_proxy_name(int id) {
|
QString DialogEditGroup::get_proxy_name(int id) {
|
||||||
auto profiles = Configs::profileManager->profiles;
|
auto profiles = Configs::profileManager->profiles;
|
||||||
return profiles.count(id) == 0 ? "None" : profiles[id]->bean->DisplayName();
|
return profiles.count(id) == 0 ? "None" : profiles[id]->outbound->DisplayName();
|
||||||
}
|
}
|
||||||
@ -1678,7 +1678,6 @@ void MainWindow::on_menu_add_from_clipboard_triggered() {
|
|||||||
Subscription::groupUpdater->AsyncUpdate(clipboard);
|
Subscription::groupUpdater->AsyncUpdate(clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO fix full export
|
|
||||||
void MainWindow::on_menu_clone_triggered() {
|
void MainWindow::on_menu_clone_triggered() {
|
||||||
auto ents = get_now_selected_list();
|
auto ents = get_now_selected_list();
|
||||||
if (ents.isEmpty()) return;
|
if (ents.isEmpty()) return;
|
||||||
@ -1688,7 +1687,7 @@ void MainWindow::on_menu_clone_triggered() {
|
|||||||
|
|
||||||
QStringList sls;
|
QStringList sls;
|
||||||
for (const auto &ent: ents) {
|
for (const auto &ent: ents) {
|
||||||
sls << ent->outbound->ExportToLink();
|
sls << ent->outbound->ExportJsonLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
Subscription::groupUpdater->AsyncUpdate(sls.join("\n"));
|
Subscription::groupUpdater->AsyncUpdate(sls.join("\n"));
|
||||||
@ -1765,7 +1764,7 @@ void MainWindow::on_menu_copy_links_nkr_triggered() {
|
|||||||
auto ents = get_now_selected_list();
|
auto ents = get_now_selected_list();
|
||||||
QStringList links;
|
QStringList links;
|
||||||
for (const auto &ent: ents) {
|
for (const auto &ent: ents) {
|
||||||
links += ent->outbound->ExportToLink();
|
links += ent->outbound->ExportJsonLink();
|
||||||
}
|
}
|
||||||
if (links.length() == 0) return;
|
if (links.length() == 0) return;
|
||||||
QApplication::clipboard()->setText(links.join("\n"));
|
QApplication::clipboard()->setText(links.join("\n"));
|
||||||
|
|||||||
@ -83,7 +83,7 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin
|
|||||||
QString::fromStdString(res.error.value()).contains("context canceled")) ent->latency=0;
|
QString::fromStdString(res.error.value()).contains("context canceled")) ent->latency=0;
|
||||||
else {
|
else {
|
||||||
ent->latency = -1;
|
ent->latency = -1;
|
||||||
MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
|
MW_show_log(tr("[%1] test error: %2").arg(ent->outbound->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ent->Save();
|
ent->Save();
|
||||||
@ -127,7 +127,7 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin
|
|||||||
QString::fromStdString(res.error.value()).contains("context canceled")) ent->latency=0;
|
QString::fromStdString(res.error.value()).contains("context canceled")) ent->latency=0;
|
||||||
else {
|
else {
|
||||||
ent->latency = -1;
|
ent->latency = -1;
|
||||||
MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
|
MW_show_log(tr("[%1] test error: %2").arg(ent->outbound->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ent->Save();
|
ent->Save();
|
||||||
@ -285,7 +285,7 @@ void MainWindow::querySpeedtest(QDateTime lastProxyListUpdate, const QMap<QStrin
|
|||||||
runOnUiThread([=, this, &lastProxyListUpdate]
|
runOnUiThread([=, this, &lastProxyListUpdate]
|
||||||
{
|
{
|
||||||
showSpeedtestData = true;
|
showSpeedtestData = true;
|
||||||
currentSptProfileName = profile->bean->name;
|
currentSptProfileName = profile->outbound->name;
|
||||||
currentTestResult = res.result.value();
|
currentTestResult = res.result.value();
|
||||||
UpdateDataView();
|
UpdateDataView();
|
||||||
|
|
||||||
@ -414,7 +414,7 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC
|
|||||||
ent->ul_speed = "N/A";
|
ent->ul_speed = "N/A";
|
||||||
ent->latency = -1;
|
ent->latency = -1;
|
||||||
ent->test_country = "";
|
ent->test_country = "";
|
||||||
MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
|
MW_show_log(tr("[%1] speed test error: %2").arg(ent->outbound->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
|
||||||
}
|
}
|
||||||
ent->Save();
|
ent->Save();
|
||||||
}
|
}
|
||||||
@ -578,9 +578,9 @@ void MainWindow::profile_start(int _id) {
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
// do start
|
// do start
|
||||||
MW_show_log(">>>>>>>> " + tr("Starting profile %1").arg(ent->bean->DisplayTypeAndName()));
|
MW_show_log(">>>>>>>> " + tr("Starting profile %1").arg(ent->outbound->DisplayTypeAndName()));
|
||||||
if (!profile_start_stage2()) {
|
if (!profile_start_stage2()) {
|
||||||
MW_show_log("<<<<<<<< " + tr("Failed to start profile %1").arg(ent->bean->DisplayTypeAndName()));
|
MW_show_log("<<<<<<<< " + tr("Failed to start profile %1").arg(ent->outbound->DisplayTypeAndName()));
|
||||||
}
|
}
|
||||||
mu_starting.unlock();
|
mu_starting.unlock();
|
||||||
// cancel timeout
|
// cancel timeout
|
||||||
@ -664,7 +664,7 @@ void MainWindow::profile_stop(bool crash, bool block, bool manual) {
|
|||||||
|
|
||||||
runOnNewThread([=, this, &blocker] {
|
runOnNewThread([=, this, &blocker] {
|
||||||
// do stop
|
// do stop
|
||||||
MW_show_log(">>>>>>>> " + tr("Stopping profile %1").arg(running->bean->DisplayTypeAndName()));
|
MW_show_log(">>>>>>>> " + tr("Stopping profile %1").arg(running->outbound->DisplayTypeAndName()));
|
||||||
if (!profile_stop_stage2()) {
|
if (!profile_stop_stage2()) {
|
||||||
MW_show_log("<<<<<<<< " + tr("Failed to stop, please restart the program."));
|
MW_show_log("<<<<<<<< " + tr("Failed to stop, please restart the program."));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,9 +19,9 @@ ProxyItem::~ProxyItem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ProxyItem::refresh_data() {
|
void ProxyItem::refresh_data() {
|
||||||
ui->type->setText(ent->bean->DisplayType());
|
ui->type->setText(ent->outbound->DisplayType());
|
||||||
ui->name->setText(ent->bean->DisplayName());
|
ui->name->setText(ent->outbound->DisplayName());
|
||||||
ui->address->setText(ent->bean->DisplayAddress());
|
ui->address->setText(ent->outbound->DisplayAddress());
|
||||||
ui->traffic->setText(ent->traffic_data->DisplayTraffic());
|
ui->traffic->setText(ent->traffic_data->DisplayTraffic());
|
||||||
ui->test_result->setText(ent->DisplayTestResult());
|
ui->test_result->setText(ent->DisplayTestResult());
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ void ProxyItem::refresh_data() {
|
|||||||
|
|
||||||
void ProxyItem::on_remove_clicked() {
|
void ProxyItem::on_remove_clicked() {
|
||||||
if (!this->remove_confirm ||
|
if (!this->remove_confirm ||
|
||||||
QMessageBox::question(this, tr("Confirmation"), tr("Remove %1?").arg(ent->bean->DisplayName())) == QMessageBox::StandardButton::Yes) {
|
QMessageBox::question(this, tr("Confirmation"), tr("Remove %1?").arg(ent->outbound->DisplayName())) == QMessageBox::StandardButton::Yes) {
|
||||||
// TODO do remove (or not) -> callback
|
// TODO do remove (or not) -> callback
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,20 +39,7 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
network_title_base = ui->network_box->title();
|
network_title_base = ui->network_box->title();
|
||||||
connect(ui->network, &QComboBox::currentTextChanged, this, [=,this](const QString &txt) {
|
connect(ui->network, &QComboBox::currentTextChanged, this, [=,this](const QString &txt) {
|
||||||
ui->network_box->setTitle(network_title_base.arg(txt));
|
ui->network_box->setTitle(network_title_base.arg(txt));
|
||||||
if (txt == "tcp") {
|
if (txt == "grpc") {
|
||||||
ui->header_type->setVisible(true);
|
|
||||||
ui->header_type_l->setVisible(true);
|
|
||||||
ui->headers->setVisible(false);
|
|
||||||
ui->headers_l->setVisible(false);
|
|
||||||
ui->method->setVisible(false);
|
|
||||||
ui->method_l->setVisible(false);
|
|
||||||
ui->path->setVisible(true);
|
|
||||||
ui->path_l->setVisible(true);
|
|
||||||
ui->host->setVisible(true);
|
|
||||||
ui->host_l->setVisible(true);
|
|
||||||
} else if (txt == "grpc") {
|
|
||||||
ui->header_type->setVisible(false);
|
|
||||||
ui->header_type_l->setVisible(false);
|
|
||||||
ui->headers->setVisible(false);
|
ui->headers->setVisible(false);
|
||||||
ui->headers_l->setVisible(false);
|
ui->headers_l->setVisible(false);
|
||||||
ui->method->setVisible(false);
|
ui->method->setVisible(false);
|
||||||
@ -62,8 +49,6 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host->setVisible(false);
|
ui->host->setVisible(false);
|
||||||
ui->host_l->setVisible(false);
|
ui->host_l->setVisible(false);
|
||||||
} else if (txt == "ws" || txt == "httpupgrade") {
|
} else if (txt == "ws" || txt == "httpupgrade") {
|
||||||
ui->header_type->setVisible(false);
|
|
||||||
ui->header_type_l->setVisible(false);
|
|
||||||
ui->headers->setVisible(true);
|
ui->headers->setVisible(true);
|
||||||
ui->headers_l->setVisible(true);
|
ui->headers_l->setVisible(true);
|
||||||
ui->method->setVisible(false);
|
ui->method->setVisible(false);
|
||||||
@ -73,8 +58,6 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host->setVisible(true);
|
ui->host->setVisible(true);
|
||||||
ui->host_l->setVisible(true);
|
ui->host_l->setVisible(true);
|
||||||
} else if (txt == "http") {
|
} else if (txt == "http") {
|
||||||
ui->header_type->setVisible(false);
|
|
||||||
ui->header_type_l->setVisible(false);
|
|
||||||
ui->headers->setVisible(true);
|
ui->headers->setVisible(true);
|
||||||
ui->headers_l->setVisible(true);
|
ui->headers_l->setVisible(true);
|
||||||
ui->method->setVisible(true);
|
ui->method->setVisible(true);
|
||||||
@ -84,8 +67,6 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host->setVisible(true);
|
ui->host->setVisible(true);
|
||||||
ui->host_l->setVisible(true);
|
ui->host_l->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
ui->header_type->setVisible(false);
|
|
||||||
ui->header_type_l->setVisible(false);
|
|
||||||
ui->headers->setVisible(false);
|
ui->headers->setVisible(false);
|
||||||
ui->headers_l->setVisible(false);
|
ui->headers_l->setVisible(false);
|
||||||
ui->method->setVisible(false);
|
ui->method->setVisible(false);
|
||||||
@ -164,8 +145,8 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
LOAD_TYPE("wireguard")
|
LOAD_TYPE("wireguard")
|
||||||
LOAD_TYPE("tailscale")
|
LOAD_TYPE("tailscale")
|
||||||
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), "outbound");
|
||||||
ui->type->addItem(tr("Custom (%1 config)").arg(software_core_name), "internal-full");
|
ui->type->addItem(tr("Custom (%1 config)").arg(software_core_name), "fullconfig");
|
||||||
ui->type->addItem(tr("Extra Core"), "extracore");
|
ui->type->addItem(tr("Extra Core"), "extracore");
|
||||||
LOAD_TYPE("chain")
|
LOAD_TYPE("chain")
|
||||||
|
|
||||||
@ -259,7 +240,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
auto _innerWidget = new EditSSH(this);
|
auto _innerWidget = new EditSSH(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
innerEditor = _innerWidget;
|
innerEditor = _innerWidget;
|
||||||
} else if (type == "internal" || type == "internal-full" || type == "custom") {
|
} else if (type == "outbound" || type == "fullconfig" || type == "custom") {
|
||||||
auto _innerWidget = new EditCustom(this);
|
auto _innerWidget = new EditCustom(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
innerEditor = _innerWidget;
|
innerEditor = _innerWidget;
|
||||||
@ -286,7 +267,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hide some widget
|
// hide some widget
|
||||||
auto showAddressPort = type != "chain" && customType != "internal" && customType != "internal-full" && type != "extracore" && type != "tailscale";
|
auto showAddressPort = type != "chain" && customType != "outbound" && customType != "fullconfig" && type != "extracore" && type != "tailscale";
|
||||||
ui->address->setVisible(showAddressPort);
|
ui->address->setVisible(showAddressPort);
|
||||||
ui->address_l->setVisible(showAddressPort);
|
ui->address_l->setVisible(showAddressPort);
|
||||||
ui->port->setVisible(showAddressPort);
|
ui->port->setVisible(showAddressPort);
|
||||||
@ -296,8 +277,13 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
ui->right_all_w->setVisible(true);
|
ui->right_all_w->setVisible(true);
|
||||||
auto tls = ent->outbound->GetTLS();
|
auto tls = ent->outbound->GetTLS();
|
||||||
auto transport = ent->outbound->GetTransport();
|
auto transport = ent->outbound->GetTransport();
|
||||||
|
if (ent->outbound->MustTLS()) {
|
||||||
|
ui->security->setCurrentText("tls");
|
||||||
|
ui->security->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
ui->security->setCurrentText(tls->enabled ? "tls" : "");
|
||||||
|
}
|
||||||
ui->network->setCurrentText(transport->type);
|
ui->network->setCurrentText(transport->type);
|
||||||
ui->security->setCurrentText(tls->enabled ? "tls" : "");
|
|
||||||
ui->path->setText(transport->path);
|
ui->path->setText(transport->path);
|
||||||
ui->host->setText(transport->host);
|
ui->host->setText(transport->host);
|
||||||
ui->method->setText(transport->method);
|
ui->method->setText(transport->method);
|
||||||
@ -357,11 +343,9 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
if (ent->outbound->HasTransport()) {
|
if (ent->outbound->HasTransport()) {
|
||||||
ui->network_l->setVisible(true);
|
ui->network_l->setVisible(true);
|
||||||
ui->network->setVisible(true);
|
ui->network->setVisible(true);
|
||||||
ui->network_box->setVisible(true);
|
|
||||||
} else {
|
} else {
|
||||||
ui->network_l->setVisible(false);
|
ui->network_l->setVisible(false);
|
||||||
ui->network->setVisible(false);
|
ui->network->setVisible(false);
|
||||||
ui->network_box->setVisible(false);
|
|
||||||
}
|
}
|
||||||
if (ent->outbound->HasTLS()) {
|
if (ent->outbound->HasTLS()) {
|
||||||
ui->security->setVisible(true);
|
ui->security->setVisible(true);
|
||||||
@ -385,7 +369,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
}
|
}
|
||||||
ui->stream_box->setVisible(streamBoxVisible);
|
ui->stream_box->setVisible(streamBoxVisible);
|
||||||
|
|
||||||
auto rightNoBox = (ui->stream_box->isHidden() && ui->network_box->isHidden() && ui->security_box->isHidden());
|
auto rightNoBox = (ui->security_box->isHidden() && ui->network_box->isHidden() && ui->tls_camouflage_box->isHidden());
|
||||||
if (rightNoBox && !ui->right_all_w->isHidden()) {
|
if (rightNoBox && !ui->right_all_w->isHidden()) {
|
||||||
ui->right_all_w->setVisible(false);
|
ui->right_all_w->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
EditTrojan::EditTrojan(QWidget *parent)
|
EditTrojan::EditTrojan(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
ui(new Ui::EditTrojan) {
|
ui(new Ui::EditTrojan) {
|
||||||
|
ui->setupUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditTrojan::~EditTrojan() {
|
EditTrojan::~EditTrojan() {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ QString get_outbound_name(int id) {
|
|||||||
if (id == -1) return "proxy";
|
if (id == -1) return "proxy";
|
||||||
if (id == -2) return "direct";
|
if (id == -2) return "direct";
|
||||||
auto profiles = Configs::profileManager->profiles;
|
auto profiles = Configs::profileManager->profiles;
|
||||||
if (profiles.count(id)) return profiles[id]->bean->name;
|
if (profiles.count(id)) return profiles[id]->outbound->name;
|
||||||
return "INVALID OUTBOUND";
|
return "INVALID OUTBOUND";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ QStringList get_all_outbounds() {
|
|||||||
QStringList res;
|
QStringList res;
|
||||||
auto profiles = Configs::profileManager->profiles;
|
auto profiles = Configs::profileManager->profiles;
|
||||||
for (const auto &item: profiles) {
|
for (const auto &item: profiles) {
|
||||||
res.append(item.second->bean->DisplayName());
|
res.append(item.second->outbound->DisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user