mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 12:34:37 +03:00
v2ray format migration
This commit is contained in:
@@ -150,7 +150,6 @@ set(PROJECT_SOURCES
|
|||||||
db/ConfigBuilder.cpp
|
db/ConfigBuilder.cpp
|
||||||
|
|
||||||
fmt/AbstractBean.cpp
|
fmt/AbstractBean.cpp
|
||||||
fmt/Bean2CoreObj_ray.cpp
|
|
||||||
fmt/Bean2CoreObj_box.cpp
|
fmt/Bean2CoreObj_box.cpp
|
||||||
fmt/Bean2External.cpp
|
fmt/Bean2External.cpp
|
||||||
fmt/Bean2Link.cpp
|
fmt/Bean2Link.cpp
|
||||||
|
|||||||
@@ -64,11 +64,7 @@ namespace NekoGui {
|
|||||||
if (customBean != nullptr && customBean->core == "internal-full") {
|
if (customBean != nullptr && customBean->core == "internal-full") {
|
||||||
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
||||||
} else {
|
} else {
|
||||||
if (IS_NEKO_BOX) {
|
BuildConfigSingBox(status);
|
||||||
BuildConfigSingBox(status);
|
|
||||||
} else {
|
|
||||||
BuildConfigV2Ray(status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply custom config
|
// apply custom config
|
||||||
@@ -157,254 +153,6 @@ namespace NekoGui {
|
|||||||
status->ipListDirect += line; \
|
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,
|
QString BuildChainInternal(int chainId, const QList<std::shared_ptr<ProxyEntity>> &ents,
|
||||||
const std::shared_ptr<BuildConfigStatus> &status) {
|
const std::shared_ptr<BuildConfigStatus> &status) {
|
||||||
QString chainTag = "c-" + Int2String(chainId);
|
QString chainTag = "c-" + Int2String(chainId);
|
||||||
@@ -454,29 +202,14 @@ namespace NekoGui {
|
|||||||
// chain rules: past
|
// chain rules: past
|
||||||
if (pastExternalStat == 0) {
|
if (pastExternalStat == 0) {
|
||||||
auto replaced = status->outbounds.last().toObject();
|
auto replaced = status->outbounds.last().toObject();
|
||||||
if (IS_NEKO_BOX) {
|
replaced["detour"] = tagOut;
|
||||||
replaced["detour"] = tagOut;
|
|
||||||
} else {
|
|
||||||
replaced["proxySettings"] = QJsonObject{
|
|
||||||
{"tag", tagOut},
|
|
||||||
{"transportLayer", true},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
status->outbounds.removeLast();
|
status->outbounds.removeLast();
|
||||||
status->outbounds += replaced;
|
status->outbounds += replaced;
|
||||||
} else {
|
} else {
|
||||||
if (IS_NEKO_BOX) {
|
status->routingRules += QJsonObject{
|
||||||
status->routingRules += QJsonObject{
|
{"inbound", QJsonArray{pastTag + "-mapping"}},
|
||||||
{"inbound", QJsonArray{pastTag + "-mapping"}},
|
{"outbound", tagOut},
|
||||||
{"outbound", tagOut},
|
};
|
||||||
};
|
|
||||||
} else {
|
|
||||||
status->routingRules += QJsonObject{
|
|
||||||
{"type", "field"},
|
|
||||||
{"inboundTag", QJsonArray{pastTag + "-mapping"}},
|
|
||||||
{"outboundTag", tagOut},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// index == 0 means last profile in chain / not chain
|
// 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 == 2) dataStore->need_keep_vpn_off = true;
|
||||||
if (thisExternalStat == 1) {
|
if (thisExternalStat == 1) {
|
||||||
// mapping
|
// mapping
|
||||||
if (IS_NEKO_BOX) {
|
status->inbounds += QJsonObject{
|
||||||
status->inbounds += QJsonObject{
|
{"type", "direct"},
|
||||||
{"type", "direct"},
|
{"tag", tagOut + "-mapping"},
|
||||||
{"tag", tagOut + "-mapping"},
|
{"listen", "127.0.0.1"},
|
||||||
{"listen", "127.0.0.1"},
|
{"listen_port", ext_mapping_port},
|
||||||
{"listen_port", ext_mapping_port},
|
{"override_address", ent->bean->serverAddress},
|
||||||
{"override_address", ent->bean->serverAddress},
|
{"override_port", ent->bean->serverPort},
|
||||||
{"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"},
|
|
||||||
}},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// no chain rule and not outbound, so need to set to direct
|
// no chain rule and not outbound, so need to set to direct
|
||||||
if (isFirstProfile) {
|
if (isFirstProfile) {
|
||||||
if (IS_NEKO_BOX) {
|
status->routingRules += QJsonObject{
|
||||||
status->routingRules += QJsonObject{
|
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
||||||
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
{"outbound", "direct"},
|
||||||
{"outbound", "direct"},
|
};
|
||||||
};
|
|
||||||
} else {
|
|
||||||
status->routingRules += QJsonObject{
|
|
||||||
{"type", "field"},
|
|
||||||
{"inboundTag", QJsonArray{tagOut + "-mapping"}},
|
|
||||||
{"outboundTag", "direct"},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,23 +284,11 @@ namespace NekoGui {
|
|||||||
status->result->extRs.emplace_back(std::make_shared<NekoGui_fmt::ExternalBuildResult>(extR));
|
status->result->extRs.emplace_back(std::make_shared<NekoGui_fmt::ExternalBuildResult>(extR));
|
||||||
|
|
||||||
// SOCKS OUTBOUND
|
// SOCKS OUTBOUND
|
||||||
if (IS_NEKO_BOX) {
|
outbound["type"] = "socks";
|
||||||
outbound["type"] = "socks";
|
outbound["server"] = "127.0.0.1";
|
||||||
outbound["server"] = "127.0.0.1";
|
outbound["server_port"] = ext_socks_port;
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const auto coreR = IS_NEKO_BOX ? ent->bean->BuildCoreObjSingBox() : ent->bean->BuildCoreObjV2Ray();
|
const auto coreR = ent->bean->BuildCoreObjSingBox();
|
||||||
if (coreR.outbound.isEmpty()) {
|
if (coreR.outbound.isEmpty()) {
|
||||||
status->result->error = "unsupported outbound";
|
status->result->error = "unsupported outbound";
|
||||||
return {};
|
return {};
|
||||||
@@ -613,14 +311,8 @@ namespace NekoGui {
|
|||||||
needMux &= dataStore->mux_concurrency > 0;
|
needMux &= dataStore->mux_concurrency > 0;
|
||||||
|
|
||||||
if (stream != nullptr) {
|
if (stream != nullptr) {
|
||||||
if (IS_NEKO_BOX) {
|
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
||||||
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
needMux = false;
|
||||||
needMux = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (stream->network == "grpc" || stream->network == "quic") {
|
|
||||||
needMux = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (stream->multiplex_status == 0) {
|
if (stream->multiplex_status == 0) {
|
||||||
if (!dataStore->mux_default_on) needMux = false;
|
if (!dataStore->mux_default_on) needMux = false;
|
||||||
@@ -635,32 +327,18 @@ namespace NekoGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// common
|
// common
|
||||||
if (IS_NEKO_BOX) {
|
// apply domain_strategy
|
||||||
// apply domain_strategy
|
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
||||||
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
// apply mux
|
||||||
// apply mux
|
if (!muxApplied && needMux) {
|
||||||
if (!muxApplied && needMux) {
|
auto muxObj = QJsonObject{
|
||||||
auto muxObj = QJsonObject{
|
{"enabled", true},
|
||||||
{"enabled", true},
|
{"protocol", dataStore->mux_protocol},
|
||||||
{"protocol", dataStore->mux_protocol},
|
{"padding", dataStore->mux_padding},
|
||||||
{"padding", dataStore->mux_padding},
|
{"max_streams", dataStore->mux_concurrency},
|
||||||
{"max_streams", dataStore->mux_concurrency},
|
};
|
||||||
};
|
outbound["multiplex"] = muxObj;
|
||||||
outbound["multiplex"] = muxObj;
|
muxApplied = true;
|
||||||
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 custom outbound settings
|
// apply custom outbound settings
|
||||||
@@ -720,7 +398,7 @@ namespace NekoGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// tun-in
|
// 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;
|
QJsonObject inboundObj;
|
||||||
inboundObj["tag"] = "tun-in";
|
inboundObj["tag"] = "tun-in";
|
||||||
inboundObj["type"] = "tun";
|
inboundObj["type"] = "tun";
|
||||||
@@ -869,7 +547,7 @@ namespace NekoGui {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Fakedns
|
// 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{
|
dnsServers += QJsonObject{
|
||||||
{"tag", "dns-fake"},
|
{"tag", "dns-fake"},
|
||||||
{"address", "fakeip"},
|
{"address", "fakeip"},
|
||||||
@@ -911,7 +589,7 @@ namespace NekoGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fakedns rule
|
// 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{
|
dnsRules += QJsonObject{
|
||||||
{"inbound", "tun-in"},
|
{"inbound", "tun-in"},
|
||||||
{"server", "dns-fake"},
|
{"server", "dns-fake"},
|
||||||
@@ -969,7 +647,7 @@ namespace NekoGui {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// tun user rule
|
// 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";
|
auto match_out = dataStore->vpn_rule_white ? "proxy" : "bypass";
|
||||||
|
|
||||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
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);
|
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);
|
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status);
|
||||||
|
|
||||||
QString BuildChain(int chainId, 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 int NeedExternal(bool isFirstProfile) { return 0; };
|
||||||
|
|
||||||
virtual CoreObjOutboundBuildResult BuildCoreObjV2Ray() { return {}; };
|
|
||||||
|
|
||||||
virtual CoreObjOutboundBuildResult BuildCoreObjSingBox() { return {}; };
|
virtual CoreObjOutboundBuildResult BuildCoreObjSingBox() { return {}; };
|
||||||
|
|
||||||
virtual ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) { 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;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (IS_NEKO_BOX) {
|
if (!forceExternal && (proxy_type == proxy_TUIC || hyProtocol == hysteria_protocol_udp)) {
|
||||||
if (!forceExternal && (proxy_type == proxy_TUIC || hyProtocol == hysteria_protocol_udp)) {
|
// sing-box support
|
||||||
// sing-box support
|
return 0;
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
// hysteria core support
|
|
||||||
return hysteriaCore();
|
|
||||||
}
|
|
||||||
} else if (proxy_type == proxy_TUIC) {
|
|
||||||
return tuicCore();
|
|
||||||
} else if (proxy_type == proxy_Hysteria2) {
|
|
||||||
return hysteria2Core();
|
|
||||||
} else {
|
} else {
|
||||||
|
// hysteria core support
|
||||||
return hysteriaCore();
|
return hysteriaCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace NekoGui_fmt {
|
|||||||
QString DisplayType() override {
|
QString DisplayType() override {
|
||||||
if (core == "internal") {
|
if (core == "internal") {
|
||||||
auto obj = QString2QJsonObject(config_simple);
|
auto obj = QString2QJsonObject(config_simple);
|
||||||
return obj[IS_NEKO_BOX ? "type" : "protocol"].toString();
|
return obj["type"].toString();
|
||||||
} else if (core == "internal-full") {
|
} else if (core == "internal-full") {
|
||||||
return software_core_name + " config";
|
return software_core_name + " config";
|
||||||
}
|
}
|
||||||
@@ -36,11 +36,7 @@ namespace NekoGui_fmt {
|
|||||||
QString DisplayAddress() override {
|
QString DisplayAddress() override {
|
||||||
if (core == "internal") {
|
if (core == "internal") {
|
||||||
auto obj = QString2QJsonObject(config_simple);
|
auto obj = QString2QJsonObject(config_simple);
|
||||||
if (IS_NEKO_BOX) {
|
return ::DisplayAddress(obj["server"].toString(), obj["server_port"].toInt());
|
||||||
return ::DisplayAddress(obj["server"].toString(), obj["server_port"].toInt());
|
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
} else if (core == "internal-full") {
|
} else if (core == "internal-full") {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -52,7 +48,5 @@ namespace NekoGui_fmt {
|
|||||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
|
||||||
};
|
};
|
||||||
} // namespace NekoGui_fmt
|
} // namespace NekoGui_fmt
|
||||||
@@ -1,15 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Preset {
|
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 {
|
namespace SingBox {
|
||||||
inline QStringList VpnImplementation = {"gvisor", "system", "mixed"};
|
inline QStringList VpnImplementation = {"gvisor", "system", "mixed"};
|
||||||
inline QStringList DomainStrategy = {"", "ipv4_only", "ipv6_only", "prefer_ipv4", "prefer_ipv6"};
|
inline QStringList DomainStrategy = {"", "ipv4_only", "ipv6_only", "prefer_ipv4", "prefer_ipv6"};
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ namespace NekoGui_fmt {
|
|||||||
|
|
||||||
QString DisplayType() override { return "Shadowsocks"; };
|
QString DisplayType() override { return "Shadowsocks"; };
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
bool TryParseLink(const QString &link);
|
bool TryParseLink(const QString &link);
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ namespace NekoGui_fmt {
|
|||||||
|
|
||||||
QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; };
|
QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; };
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
bool TryParseLink(const QString &link);
|
bool TryParseLink(const QString &link);
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ namespace NekoGui_fmt {
|
|||||||
|
|
||||||
QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; };
|
QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; };
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
bool TryParseLink(const QString &link);
|
bool TryParseLink(const QString &link);
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ namespace NekoGui_fmt {
|
|||||||
_add(new configItem("mux_s", &multiplex_status, itemType::integer));
|
_add(new configItem("mux_s", &multiplex_status, itemType::integer));
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject BuildStreamSettingsV2Ray();
|
|
||||||
|
|
||||||
void BuildStreamSettingsSingBox(QJsonObject *outbound);
|
void BuildStreamSettingsSingBox(QJsonObject *outbound);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ namespace NekoGui_fmt {
|
|||||||
|
|
||||||
QString DisplayType() override { return "VMess"; };
|
QString DisplayType() override { return "VMess"; };
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
bool TryParseLink(const QString &link);
|
bool TryParseLink(const QString &link);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace NekoGui_network {
|
|||||||
if (NekoGui::dataStore->sub_use_proxy) {
|
if (NekoGui::dataStore->sub_use_proxy) {
|
||||||
QNetworkProxy p;
|
QNetworkProxy p;
|
||||||
// Note: sing-box mixed socks5 protocol error
|
// 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.setHostName("127.0.0.1");
|
||||||
p.setPort(NekoGui::dataStore->inbound_socks_port);
|
p.setPort(NekoGui::dataStore->inbound_socks_port);
|
||||||
if (NekoGui::dataStore->inbound_auth->NeedAuth()) {
|
if (NekoGui::dataStore->inbound_auth->NeedAuth()) {
|
||||||
|
|||||||
@@ -237,7 +237,6 @@ namespace NekoGui {
|
|||||||
_add(new configItem("current_group", ¤t_group, itemType::integer));
|
_add(new configItem("current_group", ¤t_group, itemType::integer));
|
||||||
_add(new configItem("inbound_address", &inbound_address, itemType::string));
|
_add(new configItem("inbound_address", &inbound_address, itemType::string));
|
||||||
_add(new configItem("inbound_socks_port", &inbound_socks_port, itemType::integer));
|
_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("log_level", &log_level, itemType::string));
|
||||||
_add(new configItem("mux_protocol", &mux_protocol, itemType::string));
|
_add(new configItem("mux_protocol", &mux_protocol, itemType::string));
|
||||||
_add(new configItem("mux_concurrency", &mux_concurrency, itemType::integer));
|
_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", &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_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_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));
|
_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) {
|
void DataStore::UpdateStartedId(int id) {
|
||||||
@@ -310,11 +304,7 @@ namespace NekoGui {
|
|||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
QString version = SubStrBefore(NKR_VERSION, "-");
|
QString version = SubStrBefore(NKR_VERSION, "-");
|
||||||
if (!version.contains(".")) version = "2.0";
|
if (!version.contains(".")) version = "2.0";
|
||||||
if (IS_NEKO_BOX) {
|
return "NekoBox/PC/" + version + " (Prefer ClashMeta Format)";
|
||||||
return "NekoBox/PC/" + version + " (Prefer ClashMeta Format)";
|
|
||||||
} else {
|
|
||||||
return "NekoRay/PC/" + version + " (Prefer ClashMeta Format)";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return user_agent;
|
return user_agent;
|
||||||
}
|
}
|
||||||
@@ -335,10 +325,8 @@ namespace NekoGui {
|
|||||||
"domain:firebase.io\n"
|
"domain:firebase.io\n"
|
||||||
"domain:crashlytics.com\n";
|
"domain:crashlytics.com\n";
|
||||||
}
|
}
|
||||||
if (IS_NEKO_BOX) {
|
if (!Preset::SingBox::DomainStrategy.contains(domain_strategy)) domain_strategy = "";
|
||||||
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(outbound_domain_strategy)) outbound_domain_strategy = "";
|
|
||||||
}
|
|
||||||
_add(new configItem("direct_ip", &this->direct_ip, itemType::string));
|
_add(new configItem("direct_ip", &this->direct_ip, itemType::string));
|
||||||
_add(new configItem("direct_domain", &this->direct_domain, itemType::string));
|
_add(new configItem("direct_domain", &this->direct_domain, itemType::string));
|
||||||
_add(new configItem("proxy_ip", &this->proxy_ip, itemType::string));
|
_add(new configItem("proxy_ip", &this->proxy_ip, itemType::string));
|
||||||
|
|||||||
@@ -17,7 +17,5 @@ namespace NekoGui {
|
|||||||
bool IsAdmin();
|
bool IsAdmin();
|
||||||
} // namespace NekoGui
|
} // namespace NekoGui
|
||||||
|
|
||||||
#define IS_NEKO_BOX (NekoGui::coreType == NekoGui::CoreType::SING_BOX)
|
#define ROUTES_PREFIX_NAME QString("routes_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 QString(ROUTES_PREFIX_NAME + "/")
|
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace NekoGui {
|
|||||||
// Saved
|
// Saved
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
QString log_level = "warning";
|
QString log_level = "info";
|
||||||
QString test_latency_url = "http://cp.cloudflare.com/";
|
QString test_latency_url = "http://cp.cloudflare.com/";
|
||||||
QString test_download_url = "http://cachefly.cachefly.net/10mb.test";
|
QString test_download_url = "http://cachefly.cachefly.net/10mb.test";
|
||||||
int test_download_timeout = 30;
|
int test_download_timeout = 30;
|
||||||
@@ -102,7 +102,7 @@ namespace NekoGui {
|
|||||||
int traffic_loop_interval = 1000;
|
int traffic_loop_interval = 1000;
|
||||||
bool connection_statistics = false;
|
bool connection_statistics = false;
|
||||||
int current_group = 0; // group id
|
int current_group = 0; // group id
|
||||||
QString mux_protocol = "";
|
QString mux_protocol = "h2mux";
|
||||||
bool mux_padding = false;
|
bool mux_padding = false;
|
||||||
int mux_concurrency = 8;
|
int mux_concurrency = 8;
|
||||||
bool mux_default_on = false;
|
bool mux_default_on = false;
|
||||||
@@ -136,7 +136,6 @@ namespace NekoGui {
|
|||||||
// Socks & HTTP Inbound
|
// Socks & HTTP Inbound
|
||||||
QString inbound_address = "127.0.0.1";
|
QString inbound_address = "127.0.0.1";
|
||||||
int inbound_socks_port = 2080; // or Mixed
|
int inbound_socks_port = 2080; // or Mixed
|
||||||
int inbound_http_port = 2081;
|
|
||||||
InboundAuthorization *inbound_auth = new InboundAuthorization;
|
InboundAuthorization *inbound_auth = new InboundAuthorization;
|
||||||
QString custom_inbound = "{\"inbounds\": []}";
|
QString custom_inbound = "{\"inbounds\": []}";
|
||||||
|
|
||||||
@@ -166,9 +165,6 @@ namespace NekoGui {
|
|||||||
int core_box_clash_api = -9090;
|
int core_box_clash_api = -9090;
|
||||||
QString core_box_clash_api_secret = "";
|
QString core_box_clash_api_secret = "";
|
||||||
QString core_box_underlying_dns = "";
|
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
|
// Other Core
|
||||||
ExtraCore *extraCore = new ExtraCore;
|
ExtraCore *extraCore = new ExtraCore;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
inline QString software_name = "NekoRay";
|
inline QString software_name = "NekoBox";
|
||||||
inline QString software_core_name = "Xray";
|
inline QString software_core_name = "sing-box";
|
||||||
|
|
||||||
// Main Functions
|
// Main Functions
|
||||||
|
|
||||||
|
|||||||
@@ -147,8 +147,6 @@ namespace NekoGui_sys {
|
|||||||
v2ray_asset_dir = QFileInfo(v2ray_asset_dir).absolutePath();
|
v2ray_asset_dir = QFileInfo(v2ray_asset_dir).absolutePath();
|
||||||
env << "XRAY_LOCATION_ASSET=" + v2ray_asset_dir;
|
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();
|
ExternalProcess::Start();
|
||||||
write((NekoGui::dataStore->core_token + "\n").toUtf8());
|
write((NekoGui::dataStore->core_token + "\n").toUtf8());
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
<source>Enable</source>
|
<source>Enable</source>
|
||||||
<translation>فعال کردن</translation>
|
<translation>فعال کردن</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>HTTP Listen Port</source>
|
|
||||||
<translation>پورت HTTP درحال شنود</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Listen Address</source>
|
<source>Listen Address</source>
|
||||||
<translation>آدرس درحال شنود</translation>
|
<translation>آدرس درحال شنود</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Socks Listen Port</source>
|
|
||||||
<translation>پورت ساکس درحال شنود</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>concurrency</source>
|
<source>concurrency</source>
|
||||||
<translation>همزمانی</translation>
|
<translation>همزمانی</translation>
|
||||||
@@ -197,16 +189,6 @@
|
|||||||
<source>Override underlying DNS</source>
|
<source>Override underlying DNS</source>
|
||||||
<translation type="unfinished">لغو دی ان اس زیربنایی</translation>
|
<translation type="unfinished">لغو دی ان اس زیربنایی</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Default On</source>
|
<source>Default On</source>
|
||||||
<translation type="unfinished">به صورت پیشفرض فعال</translation>
|
<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>
|
<source>Old Share Link Format</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mixed (SOCKS+HTTP) Listen Port</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>DialogEditGroup</name>
|
<name>DialogEditGroup</name>
|
||||||
@@ -1368,14 +1354,6 @@ This needs to be run NekoBox with administrator privileges.</source>
|
|||||||
<source>Imported %1 profile(s)</source>
|
<source>Imported %1 profile(s)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Current server is incompatible with Tun. Please stop the server first, enable Tun Mode, and then restart.</source>
|
<source>Current server is incompatible with Tun. Please stop the server first, enable Tun Mode, and then restart.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@@ -1384,11 +1362,6 @@ This needs to be run NekoBox with administrator privileges.</source>
|
|||||||
<source>Not Running</source>
|
<source>Not Running</source>
|
||||||
<translation>در حال اجرا نیست</translation>
|
<translation>در حال اجرا نیست</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>None</source>
|
|
||||||
<translatorcomment>هیچ یک</translatorcomment>
|
|
||||||
<translation>هیچ یک</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Select</source>
|
<source>Select</source>
|
||||||
<translation>انتخاب</translation>
|
<translation>انتخاب</translation>
|
||||||
|
|||||||
@@ -23,14 +23,6 @@
|
|||||||
<source>Edit</source>
|
<source>Edit</source>
|
||||||
<translation>Изменить</translation>
|
<translation>Изменить</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Socks Listen Port</source>
|
|
||||||
<translation>Адрес входящих SOCKS</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>HTTP Listen Port</source>
|
|
||||||
<translation>Адрес входящих HTTP</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Enable</source>
|
<source>Enable</source>
|
||||||
<translation>Вкл</translation>
|
<translation>Вкл</translation>
|
||||||
@@ -211,18 +203,6 @@
|
|||||||
<source>Override underlying DNS</source>
|
<source>Override underlying DNS</source>
|
||||||
<translation>Переопределить нижестоящий DNS</translation>
|
<translation>Переопределить нижестоящий DNS</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Timeout (s)</source>
|
<source>Timeout (s)</source>
|
||||||
<translation>Таймаут (с)</translation>
|
<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>
|
<source>Old Share Link Format</source>
|
||||||
<translation>Поделиться ссылкой в старом формате</translation>
|
<translation>Поделиться ссылкой в старом формате</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mixed (SOCKS+HTTP) Listen Port</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>DialogEditGroup</name>
|
<name>DialogEditGroup</name>
|
||||||
@@ -1394,14 +1378,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
|
|||||||
<source>Imported %1 profile(s)</source>
|
<source>Imported %1 profile(s)</source>
|
||||||
<translation>Импортирован(ы) %1 профиль(ей)</translation>
|
<translation>Импортирован(ы) %1 профиль(ей)</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Please run NekoBox as admin</source>
|
<source>Please run NekoBox as admin</source>
|
||||||
<translation>Пожалуйста, запустите NekoBox с правами администратора</translation>
|
<translation>Пожалуйста, запустите NekoBox с правами администратора</translation>
|
||||||
@@ -1414,10 +1390,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
|
|||||||
<source>Not Running</source>
|
<source>Not Running</source>
|
||||||
<translation>Не запущен</translation>
|
<translation>Не запущен</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>None</source>
|
|
||||||
<translation>Нет</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Select</source>
|
<source>Select</source>
|
||||||
<translation>Выбор</translation>
|
<translation>Выбор</translation>
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
<source>Enable</source>
|
<source>Enable</source>
|
||||||
<translation>启用</translation>
|
<translation>启用</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>HTTP Listen Port</source>
|
|
||||||
<translation>HTTP 监听端口</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Listen Address</source>
|
<source>Listen Address</source>
|
||||||
<translation>监听地址</translation>
|
<translation>监听地址</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Socks Listen Port</source>
|
|
||||||
<translation>Socks 监听端口</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>concurrency</source>
|
<source>concurrency</source>
|
||||||
<translation>并发</translation>
|
<translation>并发</translation>
|
||||||
@@ -203,18 +195,6 @@
|
|||||||
<source>Override underlying DNS</source>
|
<source>Override underlying DNS</source>
|
||||||
<translation>覆盖底层 DNS</translation>
|
<translation>覆盖底层 DNS</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Default On</source>
|
<source>Default On</source>
|
||||||
<translation>默认开启</translation>
|
<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>
|
<source>Interval (minute, invalid if less than 30)</source>
|
||||||
<translation>时间间隔(分钟,少于 30 分钟无效)</translation>
|
<translation>时间间隔(分钟,少于 30 分钟无效)</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mixed (SOCKS+HTTP) Listen Port</source>
|
||||||
|
<translation>Mixed (SOCKS+HTTP) 监听端口</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>DialogEditGroup</name>
|
<name>DialogEditGroup</name>
|
||||||
@@ -1210,10 +1194,6 @@ This needs to be run NekoBox with administrator privileges.</source>
|
|||||||
<source>Imported %1 profile(s)</source>
|
<source>Imported %1 profile(s)</source>
|
||||||
<translation>导入了 %1 个配置</translation>
|
<translation>导入了 %1 个配置</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>None</source>
|
|
||||||
<translation>无</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unavailable</source>
|
<source>Unavailable</source>
|
||||||
<translation>不可用</translation>
|
<translation>不可用</translation>
|
||||||
|
|||||||
@@ -59,16 +59,8 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
|||||||
|
|
||||||
// Common
|
// Common
|
||||||
|
|
||||||
if (IS_NEKO_BOX) {
|
ui->log_level->addItems(QString("trace debug info warn error fatal panic").split(" "));
|
||||||
ui->groupBox_http->hide();
|
ui->mux_protocol->addItems({"h2mux", "smux", "yamux"});
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh_auth();
|
refresh_auth();
|
||||||
|
|
||||||
@@ -76,7 +68,6 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
|||||||
D_LOAD_COMBO_STRING(log_level)
|
D_LOAD_COMBO_STRING(log_level)
|
||||||
CACHE.custom_inbound = NekoGui::dataStore->custom_inbound;
|
CACHE.custom_inbound = NekoGui::dataStore->custom_inbound;
|
||||||
D_LOAD_INT(inbound_socks_port)
|
D_LOAD_INT(inbound_socks_port)
|
||||||
D_LOAD_INT_ENABLE(inbound_http_port, http_enable)
|
|
||||||
D_LOAD_INT(test_concurrent)
|
D_LOAD_INT(test_concurrent)
|
||||||
D_LOAD_INT(test_download_timeout)
|
D_LOAD_INT(test_download_timeout)
|
||||||
D_LOAD_STRING(test_latency_url)
|
D_LOAD_STRING(test_latency_url)
|
||||||
@@ -102,9 +93,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Style
|
// 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(check_include_pre)
|
||||||
D_LOAD_BOOL(connection_statistics)
|
D_LOAD_BOOL(connection_statistics)
|
||||||
@@ -225,7 +214,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
|||||||
|
|
||||||
// Security
|
// Security
|
||||||
|
|
||||||
ui->utlsFingerprint->addItems(IS_NEKO_BOX ? Preset::SingBox::UtlsFingerPrint : Preset::Xray::UtlsFingerPrint);
|
ui->utlsFingerprint->addItems(Preset::SingBox::UtlsFingerPrint);
|
||||||
|
|
||||||
D_LOAD_BOOL(skip_cert)
|
D_LOAD_BOOL(skip_cert)
|
||||||
ui->utlsFingerprint->setCurrentText(NekoGui::dataStore->utlsFingerprint);
|
ui->utlsFingerprint->setCurrentText(NekoGui::dataStore->utlsFingerprint);
|
||||||
@@ -242,7 +231,6 @@ void DialogBasicSettings::accept() {
|
|||||||
D_SAVE_COMBO_STRING(log_level)
|
D_SAVE_COMBO_STRING(log_level)
|
||||||
NekoGui::dataStore->custom_inbound = CACHE.custom_inbound;
|
NekoGui::dataStore->custom_inbound = CACHE.custom_inbound;
|
||||||
D_SAVE_INT(inbound_socks_port)
|
D_SAVE_INT(inbound_socks_port)
|
||||||
D_SAVE_INT_ENABLE(inbound_http_port, http_enable)
|
|
||||||
D_SAVE_INT(test_concurrent)
|
D_SAVE_INT(test_concurrent)
|
||||||
D_SAVE_INT(test_download_timeout)
|
D_SAVE_INT(test_download_timeout)
|
||||||
D_SAVE_STRING(test_latency_url)
|
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;
|
||||||
MyLineEdit *core_box_clash_api_secret;
|
MyLineEdit *core_box_clash_api_secret;
|
||||||
MyLineEdit *core_box_underlying_dns;
|
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"));
|
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 = new MyLineEdit;
|
||||||
core_box_underlying_dns->setText(NekoGui::dataStore->core_box_underlying_dns);
|
core_box_underlying_dns->setText(NekoGui::dataStore->core_box_underlying_dns);
|
||||||
core_box_underlying_dns->setMinimumWidth(300);
|
core_box_underlying_dns->setMinimumWidth(300);
|
||||||
layout->addWidget(core_box_underlying_dns_l, ++line, 0);
|
layout->addWidget(core_box_underlying_dns_l, ++line, 0);
|
||||||
layout->addWidget(core_box_underlying_dns, line, 1);
|
layout->addWidget(core_box_underlying_dns, line, 1);
|
||||||
//
|
//
|
||||||
if (IS_NEKO_BOX) {
|
auto core_box_enable_clash_api_l = new QLabel("Enable Clash API");
|
||||||
auto core_box_enable_clash_api_l = new QLabel("Enable Clash API");
|
core_box_enable_clash_api = new QCheckBox;
|
||||||
core_box_enable_clash_api = new QCheckBox;
|
core_box_enable_clash_api->setChecked(NekoGui::dataStore->core_box_clash_api > 0);
|
||||||
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_l, ++line, 0);
|
layout->addWidget(core_box_enable_clash_api, line, 1);
|
||||||
layout->addWidget(core_box_enable_clash_api, line, 1);
|
//
|
||||||
//
|
auto core_box_clash_api_l = new QLabel("Clash API Listen Port");
|
||||||
auto core_box_clash_api_l = new QLabel("Clash API Listen Port");
|
core_box_clash_api = new MyLineEdit;
|
||||||
core_box_clash_api = new MyLineEdit;
|
core_box_clash_api->setText(Int2String(std::abs(NekoGui::dataStore->core_box_clash_api)));
|
||||||
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_l, ++line, 0);
|
layout->addWidget(core_box_clash_api, line, 1);
|
||||||
layout->addWidget(core_box_clash_api, line, 1);
|
//
|
||||||
//
|
auto core_box_clash_api_secret_l = new QLabel("Clash API Secret");
|
||||||
auto core_box_clash_api_secret_l = new QLabel("Clash API Secret");
|
core_box_clash_api_secret = new MyLineEdit;
|
||||||
core_box_clash_api_secret = new MyLineEdit;
|
core_box_clash_api_secret->setText(NekoGui::dataStore->core_box_clash_api_secret);
|
||||||
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_l, ++line, 0);
|
layout->addWidget(core_box_clash_api_secret, line, 1);
|
||||||
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 box = new QDialogButtonBox;
|
auto box = new QDialogButtonBox;
|
||||||
box->setOrientation(Qt::Horizontal);
|
box->setOrientation(Qt::Horizontal);
|
||||||
box->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
|
box->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
|
||||||
connect(box, &QDialogButtonBox::accepted, w, [=] {
|
connect(box, &QDialogButtonBox::accepted, w, [=] {
|
||||||
NekoGui::dataStore->core_box_underlying_dns = core_box_underlying_dns->text();
|
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 = 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();
|
||||||
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
|
|
||||||
}
|
|
||||||
MW_dialog_message(Dialog_DialogBasicSettings, "UpdateDataStore");
|
MW_dialog_message(Dialog_DialogBasicSettings, "UpdateDataStore");
|
||||||
w->accept();
|
w->accept();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="inbound_socks_port_l">
|
<widget class="QLabel" name="inbound_socks_port_l">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Socks Listen Port</string>
|
<string>Mixed (SOCKS+HTTP) Listen Port</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -112,36 +112,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -709,8 +679,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>198</width>
|
<width>632</width>
|
||||||
<height>58</height>
|
<height>299</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
|||||||
@@ -22,19 +22,13 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(ne
|
|||||||
|
|
||||||
QStringList qsValue = {""};
|
QStringList qsValue = {""};
|
||||||
QString dnsHelpDocumentUrl;
|
QString dnsHelpDocumentUrl;
|
||||||
if (IS_NEKO_BOX) {
|
//
|
||||||
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
||||||
ui->domainStrategyCombo->addItems(Preset::SingBox::DomainStrategy);
|
ui->domainStrategyCombo->addItems(Preset::SingBox::DomainStrategy);
|
||||||
qsValue += QString("prefer_ipv4 prefer_ipv6 ipv4_only ipv6_only").split(" ");
|
qsValue += QString("prefer_ipv4 prefer_ipv6 ipv4_only ipv6_only").split(" ");
|
||||||
ui->dns_object->setPlaceholderText(DecodeB64IfValid("ewogICJzZXJ2ZXJzIjogW10sCiAgInJ1bGVzIjogW10sCiAgImZpbmFsIjogIiIsCiAgInN0cmF0ZWd5IjogIiIsCiAgImRpc2FibGVfY2FjaGUiOiBmYWxzZSwKICAiZGlzYWJsZV9leHBpcmUiOiBmYWxzZSwKICAiaW5kZXBlbmRlbnRfY2FjaGUiOiBmYWxzZSwKICAicmV2ZXJzZV9tYXBwaW5nIjogZmFsc2UsCiAgImZha2VpcCI6IHt9Cn0="));
|
ui->dns_object->setPlaceholderText(DecodeB64IfValid("ewogICJzZXJ2ZXJzIjogW10sCiAgInJ1bGVzIjogW10sCiAgImZpbmFsIjogIiIsCiAgInN0cmF0ZWd5IjogIiIsCiAgImRpc2FibGVfY2FjaGUiOiBmYWxzZSwKICAiZGlzYWJsZV9leHBpcmUiOiBmYWxzZSwKICAiaW5kZXBlbmRlbnRfY2FjaGUiOiBmYWxzZSwKICAicmV2ZXJzZV9tYXBwaW5nIjogZmFsc2UsCiAgImZha2VpcCI6IHt9Cn0="));
|
||||||
dnsHelpDocumentUrl = "https://sing-box.sagernet.org/configuration/dns/";
|
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->direct_dns_strategy->addItems(qsValue);
|
ui->direct_dns_strategy->addItems(qsValue);
|
||||||
ui->remote_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);
|
ui->hide_console->setVisible(false);
|
||||||
#endif
|
#endif
|
||||||
ui->strict_route->setChecked(NekoGui::dataStore->vpn_strict_route);
|
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);
|
ui->single_core->setChecked(NekoGui::dataStore->vpn_internal_tun);
|
||||||
//
|
//
|
||||||
D_LOAD_STRING_PLAIN(vpn_rule_cidr)
|
D_LOAD_STRING_PLAIN(vpn_rule_cidr)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host_l->setVisible(false);
|
ui->host_l->setVisible(false);
|
||||||
}
|
}
|
||||||
// 传输设置 ED
|
// 传输设置 ED
|
||||||
if (txt == "ws" && IS_NEKO_BOX) {
|
if (txt == "ws") {
|
||||||
ui->ws_early_data_length->setVisible(true);
|
ui->ws_early_data_length->setVisible(true);
|
||||||
ui->ws_early_data_length_l->setVisible(true);
|
ui->ws_early_data_length_l->setVisible(true);
|
||||||
ui->ws_early_data_name->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);
|
ui->ws_early_data_name_l->setVisible(false);
|
||||||
}
|
}
|
||||||
// 传输设置 for NekoBox
|
// 传输设置 for NekoBox
|
||||||
if (IS_NEKO_BOX) {
|
if (!ui->utlsFingerprint->count()) ui->utlsFingerprint->addItems(Preset::SingBox::UtlsFingerPrint);
|
||||||
if (!ui->utlsFingerprint->count()) ui->utlsFingerprint->addItems(Preset::SingBox::UtlsFingerPrint);
|
|
||||||
} else {
|
|
||||||
if (!ui->utlsFingerprint->count()) ui->utlsFingerprint->addItems(Preset::Xray::UtlsFingerPrint);
|
|
||||||
}
|
|
||||||
// 传输设置 是否可见
|
// 传输设置 是否可见
|
||||||
int networkBoxVisible = 0;
|
int networkBoxVisible = 0;
|
||||||
for (auto label: ui->network_box->findChildren<QLabel *>()) {
|
for (auto label: ui->network_box->findChildren<QLabel *>()) {
|
||||||
@@ -89,19 +85,13 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
});
|
});
|
||||||
ui->network->removeItem(0);
|
ui->network->removeItem(0);
|
||||||
|
|
||||||
// if (IS_NEKO_BOX) {
|
|
||||||
// ui->network->addItem("httpupgrade");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// security changed
|
// security changed
|
||||||
connect(ui->security, &QComboBox::currentTextChanged, this, [=](const QString &txt) {
|
connect(ui->security, &QComboBox::currentTextChanged, this, [=](const QString &txt) {
|
||||||
if (txt == "tls") {
|
if (txt == "tls") {
|
||||||
ui->security_box->setVisible(true);
|
ui->security_box->setVisible(true);
|
||||||
ui->tls_camouflage_box->setVisible(true);
|
ui->tls_camouflage_box->setVisible(true);
|
||||||
if (IS_NEKO_BOX) {
|
ui->reality_spx->hide();
|
||||||
ui->reality_spx->hide();
|
ui->reality_spx_l->hide();
|
||||||
ui->reality_spx_l->hide();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ui->security_box->setVisible(false);
|
ui->security_box->setVisible(false);
|
||||||
ui->tls_camouflage_box->setVisible(false);
|
ui->tls_camouflage_box->setVisible(false);
|
||||||
@@ -286,47 +276,43 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
ADD_ASTERISK(this)
|
ADD_ASTERISK(this)
|
||||||
|
|
||||||
// 设置 for NekoBox
|
// 设置 for NekoBox
|
||||||
if (IS_NEKO_BOX) {
|
if (type == "vmess" || type == "vless") {
|
||||||
if (type == "vmess" || type == "vless") {
|
ui->packet_encoding->setVisible(true);
|
||||||
ui->packet_encoding->setVisible(true);
|
ui->packet_encoding_l->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);
|
|
||||||
} else {
|
} else {
|
||||||
ui->packet_encoding->setVisible(false);
|
ui->packet_encoding->setVisible(false);
|
||||||
ui->packet_encoding_l->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 之后,有些类型没有右边的设置
|
// 载入 type 之后,有些类型没有右边的设置
|
||||||
auto rightNoBox = (ui->stream_box->isHidden() && ui->network_box->isHidden() && ui->security_box->isHidden());
|
auto rightNoBox = (ui->stream_box->isHidden() && ui->network_box->isHidden() && ui->security_box->isHidden());
|
||||||
|
|||||||
@@ -245,6 +245,11 @@
|
|||||||
<string notr="true">ws</string>
|
<string notr="true">ws</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">httpupgrade</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">http</string>
|
<string notr="true">http</string>
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ void EditQUIC::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
|||||||
ui->heartbeat->hide();
|
ui->heartbeat->hide();
|
||||||
ui->heartbeat_l->hide();
|
ui->heartbeat_l->hide();
|
||||||
ui->uos->hide();
|
ui->uos->hide();
|
||||||
if (!IS_NEKO_BOX) ui->forceExternal->hide();
|
|
||||||
|
|
||||||
if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria) { // hy1
|
if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria) { // hy1
|
||||||
ui->password->hide();
|
ui->password->hide();
|
||||||
@@ -77,13 +76,11 @@ void EditQUIC::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
|||||||
ui->alpn->hide();
|
ui->alpn->hide();
|
||||||
ui->alpn_l->hide();
|
ui->alpn_l->hide();
|
||||||
ui->TLS->removeItem(ui->alpn_sp);
|
ui->TLS->removeItem(ui->alpn_sp);
|
||||||
if (IS_NEKO_BOX) {
|
ui->disableMtuDiscovery->hide();
|
||||||
ui->disableMtuDiscovery->hide();
|
ui->connectionReceiveWindow->hide();
|
||||||
ui->connectionReceiveWindow->hide();
|
ui->connectionReceiveWindow_l->hide();
|
||||||
ui->connectionReceiveWindow_l->hide();
|
ui->streamReceiveWindow->hide();
|
||||||
ui->streamReceiveWindow->hide();
|
ui->streamReceiveWindow_l->hide();
|
||||||
ui->streamReceiveWindow_l->hide();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_TUIC) {
|
} else if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_TUIC) {
|
||||||
ui->hopPort->hide();
|
ui->hopPort->hide();
|
||||||
@@ -107,9 +104,7 @@ void EditQUIC::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
|||||||
ui->streamReceiveWindow_l->hide();
|
ui->streamReceiveWindow_l->hide();
|
||||||
ui->connectionReceiveWindow->hide();
|
ui->connectionReceiveWindow->hide();
|
||||||
ui->connectionReceiveWindow_l->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),
|
EditShadowSocks::EditShadowSocks(QWidget *parent) : QWidget(parent),
|
||||||
ui(new Ui::EditShadowSocks) {
|
ui(new Ui::EditShadowSocks) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->method->addItems(IS_NEKO_BOX ? Preset::SingBox::ShadowsocksMethods : Preset::Xray::ShadowsocksMethods);
|
ui->method->addItems(Preset::SingBox::ShadowsocksMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditShadowSocks::~EditShadowSocks() {
|
EditShadowSocks::~EditShadowSocks() {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void EditTrojanVLESS::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
|||||||
ui->flow_l->hide();
|
ui->flow_l->hide();
|
||||||
}
|
}
|
||||||
ui->password->setText(bean->password);
|
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);
|
ui->flow->setCurrentText(bean->flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,18 +91,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// software_name
|
if (QDir("dashboard").count() == 0) {
|
||||||
if (IS_NEKO_BOX) {
|
QDir().mkdir("dashboard");
|
||||||
software_name = "NekoBox";
|
QFile::copy(":/neko/dashboard-notice.html", "dashboard/index.html");
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// top bar
|
// 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;
|
if (NekoGui::dataStore->core_port <= 0) NekoGui::dataStore->core_port = 19810;
|
||||||
|
|
||||||
auto core_path = QApplication::applicationDirPath() + "/";
|
auto core_path = QApplication::applicationDirPath() + "/";
|
||||||
core_path += IS_NEKO_BOX ? "nekobox_core" : "nekoray_core";
|
core_path += "nekobox_core";
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args.push_back(IS_NEKO_BOX ? "nekobox" : "nekoray");
|
args.push_back("nekobox");
|
||||||
args.push_back("-port");
|
args.push_back("-port");
|
||||||
args.push_back(Int2String(NekoGui::dataStore->core_port));
|
args.push_back(Int2String(NekoGui::dataStore->core_port));
|
||||||
if (NekoGui::dataStore->flag_debug) args.push_back("-debug");
|
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) {
|
void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||||
if (enable != NekoGui::dataStore->spmode_system_proxy) {
|
if (enable != NekoGui::dataStore->spmode_system_proxy) {
|
||||||
if (enable) {
|
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 socks_port = NekoGui::dataStore->inbound_socks_port;
|
||||||
auto http_port = NekoGui::dataStore->inbound_http_port;
|
auto http_port = NekoGui::dataStore->inbound_socks_port;
|
||||||
if (IS_NEKO_BOX) http_port = socks_port;
|
|
||||||
SetSystemProxy(http_port, socks_port);
|
SetSystemProxy(http_port, socks_port);
|
||||||
} else {
|
} else {
|
||||||
ClearSystemProxy();
|
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) {
|
void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
||||||
if (enable != NekoGui::dataStore->spmode_vpn) {
|
if (enable != NekoGui::dataStore->spmode_vpn) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
if (NekoGui::dataStore->vpn_internal_tun) {
|
||||||
bool requestPermission = !NekoGui::IsAdmin();
|
bool requestPermission = !NekoGui::IsAdmin();
|
||||||
if (requestPermission) {
|
if (requestPermission) {
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
@@ -799,7 +778,7 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
if (NekoGui::dataStore->vpn_internal_tun) {
|
||||||
// current core is sing-box
|
// current core is sing-box
|
||||||
} else {
|
} else {
|
||||||
if (!StopVPNProcess()) {
|
if (!StopVPNProcess()) {
|
||||||
@@ -820,7 +799,7 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
|||||||
NekoGui::dataStore->spmode_vpn = enable;
|
NekoGui::dataStore->spmode_vpn = enable;
|
||||||
refresh_status();
|
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) {
|
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);
|
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 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);
|
auto inbound_txt = QString("Mixed: %1").arg(display_socks);
|
||||||
if (IS_NEKO_BOX) inbound_txt = QString("Mixed: %1").arg(display_socks);
|
|
||||||
ui->label_inbound->setText(inbound_txt);
|
ui->label_inbound->setText(inbound_txt);
|
||||||
//
|
//
|
||||||
ui->checkBox_VPN->setChecked(NekoGui::dataStore->spmode_vpn);
|
ui->checkBox_VPN->setChecked(NekoGui::dataStore->spmode_vpn);
|
||||||
|
|||||||
Reference in New Issue
Block a user