update to clash meta format

This commit is contained in:
arm64v8a
2023-04-18 15:53:41 +09:00
parent 990f1006d1
commit 572c415a23
3 changed files with 79 additions and 3 deletions

View File

@@ -93,7 +93,7 @@ namespace NekoRay {
QString splitter_state = ""; QString splitter_state = "";
// Subscription // Subscription
QString user_agent = "Nekoray/1.0 (Prefer Clash Format)"; QString user_agent = ""; // set at main.cpp
bool sub_use_proxy = false; bool sub_use_proxy = false;
bool sub_clear = false; bool sub_clear = false;
bool sub_insecure = false; bool sub_insecure = false;

View File

@@ -244,6 +244,16 @@ int main(int argc, char* argv[]) {
MW_dialog_message("", "Raise"); MW_dialog_message("", "Raise");
}); });
// Do preset update
if (NekoRay::dataStore->user_agent.isEmpty() || NekoRay::dataStore->user_agent.startsWith("Nekoray/1.0") || NekoRay::dataStore->user_agent.startsWith("ClashForAndroid")) {
if (IS_NEKO_BOX) {
NekoRay::dataStore->user_agent = "NekoBox/PC/2.0 (Prefer ClashMeta Format)";
} else {
NekoRay::dataStore->user_agent = "NekoRay/PC/2.0 (Prefer ClashMeta Format)";
}
NekoRay::dataStore->Save();
}
UI_InitMainWindow(); UI_InitMainWindow();
return QApplication::exec(); return QApplication::exec();
} }

View File

@@ -175,6 +175,23 @@ namespace NekoRay::sub {
} }
} }
QStringList Node2QStringList(const YAML::Node &n) {
try {
if (n.IsSequence()) {
QStringList list;
for (auto item: n) {
list << item.as<std::string>().c_str();
}
return list;
} else {
return {};
}
} catch (const YAML::Exception &ex) {
qDebug() << ex.what();
return {};
}
}
int Node2Int(const YAML::Node &n, const int &def = 0) { int Node2Int(const YAML::Node &n, const int &def = 0) {
try { try {
return n.as<int>(); return n.as<int>();
@@ -188,6 +205,11 @@ namespace NekoRay::sub {
try { try {
return n.as<bool>(); return n.as<bool>();
} catch (const YAML::Exception &ex) { } catch (const YAML::Exception &ex) {
try {
return n.as<int>();
} catch (const YAML::Exception &ex2) {
ex2.what();
}
qDebug() << ex.what(); qDebug() << ex.what();
return def; return def;
} }
@@ -211,8 +233,11 @@ namespace NekoRay::sub {
auto proxies = YAML::Load(str.toStdString())["proxies"]; auto proxies = YAML::Load(str.toStdString())["proxies"];
for (auto proxy: proxies) { for (auto proxy: proxies) {
auto type = Node2QString(proxy["type"]); auto type = Node2QString(proxy["type"]);
auto type_clash = type;
if (type == "ss" || type == "ssr") type = "shadowsocks"; if (type == "ss" || type == "ssr") type = "shadowsocks";
if (type == "socks5") type = "socks"; if (type == "socks5") type = "socks";
if (type == "hysteria") type = "custom";
auto ent = ProfileManager::NewProxyEntity(type); auto ent = ProfileManager::NewProxyEntity(type);
if (ent->bean->version == -114514) continue; if (ent->bean->version == -114514) continue;
@@ -261,14 +286,20 @@ namespace NekoRay::sub {
bean->password = Node2QString(proxy["password"]); bean->password = Node2QString(proxy["password"]);
if (Node2Bool(proxy["tls"])) bean->stream->security = "tls"; if (Node2Bool(proxy["tls"])) bean->stream->security = "tls";
if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true; if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true;
} else if (type == "trojan") { } else if (type == "trojan" || type == "vless") {
needFix = true; needFix = true;
auto bean = ent->TrojanVLESSBean(); auto bean = ent->TrojanVLESSBean();
if (type == "vless") {
bean->flow = Node2QString(proxy["flow"]);
bean->password = Node2QString(proxy["uuid"]);
} else {
bean->password = Node2QString(proxy["password"]); bean->password = Node2QString(proxy["password"]);
}
bean->stream->security = "tls"; bean->stream->security = "tls";
bean->stream->network = Node2QString(proxy["network"], "tcp"); bean->stream->network = Node2QString(proxy["network"], "tcp");
bean->stream->sni = FIRST_OR_SECOND(Node2QString(proxy["sni"]), Node2QString(proxy["servername"])); bean->stream->sni = FIRST_OR_SECOND(Node2QString(proxy["sni"]), Node2QString(proxy["servername"]));
if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true; if (Node2Bool(proxy["skip-cert-verify"])) bean->stream->allow_insecure = true;
if (IS_NEKO_BOX) bean->stream->utlsFingerprint = Node2QString(proxy["client-fingerprint"]);
// opts // opts
auto ws = NodeChild(proxy, {"ws-opts", "ws-opt"}); auto ws = NodeChild(proxy, {"ws-opts", "ws-opt"});
@@ -286,6 +317,12 @@ namespace NekoRay::sub {
if (grpc.IsMap()) { if (grpc.IsMap()) {
bean->stream->path = Node2QString(grpc["grpc-service-name"]); bean->stream->path = Node2QString(grpc["grpc-service-name"]);
} }
auto reality = NodeChild(proxy, {"reality-opts"});
if (reality.IsMap()) {
bean->stream->reality_pbk = Node2QString(reality["public-key"]);
bean->stream->reality_sid = Node2QString(reality["short-id"]);
}
} else if (type == "vmess") { } else if (type == "vmess") {
needFix = true; needFix = true;
auto bean = ent->VMessBean(); auto bean = ent->VMessBean();
@@ -341,6 +378,35 @@ namespace NekoRay::sub {
break; break;
} }
} }
} else if (type_clash == "hysteria") {
if (!IS_NEKO_BOX) {
MW_show_log("Found Clash Meta format hysteria. This is only supported in NekoBox, please switch the core.");
continue;
}
auto bean = ent->CustomBean();
bean->core = "internal";
QJsonObject coreTlsObj{
{"enabled", true},
{"insecure", Node2Bool(proxy["skip-cert-verify"])},
{"alpn", QList2QJsonArray(Node2QStringList(proxy["alpn"]))},
{"server_name", Node2QString(proxy["sni"])},
};
QJsonObject coreHysteriaObj{
{"type", "hysteria"},
{"tag", Node2QString(proxy["name"])},
{"server", Node2QString(proxy["server"])},
{"server_port", Node2Int(proxy["port"])},
{"auth_str", Node2QString(proxy["auth_str"])},
{"up_mbps", Node2Int(proxy["up"])},
{"down_mbps", Node2Int(proxy["down"])},
{"disable_mtu_discovery", Node2Bool(proxy["disable_mtu_discovery"])},
{"tls", coreTlsObj},
};
bean->config_simple = QJsonObject2QString(coreHysteriaObj, false);
} else { } else {
continue; continue;
} }