mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 20:44:38 +03:00
v2ray format migration
This commit is contained in:
@@ -150,7 +150,6 @@ set(PROJECT_SOURCES
|
||||
db/ConfigBuilder.cpp
|
||||
|
||||
fmt/AbstractBean.cpp
|
||||
fmt/Bean2CoreObj_ray.cpp
|
||||
fmt/Bean2CoreObj_box.cpp
|
||||
fmt/Bean2External.cpp
|
||||
fmt/Bean2Link.cpp
|
||||
|
||||
@@ -64,11 +64,7 @@ namespace NekoGui {
|
||||
if (customBean != nullptr && customBean->core == "internal-full") {
|
||||
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
||||
} else {
|
||||
if (IS_NEKO_BOX) {
|
||||
BuildConfigSingBox(status);
|
||||
} else {
|
||||
BuildConfigV2Ray(status);
|
||||
}
|
||||
BuildConfigSingBox(status);
|
||||
}
|
||||
|
||||
// apply custom config
|
||||
@@ -157,254 +153,6 @@ namespace NekoGui {
|
||||
status->ipListDirect += line; \
|
||||
}
|
||||
|
||||
// V2Ray
|
||||
|
||||
void BuildConfigV2Ray(const std::shared_ptr<BuildConfigStatus> &status) {
|
||||
// Log
|
||||
auto logObj = QJsonObject{{"loglevel", dataStore->log_level}};
|
||||
status->result->coreConfig.insert("log", logObj);
|
||||
|
||||
// Inbounds
|
||||
QJsonObject sniffing{
|
||||
{"destOverride", QJsonArray{"http", "tls", "quic"}},
|
||||
{"enabled", true},
|
||||
{"metadataOnly", false},
|
||||
{"routeOnly", dataStore->routing->sniffing_mode == SniffingMode::FOR_ROUTING},
|
||||
};
|
||||
|
||||
// socks-in
|
||||
if (IsValidPort(dataStore->inbound_socks_port) && !status->forTest) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "socks-in";
|
||||
inboundObj["protocol"] = "socks";
|
||||
inboundObj["listen"] = dataStore->inbound_address;
|
||||
inboundObj["port"] = dataStore->inbound_socks_port;
|
||||
QJsonObject socksSettings = {{"udp", true}};
|
||||
if (dataStore->routing->sniffing_mode != SniffingMode::DISABLE) {
|
||||
inboundObj["sniffing"] = sniffing;
|
||||
}
|
||||
if (dataStore->inbound_auth->NeedAuth()) {
|
||||
socksSettings["auth"] = "password";
|
||||
socksSettings["accounts"] = QJsonArray{
|
||||
QJsonObject{
|
||||
{"user", dataStore->inbound_auth->username},
|
||||
{"pass", dataStore->inbound_auth->password},
|
||||
},
|
||||
};
|
||||
}
|
||||
inboundObj["settings"] = socksSettings;
|
||||
status->inbounds += inboundObj;
|
||||
}
|
||||
// http-in
|
||||
if (IsValidPort(dataStore->inbound_http_port) && !status->forTest) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "http-in";
|
||||
inboundObj["protocol"] = "http";
|
||||
inboundObj["listen"] = dataStore->inbound_address;
|
||||
inboundObj["port"] = dataStore->inbound_http_port;
|
||||
if (dataStore->routing->sniffing_mode != SniffingMode::DISABLE) {
|
||||
inboundObj["sniffing"] = sniffing;
|
||||
}
|
||||
if (dataStore->inbound_auth->NeedAuth()) {
|
||||
inboundObj["settings"] = QJsonObject{
|
||||
{"accounts", QJsonArray{
|
||||
QJsonObject{
|
||||
{"user", dataStore->inbound_auth->username},
|
||||
{"pass", dataStore->inbound_auth->password},
|
||||
},
|
||||
}},
|
||||
};
|
||||
}
|
||||
status->inbounds += inboundObj;
|
||||
}
|
||||
|
||||
// Outbounds
|
||||
auto tagProxy = BuildChain(0, status);
|
||||
if (!status->result->error.isEmpty()) return;
|
||||
|
||||
// direct & bypass & block
|
||||
status->outbounds += QJsonObject{
|
||||
{"protocol", "freedom"},
|
||||
{"domainStrategy", dataStore->core_ray_freedom_domainStrategy},
|
||||
{"tag", "direct"},
|
||||
};
|
||||
status->outbounds += QJsonObject{
|
||||
{"protocol", "freedom"},
|
||||
{"domainStrategy", dataStore->core_ray_freedom_domainStrategy},
|
||||
{"tag", "bypass"},
|
||||
};
|
||||
status->outbounds += QJsonObject{
|
||||
{"protocol", "blackhole"},
|
||||
{"tag", "block"},
|
||||
};
|
||||
|
||||
// DNS out
|
||||
if (!status->forTest) {
|
||||
QJsonObject dnsOut;
|
||||
dnsOut["protocol"] = "dns";
|
||||
dnsOut["tag"] = "dns-out";
|
||||
QJsonObject dnsOut_settings;
|
||||
dnsOut_settings["network"] = "tcp";
|
||||
dnsOut_settings["port"] = 53;
|
||||
dnsOut_settings["address"] = "8.8.8.8";
|
||||
dnsOut_settings["userLevel"] = 1;
|
||||
dnsOut["settings"] = dnsOut_settings;
|
||||
dnsOut["proxySettings"] = QJsonObject{{"tag", tagProxy},
|
||||
{"transportLayer", true}};
|
||||
|
||||
status->outbounds += dnsOut;
|
||||
status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"port", "53"},
|
||||
{"inboundTag", QJsonArray{"socks-in", "http-in"}},
|
||||
{"outboundTag", "dns-out"},
|
||||
};
|
||||
}
|
||||
|
||||
// custom inbound
|
||||
if (!status->forTest) QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray())
|
||||
|
||||
status->result->coreConfig.insert("inbounds", status->inbounds);
|
||||
status->result->coreConfig.insert("outbounds", status->outbounds);
|
||||
|
||||
// user rule
|
||||
if (!status->forTest) {
|
||||
DOMAIN_USER_RULE
|
||||
IP_USER_RULE
|
||||
}
|
||||
|
||||
// final add DNS
|
||||
QJsonObject dns;
|
||||
QJsonArray dnsServers;
|
||||
|
||||
// Remote or FakeDNS
|
||||
QJsonObject dnsServerRemote;
|
||||
dnsServerRemote["address"] = dataStore->routing->remote_dns;
|
||||
dnsServerRemote["domains"] = QList2QJsonArray<QString>(status->domainListDNSRemote);
|
||||
dnsServerRemote["queryStrategy"] = dataStore->routing->remote_dns_strategy;
|
||||
if (!status->forTest) dnsServers += dnsServerRemote;
|
||||
|
||||
// Direct
|
||||
auto directDnsAddress = dataStore->routing->direct_dns;
|
||||
if (directDnsAddress.contains("://")) {
|
||||
auto directDnsIp = SubStrBefore(SubStrAfter(directDnsAddress, "://"), "/");
|
||||
if (IsIpAddress(directDnsIp)) {
|
||||
status->routingRules.push_front(QJsonObject{
|
||||
{"type", "field"},
|
||||
{"ip", QJsonArray{directDnsIp}},
|
||||
{"outboundTag", "direct"},
|
||||
});
|
||||
} else {
|
||||
status->routingRules.push_front(QJsonObject{
|
||||
{"type", "field"},
|
||||
{"domain", QJsonArray{directDnsIp}},
|
||||
{"outboundTag", "direct"},
|
||||
});
|
||||
}
|
||||
} else if (directDnsAddress != "localhost") {
|
||||
status->routingRules.push_front(QJsonObject{
|
||||
{"type", "field"},
|
||||
{"ip", QJsonArray{directDnsAddress}},
|
||||
{"outboundTag", "direct"},
|
||||
});
|
||||
}
|
||||
QJsonObject directObj{
|
||||
{"address", directDnsAddress.replace("https://", "https+local://")},
|
||||
{"queryStrategy", dataStore->routing->direct_dns_strategy},
|
||||
{"domains", QList2QJsonArray<QString>(status->domainListDNSDirect)},
|
||||
};
|
||||
if (dataStore->routing->dns_final_out == "bypass") {
|
||||
dnsServers.prepend(directObj);
|
||||
} else {
|
||||
dnsServers.append(directObj);
|
||||
}
|
||||
|
||||
dns["disableFallback"] = true;
|
||||
dns["servers"] = dnsServers;
|
||||
dns["tag"] = "dns";
|
||||
|
||||
if (dataStore->routing->use_dns_object) {
|
||||
dns = QString2QJsonObject(dataStore->routing->dns_object);
|
||||
}
|
||||
status->result->coreConfig.insert("dns", dns);
|
||||
|
||||
// Routing
|
||||
QJsonObject routing;
|
||||
routing["domainStrategy"] = dataStore->routing->domain_strategy;
|
||||
if (status->forTest) routing["domainStrategy"] = "AsIs";
|
||||
|
||||
// final add user rule (block)
|
||||
QJsonObject routingRule_tmp;
|
||||
routingRule_tmp["type"] = "field";
|
||||
routingRule_tmp["outboundTag"] = "block";
|
||||
if (!status->ipListBlock.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["ip"] = QList2QJsonArray<QString>(status->ipListBlock);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
if (!status->domainListBlock.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["domain"] = QList2QJsonArray<QString>(status->domainListBlock);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
|
||||
// final add user rule (proxy)
|
||||
routingRule_tmp["outboundTag"] = "proxy";
|
||||
if (!status->ipListRemote.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["ip"] = QList2QJsonArray<QString>(status->ipListRemote);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
if (!status->domainListRemote.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["domain"] = QList2QJsonArray<QString>(status->domainListRemote);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
|
||||
// final add user rule (bypass)
|
||||
routingRule_tmp["outboundTag"] = "bypass";
|
||||
if (!status->ipListDirect.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["ip"] = QList2QJsonArray<QString>(status->ipListDirect);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
if (!status->domainListDirect.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["domain"] = QList2QJsonArray<QString>(status->domainListDirect);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
|
||||
// def_outbound
|
||||
if (!status->forTest) status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"port", "0-65535"},
|
||||
{"outboundTag", dataStore->routing->def_outbound},
|
||||
};
|
||||
|
||||
// final add routing rule
|
||||
auto routingRules = QString2QJsonObject(dataStore->routing->custom)["rules"].toArray();
|
||||
if (status->forTest) routingRules = {};
|
||||
if (!status->forTest) QJSONARRAY_ADD(routingRules, QString2QJsonObject(dataStore->custom_route_global)["rules"].toArray())
|
||||
QJSONARRAY_ADD(routingRules, status->routingRules)
|
||||
routing["rules"] = routingRules;
|
||||
status->result->coreConfig.insert("routing", routing);
|
||||
|
||||
// Policy & stats
|
||||
QJsonObject policy;
|
||||
QJsonObject levels;
|
||||
QJsonObject level1;
|
||||
level1["connIdle"] = 30;
|
||||
levels["1"] = level1;
|
||||
policy["levels"] = levels;
|
||||
|
||||
QJsonObject policySystem;
|
||||
policySystem["statsOutboundDownlink"] = true;
|
||||
policySystem["statsOutboundUplink"] = true;
|
||||
policy["system"] = policySystem;
|
||||
status->result->coreConfig.insert("policy", policy);
|
||||
status->result->coreConfig.insert("stats", QJsonObject());
|
||||
}
|
||||
|
||||
QString BuildChainInternal(int chainId, const QList<std::shared_ptr<ProxyEntity>> &ents,
|
||||
const std::shared_ptr<BuildConfigStatus> &status) {
|
||||
QString chainTag = "c-" + Int2String(chainId);
|
||||
@@ -454,29 +202,14 @@ namespace NekoGui {
|
||||
// chain rules: past
|
||||
if (pastExternalStat == 0) {
|
||||
auto replaced = status->outbounds.last().toObject();
|
||||
if (IS_NEKO_BOX) {
|
||||
replaced["detour"] = tagOut;
|
||||
} else {
|
||||
replaced["proxySettings"] = QJsonObject{
|
||||
{"tag", tagOut},
|
||||
{"transportLayer", true},
|
||||
};
|
||||
}
|
||||
replaced["detour"] = tagOut;
|
||||
status->outbounds.removeLast();
|
||||
status->outbounds += replaced;
|
||||
} else {
|
||||
if (IS_NEKO_BOX) {
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{pastTag + "-mapping"}},
|
||||
{"outbound", tagOut},
|
||||
};
|
||||
} else {
|
||||
status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"inboundTag", QJsonArray{pastTag + "-mapping"}},
|
||||
{"outboundTag", tagOut},
|
||||
};
|
||||
}
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{pastTag + "-mapping"}},
|
||||
{"outbound", tagOut},
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// index == 0 means last profile in chain / not chain
|
||||
@@ -515,43 +248,20 @@ namespace NekoGui {
|
||||
if (thisExternalStat == 2) dataStore->need_keep_vpn_off = true;
|
||||
if (thisExternalStat == 1) {
|
||||
// mapping
|
||||
if (IS_NEKO_BOX) {
|
||||
status->inbounds += QJsonObject{
|
||||
{"type", "direct"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"listen_port", ext_mapping_port},
|
||||
{"override_address", ent->bean->serverAddress},
|
||||
{"override_port", ent->bean->serverPort},
|
||||
};
|
||||
} else {
|
||||
status->inbounds += QJsonObject{
|
||||
{"protocol", "dokodemo-door"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"port", ext_mapping_port},
|
||||
{"settings", QJsonObject{
|
||||
// to
|
||||
{"address", ent->bean->serverAddress},
|
||||
{"port", ent->bean->serverPort},
|
||||
{"network", "tcp,udp"},
|
||||
}},
|
||||
};
|
||||
}
|
||||
status->inbounds += QJsonObject{
|
||||
{"type", "direct"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"listen_port", ext_mapping_port},
|
||||
{"override_address", ent->bean->serverAddress},
|
||||
{"override_port", ent->bean->serverPort},
|
||||
};
|
||||
// no chain rule and not outbound, so need to set to direct
|
||||
if (isFirstProfile) {
|
||||
if (IS_NEKO_BOX) {
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
||||
{"outbound", "direct"},
|
||||
};
|
||||
} else {
|
||||
status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"inboundTag", QJsonArray{tagOut + "-mapping"}},
|
||||
{"outboundTag", "direct"},
|
||||
};
|
||||
}
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
||||
{"outbound", "direct"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,23 +284,11 @@ namespace NekoGui {
|
||||
status->result->extRs.emplace_back(std::make_shared<NekoGui_fmt::ExternalBuildResult>(extR));
|
||||
|
||||
// SOCKS OUTBOUND
|
||||
if (IS_NEKO_BOX) {
|
||||
outbound["type"] = "socks";
|
||||
outbound["server"] = "127.0.0.1";
|
||||
outbound["server_port"] = ext_socks_port;
|
||||
} else {
|
||||
outbound["protocol"] = "socks";
|
||||
QJsonObject settings;
|
||||
QJsonArray servers;
|
||||
QJsonObject server;
|
||||
server["address"] = "127.0.0.1";
|
||||
server["port"] = ext_socks_port;
|
||||
servers.push_back(server);
|
||||
settings["servers"] = servers;
|
||||
outbound["settings"] = settings;
|
||||
}
|
||||
outbound["type"] = "socks";
|
||||
outbound["server"] = "127.0.0.1";
|
||||
outbound["server_port"] = ext_socks_port;
|
||||
} else {
|
||||
const auto coreR = IS_NEKO_BOX ? ent->bean->BuildCoreObjSingBox() : ent->bean->BuildCoreObjV2Ray();
|
||||
const auto coreR = ent->bean->BuildCoreObjSingBox();
|
||||
if (coreR.outbound.isEmpty()) {
|
||||
status->result->error = "unsupported outbound";
|
||||
return {};
|
||||
@@ -613,14 +311,8 @@ namespace NekoGui {
|
||||
needMux &= dataStore->mux_concurrency > 0;
|
||||
|
||||
if (stream != nullptr) {
|
||||
if (IS_NEKO_BOX) {
|
||||
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
||||
needMux = false;
|
||||
}
|
||||
} else {
|
||||
if (stream->network == "grpc" || stream->network == "quic") {
|
||||
needMux = false;
|
||||
}
|
||||
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
||||
needMux = false;
|
||||
}
|
||||
if (stream->multiplex_status == 0) {
|
||||
if (!dataStore->mux_default_on) needMux = false;
|
||||
@@ -635,32 +327,18 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
// common
|
||||
if (IS_NEKO_BOX) {
|
||||
// apply domain_strategy
|
||||
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
||||
// apply mux
|
||||
if (!muxApplied && needMux) {
|
||||
auto muxObj = QJsonObject{
|
||||
{"enabled", true},
|
||||
{"protocol", dataStore->mux_protocol},
|
||||
{"padding", dataStore->mux_padding},
|
||||
{"max_streams", dataStore->mux_concurrency},
|
||||
};
|
||||
outbound["multiplex"] = muxObj;
|
||||
muxApplied = true;
|
||||
}
|
||||
} else {
|
||||
// apply domain_strategy
|
||||
if (!status->forTest) outbound["domainStrategy"] = dataStore->routing->outbound_domain_strategy;
|
||||
// apply mux
|
||||
if (!muxApplied && needMux) {
|
||||
auto muxObj = QJsonObject{
|
||||
{"enabled", true},
|
||||
{"concurrency", dataStore->mux_concurrency},
|
||||
};
|
||||
outbound["mux"] = muxObj;
|
||||
muxApplied = true;
|
||||
}
|
||||
// apply domain_strategy
|
||||
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
||||
// apply mux
|
||||
if (!muxApplied && needMux) {
|
||||
auto muxObj = QJsonObject{
|
||||
{"enabled", true},
|
||||
{"protocol", dataStore->mux_protocol},
|
||||
{"padding", dataStore->mux_padding},
|
||||
{"max_streams", dataStore->mux_concurrency},
|
||||
};
|
||||
outbound["multiplex"] = muxObj;
|
||||
muxApplied = true;
|
||||
}
|
||||
|
||||
// apply custom outbound settings
|
||||
@@ -720,7 +398,7 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
// tun-in
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "tun-in";
|
||||
inboundObj["type"] = "tun";
|
||||
@@ -869,7 +547,7 @@ namespace NekoGui {
|
||||
};
|
||||
|
||||
// Fakedns
|
||||
if (dataStore->fake_dns && IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->fake_dns && dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
dnsServers += QJsonObject{
|
||||
{"tag", "dns-fake"},
|
||||
{"address", "fakeip"},
|
||||
@@ -911,7 +589,7 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
// fakedns rule
|
||||
if (dataStore->fake_dns && IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->fake_dns && dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
dnsRules += QJsonObject{
|
||||
{"inbound", "tun-in"},
|
||||
{"server", "dns-fake"},
|
||||
@@ -969,7 +647,7 @@ namespace NekoGui {
|
||||
};
|
||||
|
||||
// tun user rule
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
auto match_out = dataStore->vpn_rule_white ? "proxy" : "bypass";
|
||||
|
||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
||||
|
||||
@@ -46,8 +46,6 @@ namespace NekoGui {
|
||||
|
||||
std::shared_ptr<BuildConfigResult> BuildConfig(const std::shared_ptr<ProxyEntity> &ent, bool forTest, bool forExport);
|
||||
|
||||
void BuildConfigV2Ray(const std::shared_ptr<BuildConfigStatus> &status);
|
||||
|
||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status);
|
||||
|
||||
QString BuildChain(int chainId, const std::shared_ptr<BuildConfigStatus> &status);
|
||||
|
||||
@@ -59,8 +59,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
virtual int NeedExternal(bool isFirstProfile) { return 0; };
|
||||
|
||||
virtual CoreObjOutboundBuildResult BuildCoreObjV2Ray() { return {}; };
|
||||
|
||||
virtual CoreObjOutboundBuildResult BuildCoreObjSingBox() { return {}; };
|
||||
|
||||
virtual ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) { return {}; };
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
#include "db/ProxyEntity.hpp"
|
||||
#include "fmt/includes.h"
|
||||
|
||||
#define MAKE_SETTINGS_STREAM_SETTINGS \
|
||||
outbound["settings"] = settings; \
|
||||
auto streamSettings = stream->BuildStreamSettingsV2Ray(); \
|
||||
outbound["streamSettings"] = streamSettings;
|
||||
|
||||
namespace NekoGui_fmt {
|
||||
QJsonObject V2rayStreamSettings::BuildStreamSettingsV2Ray() {
|
||||
QJsonObject streamSettings{{"network", network}};
|
||||
|
||||
if (network == "ws") {
|
||||
QJsonObject ws;
|
||||
if (!host.isEmpty()) ws["headers"] = QJsonObject{{"Host", host}};
|
||||
// ws path & ed
|
||||
if (!path.isEmpty()) ws["path"] = path;
|
||||
streamSettings["wsSettings"] = ws;
|
||||
} else if (network == "http") {
|
||||
QJsonObject http;
|
||||
if (!path.isEmpty()) http["path"] = path;
|
||||
if (!host.isEmpty()) http["host"] = QList2QJsonArray(host.split(","));
|
||||
streamSettings["httpSettings"] = http;
|
||||
} else if (network == "grpc") {
|
||||
QJsonObject grpc;
|
||||
if (!path.isEmpty()) grpc["serviceName"] = path;
|
||||
streamSettings["grpcSettings"] = grpc;
|
||||
} else if (network == "quic") {
|
||||
QJsonObject quic;
|
||||
if (!header_type.isEmpty()) quic["header"] = QJsonObject{{"type", header_type}};
|
||||
if (!path.isEmpty()) quic["key"] = path;
|
||||
if (!host.isEmpty()) quic["security"] = host;
|
||||
streamSettings["quicSettings"] = quic;
|
||||
} else if (network == "tcp" && !header_type.isEmpty()) {
|
||||
QJsonObject header{{"type", header_type}};
|
||||
if (header_type == "http") {
|
||||
header["request"] = QJsonObject{
|
||||
{"path", QList2QJsonArray(path.split(","))},
|
||||
{"headers", QJsonObject{{"Host", QList2QJsonArray(host.split(","))}}},
|
||||
};
|
||||
}
|
||||
streamSettings["tcpSettings"] = QJsonObject{{"header", header}};
|
||||
}
|
||||
|
||||
if (security == "tls") {
|
||||
QJsonObject tls;
|
||||
if (!utlsFingerprint.isEmpty()) tls["fingerprint"] = utlsFingerprint;
|
||||
if (!sni.trimmed().isEmpty()) tls["serverName"] = sni;
|
||||
if (reality_pbk.trimmed().isEmpty()) {
|
||||
if (allow_insecure || NekoGui::dataStore->skip_cert) tls["allowInsecure"] = true;
|
||||
if (!alpn.trimmed().isEmpty()) tls["alpn"] = QList2QJsonArray(alpn.split(","));
|
||||
if (!certificate.trimmed().isEmpty()) {
|
||||
tls["disableSystemRoot"] = true;
|
||||
tls["certificates"] = QJsonArray{
|
||||
QJsonObject{
|
||||
{"usage", "verify"},
|
||||
{"certificate", QList2QJsonArray(SplitLines(certificate.trimmed()))},
|
||||
},
|
||||
};
|
||||
}
|
||||
streamSettings["tlsSettings"] = tls;
|
||||
streamSettings["security"] = "tls";
|
||||
} else {
|
||||
tls["publicKey"] = reality_pbk;
|
||||
tls["shortId"] = reality_sid;
|
||||
tls["spiderX"] = reality_spx;
|
||||
if (utlsFingerprint.isEmpty()) tls["fingerprint"] = "chrome";
|
||||
streamSettings["realitySettings"] = tls;
|
||||
streamSettings["security"] = "reality";
|
||||
}
|
||||
}
|
||||
|
||||
return streamSettings;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult SocksHttpBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
|
||||
QJsonObject outbound;
|
||||
outbound["protocol"] = socks_http_type == type_HTTP ? "http" : "socks";
|
||||
|
||||
QJsonObject settings;
|
||||
QJsonArray servers;
|
||||
QJsonObject server;
|
||||
|
||||
server["address"] = serverAddress;
|
||||
server["port"] = serverPort;
|
||||
|
||||
QJsonArray users;
|
||||
QJsonObject user;
|
||||
user["user"] = username;
|
||||
user["pass"] = password;
|
||||
users.push_back(user);
|
||||
if (!username.isEmpty() && !password.isEmpty()) server["users"] = users;
|
||||
|
||||
servers.push_back(server);
|
||||
settings["servers"] = servers;
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult ShadowSocksBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
|
||||
QJsonObject outbound{{"protocol", "shadowsocks"}};
|
||||
|
||||
QJsonObject settings;
|
||||
QJsonArray servers;
|
||||
QJsonObject server;
|
||||
|
||||
server["address"] = serverAddress;
|
||||
server["port"] = serverPort;
|
||||
server["method"] = method;
|
||||
server["password"] = password;
|
||||
|
||||
if (uot != 0) {
|
||||
server["uot"] = true;
|
||||
server["UoTVersion"] = uot;
|
||||
} else {
|
||||
server["uot"] = false;
|
||||
}
|
||||
|
||||
servers.push_back(server);
|
||||
settings["servers"] = servers;
|
||||
|
||||
if (!plugin.trimmed().isEmpty()) {
|
||||
settings["plugin"] = SubStrBefore(plugin, ";");
|
||||
settings["pluginOpts"] = SubStrAfter(plugin, ";");
|
||||
}
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult VMessBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
QJsonObject outbound{{"protocol", "vmess"}};
|
||||
|
||||
QJsonObject settings{
|
||||
{"vnext", QJsonArray{
|
||||
QJsonObject{
|
||||
{"address", serverAddress},
|
||||
{"port", serverPort},
|
||||
{"users", QJsonArray{
|
||||
QJsonObject{
|
||||
{"id", uuid.trimmed()},
|
||||
{"alterId", aid},
|
||||
{"security", security},
|
||||
}}},
|
||||
}}}};
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult TrojanVLESSBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
QJsonObject outbound{
|
||||
{"protocol", proxy_type == proxy_VLESS ? "vless" : "trojan"},
|
||||
};
|
||||
|
||||
QJsonObject settings;
|
||||
if (proxy_type == proxy_VLESS) {
|
||||
if (flow == "none") {
|
||||
flow = "";
|
||||
}
|
||||
settings = QJsonObject{
|
||||
{"vnext", QJsonArray{
|
||||
QJsonObject{
|
||||
{"address", serverAddress},
|
||||
{"port", serverPort},
|
||||
{"users", QJsonArray{
|
||||
QJsonObject{
|
||||
{"id", password.trimmed()},
|
||||
{"encryption", "none"},
|
||||
{"flow", flow},
|
||||
}}},
|
||||
}}}};
|
||||
} else {
|
||||
settings = QJsonObject{
|
||||
{"servers", QJsonArray{
|
||||
QJsonObject{
|
||||
{"address", serverAddress},
|
||||
{"port", serverPort},
|
||||
{"password", password},
|
||||
}}}};
|
||||
}
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult CustomBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
|
||||
if (core == "internal") {
|
||||
result.outbound = QString2QJsonObject(config_simple);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace NekoGui_fmt
|
||||
@@ -70,19 +70,11 @@ namespace NekoGui_fmt {
|
||||
return 1;
|
||||
};
|
||||
|
||||
if (IS_NEKO_BOX) {
|
||||
if (!forceExternal && (proxy_type == proxy_TUIC || hyProtocol == hysteria_protocol_udp)) {
|
||||
// sing-box support
|
||||
return 0;
|
||||
} else {
|
||||
// hysteria core support
|
||||
return hysteriaCore();
|
||||
}
|
||||
} else if (proxy_type == proxy_TUIC) {
|
||||
return tuicCore();
|
||||
} else if (proxy_type == proxy_Hysteria2) {
|
||||
return hysteria2Core();
|
||||
if (!forceExternal && (proxy_type == proxy_TUIC || hyProtocol == hysteria_protocol_udp)) {
|
||||
// sing-box support
|
||||
return 0;
|
||||
} else {
|
||||
// hysteria core support
|
||||
return hysteriaCore();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace NekoGui_fmt {
|
||||
QString DisplayType() override {
|
||||
if (core == "internal") {
|
||||
auto obj = QString2QJsonObject(config_simple);
|
||||
return obj[IS_NEKO_BOX ? "type" : "protocol"].toString();
|
||||
return obj["type"].toString();
|
||||
} else if (core == "internal-full") {
|
||||
return software_core_name + " config";
|
||||
}
|
||||
@@ -36,11 +36,7 @@ namespace NekoGui_fmt {
|
||||
QString DisplayAddress() override {
|
||||
if (core == "internal") {
|
||||
auto obj = QString2QJsonObject(config_simple);
|
||||
if (IS_NEKO_BOX) {
|
||||
return ::DisplayAddress(obj["server"].toString(), obj["server_port"].toInt());
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
return ::DisplayAddress(obj["server"].toString(), obj["server_port"].toInt());
|
||||
} else if (core == "internal-full") {
|
||||
return {};
|
||||
}
|
||||
@@ -52,7 +48,5 @@ namespace NekoGui_fmt {
|
||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
};
|
||||
} // namespace NekoGui_fmt
|
||||
@@ -1,15 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace Preset {
|
||||
namespace Xray {
|
||||
inline QStringList UtlsFingerPrint = {"", "chrome", "firefox", "edge", "safari", "360", "qq", "ios", "android", "random", "randomized"};
|
||||
inline QStringList ShadowsocksMethods = {"aes-128-gcm", "aes-256-gcm", "aes-192-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305",
|
||||
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
||||
"rc4", "rc4-md5", "bf-cfb", "chacha20", "chacha20-ietf", "xchacha20", "none"};
|
||||
inline QStringList Flows = {"xtls-rprx-vision", "xtls-rprx-vision-udp443"};
|
||||
} // namespace Xray
|
||||
|
||||
namespace SingBox {
|
||||
inline QStringList VpnImplementation = {"gvisor", "system", "mixed"};
|
||||
inline QStringList DomainStrategy = {"", "ipv4_only", "ipv6_only", "prefer_ipv4", "prefer_ipv6"};
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return "Shadowsocks"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@@ -24,8 +24,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@@ -49,8 +49,6 @@ namespace NekoGui_fmt {
|
||||
_add(new configItem("mux_s", &multiplex_status, itemType::integer));
|
||||
}
|
||||
|
||||
QJsonObject BuildStreamSettingsV2Ray();
|
||||
|
||||
void BuildStreamSettingsSingBox(QJsonObject *outbound);
|
||||
};
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return "VMess"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace NekoGui_network {
|
||||
if (NekoGui::dataStore->sub_use_proxy) {
|
||||
QNetworkProxy p;
|
||||
// Note: sing-box mixed socks5 protocol error
|
||||
p.setType(IS_NEKO_BOX ? QNetworkProxy::HttpProxy : QNetworkProxy::Socks5Proxy);
|
||||
p.setType(QNetworkProxy::HttpProxy);
|
||||
p.setHostName("127.0.0.1");
|
||||
p.setPort(NekoGui::dataStore->inbound_socks_port);
|
||||
if (NekoGui::dataStore->inbound_auth->NeedAuth()) {
|
||||
|
||||
@@ -237,7 +237,6 @@ namespace NekoGui {
|
||||
_add(new configItem("current_group", ¤t_group, itemType::integer));
|
||||
_add(new configItem("inbound_address", &inbound_address, itemType::string));
|
||||
_add(new configItem("inbound_socks_port", &inbound_socks_port, itemType::integer));
|
||||
_add(new configItem("inbound_http_port", &inbound_http_port, itemType::integer));
|
||||
_add(new configItem("log_level", &log_level, itemType::string));
|
||||
_add(new configItem("mux_protocol", &mux_protocol, itemType::string));
|
||||
_add(new configItem("mux_concurrency", &mux_concurrency, itemType::integer));
|
||||
@@ -284,12 +283,7 @@ namespace NekoGui {
|
||||
_add(new configItem("core_box_clash_api", &core_box_clash_api, itemType::integer));
|
||||
_add(new configItem("core_box_clash_api_secret", &core_box_clash_api_secret, itemType::string));
|
||||
_add(new configItem("core_box_underlying_dns", &core_box_underlying_dns, itemType::string));
|
||||
_add(new configItem("core_ray_direct_dns", &core_ray_direct_dns, itemType::boolean));
|
||||
_add(new configItem("core_ray_freedom_domainStrategy", &core_ray_freedom_domainStrategy, itemType::string));
|
||||
_add(new configItem("vpn_internal_tun", &vpn_internal_tun, itemType::boolean));
|
||||
#ifdef Q_OS_WIN
|
||||
_add(new configItem("core_ray_windows_disable_auto_interface", &core_ray_windows_disable_auto_interface, itemType::boolean));
|
||||
#endif
|
||||
}
|
||||
|
||||
void DataStore::UpdateStartedId(int id) {
|
||||
@@ -310,11 +304,7 @@ namespace NekoGui {
|
||||
if (isDefault) {
|
||||
QString version = SubStrBefore(NKR_VERSION, "-");
|
||||
if (!version.contains(".")) version = "2.0";
|
||||
if (IS_NEKO_BOX) {
|
||||
return "NekoBox/PC/" + version + " (Prefer ClashMeta Format)";
|
||||
} else {
|
||||
return "NekoRay/PC/" + version + " (Prefer ClashMeta Format)";
|
||||
}
|
||||
return "NekoBox/PC/" + version + " (Prefer ClashMeta Format)";
|
||||
}
|
||||
return user_agent;
|
||||
}
|
||||
@@ -335,10 +325,8 @@ namespace NekoGui {
|
||||
"domain:firebase.io\n"
|
||||
"domain:crashlytics.com\n";
|
||||
}
|
||||
if (IS_NEKO_BOX) {
|
||||
if (!Preset::SingBox::DomainStrategy.contains(domain_strategy)) domain_strategy = "";
|
||||
if (!Preset::SingBox::DomainStrategy.contains(outbound_domain_strategy)) outbound_domain_strategy = "";
|
||||
}
|
||||
if (!Preset::SingBox::DomainStrategy.contains(domain_strategy)) domain_strategy = "";
|
||||
if (!Preset::SingBox::DomainStrategy.contains(outbound_domain_strategy)) outbound_domain_strategy = "";
|
||||
_add(new configItem("direct_ip", &this->direct_ip, itemType::string));
|
||||
_add(new configItem("direct_domain", &this->direct_domain, itemType::string));
|
||||
_add(new configItem("proxy_ip", &this->proxy_ip, itemType::string));
|
||||
|
||||
@@ -17,7 +17,5 @@ namespace NekoGui {
|
||||
bool IsAdmin();
|
||||
} // namespace NekoGui
|
||||
|
||||
#define IS_NEKO_BOX (NekoGui::coreType == NekoGui::CoreType::SING_BOX)
|
||||
#define IS_NEKO_BOX_INTERNAL_TUN (IS_NEKO_BOX && NekoGui::dataStore->vpn_internal_tun)
|
||||
#define ROUTES_PREFIX_NAME QString(IS_NEKO_BOX ? "routes_box" : "routes")
|
||||
#define ROUTES_PREFIX_NAME QString("routes_box")
|
||||
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace NekoGui {
|
||||
// Saved
|
||||
|
||||
// Misc
|
||||
QString log_level = "warning";
|
||||
QString log_level = "info";
|
||||
QString test_latency_url = "http://cp.cloudflare.com/";
|
||||
QString test_download_url = "http://cachefly.cachefly.net/10mb.test";
|
||||
int test_download_timeout = 30;
|
||||
@@ -102,7 +102,7 @@ namespace NekoGui {
|
||||
int traffic_loop_interval = 1000;
|
||||
bool connection_statistics = false;
|
||||
int current_group = 0; // group id
|
||||
QString mux_protocol = "";
|
||||
QString mux_protocol = "h2mux";
|
||||
bool mux_padding = false;
|
||||
int mux_concurrency = 8;
|
||||
bool mux_default_on = false;
|
||||
@@ -136,7 +136,6 @@ namespace NekoGui {
|
||||
// Socks & HTTP Inbound
|
||||
QString inbound_address = "127.0.0.1";
|
||||
int inbound_socks_port = 2080; // or Mixed
|
||||
int inbound_http_port = 2081;
|
||||
InboundAuthorization *inbound_auth = new InboundAuthorization;
|
||||
QString custom_inbound = "{\"inbounds\": []}";
|
||||
|
||||
@@ -166,9 +165,6 @@ namespace NekoGui {
|
||||
int core_box_clash_api = -9090;
|
||||
QString core_box_clash_api_secret = "";
|
||||
QString core_box_underlying_dns = "";
|
||||
bool core_ray_direct_dns = false;
|
||||
bool core_ray_windows_disable_auto_interface = false;
|
||||
QString core_ray_freedom_domainStrategy = "";
|
||||
|
||||
// Other Core
|
||||
ExtraCore *extraCore = new ExtraCore;
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
//
|
||||
|
||||
inline QString software_name = "NekoRay";
|
||||
inline QString software_core_name = "Xray";
|
||||
inline QString software_name = "NekoBox";
|
||||
inline QString software_core_name = "sing-box";
|
||||
|
||||
// Main Functions
|
||||
|
||||
|
||||
@@ -147,8 +147,6 @@ namespace NekoGui_sys {
|
||||
v2ray_asset_dir = QFileInfo(v2ray_asset_dir).absolutePath();
|
||||
env << "XRAY_LOCATION_ASSET=" + v2ray_asset_dir;
|
||||
}
|
||||
if (NekoGui::dataStore->core_ray_direct_dns) env << "NKR_CORE_RAY_DIRECT_DNS=1";
|
||||
if (NekoGui::dataStore->core_ray_windows_disable_auto_interface) env << "NKR_CORE_RAY_WINDOWS_DISABLE_AUTO_INTERFACE=1";
|
||||
//
|
||||
ExternalProcess::Start();
|
||||
write((NekoGui::dataStore->core_token + "\n").toUtf8());
|
||||
|
||||
@@ -11,18 +11,10 @@
|
||||
<source>Enable</source>
|
||||
<translation>فعال کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP Listen Port</source>
|
||||
<translation>پورت HTTP درحال شنود</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen Address</source>
|
||||
<translation>آدرس درحال شنود</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Socks Listen Port</source>
|
||||
<translation>پورت ساکس درحال شنود</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>concurrency</source>
|
||||
<translation>همزمانی</translation>
|
||||
@@ -197,16 +189,6 @@
|
||||
<source>Override underlying DNS</source>
|
||||
<translation type="unfinished">لغو دی ان اس زیربنایی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>It is recommended to leave it blank, but it sometimes does not work, at this time you can set this option.
|
||||
For NekoRay, this rewrites the underlying(localhost) DNS in Tun Mode.
|
||||
For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mode, and also URL Test.</source>
|
||||
<translation type="unfinished">پیشنهاد میشود که این گزینه را انتخاب نشده باقی بگذارید ، اما گاهی اوقات کار نمیکند در این مواقع شما میتوانید این گزینه را انتخاب کنید ، برای Nekoray این گزینه دی ان اس زیربنایی را در حالت تونل بازنویسی میکند ، و برای NekoBox این گزینه دی ان اس زیربنایی را هم در حالت تونل و هم در حالت معمولی و تست آدرس بازنویسی میکند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If you Tun Mode is not working, try to change this option.</source>
|
||||
<translation type="unfinished">اگر حالت تونل برای شما کار نمیکند ، این گزینه را تغییر دهید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Default On</source>
|
||||
<translation type="unfinished">به صورت پیشفرض فعال</translation>
|
||||
@@ -243,6 +225,10 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Old Share Link Format</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mixed (SOCKS+HTTP) Listen Port</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditGroup</name>
|
||||
@@ -1368,14 +1354,6 @@ This needs to be run NekoBox with administrator privileges.</source>
|
||||
<source>Imported %1 profile(s)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Http inbound is not enabled, can't set system proxy.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings</source>
|
||||
<translation>تنظیمات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Current server is incompatible with Tun. Please stop the server first, enable Tun Mode, and then restart.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@@ -1384,11 +1362,6 @@ This needs to be run NekoBox with administrator privileges.</source>
|
||||
<source>Not Running</source>
|
||||
<translation>در حال اجرا نیست</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>None</source>
|
||||
<translatorcomment>هیچ یک</translatorcomment>
|
||||
<translation>هیچ یک</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select</source>
|
||||
<translation>انتخاب</translation>
|
||||
|
||||
@@ -23,14 +23,6 @@
|
||||
<source>Edit</source>
|
||||
<translation>Изменить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Socks Listen Port</source>
|
||||
<translation>Адрес входящих SOCKS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP Listen Port</source>
|
||||
<translation>Адрес входящих HTTP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable</source>
|
||||
<translation>Вкл</translation>
|
||||
@@ -211,18 +203,6 @@
|
||||
<source>Override underlying DNS</source>
|
||||
<translation>Переопределить нижестоящий DNS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>It is recommended to leave it blank, but it sometimes does not work, at this time you can set this option.
|
||||
For NekoRay, this rewrites the underlying(localhost) DNS in Tun Mode.
|
||||
For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mode, and also URL Test.</source>
|
||||
<translation>Рекомендуется оставить параметр пустым, но иногда это не срабатывает как надо, и в таком случае можно использовать эту опцию.
|
||||
Для NekoRay это переопределяет нижестоящий (localhost) DNS в Tun режиме.
|
||||
Для NekoBox это переопределяет нижестоящий (localhost) DNS в Tun режиме, нормальном режиме, а также при URL тесте.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If you Tun Mode is not working, try to change this option.</source>
|
||||
<translation>Если TUN-режим не работает, попробуйте изменить эту опцию.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Timeout (s)</source>
|
||||
<translation>Таймаут (с)</translation>
|
||||
@@ -243,6 +223,10 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Old Share Link Format</source>
|
||||
<translation>Поделиться ссылкой в старом формате</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mixed (SOCKS+HTTP) Listen Port</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditGroup</name>
|
||||
@@ -1394,14 +1378,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
|
||||
<source>Imported %1 profile(s)</source>
|
||||
<translation>Импортирован(ы) %1 профиль(ей)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Http inbound is not enabled, can't set system proxy.</source>
|
||||
<translation>HTTP inbound не включен в настройках, невозможно установить системный прокси.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings</source>
|
||||
<translation>Настройки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please run NekoBox as admin</source>
|
||||
<translation>Пожалуйста, запустите NekoBox с правами администратора</translation>
|
||||
@@ -1414,10 +1390,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
|
||||
<source>Not Running</source>
|
||||
<translation>Не запущен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>None</source>
|
||||
<translation>Нет</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select</source>
|
||||
<translation>Выбор</translation>
|
||||
|
||||
@@ -11,18 +11,10 @@
|
||||
<source>Enable</source>
|
||||
<translation>启用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HTTP Listen Port</source>
|
||||
<translation>HTTP 监听端口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen Address</source>
|
||||
<translation>监听地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Socks Listen Port</source>
|
||||
<translation>Socks 监听端口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>concurrency</source>
|
||||
<translation>并发</translation>
|
||||
@@ -203,18 +195,6 @@
|
||||
<source>Override underlying DNS</source>
|
||||
<translation>覆盖底层 DNS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>It is recommended to leave it blank, but it sometimes does not work, at this time you can set this option.
|
||||
For NekoRay, this rewrites the underlying(localhost) DNS in Tun Mode.
|
||||
For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mode, and also URL Test.</source>
|
||||
<translation>建议留空,但有时会出现问题,这时可以设置这个选项。
|
||||
对于 NekoRay 来说,在 Tun 模式下会重写 underlying(localhost) DNS。
|
||||
对于 NekoBox 来说,在 Tun 模式、正常模式和 URL 测试中会重写 underlying(localhost) DNS。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If you Tun Mode is not working, try to change this option.</source>
|
||||
<translation>如果您的 Tun 模式有问题,请尝试更改此选项。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Default On</source>
|
||||
<translation>默认开启</translation>
|
||||
@@ -243,6 +223,10 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Interval (minute, invalid if less than 30)</source>
|
||||
<translation>时间间隔(分钟,少于 30 分钟无效)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mixed (SOCKS+HTTP) Listen Port</source>
|
||||
<translation>Mixed (SOCKS+HTTP) 监听端口</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditGroup</name>
|
||||
@@ -1210,10 +1194,6 @@ This needs to be run NekoBox with administrator privileges.</source>
|
||||
<source>Imported %1 profile(s)</source>
|
||||
<translation>导入了 %1 个配置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>None</source>
|
||||
<translation>无</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unavailable</source>
|
||||
<translation>不可用</translation>
|
||||
|
||||
@@ -59,16 +59,8 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
|
||||
// Common
|
||||
|
||||
if (IS_NEKO_BOX) {
|
||||
ui->groupBox_http->hide();
|
||||
ui->inbound_socks_port_l->setText(ui->inbound_socks_port_l->text().replace("Socks", "Mixed (SOCKS+HTTP)"));
|
||||
ui->log_level->addItems(QString("trace debug info warn error fatal panic").split(" "));
|
||||
ui->mux_protocol->addItems({"h2mux", "smux", "yamux"});
|
||||
} else {
|
||||
ui->log_level->addItems({"debug", "info", "warning", "none"});
|
||||
ui->mux_protocol->hide();
|
||||
ui->mux_padding->hide();
|
||||
}
|
||||
ui->log_level->addItems(QString("trace debug info warn error fatal panic").split(" "));
|
||||
ui->mux_protocol->addItems({"h2mux", "smux", "yamux"});
|
||||
|
||||
refresh_auth();
|
||||
|
||||
@@ -76,7 +68,6 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
D_LOAD_COMBO_STRING(log_level)
|
||||
CACHE.custom_inbound = NekoGui::dataStore->custom_inbound;
|
||||
D_LOAD_INT(inbound_socks_port)
|
||||
D_LOAD_INT_ENABLE(inbound_http_port, http_enable)
|
||||
D_LOAD_INT(test_concurrent)
|
||||
D_LOAD_INT(test_download_timeout)
|
||||
D_LOAD_STRING(test_latency_url)
|
||||
@@ -102,9 +93,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
#endif
|
||||
|
||||
// Style
|
||||
if (IS_NEKO_BOX) {
|
||||
ui->connection_statistics_box->setDisabled(true);
|
||||
}
|
||||
ui->connection_statistics_box->setDisabled(true);
|
||||
//
|
||||
D_LOAD_BOOL(check_include_pre)
|
||||
D_LOAD_BOOL(connection_statistics)
|
||||
@@ -225,7 +214,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
|
||||
// Security
|
||||
|
||||
ui->utlsFingerprint->addItems(IS_NEKO_BOX ? Preset::SingBox::UtlsFingerPrint : Preset::Xray::UtlsFingerPrint);
|
||||
ui->utlsFingerprint->addItems(Preset::SingBox::UtlsFingerPrint);
|
||||
|
||||
D_LOAD_BOOL(skip_cert)
|
||||
ui->utlsFingerprint->setCurrentText(NekoGui::dataStore->utlsFingerprint);
|
||||
@@ -242,7 +231,6 @@ void DialogBasicSettings::accept() {
|
||||
D_SAVE_COMBO_STRING(log_level)
|
||||
NekoGui::dataStore->custom_inbound = CACHE.custom_inbound;
|
||||
D_SAVE_INT(inbound_socks_port)
|
||||
D_SAVE_INT_ENABLE(inbound_http_port, http_enable)
|
||||
D_SAVE_INT(test_concurrent)
|
||||
D_SAVE_INT(test_download_timeout)
|
||||
D_SAVE_STRING(test_latency_url)
|
||||
@@ -395,80 +383,39 @@ void DialogBasicSettings::on_core_settings_clicked() {
|
||||
MyLineEdit *core_box_clash_api;
|
||||
MyLineEdit *core_box_clash_api_secret;
|
||||
MyLineEdit *core_box_underlying_dns;
|
||||
QCheckBox *core_ray_direct_dns;
|
||||
QCheckBox *core_ray_windows_disable_auto_interface;
|
||||
QComboBox *core_ray_freedom_domainStrategy;
|
||||
//
|
||||
auto core_box_underlying_dns_l = new QLabel(tr("Override underlying DNS"));
|
||||
core_box_underlying_dns_l->setToolTip(tr(
|
||||
"It is recommended to leave it blank, but it sometimes does not work, at this time you can set this option.\n"
|
||||
"For NekoRay, this rewrites the underlying(localhost) DNS in Tun Mode.\n"
|
||||
"For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mode, and also URL Test."));
|
||||
core_box_underlying_dns = new MyLineEdit;
|
||||
core_box_underlying_dns->setText(NekoGui::dataStore->core_box_underlying_dns);
|
||||
core_box_underlying_dns->setMinimumWidth(300);
|
||||
layout->addWidget(core_box_underlying_dns_l, ++line, 0);
|
||||
layout->addWidget(core_box_underlying_dns, line, 1);
|
||||
//
|
||||
if (IS_NEKO_BOX) {
|
||||
auto core_box_enable_clash_api_l = new QLabel("Enable Clash API");
|
||||
core_box_enable_clash_api = new QCheckBox;
|
||||
core_box_enable_clash_api->setChecked(NekoGui::dataStore->core_box_clash_api > 0);
|
||||
layout->addWidget(core_box_enable_clash_api_l, ++line, 0);
|
||||
layout->addWidget(core_box_enable_clash_api, line, 1);
|
||||
//
|
||||
auto core_box_clash_api_l = new QLabel("Clash API Listen Port");
|
||||
core_box_clash_api = new MyLineEdit;
|
||||
core_box_clash_api->setText(Int2String(std::abs(NekoGui::dataStore->core_box_clash_api)));
|
||||
layout->addWidget(core_box_clash_api_l, ++line, 0);
|
||||
layout->addWidget(core_box_clash_api, line, 1);
|
||||
//
|
||||
auto core_box_clash_api_secret_l = new QLabel("Clash API Secret");
|
||||
core_box_clash_api_secret = new MyLineEdit;
|
||||
core_box_clash_api_secret->setText(NekoGui::dataStore->core_box_clash_api_secret);
|
||||
layout->addWidget(core_box_clash_api_secret_l, ++line, 0);
|
||||
layout->addWidget(core_box_clash_api_secret, line, 1);
|
||||
} else {
|
||||
auto core_ray_direct_dns_l = new QLabel("NKR_CORE_RAY_DIRECT_DNS");
|
||||
core_ray_direct_dns_l->setToolTip(tr("If you Tun Mode is not working, try to change this option."));
|
||||
core_ray_direct_dns = new QCheckBox;
|
||||
core_ray_direct_dns->setChecked(NekoGui::dataStore->core_ray_direct_dns);
|
||||
connect(core_ray_direct_dns, &QCheckBox::clicked, this, [&] { CACHE.needRestart = true; });
|
||||
layout->addWidget(core_ray_direct_dns_l, ++line, 0);
|
||||
layout->addWidget(core_ray_direct_dns, line, 1);
|
||||
//
|
||||
auto core_ray_freedom_domainStrategy_l = new QLabel("Freedom Strategy");
|
||||
core_ray_freedom_domainStrategy = new QComboBox;
|
||||
core_ray_freedom_domainStrategy->addItems({"", "AsIs", "UseIP", "UseIPv4", "UseIPv6"});
|
||||
core_ray_freedom_domainStrategy->setCurrentText(NekoGui::dataStore->core_ray_freedom_domainStrategy);
|
||||
layout->addWidget(core_ray_freedom_domainStrategy_l, ++line, 0);
|
||||
layout->addWidget(core_ray_freedom_domainStrategy, line, 1);
|
||||
#ifdef Q_OS_WIN
|
||||
auto core_ray_windows_disable_auto_interface_l = new QLabel("NKR_CORE_RAY_WINDOWS_DISABLE_AUTO_INTERFACE");
|
||||
core_ray_windows_disable_auto_interface_l->setToolTip(tr("If you Tun Mode is not working, try to change this option."));
|
||||
core_ray_windows_disable_auto_interface = new QCheckBox;
|
||||
core_ray_windows_disable_auto_interface->setChecked(NekoGui::dataStore->core_ray_windows_disable_auto_interface);
|
||||
connect(core_ray_windows_disable_auto_interface, &QCheckBox::clicked, this, [&] { CACHE.needRestart = true; });
|
||||
layout->addWidget(core_ray_windows_disable_auto_interface_l, ++line, 0);
|
||||
layout->addWidget(core_ray_windows_disable_auto_interface, line, 1);
|
||||
#endif
|
||||
}
|
||||
auto core_box_enable_clash_api_l = new QLabel("Enable Clash API");
|
||||
core_box_enable_clash_api = new QCheckBox;
|
||||
core_box_enable_clash_api->setChecked(NekoGui::dataStore->core_box_clash_api > 0);
|
||||
layout->addWidget(core_box_enable_clash_api_l, ++line, 0);
|
||||
layout->addWidget(core_box_enable_clash_api, line, 1);
|
||||
//
|
||||
auto core_box_clash_api_l = new QLabel("Clash API Listen Port");
|
||||
core_box_clash_api = new MyLineEdit;
|
||||
core_box_clash_api->setText(Int2String(std::abs(NekoGui::dataStore->core_box_clash_api)));
|
||||
layout->addWidget(core_box_clash_api_l, ++line, 0);
|
||||
layout->addWidget(core_box_clash_api, line, 1);
|
||||
//
|
||||
auto core_box_clash_api_secret_l = new QLabel("Clash API Secret");
|
||||
core_box_clash_api_secret = new MyLineEdit;
|
||||
core_box_clash_api_secret->setText(NekoGui::dataStore->core_box_clash_api_secret);
|
||||
layout->addWidget(core_box_clash_api_secret_l, ++line, 0);
|
||||
layout->addWidget(core_box_clash_api_secret, line, 1);
|
||||
//
|
||||
auto box = new QDialogButtonBox;
|
||||
box->setOrientation(Qt::Horizontal);
|
||||
box->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
|
||||
connect(box, &QDialogButtonBox::accepted, w, [=] {
|
||||
NekoGui::dataStore->core_box_underlying_dns = core_box_underlying_dns->text();
|
||||
if (IS_NEKO_BOX) {
|
||||
NekoGui::dataStore->core_box_clash_api = core_box_clash_api->text().toInt() * (core_box_enable_clash_api->isChecked() ? 1 : -1);
|
||||
NekoGui::dataStore->core_box_clash_api_secret = core_box_clash_api_secret->text();
|
||||
} else {
|
||||
NekoGui::dataStore->core_ray_direct_dns = core_ray_direct_dns->isChecked();
|
||||
NekoGui::dataStore->core_ray_freedom_domainStrategy = core_ray_freedom_domainStrategy->currentText();
|
||||
#ifdef Q_OS_WIN
|
||||
NekoGui::dataStore->core_ray_windows_disable_auto_interface = core_ray_windows_disable_auto_interface->isChecked();
|
||||
#endif
|
||||
}
|
||||
NekoGui::dataStore->core_box_clash_api = core_box_clash_api->text().toInt() * (core_box_enable_clash_api->isChecked() ? 1 : -1);
|
||||
NekoGui::dataStore->core_box_clash_api_secret = core_box_clash_api_secret->text();
|
||||
MW_dialog_message(Dialog_DialogBasicSettings, "UpdateDataStore");
|
||||
w->accept();
|
||||
});
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="inbound_socks_port_l">
|
||||
<property name="text">
|
||||
<string>Socks Listen Port</string>
|
||||
<string>Mixed (SOCKS+HTTP) Listen Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -112,36 +112,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_http">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>HTTP Listen Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="inbound_http_port">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="http_enable">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -709,8 +679,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>198</width>
|
||||
<height>58</height>
|
||||
<width>632</width>
|
||||
<height>299</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
|
||||
@@ -22,19 +22,13 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(ne
|
||||
|
||||
QStringList qsValue = {""};
|
||||
QString dnsHelpDocumentUrl;
|
||||
if (IS_NEKO_BOX) {
|
||||
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
||||
ui->domainStrategyCombo->addItems(Preset::SingBox::DomainStrategy);
|
||||
qsValue += QString("prefer_ipv4 prefer_ipv6 ipv4_only ipv6_only").split(" ");
|
||||
ui->dns_object->setPlaceholderText(DecodeB64IfValid("ewogICJzZXJ2ZXJzIjogW10sCiAgInJ1bGVzIjogW10sCiAgImZpbmFsIjogIiIsCiAgInN0cmF0ZWd5IjogIiIsCiAgImRpc2FibGVfY2FjaGUiOiBmYWxzZSwKICAiZGlzYWJsZV9leHBpcmUiOiBmYWxzZSwKICAiaW5kZXBlbmRlbnRfY2FjaGUiOiBmYWxzZSwKICAicmV2ZXJzZV9tYXBwaW5nIjogZmFsc2UsCiAgImZha2VpcCI6IHt9Cn0="));
|
||||
dnsHelpDocumentUrl = "https://sing-box.sagernet.org/configuration/dns/";
|
||||
} else {
|
||||
ui->outbound_domain_strategy->addItems({"AsIs", "UseIPv4", "UseIPv6", "PreferIPv4", "PreferIPv6"});
|
||||
ui->domainStrategyCombo->addItems({"AsIs", "IPIfNonMatch", "IPOnDemand"});
|
||||
qsValue += QString("use_ip use_ip4 use_ip6").split(" ");
|
||||
ui->dns_object->setPlaceholderText(DecodeB64IfValid("ewogICJzZXJ2ZXJzIjogW10KfQ=="));
|
||||
dnsHelpDocumentUrl = "https://www.v2fly.org/config/dns.html";
|
||||
}
|
||||
//
|
||||
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
||||
ui->domainStrategyCombo->addItems(Preset::SingBox::DomainStrategy);
|
||||
qsValue += QString("prefer_ipv4 prefer_ipv6 ipv4_only ipv6_only").split(" ");
|
||||
ui->dns_object->setPlaceholderText(DecodeB64IfValid("ewogICJzZXJ2ZXJzIjogW10sCiAgInJ1bGVzIjogW10sCiAgImZpbmFsIjogIiIsCiAgInN0cmF0ZWd5IjogIiIsCiAgImRpc2FibGVfY2FjaGUiOiBmYWxzZSwKICAiZGlzYWJsZV9leHBpcmUiOiBmYWxzZSwKICAiaW5kZXBlbmRlbnRfY2FjaGUiOiBmYWxzZSwKICAicmV2ZXJzZV9tYXBwaW5nIjogZmFsc2UsCiAgImZha2VpcCI6IHt9Cn0="));
|
||||
dnsHelpDocumentUrl = "https://sing-box.sagernet.org/configuration/dns/";
|
||||
//
|
||||
ui->direct_dns_strategy->addItems(qsValue);
|
||||
ui->remote_dns_strategy->addItems(qsValue);
|
||||
//
|
||||
|
||||
@@ -20,7 +20,6 @@ DialogVPNSettings::DialogVPNSettings(QWidget *parent) : QDialog(parent), ui(new
|
||||
ui->hide_console->setVisible(false);
|
||||
#endif
|
||||
ui->strict_route->setChecked(NekoGui::dataStore->vpn_strict_route);
|
||||
ui->single_core->setVisible(IS_NEKO_BOX);
|
||||
ui->single_core->setChecked(NekoGui::dataStore->vpn_internal_tun);
|
||||
//
|
||||
D_LOAD_STRING_PLAIN(vpn_rule_cidr)
|
||||
|
||||
@@ -62,7 +62,7 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
||||
ui->host_l->setVisible(false);
|
||||
}
|
||||
// 传输设置 ED
|
||||
if (txt == "ws" && IS_NEKO_BOX) {
|
||||
if (txt == "ws") {
|
||||
ui->ws_early_data_length->setVisible(true);
|
||||
ui->ws_early_data_length_l->setVisible(true);
|
||||
ui->ws_early_data_name->setVisible(true);
|
||||
@@ -74,11 +74,7 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
||||
ui->ws_early_data_name_l->setVisible(false);
|
||||
}
|
||||
// 传输设置 for NekoBox
|
||||
if (IS_NEKO_BOX) {
|
||||
if (!ui->utlsFingerprint->count()) ui->utlsFingerprint->addItems(Preset::SingBox::UtlsFingerPrint);
|
||||
} else {
|
||||
if (!ui->utlsFingerprint->count()) ui->utlsFingerprint->addItems(Preset::Xray::UtlsFingerPrint);
|
||||
}
|
||||
if (!ui->utlsFingerprint->count()) ui->utlsFingerprint->addItems(Preset::SingBox::UtlsFingerPrint);
|
||||
// 传输设置 是否可见
|
||||
int networkBoxVisible = 0;
|
||||
for (auto label: ui->network_box->findChildren<QLabel *>()) {
|
||||
@@ -89,19 +85,13 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
||||
});
|
||||
ui->network->removeItem(0);
|
||||
|
||||
// if (IS_NEKO_BOX) {
|
||||
// ui->network->addItem("httpupgrade");
|
||||
// }
|
||||
|
||||
// security changed
|
||||
connect(ui->security, &QComboBox::currentTextChanged, this, [=](const QString &txt) {
|
||||
if (txt == "tls") {
|
||||
ui->security_box->setVisible(true);
|
||||
ui->tls_camouflage_box->setVisible(true);
|
||||
if (IS_NEKO_BOX) {
|
||||
ui->reality_spx->hide();
|
||||
ui->reality_spx_l->hide();
|
||||
}
|
||||
ui->reality_spx->hide();
|
||||
ui->reality_spx_l->hide();
|
||||
} else {
|
||||
ui->security_box->setVisible(false);
|
||||
ui->tls_camouflage_box->setVisible(false);
|
||||
@@ -286,47 +276,43 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
||||
ADD_ASTERISK(this)
|
||||
|
||||
// 设置 for NekoBox
|
||||
if (IS_NEKO_BOX) {
|
||||
if (type == "vmess" || type == "vless") {
|
||||
ui->packet_encoding->setVisible(true);
|
||||
ui->packet_encoding_l->setVisible(true);
|
||||
} else {
|
||||
ui->packet_encoding->setVisible(false);
|
||||
ui->packet_encoding_l->setVisible(false);
|
||||
}
|
||||
if (type == "vmess" || type == "vless" || type == "trojan") {
|
||||
ui->network_l->setVisible(true);
|
||||
ui->network->setVisible(true);
|
||||
ui->network_box->setVisible(true);
|
||||
} else {
|
||||
ui->network_l->setVisible(false);
|
||||
ui->network->setVisible(false);
|
||||
ui->network_box->setVisible(false);
|
||||
}
|
||||
if (type == "vmess" || type == "vless" || type == "trojan" || type == "http") {
|
||||
ui->security->setVisible(true);
|
||||
ui->security_l->setVisible(true);
|
||||
} else {
|
||||
ui->security->setVisible(false);
|
||||
ui->security_l->setVisible(false);
|
||||
}
|
||||
if (type == "vmess" || type == "vless" || type == "trojan" || type == "shadowsocks") {
|
||||
ui->multiplex->setVisible(true);
|
||||
ui->multiplex_l->setVisible(true);
|
||||
} else {
|
||||
ui->multiplex->setVisible(false);
|
||||
ui->multiplex_l->setVisible(false);
|
||||
}
|
||||
// 设置 是否可见
|
||||
int streamBoxVisible = 0;
|
||||
for (auto label: ui->stream_box->findChildren<QLabel *>()) {
|
||||
if (!label->isHidden()) streamBoxVisible++;
|
||||
}
|
||||
ui->stream_box->setVisible(streamBoxVisible);
|
||||
if (type == "vmess" || type == "vless") {
|
||||
ui->packet_encoding->setVisible(true);
|
||||
ui->packet_encoding_l->setVisible(true);
|
||||
} else {
|
||||
ui->packet_encoding->setVisible(false);
|
||||
ui->packet_encoding_l->setVisible(false);
|
||||
}
|
||||
if (type == "vmess" || type == "vless" || type == "trojan") {
|
||||
ui->network_l->setVisible(true);
|
||||
ui->network->setVisible(true);
|
||||
ui->network_box->setVisible(true);
|
||||
} else {
|
||||
ui->network_l->setVisible(false);
|
||||
ui->network->setVisible(false);
|
||||
ui->network_box->setVisible(false);
|
||||
}
|
||||
if (type == "vmess" || type == "vless" || type == "trojan" || type == "http") {
|
||||
ui->security->setVisible(true);
|
||||
ui->security_l->setVisible(true);
|
||||
} else {
|
||||
ui->security->setVisible(false);
|
||||
ui->security_l->setVisible(false);
|
||||
}
|
||||
if (type == "vmess" || type == "vless" || type == "trojan" || type == "shadowsocks") {
|
||||
ui->multiplex->setVisible(true);
|
||||
ui->multiplex_l->setVisible(true);
|
||||
} else {
|
||||
ui->multiplex->setVisible(false);
|
||||
ui->multiplex_l->setVisible(false);
|
||||
}
|
||||
|
||||
// 设置 是否可见
|
||||
int streamBoxVisible = 0;
|
||||
for (auto label: ui->stream_box->findChildren<QLabel *>()) {
|
||||
if (!label->isHidden()) streamBoxVisible++;
|
||||
}
|
||||
ui->stream_box->setVisible(streamBoxVisible);
|
||||
|
||||
// 载入 type 之后,有些类型没有右边的设置
|
||||
auto rightNoBox = (ui->stream_box->isHidden() && ui->network_box->isHidden() && ui->security_box->isHidden());
|
||||
|
||||
@@ -245,6 +245,11 @@
|
||||
<string notr="true">ws</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">httpupgrade</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">http</string>
|
||||
|
||||
@@ -60,7 +60,6 @@ void EditQUIC::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
||||
ui->heartbeat->hide();
|
||||
ui->heartbeat_l->hide();
|
||||
ui->uos->hide();
|
||||
if (!IS_NEKO_BOX) ui->forceExternal->hide();
|
||||
|
||||
if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria) { // hy1
|
||||
ui->password->hide();
|
||||
@@ -77,13 +76,11 @@ void EditQUIC::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
||||
ui->alpn->hide();
|
||||
ui->alpn_l->hide();
|
||||
ui->TLS->removeItem(ui->alpn_sp);
|
||||
if (IS_NEKO_BOX) {
|
||||
ui->disableMtuDiscovery->hide();
|
||||
ui->connectionReceiveWindow->hide();
|
||||
ui->connectionReceiveWindow_l->hide();
|
||||
ui->streamReceiveWindow->hide();
|
||||
ui->streamReceiveWindow_l->hide();
|
||||
}
|
||||
ui->disableMtuDiscovery->hide();
|
||||
ui->connectionReceiveWindow->hide();
|
||||
ui->connectionReceiveWindow_l->hide();
|
||||
ui->streamReceiveWindow->hide();
|
||||
ui->streamReceiveWindow_l->hide();
|
||||
}
|
||||
} else if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_TUIC) {
|
||||
ui->hopPort->hide();
|
||||
@@ -107,9 +104,7 @@ void EditQUIC::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
||||
ui->streamReceiveWindow_l->hide();
|
||||
ui->connectionReceiveWindow->hide();
|
||||
ui->connectionReceiveWindow_l->hide();
|
||||
if (!IS_NEKO_BOX) {
|
||||
ui->uos->hide();
|
||||
}
|
||||
ui->uos->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
EditShadowSocks::EditShadowSocks(QWidget *parent) : QWidget(parent),
|
||||
ui(new Ui::EditShadowSocks) {
|
||||
ui->setupUi(this);
|
||||
ui->method->addItems(IS_NEKO_BOX ? Preset::SingBox::ShadowsocksMethods : Preset::Xray::ShadowsocksMethods);
|
||||
ui->method->addItems(Preset::SingBox::ShadowsocksMethods);
|
||||
}
|
||||
|
||||
EditShadowSocks::~EditShadowSocks() {
|
||||
|
||||
@@ -23,7 +23,7 @@ void EditTrojanVLESS::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
||||
ui->flow_l->hide();
|
||||
}
|
||||
ui->password->setText(bean->password);
|
||||
ui->flow->addItems(IS_NEKO_BOX ? Preset::SingBox::Flows : Preset::Xray::Flows);
|
||||
ui->flow->addItems(Preset::SingBox::Flows);
|
||||
ui->flow->setCurrentText(bean->flow);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,18 +91,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
}
|
||||
}
|
||||
|
||||
// software_name
|
||||
if (IS_NEKO_BOX) {
|
||||
software_name = "NekoBox";
|
||||
software_core_name = "sing-box";
|
||||
// replace default values
|
||||
if (NekoGui::dataStore->log_level == "warning") NekoGui::dataStore->log_level = "info";
|
||||
if (NekoGui::dataStore->mux_protocol.isEmpty()) NekoGui::dataStore->mux_protocol = "h2mux";
|
||||
//
|
||||
if (QDir("dashboard").count() == 0) {
|
||||
QDir().mkdir("dashboard");
|
||||
QFile::copy(":/neko/dashboard-notice.html", "dashboard/index.html");
|
||||
}
|
||||
if (QDir("dashboard").count() == 0) {
|
||||
QDir().mkdir("dashboard");
|
||||
QFile::copy(":/neko/dashboard-notice.html", "dashboard/index.html");
|
||||
}
|
||||
|
||||
// top bar
|
||||
@@ -398,10 +389,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
if (NekoGui::dataStore->core_port <= 0) NekoGui::dataStore->core_port = 19810;
|
||||
|
||||
auto core_path = QApplication::applicationDirPath() + "/";
|
||||
core_path += IS_NEKO_BOX ? "nekobox_core" : "nekoray_core";
|
||||
core_path += "nekobox_core";
|
||||
|
||||
QStringList args;
|
||||
args.push_back(IS_NEKO_BOX ? "nekobox" : "nekoray");
|
||||
args.push_back("nekobox");
|
||||
args.push_back("-port");
|
||||
args.push_back(Int2String(NekoGui::dataStore->core_port));
|
||||
if (NekoGui::dataStore->flag_debug) args.push_back("-debug");
|
||||
@@ -726,20 +717,8 @@ void MainWindow::on_menu_exit_triggered() {
|
||||
void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||
if (enable != NekoGui::dataStore->spmode_system_proxy) {
|
||||
if (enable) {
|
||||
#if defined(Q_OS_WIN)
|
||||
if (!IS_NEKO_BOX && !IsValidPort(NekoGui::dataStore->inbound_http_port)) {
|
||||
auto btn = QMessageBox::warning(this, software_name,
|
||||
tr("Http inbound is not enabled, can't set system proxy."),
|
||||
"OK", tr("Settings"), "", 0, 0);
|
||||
if (btn == 1) {
|
||||
on_menu_basic_settings_triggered();
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
auto socks_port = NekoGui::dataStore->inbound_socks_port;
|
||||
auto http_port = NekoGui::dataStore->inbound_http_port;
|
||||
if (IS_NEKO_BOX) http_port = socks_port;
|
||||
auto http_port = NekoGui::dataStore->inbound_socks_port;
|
||||
SetSystemProxy(http_port, socks_port);
|
||||
} else {
|
||||
ClearSystemProxy();
|
||||
@@ -761,7 +740,7 @@ void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||
void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
||||
if (enable != NekoGui::dataStore->spmode_vpn) {
|
||||
if (enable) {
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
||||
if (NekoGui::dataStore->vpn_internal_tun) {
|
||||
bool requestPermission = !NekoGui::IsAdmin();
|
||||
if (requestPermission) {
|
||||
#ifdef Q_OS_LINUX
|
||||
@@ -799,7 +778,7 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
||||
if (NekoGui::dataStore->vpn_internal_tun) {
|
||||
// current core is sing-box
|
||||
} else {
|
||||
if (!StopVPNProcess()) {
|
||||
@@ -820,7 +799,7 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
||||
NekoGui::dataStore->spmode_vpn = enable;
|
||||
refresh_status();
|
||||
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && NekoGui::dataStore->started_id >= 0) neko_start(NekoGui::dataStore->started_id);
|
||||
if (NekoGui::dataStore->vpn_internal_tun && NekoGui::dataStore->started_id >= 0) neko_start(NekoGui::dataStore->started_id);
|
||||
}
|
||||
|
||||
void MainWindow::refresh_status(const QString &traffic_update) {
|
||||
@@ -858,13 +837,8 @@ void MainWindow::refresh_status(const QString &traffic_update) {
|
||||
ui->label_running->setText(txt);
|
||||
}
|
||||
//
|
||||
auto display_http = tr("None");
|
||||
if (IsValidPort(NekoGui::dataStore->inbound_http_port)) {
|
||||
display_http = DisplayAddress(NekoGui::dataStore->inbound_address, NekoGui::dataStore->inbound_http_port);
|
||||
}
|
||||
auto display_socks = DisplayAddress(NekoGui::dataStore->inbound_address, NekoGui::dataStore->inbound_socks_port);
|
||||
auto inbound_txt = QString("Socks: %1\nHTTP: %2").arg(display_socks, display_http);
|
||||
if (IS_NEKO_BOX) inbound_txt = QString("Mixed: %1").arg(display_socks);
|
||||
auto inbound_txt = QString("Mixed: %1").arg(display_socks);
|
||||
ui->label_inbound->setText(inbound_txt);
|
||||
//
|
||||
ui->checkBox_VPN->setChecked(NekoGui::dataStore->spmode_vpn);
|
||||
|
||||
Reference in New Issue
Block a user