diff --git a/fmt/Bean2CoreObj_box.cpp b/fmt/Bean2CoreObj_box.cpp index 4c631a8..13f3215 100644 --- a/fmt/Bean2CoreObj_box.cpp +++ b/fmt/Bean2CoreObj_box.cpp @@ -202,7 +202,7 @@ namespace NekoGui_fmt { if (authPayloadType == hysteria_auth_string) outbound["auth_str"] = authPayload; } else if (proxy_type == proxy_Hysteria2) { outbound["type"] = "hysteria2"; - outbound["password"] = authPayload; + outbound["password"] = password; outbound["up_mbps"] = uploadMbps; outbound["down_mbps"] = downloadMbps; if (!obfsPassword.isEmpty()) { diff --git a/fmt/Bean2External.cpp b/fmt/Bean2External.cpp index 411f7c7..14daea6 100644 --- a/fmt/Bean2External.cpp +++ b/fmt/Bean2External.cpp @@ -198,11 +198,7 @@ namespace NekoGui_fmt { {"listen", "127.0.0.1:" + Int2String(socks_port)}, {"disableUDP", false}, }; - if (username.isEmpty()) { - config["auth"] = authPayload; - } else { - config["auth"] = username + ":" + authPayload; - } + config["auth"] = password; QJsonObject bandwidth; if (uploadMbps > 0) bandwidth["up"] = Int2String(uploadMbps) + " mbps"; diff --git a/fmt/Bean2Link.cpp b/fmt/Bean2Link.cpp index 5426767..f8a73d0 100644 --- a/fmt/Bean2Link.cpp +++ b/fmt/Bean2Link.cpp @@ -214,6 +214,26 @@ namespace NekoGui_fmt { if (disableSni) q.addQueryItem("disable_sni", "1"); if (!q.isEmpty()) url.setQuery(q); if (!name.isEmpty()) url.setFragment(name); + } else if (proxy_type == proxy_Hysteria2) { + url.setScheme("hy2"); + url.setHost(serverAddress); + url.setPort(serverPort); + if (password.contains(":")) { + url.setUserName(SubStrBefore(password, ":")); + url.setPassword(SubStrAfter(password, ":")); + } else { + url.setUserName(password); + } + QUrlQuery q; + if (!obfsPassword.isEmpty()) { + q.addQueryItem("obfs", "salamander"); + q.addQueryItem("obfs-password", obfsPassword); + } + // if (!hopPort.trimmed().isEmpty()) q.addQueryItem("mport", hopPort); + if (allowInsecure) q.addQueryItem("insecure", "1"); + if (!sni.isEmpty()) q.addQueryItem("sni", sni); + if (!q.isEmpty()) url.setQuery(q); + if (!name.isEmpty()) url.setFragment(name); } return url.toString(QUrl::FullyEncoded); } diff --git a/fmt/Link2Bean.cpp b/fmt/Link2Bean.cpp index 2141c85..bdff875 100644 --- a/fmt/Link2Bean.cpp +++ b/fmt/Link2Bean.cpp @@ -233,10 +233,9 @@ namespace NekoGui_fmt { name = url.fragment(); serverAddress = url.host(); serverPort = url.port(); - serverAddress = url.host(); // default sni hopPort = query.queryItemValue("mport"); obfsPassword = query.queryItemValue("obfsParam"); - allowInsecure = query.queryItemValue("insecure") == "1"; + allowInsecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure")); uploadMbps = query.queryItemValue("upmbps").toInt(); downloadMbps = query.queryItemValue("downmbps").toInt(); @@ -275,6 +274,21 @@ namespace NekoGui_fmt { udpRelayMode = query.queryItemValue("udp_relay_mode"); allowInsecure = query.queryItemValue("allow_insecure") == "1"; disableSni = query.queryItemValue("disable_sni") == "1"; + } else if (QStringList{"hy2", "hysteria2"}.contains(url.scheme())) { + name = url.fragment(); + serverAddress = url.host(); + serverPort = url.port(); + // hopPort = query.queryItemValue("mport"); + obfsPassword = query.queryItemValue("obfs-password"); + allowInsecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure")); + + if (url.password().isEmpty()) { + password = url.userName(); + } else { + password = url.userName() + ":" + url.password(); + } + + sni = query.queryItemValue("sni"); } return true; diff --git a/fmt/QUICBean.hpp b/fmt/QUICBean.hpp index 405ee04..b4650ed 100644 --- a/fmt/QUICBean.hpp +++ b/fmt/QUICBean.hpp @@ -12,7 +12,7 @@ namespace NekoGui_fmt { bool forceExternal = false; - // Hysteria + // Hysteria 1 static constexpr int hysteria_protocol_udp = 0; static constexpr int hysteria_protocol_facktcp = 1; @@ -23,8 +23,10 @@ namespace NekoGui_fmt { static constexpr int hysteria_auth_string = 1; static constexpr int hysteria_auth_base64 = 2; int authPayloadType = 0; - QString authPayload = ""; + + // Hysteria 1&2 + QString obfsPassword = ""; int uploadMbps = 100; @@ -37,19 +39,19 @@ namespace NekoGui_fmt { int hopInterval = 10; QString hopPort = ""; - // Hysteria 2 (Something same as hy1) - QString username = ""; - // TUIC QString uuid = ""; - QString password = ""; QString congestionControl = "bbr"; QString udpRelayMode = "native"; bool zeroRttHandshake = false; QString heartbeat = "10s"; bool uos = false; + // HY2&TUIC + + QString password = ""; + // TLS bool allowInsecure = false; @@ -76,9 +78,8 @@ namespace NekoGui_fmt { } else { // hy2 uploadMbps = 0; downloadMbps = 0; - _add(new configItem("username", &username, itemType::string)); + _add(new configItem("password", &password, itemType::string)); } - } else if (proxy_type == proxy_TUIC) { _add(new configItem("uuid", &uuid, itemType::string)); _add(new configItem("password", &password, itemType::string)); @@ -114,7 +115,15 @@ namespace NekoGui_fmt { } } - QString DisplayType() override { return proxy_type == proxy_TUIC ? "TUIC" : "Hysteria"; }; + QString DisplayType() override { + if (proxy_type == proxy_TUIC) { + return "TUIC"; + } else if (proxy_type == proxy_Hysteria) { + return "Hysteria1"; + } else { + return "Hysteria2"; + } + }; int NeedExternal(bool isFirstProfile) override; diff --git a/sub/GroupUpdater.cpp b/sub/GroupUpdater.cpp index d5853d8..5de4047 100644 --- a/sub/GroupUpdater.cpp +++ b/sub/GroupUpdater.cpp @@ -124,7 +124,7 @@ namespace NekoGui_sub { if (!ok) return; } - // Hysteria + // Hysteria1 if (str.startsWith("hysteria://")) { needFix = false; ent = NekoGui::ProfileManager::NewProxyEntity("hysteria"); @@ -132,6 +132,14 @@ namespace NekoGui_sub { if (!ok) return; } + // Hysteria2 + if (str.startsWith("hysteria2://") || str.startsWith("hy2://")) { + needFix = false; + ent = NekoGui::ProfileManager::NewProxyEntity("hysteria2"); + auto ok = ent->QUICBean()->TryParseLink(str); + if (!ok) return; + } + // TUIC if (str.startsWith("tuic://")) { needFix = false; diff --git a/translations/fa_IR.ts b/translations/fa_IR.ts index 3f36bad..f69dc07 100644 --- a/translations/fa_IR.ts +++ b/translations/fa_IR.ts @@ -972,10 +972,6 @@ This needs to be run NekoBox with administrator privileges. UDP Relay Mode - - Username - نام کاربری - Force use external core diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index c849559..9703972 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -979,10 +979,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun UDP Relay Mode Режим UDP Relay - - Username - Имя пользователя - Force use external core diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 98404dc..3417563 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -980,10 +980,6 @@ This needs to be run NekoBox with administrator privileges. Disable SNI 不发送服务器名称指示 - - Username - 用户名 - Force use external core 强制使用外部核心 diff --git a/ui/edit/dialog_edit_profile.cpp b/ui/edit/dialog_edit_profile.cpp index 65d9c71..4eb524f 100644 --- a/ui/edit/dialog_edit_profile.cpp +++ b/ui/edit/dialog_edit_profile.cpp @@ -120,8 +120,8 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId, LOAD_TYPE("vmess") LOAD_TYPE("vless") LOAD_TYPE("naive") - ui->type->addItem("Hysteria1", "hysteria"); - ui->type->addItem("Hysteria2", "hysteria2"); + LOAD_TYPE("hysteria") + LOAD_TYPE("hysteria2") LOAD_TYPE("tuic") ui->type->addItem(tr("Custom (%1 outbound)").arg(software_core_name), "internal"); ui->type->addItem(tr("Custom (%1 config)").arg(software_core_name), "internal-full"); diff --git a/ui/edit/edit_quic.cpp b/ui/edit/edit_quic.cpp index b5d74d5..879af8f 100644 --- a/ui/edit/edit_quic.cpp +++ b/ui/edit/edit_quic.cpp @@ -19,23 +19,39 @@ void EditQUIC::onStart(std::shared_ptr _ent) { this->ent = _ent; auto bean = this->ent->QUICBean(); - if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria || bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria2) { - P_LOAD_STRING(hopPort); - P_LOAD_INT(hopInterval); - P_LOAD_INT(uploadMbps); - P_LOAD_INT(downloadMbps); - P_LOAD_BOOL(disableMtuDiscovery) - P_LOAD_STRING(obfsPassword); - P_LOAD_STRING(authPayload); - P_LOAD_INT(streamReceiveWindow); - P_LOAD_INT(connectionReceiveWindow); - P_LOAD_BOOL(forceExternal); + P_LOAD_STRING(hopPort); + P_LOAD_INT(hopInterval); + P_LOAD_INT(uploadMbps); + P_LOAD_INT(downloadMbps); + P_LOAD_BOOL(disableMtuDiscovery) + P_LOAD_STRING(obfsPassword); + P_LOAD_STRING(authPayload); + P_LOAD_INT(streamReceiveWindow); + P_LOAD_INT(connectionReceiveWindow); + P_LOAD_BOOL(forceExternal); + P_LOAD_COMBO_INT(hyProtocol); + P_LOAD_COMBO_INT(authPayloadType); + P_LOAD_STRING(uuid); + P_LOAD_STRING(password); + + P_LOAD_COMBO_STRING(congestionControl); + P_LOAD_COMBO_STRING(udpRelayMode); + P_LOAD_BOOL(zeroRttHandshake); + P_LOAD_STRING(heartbeat); + P_LOAD_BOOL(uos); + + // TLS + P_LOAD_STRING(sni); + P_LOAD_STRING(alpn); + P_C_LOAD_STRING(caText); + P_LOAD_BOOL(allowInsecure); + P_LOAD_BOOL(disableSni); + + if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria || bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria2) { ui->uuid->hide(); ui->uuid_l->hide(); ui->uuidgen->hide(); - ui->password->hide(); - ui->password_l->hide(); ui->congestionControl->hide(); ui->congestionControl_l->hide(); ui->udpRelayMode->hide(); @@ -47,14 +63,9 @@ void EditQUIC::onStart(std::shared_ptr _ent) { if (!IS_NEKO_BOX) ui->forceExternal->hide(); if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_Hysteria) { // hy1 - P_LOAD_COMBO_INT(hyProtocol); - P_LOAD_COMBO_INT(authPayloadType); - - ui->username_l->hide(); - ui->username->hide(); + ui->password->hide(); + ui->password_l->hide(); } else { // hy2 - P_LOAD_STRING(username); - ui->hyProtocol->hide(); ui->hyProtocol_l->hide(); ui->hyProtocol->hide(); @@ -79,14 +90,6 @@ void EditQUIC::onStart(std::shared_ptr _ent) { } } } else if (bean->proxy_type == NekoGui_fmt::QUICBean::proxy_TUIC) { - P_LOAD_STRING(uuid); - P_LOAD_STRING(password); - P_LOAD_COMBO_STRING(congestionControl); - P_LOAD_COMBO_STRING(udpRelayMode); - P_LOAD_BOOL(zeroRttHandshake); - P_LOAD_STRING(heartbeat); - P_LOAD_BOOL(uos); - ui->hopPort->hide(); ui->hopPort_l->hide(); ui->hopInterval->hide(); @@ -112,13 +115,6 @@ void EditQUIC::onStart(std::shared_ptr _ent) { ui->uos->hide(); } } - - // TLS - P_LOAD_STRING(sni); - P_LOAD_STRING(alpn); - P_C_LOAD_STRING(caText); - P_LOAD_BOOL(allowInsecure); - P_LOAD_BOOL(disableSni); } bool EditQUIC::onEnd() { @@ -139,9 +135,6 @@ bool EditQUIC::onEnd() { P_SAVE_INT(streamReceiveWindow); P_SAVE_INT(connectionReceiveWindow); - // Hysteria2 - P_SAVE_STRING(username); - // TUIC P_SAVE_STRING(uuid); P_SAVE_STRING(password); diff --git a/ui/edit/edit_quic.ui b/ui/edit/edit_quic.ui index 2e3e913..385beea 100644 --- a/ui/edit/edit_quic.ui +++ b/ui/edit/edit_quic.ui @@ -176,16 +176,20 @@ - - - - + Obfs Password + + + + Protocol + + + @@ -222,22 +226,8 @@ - - - - Protocol - - - - - - - Username - - - - + @@ -262,7 +252,7 @@ - + 0 0 @@ -275,7 +265,7 @@ - + 0 0 @@ -287,12 +277,6 @@ - - - 0 - 0 - - UUID @@ -446,7 +430,6 @@ uos hyProtocol disableMtuDiscovery - username obfsPassword authPayloadType authPayload