From 1c050cc75493611eff482c8aa9d190641fe9c0d9 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Thu, 1 Apr 2021 15:37:04 +0800
Subject: [PATCH 01/33] do not enable util plugins
---
CMakeLists.txt | 2 +-
makespec/BUILDVERSION | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aee903df0..a0f4dc51d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -337,7 +337,7 @@ target_include_directories(qv2ray_baselib PUBLIC
if(QV2RAY_HAS_BUILTIN_PLUGINS)
include(src/plugins/protocols/QvPlugin-BuiltinProtocolSupport.cmake)
include(src/plugins/subscription-adapters/QvPlugin-BuiltinSubscriptionAdapters.cmake)
- include(src/plugins/utils/QvPlugin-BuiltinUtils.cmake)
+ #include(src/plugins/utils/QvPlugin-BuiltinUtils.cmake)
endif()
# ==================================================================================
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 49fb0cd8f..af150f516 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6178
+6179
From 5238c21447837318eef4319eac55f823c53cb8ee Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Fri, 2 Apr 2021 18:08:25 +0800
Subject: [PATCH 02/33] New Crowdin updates (#1391)
---
translations/ja_JP.ts | 79 ++++++++++++++++++++++++++++++-------------
translations/yue.ts | 79 ++++++++++++++++++++++++++++++-------------
translations/zh_CN.ts | 79 ++++++++++++++++++++++++++++++-------------
translations/zh_TW.ts | 79 ++++++++++++++++++++++++++++++-------------
4 files changed, 220 insertions(+), 96 deletions(-)
diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts
index 1e5e8f440..e26ff2ccb 100644
--- a/translations/ja_JP.ts
+++ b/translations/ja_JP.ts
@@ -1223,14 +1223,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Plugin does not have settings widget.
プラグインには設定ウィジェットがありません。
-
- Disabling a plugin
- プラグインを無効にする
-
-
- This plugin will keep loaded until the next time Qv2ray starts.
- このプラグインは、次回Qv2rayが起動するまでロードされたままになります。
-
Plugin not loaded
プラグインがロードされていない
@@ -2576,22 +2568,6 @@ Maybe you have downloaded the wrong core?
Route Editor
ルートエディター
-
- Add outbound
- アウトバウンドを追加
-
-
- Add default inbound from global config
- グローバル設定からデフォルトのインバウンドを追加
-
-
- Add blackhole outbound
- ブラックホールアウトバウンドを追加
-
-
- Add Freedom outbound
- フリーアウトバウンドを追加
-
Protocol
プロトコル
@@ -2736,6 +2712,54 @@ Maybe you have downloaded the wrong core?
(All Connections)
(すべての接続)
+
+ Add Inbound
+ インバウンドを追加
+
+
+ Add Inbound from Global Settings
+ グローバル設定からインバウンドを追加
+
+
+ Import Outbound
+ アウトバウンドをインポート
+
+
+ Add Outbound
+ アウトバウンドを追加
+
+
+ Add Blackhole Outbound
+ ブラックホールアウトバウンドを追加
+
+
+ Add Freedom Outbound
+ 自由のアウトバウンドを追加
+
+
+ Add Balancer
+ バランサーを追加
+
+
+ Add Proxy Chain
+ プロキシチェーンを追加
+
+
+ Group
+ グループ
+
+
+ Connection
+ 接続
+
+
+ Copy Connection
+ 接続をコピー
+
+
+ Reference Connection
+ 参照接続
+
RouteSettingsMatrix
@@ -3739,4 +3763,11 @@ Maybe you have downloaded the wrong core?
受信タグ
+
+ MainWindowWidget
+
+ Qv2ray Utilities
+ Qv2ray ユーティリティ
+
+
diff --git a/translations/yue.ts b/translations/yue.ts
index f5ed15f28..27e4db62b 100644
--- a/translations/yue.ts
+++ b/translations/yue.ts
@@ -1234,14 +1234,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Plugin does not have settings widget.
Plugin does not have settings widget.
-
- Disabling a plugin
- Disabling a plugin
-
-
- This plugin will keep loaded until the next time Qv2ray starts.
- This plugin will keep loaded until the next time Qv2ray starts.
-
Plugin not loaded
Plugin not loaded
@@ -2593,22 +2585,6 @@ Maybe you have downloaded the wrong core?
Route Editor
Route Editor
-
- Add outbound
- Add outbound
-
-
- Add default inbound from global config
- Add default inbound from global config
-
-
- Add blackhole outbound
- Add blackhole outbound
-
-
- Add Freedom outbound
- Add Freedom outbound
-
Protocol
协定
@@ -2753,6 +2729,54 @@ Maybe you have downloaded the wrong core?
(All Connections)
(All Connections)
+
+ Add Inbound
+ Add Inbound
+
+
+ Add Inbound from Global Settings
+ Add Inbound from Global Settings
+
+
+ Import Outbound
+ Import Outbound
+
+
+ Add Outbound
+ Add Outbound
+
+
+ Add Blackhole Outbound
+ Add Blackhole Outbound
+
+
+ Add Freedom Outbound
+ Add Freedom Outbound
+
+
+ Add Balancer
+ Add Balancer
+
+
+ Add Proxy Chain
+ Add Proxy Chain
+
+
+ Group
+ 分组
+
+
+ Connection
+ Connection
+
+
+ Copy Connection
+ Copy Connection
+
+
+ Reference Connection
+ Reference Connection
+
RouteSettingsMatrix
@@ -3756,4 +3780,11 @@ Maybe you have downloaded the wrong core?
Inbound Tag
+
+ MainWindowWidget
+
+ Qv2ray Utilities
+ Qv2ray Utilities
+
+
diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts
index 83d33e5b2..f39324d17 100644
--- a/translations/zh_CN.ts
+++ b/translations/zh_CN.ts
@@ -1223,14 +1223,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Plugin does not have settings widget.
插件无设置组件。
-
- Disabling a plugin
- 禁用插件
-
-
- This plugin will keep loaded until the next time Qv2ray starts.
- 重启前插件会保持活动。
-
Plugin not loaded
插件未加载
@@ -2576,22 +2568,6 @@ Maybe you have downloaded the wrong core?
Route Editor
路由编辑器
-
- Add outbound
- 添加出站
-
-
- Add default inbound from global config
- 从全局配置中添加默认的入站设置
-
-
- Add blackhole outbound
- 添加黑洞出站
-
-
- Add Freedom outbound
- 添加自由出站
-
Protocol
协议
@@ -2736,6 +2712,54 @@ Maybe you have downloaded the wrong core?
(All Connections)
(所有连接)
+
+ Add Inbound
+ 添加入站
+
+
+ Add Inbound from Global Settings
+ 从全局设置中添加输入
+
+
+ Import Outbound
+ 导出导出
+
+
+ Add Outbound
+ 添加出站
+
+
+ Add Blackhole Outbound
+ 添加黑洞出站
+
+
+ Add Freedom Outbound
+ 添加自由出站
+
+
+ Add Balancer
+ 添加平衡器
+
+
+ Add Proxy Chain
+ 添加代理链接
+
+
+ Group
+ 分组
+
+
+ Connection
+ 连接
+
+
+ Copy Connection
+ 复制连接
+
+
+ Reference Connection
+ 引用连接
+
RouteSettingsMatrix
@@ -3739,4 +3763,11 @@ Maybe you have downloaded the wrong core?
入站标签
+
+ MainWindowWidget
+
+ Qv2ray Utilities
+ Qv2ray 工具
+
+
diff --git a/translations/zh_TW.ts b/translations/zh_TW.ts
index 9de92dd72..7c36be160 100644
--- a/translations/zh_TW.ts
+++ b/translations/zh_TW.ts
@@ -1217,14 +1217,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Plugin does not have settings widget.
該外掛程式不包含設定 Widget。
-
- Disabling a plugin
- 禁用外掛程式
-
-
- This plugin will keep loaded until the next time Qv2ray starts.
- 重啟前外掛程式會保持活動。
-
Plugin not loaded
外掛程式未載入
@@ -2570,22 +2562,6 @@ Maybe you have downloaded the wrong core?
Route Editor
路由編輯器
-
- Add outbound
- 添加出站
-
-
- Add default inbound from global config
- 從全域配置中添加預設的入站設置
-
-
- Add blackhole outbound
- 添加黑洞出站
-
-
- Add Freedom outbound
- 添加自由出站
-
Protocol
協定
@@ -2730,6 +2706,54 @@ Maybe you have downloaded the wrong core?
(All Connections)
(All Connections)
+
+ Add Inbound
+ Add Inbound
+
+
+ Add Inbound from Global Settings
+ Add Inbound from Global Settings
+
+
+ Import Outbound
+ Import Outbound
+
+
+ Add Outbound
+ Add Outbound
+
+
+ Add Blackhole Outbound
+ Add Blackhole Outbound
+
+
+ Add Freedom Outbound
+ Add Freedom Outbound
+
+
+ Add Balancer
+ Add Balancer
+
+
+ Add Proxy Chain
+ Add Proxy Chain
+
+
+ Group
+ 分組
+
+
+ Connection
+ Connection
+
+
+ Copy Connection
+ Copy Connection
+
+
+ Reference Connection
+ Reference Connection
+
RouteSettingsMatrix
@@ -3733,4 +3757,11 @@ Maybe you have downloaded the wrong core?
Inbound Tag
+
+ MainWindowWidget
+
+ Qv2ray Utilities
+ Qv2ray Utilities
+
+
From c64a8e49ac7b6d38a8c1169ae26d367104f040bb Mon Sep 17 00:00:00 2001
From: ymshenyu
Date: Wed, 7 Apr 2021 16:21:26 +0800
Subject: [PATCH 03/33] Revert c2d60a9fc2d60a9f Closes #1396
---
snap/snapcraft.yaml | 64 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 5f4c6322c..3ea4f7eeb 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -134,3 +134,67 @@ parts:
- qt5-gtk-platformtheme
after:
- ppa
+
+ qv2ray-trojan-plugin:
+ plugin: cmake
+ source-type: git
+ source: https://github.com/Qv2ray/QvPlugin-Trojan.git
+ source-branch: dev
+ build-packages:
+ - build-essential
+ - libboost-system-dev
+ - libboost-program-options-dev
+ - libssl-dev
+ - qttools5-dev
+ - qt5-default
+ stage-packages:
+ - libgcc1
+ - libstdc++6
+ - libssl1.1
+ - libqt5core5a
+ - libqt5gui5
+ - libqt5network5
+ - libqt5widgets5
+ - libboost-program-options1.71.0
+ - libboost-system1.71.0
+ cmake-parameters:
+ - -DCMAKE_INSTALL_PREFIX=/usr
+ - -DCMAKE_BUILD_TYPE=Release
+ - -DFORCE_TCP_FASTOPEN=ON
+ cmake-generator: Ninja
+ after:
+ - desktop-qt5
+
+ qv2ray-ssr-plugin:
+ plugin: cmake
+ source-type: git
+ source: https://github.com/Qv2ray/QvPlugin-SSR.git
+ source-branch: dev
+ build-packages:
+ - build-essential
+ - libsodium-dev
+ - libuv1-dev
+ - libssl-dev
+ - qttools5-dev
+ - qt5-default
+ stage-packages:
+ - libgcc1
+ - libstdc++6
+ - libssl1.1
+ - libqt5core5a
+ - libqt5gui5
+ - libqt5network5
+ - libqt5widgets5
+ - libuv1
+ - libsodium23
+ cmake-parameters:
+ - -DCMAKE_INSTALL_PREFIX=/usr
+ - -DCMAKE_BUILD_TYPE=Release
+ - -DSSR_UVW_WITH_QT=ON
+ - -DUSE_SYSTEM_SODIUM=ON
+ - -DUSE_SYSTEM_LIBUV=ON
+ - -DSTATIC_LINK_LIBUV=OFF
+ - -DSTATIC_LINK_SODIUM=OFF
+ cmake-generator: Ninja
+ after:
+ - desktop-qt5
\ No newline at end of file
From 922c7d825f882c699ca45a1a794324b8f80c2590 Mon Sep 17 00:00:00 2001
From: ymshenyu
Date: Wed, 7 Apr 2021 21:02:31 +0800
Subject: [PATCH 04/33] update snapcraft.yaml
---
snap/snapcraft.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 3ea4f7eeb..82f2c47af 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -165,7 +165,7 @@ parts:
after:
- desktop-qt5
- qv2ray-ssr-plugin:
+ qv2ray-ssr-plugin:
plugin: cmake
source-type: git
source: https://github.com/Qv2ray/QvPlugin-SSR.git
@@ -197,4 +197,4 @@ parts:
- -DSTATIC_LINK_SODIUM=OFF
cmake-generator: Ninja
after:
- - desktop-qt5
\ No newline at end of file
+ - desktop-qt5
From fb62c4a39e5cc28a89da1700b62da5e0c10299fb Mon Sep 17 00:00:00 2001
From: ymshenyu
Date: Wed, 7 Apr 2021 21:02:31 +0800
Subject: [PATCH 05/33] update snapcraft.yaml
---
snap/snapcraft.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 82f2c47af..6ad90502d 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -146,7 +146,7 @@ parts:
- libboost-program-options-dev
- libssl-dev
- qttools5-dev
- - qt5-default
+ - qtbase5-dev
stage-packages:
- libgcc1
- libstdc++6
@@ -176,7 +176,7 @@ parts:
- libuv1-dev
- libssl-dev
- qttools5-dev
- - qt5-default
+ - qtbase5-dev
stage-packages:
- libgcc1
- libstdc++6
From f66180ad376489c0b941cc1eac31033629742705 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 12 Apr 2021 21:43:55 +0800
Subject: [PATCH 06/33] adapt v2ray 4.37 new dns options
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 4 +-
src/ui/widgets/widgets/DnsSettingsWidget.cpp | 13 +++++
src/ui/widgets/widgets/DnsSettingsWidget.hpp | 4 ++
src/ui/widgets/widgets/DnsSettingsWidget.ui | 56 +++++++++++++++++---
translations/en_US.ts | 20 +++++--
6 files changed, 85 insertions(+), 14 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index af150f516..a1c8982c1 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6179
+6180
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index 4a1b403ee..b1a002c28 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -67,6 +67,8 @@ namespace Qv2ray::base::objects
QString clientIp;
QString tag;
bool disableCache = false;
+ bool disableFallback = false;
+ QString queryStrategy = "";
friend bool operator==(const DNSObject &left, const DNSObject &right)
{
return left.hosts == right.hosts && //
@@ -79,7 +81,7 @@ namespace Qv2ray::base::objects
{
return !(left == right);
}
- JSONSTRUCT_REGISTER(DNSObject, F(hosts, servers, clientIp, tag, disableCache))
+ JSONSTRUCT_REGISTER(DNSObject, F(hosts, servers, clientIp, tag, disableCache, disableFallback, queryStrategy))
};
//
// Used in config generation
diff --git a/src/ui/widgets/widgets/DnsSettingsWidget.cpp b/src/ui/widgets/widgets/DnsSettingsWidget.cpp
index 52f819d53..667f52e02 100644
--- a/src/ui/widgets/widgets/DnsSettingsWidget.cpp
+++ b/src/ui/widgets/widgets/DnsSettingsWidget.cpp
@@ -100,6 +100,9 @@ void DnsSettingsWidget::SetDNSObject(const DNSObject &_dns, const FakeDNSObject
staticResolvedDomainsTable->setItem(rowId, 1, new QTableWidgetItem(ip));
}
staticResolvedDomainsTable->resizeColumnsToContents();
+
+ dnsQueryStrategyCB->setCurrentText(dns.queryStrategy);
+ dnsDisableFallbackCB->setChecked(dns.disableFallback);
dnsDisableCacheCB->setChecked(dns.disableCache);
fakeDNSIPPool->setCurrentText(fakeDNS.ipPool);
@@ -303,3 +306,13 @@ void DnsSettingsWidget::on_dnsDisableCacheCB_stateChanged(int arg1)
{
dns.disableCache = arg1 == Qt::Checked;
}
+
+void DnsSettingsWidget::on_dnsDisableFallbackCB_stateChanged(int arg1)
+{
+ dns.disableFallback = arg1 == Qt::Checked;
+}
+
+void DnsSettingsWidget::on_dnsQueryStrategyCB_currentTextChanged(const QString &arg1)
+{
+ dns.queryStrategy = arg1;
+}
diff --git a/src/ui/widgets/widgets/DnsSettingsWidget.hpp b/src/ui/widgets/widgets/DnsSettingsWidget.hpp
index a53ef8d81..e62f851de 100644
--- a/src/ui/widgets/widgets/DnsSettingsWidget.hpp
+++ b/src/ui/widgets/widgets/DnsSettingsWidget.hpp
@@ -42,6 +42,10 @@ class DnsSettingsWidget
void on_dnsDisableCacheCB_stateChanged(int arg1);
+ void on_dnsDisableFallbackCB_stateChanged(int arg1);
+
+ void on_dnsQueryStrategyCB_currentTextChanged(const QString &arg1);
+
private:
void updateColorScheme();
void ShowCurrentDnsServerDetails();
diff --git a/src/ui/widgets/widgets/DnsSettingsWidget.ui b/src/ui/widgets/widgets/DnsSettingsWidget.ui
index 42f70580f..f14a6007e 100644
--- a/src/ui/widgets/widgets/DnsSettingsWidget.ui
+++ b/src/ui/widgets/widgets/DnsSettingsWidget.ui
@@ -6,8 +6,8 @@
0
0
- 533
- 379
+ 682
+ 474
@@ -313,31 +313,71 @@ This entry is ignored by V2Ray core when using DoH servers.
- FakeDNS
+ Miscellaneous
-
-
+
- IP Pool
+ Query Strategy
-
+
+
-
+
+ UseIP
+
+
+ -
+
+ UseIPv4
+
+
+ -
+
+ UseIPv6
+
+
+
+
+ -
+
+
+ Disable Fallback
+
+
+
+ -
+
+
+ Enabled
+
+
+
+ -
+
+
+ Fake DNS IP Pool
+
+
+
+ -
true
- -
+
-
- Pool Size
+ Fake DNS Pool Size
- -
+
-
1
diff --git a/translations/en_US.ts b/translations/en_US.ts
index 1ab2f04d2..f58097549 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -358,19 +358,31 @@ This entry is ignored by V2Ray core when using DoH servers.
- FakeDNS
+ Disable Cache
- IP Pool
+ Query Strategy
- Pool Size
+ Enabled
- Disable Cache
+ Disable Fallback
+
+
+
+ Miscellaneous
+
+
+
+ Fake DNS IP Pool
+
+
+
+ Fake DNS Pool Size
From 7eac07eeff64a64b3a707376db12f32f359b3c27 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 12 Apr 2021 21:45:12 +0800
Subject: [PATCH 07/33] set default queryStategy
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index a1c8982c1..8cf374b21 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6180
+6181
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index b1a002c28..20de435bf 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -68,7 +68,7 @@ namespace Qv2ray::base::objects
QString tag;
bool disableCache = false;
bool disableFallback = false;
- QString queryStrategy = "";
+ QString queryStrategy = "UseIP";
friend bool operator==(const DNSObject &left, const DNSObject &right)
{
return left.hosts == right.hosts && //
From 6fd6eaedcdc79332db2d843889007b71068a221d Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 12 Apr 2021 21:50:00 +0800
Subject: [PATCH 08/33] add compare function
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 12 +++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 8cf374b21..8d4e65001 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6181
+6182
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index 20de435bf..9cd3ede7e 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -71,11 +71,13 @@ namespace Qv2ray::base::objects
QString queryStrategy = "UseIP";
friend bool operator==(const DNSObject &left, const DNSObject &right)
{
- return left.hosts == right.hosts && //
- left.servers == right.servers && //
- left.clientIp == right.clientIp && //
- left.tag == right.tag && //
- left.disableCache == right.disableCache;
+ return left.hosts == right.hosts && //
+ left.servers == right.servers && //
+ left.clientIp == right.clientIp && //
+ left.tag == right.tag && //
+ left.disableCache == right.disableCache && //
+ left.disableFallback == right.disableFallback && //
+ left.queryStrategy == right.queryStrategy;
}
friend bool operator!=(const DNSObject &left, const DNSObject &right)
{
From 19ef0b184563a637eff62920caefc3a4c68ccb14 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 12 Apr 2021 22:19:21 +0800
Subject: [PATCH 09/33] fix v2ray 4.37 log highlighting
---
makespec/BUILDVERSION | 2 +-
src/core/handler/KernelInstanceHandler.cpp | 4 +---
src/ui/common/LogHighlighter.cpp | 2 +-
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 8d4e65001..7ad6b3d0b 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6182
+6183
diff --git a/src/core/handler/KernelInstanceHandler.cpp b/src/core/handler/KernelInstanceHandler.cpp
index 0875e1de6..ac2c0d875 100644
--- a/src/core/handler/KernelInstanceHandler.cpp
+++ b/src/core/handler/KernelInstanceHandler.cpp
@@ -284,9 +284,7 @@ namespace Qv2ray::core::handler
void KernelInstanceHandler::OnV2RayKernelLog_p(const QString &log)
{
for (auto line : SplitLines(log))
- emitLogMessage(line.replace(QRegularExpression{ R"(> github.com\/v2fly\/v2ray-core)" }, "\r\n > core::")
- .replace(QRegularExpression{ R"(github.com\/v2fly\/v2ray-core)" }, "core::")
- .trimmed());
+ emitLogMessage(line.trimmed());
}
void KernelInstanceHandler::StopConnection()
diff --git a/src/ui/common/LogHighlighter.cpp b/src/ui/common/LogHighlighter.cpp
index 8947d226b..f18b766ce 100644
--- a/src/ui/common/LogHighlighter.cpp
+++ b/src/ui/common/LogHighlighter.cpp
@@ -92,7 +92,7 @@ namespace Qv2ray::ui
highlightingRules.append(rule);
//
v2rayComponentFormat.setForeground(darkMode ? darkGreenColor : Qt::darkYellow);
- rule.pattern = QRegularExpression(R"( (github.com\/v2fly\/v2ray-core)[\/\w*]*: )");
+ rule.pattern = QRegularExpression(R"( (\w+\/)+\w+: )");
rule.format = v2rayComponentFormat;
highlightingRules.append(rule);
//
From 4bc34ca4a991c46872bc393effe7787f2bb689cb Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 12 Apr 2021 22:23:19 +0800
Subject: [PATCH 10/33] New Crowdin updates (#1402)
---
translations/ja_JP.ts | 28 ++++++++++++++++++++--------
translations/yue.ts | 28 ++++++++++++++++++++--------
translations/zh_CN.ts | 28 ++++++++++++++++++++--------
translations/zh_TW.ts | 28 ++++++++++++++++++++--------
4 files changed, 80 insertions(+), 32 deletions(-)
diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts
index e26ff2ccb..67c84a6b0 100644
--- a/translations/ja_JP.ts
+++ b/translations/ja_JP.ts
@@ -365,20 +365,32 @@ This entry is ignored by V2Ray core when using DoH servers.
このエントリはDoHサーバを使用する場合、V2Rayコアでは無視されます。
- FakeDNS
- FakeDNS
+ Disable Cache
+ キャッシュを無効化
- IP Pool
- IP プール
+ Query Strategy
+ クエリ戦略
- Pool Size
- プールサイズ
+ Enabled
+ 有効
- Disable Cache
- キャッシュを無効化
+ Disable Fallback
+ フォールバックを無効化
+
+
+ Miscellaneous
+ その他
+
+
+ Fake DNS IP Pool
+ 偽の DNS IP プール
+
+
+ Fake DNS Pool Size
+ 偽の DNS プールサイズ
diff --git a/translations/yue.ts b/translations/yue.ts
index 27e4db62b..f8fdfd360 100644
--- a/translations/yue.ts
+++ b/translations/yue.ts
@@ -368,20 +368,32 @@ This entry is ignored by V2Ray core when using DoH servers.
喺使用DoH服務器嘅時候,V2Ray核心將忽略此條目。
- FakeDNS
- FakeDNS
+ Disable Cache
+ Disable Cache
- IP Pool
- IP Pool
+ Query Strategy
+ Query Strategy
- Pool Size
- Pool Size
+ Enabled
+ Enabled
- Disable Cache
- Disable Cache
+ Disable Fallback
+ Disable Fallback
+
+
+ Miscellaneous
+ Miscellaneous
+
+
+ Fake DNS IP Pool
+ Fake DNS IP Pool
+
+
+ Fake DNS Pool Size
+ Fake DNS Pool Size
diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts
index f39324d17..46f8debc9 100644
--- a/translations/zh_CN.ts
+++ b/translations/zh_CN.ts
@@ -365,20 +365,32 @@ This entry is ignored by V2Ray core when using DoH servers.
当使用 DoH 模式时,此项无效。
- FakeDNS
- FakeDNS
+ Disable Cache
+ 禁用缓存
- IP Pool
- IP地址库
+ Query Strategy
+ 查询策略
- Pool Size
- 池大小
+ Enabled
+ 已启用
- Disable Cache
- 禁用缓存
+ Disable Fallback
+ 禁用后退
+
+
+ Miscellaneous
+ 其他事项
+
+
+ Fake DNS IP Pool
+ 假名 DNS IP 库
+
+
+ Fake DNS Pool Size
+ 假名 DNS 池大小
diff --git a/translations/zh_TW.ts b/translations/zh_TW.ts
index 7c36be160..cd0cbca2e 100644
--- a/translations/zh_TW.ts
+++ b/translations/zh_TW.ts
@@ -359,20 +359,32 @@ This entry is ignored by V2Ray core when using DoH servers.
當使用 DoH 模式時,此項無效。
- FakeDNS
- FakeDNS
+ Disable Cache
+ Disable Cache
- IP Pool
- IP Pool
+ Query Strategy
+ Query Strategy
- Pool Size
- Pool Size
+ Enabled
+ 已啟用
- Disable Cache
- Disable Cache
+ Disable Fallback
+ Disable Fallback
+
+
+ Miscellaneous
+ Miscellaneous
+
+
+ Fake DNS IP Pool
+ Fake DNS IP Pool
+
+
+ Fake DNS Pool Size
+ Fake DNS Pool Size
From 1d9d050887605ba0e847da406ef1fd145d2413f5 Mon Sep 17 00:00:00 2001
From: sixg0000d
Date: Mon, 12 Apr 2021 22:50:11 +0800
Subject: [PATCH 11/33] update catch.hpp (#1403)
---
test/catch.hpp | 801 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 520 insertions(+), 281 deletions(-)
diff --git a/test/catch.hpp b/test/catch.hpp
index 6beb0eadb..9c1c854fd 100644
--- a/test/catch.hpp
+++ b/test/catch.hpp
@@ -1,9 +1,9 @@
/*
- * Catch v2.12.1
- * Generated: 2020-04-21 19:29:20.964532
+ * Catch v2.13.5
+ * Generated: 2021-04-10 23:43:17.560525
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
- * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
+ * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -14,8 +14,8 @@
#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 12
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_MINOR 13
+#define CATCH_VERSION_PATCH 5
#ifdef __clang__
# pragma clang system_header
@@ -66,13 +66,16 @@
#if !defined(CATCH_CONFIG_IMPL_ONLY)
// start catch_platform.h
+// See e.g.:
+// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
#ifdef __APPLE__
-# include
-# if TARGET_OS_OSX == 1
-# define CATCH_PLATFORM_MAC
-# elif TARGET_OS_IPHONE == 1
-# define CATCH_PLATFORM_IPHONE
-# endif
+# include
+# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
+ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
+# define CATCH_PLATFORM_MAC
+# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
+# define CATCH_PLATFORM_IPHONE
+# endif
#elif defined(linux) || defined(__linux) || defined(__linux__)
# define CATCH_PLATFORM_LINUX
@@ -132,13 +135,9 @@ namespace Catch {
#endif
-#if defined(__cpp_lib_uncaught_exceptions)
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
-// We have to avoid both ICC and Clang, because they try to mask themselves
-// as gcc, and we want only GCC in this block
-#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
+// Only GCC compiler should be used in this block, so other compilers trying to
+// mask themselves as GCC should be ignored.
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
@@ -162,8 +161,8 @@ namespace Catch {
// ```
//
// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
-# if !defined(__ibmxl__)
-# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg) */
+# if !defined(__ibmxl__) && !defined(__CUDACC__)
+# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
# endif
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
@@ -244,10 +243,6 @@ namespace Catch {
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
-# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-# endif
-
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
@@ -330,7 +325,10 @@ namespace Catch {
// Check if byte is available and usable
# if __has_include() && defined(CATCH_CPP17_OR_GREATER)
- # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+ # include
+ # if __cpp_lib_byte > 0
+ # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+ # endif
# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER)
// Check if variant is available and usable
@@ -373,10 +371,6 @@ namespace Catch {
# define CATCH_CONFIG_CPP17_OPTIONAL
#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
-# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
# define CATCH_CONFIG_CPP17_STRING_VIEW
#endif
@@ -775,7 +769,7 @@ constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) n
#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
-#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
+#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
@@ -944,13 +938,13 @@ namespace Catch {
#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
// std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
- // replaced with std::invoke_result here. Also *_t format is preferred over
- // typename *::type format.
- template
- using FunctionReturnType = std::remove_reference_t>>;
+ // replaced with std::invoke_result here.
+ template
+ using FunctionReturnType = std::remove_reference_t>>;
#else
- template
- using FunctionReturnType = typename std::remove_reference::type>::type>::type;
+ // Keep ::type here because we still support C++11
+ template
+ using FunctionReturnType = typename std::remove_reference::type>::type>::type;
#endif
} // namespace Catch
@@ -1105,7 +1099,7 @@ struct AutoReg : NonCopyable {
int index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = int[];\
- (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@@ -1151,7 +1145,7 @@ struct AutoReg : NonCopyable {
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
@@ -1195,7 +1189,7 @@ struct AutoReg : NonCopyable {
void reg_tests() { \
int index = 0; \
using expander = int[]; \
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
} \
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
@@ -1229,7 +1223,7 @@ struct AutoReg : NonCopyable {
int index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = int[];\
- (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@@ -1278,7 +1272,7 @@ struct AutoReg : NonCopyable {
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@@ -1325,7 +1319,7 @@ struct AutoReg : NonCopyable {
void reg_tests(){\
int index = 0;\
using expander = int[];\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@@ -1829,8 +1823,8 @@ namespace Catch {
#endif
namespace Detail {
- template
- std::string rangeToString(InputIterator first, InputIterator last) {
+ template
+ std::string rangeToString(InputIterator first, Sentinel last) {
ReusableStringStream rss;
rss << "{ ";
if (first != last) {
@@ -1988,20 +1982,27 @@ namespace Catch {
#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
namespace Catch {
- struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
-
- // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
+ // Import begin/ end from std here
using std::begin;
using std::end;
- not_this_one begin( ... );
- not_this_one end( ... );
+ namespace detail {
+ template
+ struct void_type {
+ using type = void;
+ };
+
+ template
+ struct is_range_impl : std::false_type {
+ };
+
+ template
+ struct is_range_impl()))>::type> : std::true_type {
+ };
+ } // namespace detail
template
- struct is_range {
- static const bool value =
- !std::is_same())), not_this_one>::value &&
- !std::is_same())), not_this_one>::value;
+ struct is_range : detail::is_range_impl {
};
#if defined(_MANAGED) // Managed types are never ranges
@@ -2461,7 +2462,7 @@ namespace Catch {
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
- virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+ virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
virtual void benchmarkPreparing( std::string const& name ) = 0;
@@ -3714,8 +3715,6 @@ namespace Matchers {
struct UnorderedEqualsMatcher : MatcherBase> {
UnorderedEqualsMatcher(std::vector const& target) : m_target(target) {}
bool match(std::vector const& vec) const override {
- // Note: This is a reimplementation of std::is_permutation,
- // because I don't want to include inside the common path
if (m_target.size() != vec.size()) {
return false;
}
@@ -4075,16 +4074,16 @@ namespace Generators {
return makeGenerators( value( T( std::forward( val ) ) ), std::forward( moreGenerators )... );
}
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
template
// Note: The type after -> is weird, because VS2015 cannot parse
// the expression used in the typedef inside, when it is in
// return type. Yeah.
- auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) {
+ auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) {
using UnderlyingType = typename decltype(generatorExpression())::type;
- IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
+ IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
if (!tracker.hasGenerator()) {
tracker.setGenerator(pf::make_unique>(generatorExpression()));
}
@@ -4097,11 +4096,17 @@ namespace Generators {
} // namespace Catch
#define GENERATE( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+ CATCH_INTERNAL_LINEINFO, \
+ [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
#define GENERATE_COPY( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+ CATCH_INTERNAL_LINEINFO, \
+ [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
#define GENERATE_REF( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+ CATCH_INTERNAL_LINEINFO, \
+ [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
// end catch_generators.hpp
// start catch_generators_generic.hpp
@@ -4511,6 +4516,7 @@ namespace Catch {
virtual int abortAfter() const = 0;
virtual bool showInvisibles() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual double minDuration() const = 0;
virtual TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0;
virtual std::vector const& getTestsOrTags() const = 0;
@@ -5283,6 +5289,7 @@ namespace Catch {
Verbosity verbosity = Verbosity::Normal;
WarnAbout::What warnings = WarnAbout::Nothing;
ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
+ double minDuration = -1;
RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
UseColour::YesOrNo useColour = UseColour::Auto;
WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
@@ -5333,6 +5340,7 @@ namespace Catch {
bool warnAboutMissingAssertions() const override;
bool warnAboutNoTests() const override;
ShowDurations::OrNot showDurations() const override;
+ double minDuration() const override;
RunTests::InWhatOrder runOrder() const override;
unsigned int rngSeed() const override;
UseColour::YesOrNo useColour() const override;
@@ -5710,6 +5718,9 @@ namespace Catch {
// Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration );
+ //! Should the reporter show
+ bool shouldShowDuration( IConfig const& config, double duration );
+
std::string serializeFilters( std::vector const& container );
template
@@ -6103,8 +6114,6 @@ namespace Catch {
static std::string getDescription();
- ReporterPreferences getPreferences() const override;
-
void noMatchingTestCases(std::string const& spec) override;
void assertionStarting(AssertionInfo const&) override;
@@ -6552,20 +6561,18 @@ namespace Catch {
return {};
}
};
- template
- using ResultOf_t = typename std::result_of::type;
// invoke and not return void :(
template
- CompleteType_t> complete_invoke(Fun&& fun, Args&&... args) {
- return CompleteInvoker>::invoke(std::forward(fun), std::forward(args)...);
+ CompleteType_t> complete_invoke(Fun&& fun, Args&&... args) {
+ return CompleteInvoker>::invoke(std::forward(fun), std::forward(args)...);
}
const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
} // namespace Detail
template
- Detail::CompleteType_t> user_code(Fun&& fun) {
+ Detail::CompleteType_t> user_code(Fun&& fun) {
CATCH_TRY{
return Detail::complete_invoke(std::forward(fun));
} CATCH_CATCH_ALL{
@@ -6810,8 +6817,8 @@ namespace Catch {
Result result;
int iterations;
};
- template
- using TimingOf = Timing, Detail::CompleteType_t>>;
+ template
+ using TimingOf = Timing, Detail::CompleteType_t>>;
} // namespace Benchmark
} // namespace Catch
@@ -6822,7 +6829,7 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
template
- TimingOf measure(Fun&& fun, Args&&... args) {
+ TimingOf measure(Fun&& fun, Args&&... args) {
auto start = Clock::now();
auto&& r = Detail::complete_invoke(fun, std::forward(args)...);
auto end = Clock::now();
@@ -6841,11 +6848,11 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
template
- TimingOf measure_one(Fun&& fun, int iters, std::false_type) {
+ TimingOf measure_one(Fun&& fun, int iters, std::false_type) {
return Detail::measure(fun, iters);
}
template
- TimingOf measure_one(Fun&& fun, int iters, std::true_type) {
+ TimingOf measure_one(Fun&& fun, int iters, std::true_type) {
Detail::ChronometerModel meter;
auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
@@ -6862,7 +6869,7 @@ namespace Catch {
};
template
- TimingOf)> run_for_at_least(ClockDuration how_long, int seed, Fun&& fun) {
+ TimingOf> run_for_at_least(ClockDuration how_long, int seed, Fun&& fun) {
auto iters = seed;
while (iters < (1 << 30)) {
auto&& Timing = measure_one(fun, iters, is_callable());
@@ -7050,8 +7057,8 @@ namespace Catch {
double b2 = bias - z1;
double a1 = a(b1);
double a2 = a(b2);
- auto lo = std::max(cumn(a1), 0);
- auto hi = std::min(cumn(a2), n - 1);
+ auto lo = (std::max)(cumn(a1), 0);
+ auto hi = (std::min)(cumn(a2), n - 1);
return { point, resample[lo], resample[hi], confidence_level };
}
@@ -7120,7 +7127,9 @@ namespace Catch {
}
template
EnvironmentEstimate> estimate_clock_cost(FloatDuration resolution) {
- auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration(clock_cost_estimation_time_limit));
+ auto time_limit = (std::min)(
+ resolution * clock_cost_estimation_tick_limit,
+ FloatDuration(clock_cost_estimation_time_limit));
auto time_clock = [](int k) {
return Detail::measure([k] {
for (int i = 0; i < k; ++i) {
@@ -7460,23 +7469,37 @@ namespace TestCaseTracking {
SourceLineInfo location;
NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
+ friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
+ return lhs.name == rhs.name
+ && lhs.location == rhs.location;
+ }
};
- struct ITracker;
+ class ITracker;
using ITrackerPtr = std::shared_ptr;
- struct ITracker {
- virtual ~ITracker();
+ class ITracker {
+ NameAndLocation m_nameAndLocation;
+
+ public:
+ ITracker(NameAndLocation const& nameAndLoc) :
+ m_nameAndLocation(nameAndLoc)
+ {}
// static queries
- virtual NameAndLocation const& nameAndLocation() const = 0;
+ NameAndLocation const& nameAndLocation() const {
+ return m_nameAndLocation;
+ }
+
+ virtual ~ITracker();
// dynamic queries
virtual bool isComplete() const = 0; // Successfully completed or failed
virtual bool isSuccessfullyCompleted() const = 0;
virtual bool isOpen() const = 0; // Started but not complete
virtual bool hasChildren() const = 0;
+ virtual bool hasStarted() const = 0;
virtual ITracker& parent() = 0;
@@ -7531,7 +7554,6 @@ namespace TestCaseTracking {
};
using Children = std::vector;
- NameAndLocation m_nameAndLocation;
TrackerContext& m_ctx;
ITracker* m_parent;
Children m_children;
@@ -7540,11 +7562,13 @@ namespace TestCaseTracking {
public:
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
- NameAndLocation const& nameAndLocation() const override;
bool isComplete() const override;
bool isSuccessfullyCompleted() const override;
bool isOpen() const override;
bool hasChildren() const override;
+ bool hasStarted() const override {
+ return m_runState != NotStarted;
+ }
void addChild( ITrackerPtr const& child ) override;
@@ -7583,6 +7607,10 @@ namespace TestCaseTracking {
void addInitialFilters( std::vector const& filters );
void addNextFilters( std::vector const& filters );
+ //! Returns filters active in this tracker
+ std::vector const& getFilters() const;
+ //! Returns whitespace-trimmed name of the tracked section
+ std::string const& trimmedName() const;
};
} // namespace TestCaseTracking
@@ -7748,7 +7776,7 @@ namespace Catch {
double sb = stddev.point;
double mn = mean.point / n;
double mg_min = mn / 2.;
- double sg = std::min(mg_min / 4., sb / std::sqrt(n));
+ double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
double sg2 = sg * sg;
double sb2 = sb * sb;
@@ -7767,7 +7795,7 @@ namespace Catch {
return (nc / n) * (sb2 - nc * sg2);
};
- return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
+ return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
}
bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector::iterator first, std::vector::iterator last) {
@@ -7907,7 +7935,11 @@ namespace Catch {
#ifdef CATCH_PLATFORM_MAC
- #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
+ #if defined(__i386__) || defined(__x86_64__)
+ #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
+ #elif defined(__aarch64__)
+ #define CATCH_TRAP() __asm__(".inst 0xd4200000")
+ #endif
#elif defined(CATCH_PLATFORM_IPHONE)
@@ -7953,86 +7985,58 @@ namespace Catch {
// start catch_fatal_condition.h
-// start catch_windows_h_proxy.h
-
-
-#if defined(CATCH_PLATFORM_WINDOWS)
-
-#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
-# define CATCH_DEFINED_NOMINMAX
-# define NOMINMAX
-#endif
-#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
-# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-
-#ifdef __AFXDLL
-#include
-#else
-#include
-#endif
-
-#ifdef CATCH_DEFINED_NOMINMAX
-# undef NOMINMAX
-#endif
-#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# undef WIN32_LEAN_AND_MEAN
-#endif
-
-#endif // defined(CATCH_PLATFORM_WINDOWS)
-
-// end catch_windows_h_proxy.h
-#if defined( CATCH_CONFIG_WINDOWS_SEH )
+#include
namespace Catch {
- struct FatalConditionHandler {
-
- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
+ // Wrapper for platform-specific fatal error (signals/SEH) handlers
+ //
+ // Tries to be cooperative with other handlers, and not step over
+ // other handlers. This means that unknown structured exceptions
+ // are passed on, previous signal handlers are called, and so on.
+ //
+ // Can only be instantiated once, and assumes that once a signal
+ // is caught, the binary will end up terminating. Thus, there
+ class FatalConditionHandler {
+ bool m_started = false;
+
+ // Install/disengage implementation for specific platform.
+ // Should be if-defed to work on current platform, can assume
+ // engage-disengage 1:1 pairing.
+ void engage_platform();
+ void disengage_platform();
+ public:
+ // Should also have platform-specific implementations as needed
FatalConditionHandler();
- static void reset();
~FatalConditionHandler();
- private:
- static bool isSet;
- static ULONG guaranteeSize;
- static PVOID exceptionHandlerHandle;
- };
-
-} // namespace Catch
-
-#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
-
-#include
-
-namespace Catch {
-
- struct FatalConditionHandler {
-
- static bool isSet;
- static struct sigaction oldSigActions[];
- static stack_t oldSigStack;
- static char altStackMem[];
-
- static void handleSignal( int sig );
+ void engage() {
+ assert(!m_started && "Handler cannot be installed twice.");
+ m_started = true;
+ engage_platform();
+ }
- FatalConditionHandler();
- ~FatalConditionHandler();
- static void reset();
+ void disengage() {
+ assert(m_started && "Handler cannot be uninstalled without being installed first");
+ m_started = false;
+ disengage_platform();
+ }
};
-} // namespace Catch
-
-#else
-
-namespace Catch {
- struct FatalConditionHandler {
- void reset();
+ //! Simple RAII guard for (dis)engaging the FatalConditionHandler
+ class FatalConditionHandlerGuard {
+ FatalConditionHandler* m_handler;
+ public:
+ FatalConditionHandlerGuard(FatalConditionHandler* handler):
+ m_handler(handler) {
+ m_handler->engage();
+ }
+ ~FatalConditionHandlerGuard() {
+ m_handler->disengage();
+ }
};
-}
-#endif
+} // end namespace Catch
// end catch_fatal_condition.h
#include
@@ -8092,7 +8096,7 @@ namespace Catch {
void sectionEnded( SectionEndInfo const& endInfo ) override;
void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void benchmarkPreparing( std::string const& name ) override;
@@ -8158,6 +8162,7 @@ namespace Catch {
std::vector m_unfinishedSections;
std::vector m_activeSections;
TrackerContext m_trackerContext;
+ FatalConditionHandler m_fatalConditionhandler;
bool m_lastAssertionPassed = false;
bool m_shouldReportUnexpected = true;
bool m_includeSuccessfulResults;
@@ -9068,7 +9073,7 @@ namespace detail {
}
inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
std::string srcLC = source;
- std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( std::tolower(c) ); } );
+ std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast( std::tolower(c) ); } );
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
target = true;
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
@@ -9837,6 +9842,9 @@ namespace Catch {
| Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
["-d"]["--durations"]
( "show test durations" )
+ | Opt( config.minDuration, "seconds" )
+ ["-D"]["--min-duration"]
+ ( "show test durations for tests taking at least the given number of seconds" )
| Opt( loadTestNamesFromFile, "filename" )
["-f"]["--input-file"]
( "load test names to run from a file" )
@@ -9984,6 +9992,7 @@ namespace Catch {
bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
+ double Config::minDuration() const { return m_data.minDuration; }
RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
unsigned int Config::rngSeed() const { return m_data.rngSeed; }
UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
@@ -10026,6 +10035,36 @@ namespace Catch {
}
// end catch_errno_guard.h
+// start catch_windows_h_proxy.h
+
+
+#if defined(CATCH_PLATFORM_WINDOWS)
+
+#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+# define CATCH_DEFINED_NOMINMAX
+# define NOMINMAX
+#endif
+#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef __AFXDLL
+#include
+#else
+#include
+#endif
+
+#ifdef CATCH_DEFINED_NOMINMAX
+# undef NOMINMAX
+#endif
+#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#endif // defined(CATCH_PLATFORM_WINDOWS)
+
+// end catch_windows_h_proxy.h
#include
namespace Catch {
@@ -10542,7 +10581,7 @@ namespace Catch {
// Extracts the actual name part of an enum instance
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
StringRef extractInstanceName(StringRef enumInstance) {
- // Find last occurence of ":"
+ // Find last occurrence of ":"
size_t name_start = enumInstance.size();
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
--name_start;
@@ -10704,25 +10743,47 @@ namespace Catch {
// end catch_exception_translator_registry.cpp
// start catch_fatal_condition.cpp
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
+#include
+
+#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace Catch {
+
+ // If neither SEH nor signal handling is required, the handler impls
+ // do not have to do anything, and can be empty.
+ FatalConditionHandler::engage_platform() {}
+ FatalConditionHandler::disengage_platform() {}
+ FatalConditionHandler::FatalConditionHandler() = default;
+ FatalConditionHandler::~FatalConditionHandler() = default;
+
+} // end namespace Catch
+
+#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )
+#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
+#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
namespace {
- // Report the error condition
+ //! Signals fatal error message to the run context
void reportFatal( char const * const message ) {
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
}
-}
-#endif // signals/SEH handling
+ //! Minimal size Catch2 needs for its own fatal error handling.
+ //! Picked anecdotally, so it might not be sufficient on all
+ //! platforms, and for all configurations.
+ constexpr std::size_t minStackSizeForErrors = 32 * 1024;
+} // end unnamed namespace
+
+#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
#if defined( CATCH_CONFIG_WINDOWS_SEH )
namespace Catch {
+
struct SignalDefs { DWORD id; const char* name; };
// There is no 1-1 mapping between signals and windows exceptions.
@@ -10735,7 +10796,7 @@ namespace Catch {
{ static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
};
- LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
+ static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
for (auto const& def : signalDefs) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
reportFatal(def.name);
@@ -10746,38 +10807,50 @@ namespace Catch {
return EXCEPTION_CONTINUE_SEARCH;
}
+ // Since we do not support multiple instantiations, we put these
+ // into global variables and rely on cleaning them up in outlined
+ // constructors/destructors
+ static PVOID exceptionHandlerHandle = nullptr;
+
+ // For MSVC, we reserve part of the stack memory for handling
+ // memory overflow structured exception.
FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
- // 32k seems enough for Catch to handle stack overflow,
- // but the value was found experimentally, so there is no strong guarantee
- guaranteeSize = 32 * 1024;
- exceptionHandlerHandle = nullptr;
+ ULONG guaranteeSize = static_cast(minStackSizeForErrors);
+ if (!SetThreadStackGuarantee(&guaranteeSize)) {
+ // We do not want to fully error out, because needing
+ // the stack reserve should be rare enough anyway.
+ Catch::cerr()
+ << "Failed to reserve piece of stack."
+ << " Stack overflows will not be reported successfully.";
+ }
+ }
+
+ // We do not attempt to unset the stack guarantee, because
+ // Windows does not support lowering the stack size guarantee.
+ FatalConditionHandler::~FatalConditionHandler() = default;
+
+ void FatalConditionHandler::engage_platform() {
// Register as first handler in current chain
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
- // Pass in guarantee size to be filled
- SetThreadStackGuarantee(&guaranteeSize);
+ if (!exceptionHandlerHandle) {
+ CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
+ }
}
- void FatalConditionHandler::reset() {
- if (isSet) {
- RemoveVectoredExceptionHandler(exceptionHandlerHandle);
- SetThreadStackGuarantee(&guaranteeSize);
- exceptionHandlerHandle = nullptr;
- isSet = false;
+ void FatalConditionHandler::disengage_platform() {
+ if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
+ CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
}
+ exceptionHandlerHandle = nullptr;
}
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
- }
+} // end namespace Catch
-bool FatalConditionHandler::isSet = false;
-ULONG FatalConditionHandler::guaranteeSize = 0;
-PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
+#endif // CATCH_CONFIG_WINDOWS_SEH
-} // namespace Catch
+#if defined( CATCH_CONFIG_POSIX_SIGNALS )
-#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
+#include
namespace Catch {
@@ -10786,10 +10859,6 @@ namespace Catch {
const char* name;
};
- // 32kb for the alternate stack seems to be sufficient. However, this value
- // is experimentally determined, so that's not guaranteed.
- static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
-
static SignalDefs signalDefs[] = {
{ SIGINT, "SIGINT - Terminal interrupt signal" },
{ SIGILL, "SIGILL - Illegal instruction signal" },
@@ -10799,7 +10868,32 @@ namespace Catch {
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
};
- void FatalConditionHandler::handleSignal( int sig ) {
+// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
+// which is zero initialization, but not explicit. We want to avoid
+// that.
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+ static char* altStackMem = nullptr;
+ static std::size_t altStackSize = 0;
+ static stack_t oldSigStack{};
+ static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
+
+ static void restorePreviousSignalHandlers() {
+ // We set signal handlers back to the previous ones. Hopefully
+ // nobody overwrote them in the meantime, and doesn't expect
+ // their signal handlers to live past ours given that they
+ // installed them after ours..
+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
+ sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
+ }
+ // Return the old stack
+ sigaltstack(&oldSigStack, nullptr);
+ }
+
+ static void handleSignal( int sig ) {
char const * name = "";
for (auto const& def : signalDefs) {
if (sig == def.id) {
@@ -10807,16 +10901,33 @@ namespace Catch {
break;
}
}
- reset();
- reportFatal(name);
+ // We need to restore previous signal handlers and let them do
+ // their thing, so that the users can have the debugger break
+ // when a signal is raised, and so on.
+ restorePreviousSignalHandlers();
+ reportFatal( name );
raise( sig );
}
FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
+ assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
+ if (altStackSize == 0) {
+ altStackSize = std::max(static_cast(SIGSTKSZ), minStackSizeForErrors);
+ }
+ altStackMem = new char[altStackSize]();
+ }
+
+ FatalConditionHandler::~FatalConditionHandler() {
+ delete[] altStackMem;
+ // We signal that another instance can be constructed by zeroing
+ // out the pointer.
+ altStackMem = nullptr;
+ }
+
+ void FatalConditionHandler::engage_platform() {
stack_t sigStack;
sigStack.ss_sp = altStackMem;
- sigStack.ss_size = sigStackSize;
+ sigStack.ss_size = altStackSize;
sigStack.ss_flags = 0;
sigaltstack(&sigStack, &oldSigStack);
struct sigaction sa = { };
@@ -10828,40 +10939,17 @@ namespace Catch {
}
}
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
- }
+#if defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
- void FatalConditionHandler::reset() {
- if( isSet ) {
- // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
- sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
- }
- // Return the old stack
- sigaltstack(&oldSigStack, nullptr);
- isSet = false;
- }
+ void FatalConditionHandler::disengage_platform() {
+ restorePreviousSignalHandlers();
}
- bool FatalConditionHandler::isSet = false;
- struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
- stack_t FatalConditionHandler::oldSigStack = {};
- char FatalConditionHandler::altStackMem[sigStackSize] = {};
-
-} // namespace Catch
-
-#else
-
-namespace Catch {
- void FatalConditionHandler::reset() {}
-}
-
-#endif // signals/SEH handling
+} // end namespace Catch
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
+#endif // CATCH_CONFIG_POSIX_SIGNALS
// end catch_fatal_condition.cpp
// start catch_generators.cpp
@@ -10880,8 +10968,8 @@ namespace Generators {
GeneratorUntypedBase::~GeneratorUntypedBase() {}
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
- return getResultCapture().acquireGeneratorTracker( lineInfo );
+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+ return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
}
} // namespace Generators
@@ -11416,7 +11504,8 @@ namespace {
return lhs == rhs;
}
- auto ulpDiff = std::abs(lc - rc);
+ // static cast as a workaround for IBM XLC
+ auto ulpDiff = std::abs(static_cast(lc - rc));
return static_cast(ulpDiff) <= maxUlpDiff;
}
@@ -11590,7 +11679,6 @@ Floating::WithinRelMatcher WithinRel(float target) {
} // namespace Matchers
} // namespace Catch
-
// end catch_matchers_floating.cpp
// start catch_matchers_generic.cpp
@@ -11768,10 +11856,10 @@ namespace Catch {
Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
auto trimmed = [&] (size_t start, size_t end) {
- while (names[start] == ',' || isspace(names[start])) {
+ while (names[start] == ',' || isspace(static_cast(names[start]))) {
++start;
}
- while (names[end] == ',' || isspace(names[end])) {
+ while (names[end] == ',' || isspace(static_cast(names[end]))) {
--end;
}
return names.substr(start, end - start + 1);
@@ -12006,7 +12094,7 @@ namespace Catch {
if (tmpnam_s(m_buffer)) {
CATCH_RUNTIME_ERROR("Could not get a temp filename");
}
- if (fopen_s(&m_file, m_buffer, "w")) {
+ if (fopen_s(&m_file, m_buffer, "w+")) {
char buffer[100];
if (strerror_s(buffer, errno)) {
CATCH_RUNTIME_ERROR("Could not translate errno to a string");
@@ -12301,11 +12389,13 @@ namespace Catch {
namespace Catch {
class StartupExceptionRegistry {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
public:
void add(std::exception_ptr const& exception) noexcept;
std::vector const& getExceptions() const noexcept;
private:
std::vector m_exceptions;
+#endif
};
} // end namespace Catch
@@ -12388,7 +12478,11 @@ namespace Catch {
m_tagAliasRegistry.add( alias, tag, lineInfo );
}
void registerStartupException() noexcept override {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
m_exceptionRegistry.add(std::current_exception());
+#else
+ CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+#endif
}
IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
return m_enumValuesRegistry;
@@ -12492,17 +12586,32 @@ namespace Catch {
std::shared_ptr tracker;
ITracker& currentTracker = ctx.currentTracker();
- if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+ // Under specific circumstances, the generator we want
+ // to acquire is also the current tracker. If this is
+ // the case, we have to avoid looking through current
+ // tracker's children, and instead return the current
+ // tracker.
+ // A case where this check is important is e.g.
+ // for (int i = 0; i < 5; ++i) {
+ // int n = GENERATE(1, 2);
+ // }
+ //
+ // without it, the code above creates 5 nested generators.
+ if (currentTracker.nameAndLocation() == nameAndLocation) {
+ auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
+ assert(thisTracker);
+ assert(thisTracker->isGeneratorTracker());
+ tracker = std::static_pointer_cast(thisTracker);
+ } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
assert( childTracker );
assert( childTracker->isGeneratorTracker() );
tracker = std::static_pointer_cast( childTracker );
- }
- else {
+ } else {
tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker );
currentTracker.addChild( tracker );
}
- if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( !tracker->isComplete() ) {
tracker->open();
}
@@ -12516,8 +12625,68 @@ namespace Catch {
}
void close() override {
TrackerBase::close();
- // Generator interface only finds out if it has another item on atual move
- if (m_runState == CompletedSuccessfully && m_generator->next()) {
+ // If a generator has a child (it is followed by a section)
+ // and none of its children have started, then we must wait
+ // until later to start consuming its values.
+ // This catches cases where `GENERATE` is placed between two
+ // `SECTION`s.
+ // **The check for m_children.empty cannot be removed**.
+ // doing so would break `GENERATE` _not_ followed by `SECTION`s.
+ const bool should_wait_for_child = [&]() {
+ // No children -> nobody to wait for
+ if ( m_children.empty() ) {
+ return false;
+ }
+ // If at least one child started executing, don't wait
+ if ( std::find_if(
+ m_children.begin(),
+ m_children.end(),
+ []( TestCaseTracking::ITrackerPtr tracker ) {
+ return tracker->hasStarted();
+ } ) != m_children.end() ) {
+ return false;
+ }
+
+ // No children have started. We need to check if they _can_
+ // start, and thus we should wait for them, or they cannot
+ // start (due to filters), and we shouldn't wait for them
+ auto* parent = m_parent;
+ // This is safe: there is always at least one section
+ // tracker in a test case tracking tree
+ while ( !parent->isSectionTracker() ) {
+ parent = &( parent->parent() );
+ }
+ assert( parent &&
+ "Missing root (test case) level section" );
+
+ auto const& parentSection =
+ static_cast( *parent );
+ auto const& filters = parentSection.getFilters();
+ // No filters -> no restrictions on running sections
+ if ( filters.empty() ) {
+ return true;
+ }
+
+ for ( auto const& child : m_children ) {
+ if ( child->isSectionTracker() &&
+ std::find( filters.begin(),
+ filters.end(),
+ static_cast( *child )
+ .trimmedName() ) !=
+ filters.end() ) {
+ return true;
+ }
+ }
+ return false;
+ }();
+
+ // This check is a bit tricky, because m_generator->next()
+ // has a side-effect, where it consumes generator's current
+ // value, but we do not want to invoke the side-effect if
+ // this generator is still waiting for any child to start.
+ if ( should_wait_for_child ||
+ ( m_runState == CompletedSuccessfully &&
+ m_generator->next() ) ) {
m_children.clear();
m_runState = Executing;
}
@@ -12653,10 +12822,10 @@ namespace Catch {
return true;
}
- auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+ auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
using namespace Generators;
- GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
- assert( tracker.isOpen() );
+ GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
+ TestCaseTracking::NameAndLocation( static_cast(generatorName), lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo;
return tracker;
}
@@ -12699,17 +12868,17 @@ namespace Catch {
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void RunContext::benchmarkPreparing(std::string const& name) {
- m_reporter->benchmarkPreparing(name);
- }
+ m_reporter->benchmarkPreparing(name);
+ }
void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
m_reporter->benchmarkStarting( info );
}
void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
m_reporter->benchmarkEnded( stats );
}
- void RunContext::benchmarkFailed(std::string const & error) {
- m_reporter->benchmarkFailed(error);
- }
+ void RunContext::benchmarkFailed(std::string const & error) {
+ m_reporter->benchmarkFailed(error);
+ }
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
void RunContext::pushScopedMessage(MessageInfo const & message) {
@@ -12843,9 +13012,8 @@ namespace Catch {
}
void RunContext::invokeActiveTestCase() {
- FatalConditionHandler fatalConditionHandler; // Handle signals
+ FatalConditionHandlerGuard _(&m_fatalConditionhandler);
m_activeTestCase->invoke();
- fatalConditionHandler.reset();
}
void RunContext::handleUnfinishedSections() {
@@ -13430,6 +13598,7 @@ namespace Catch {
// end catch_singletons.cpp
// start catch_startup_exception_registry.cpp
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
namespace Catch {
void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
CATCH_TRY {
@@ -13445,6 +13614,7 @@ void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexce
}
} // end namespace Catch
+#endif
// end catch_startup_exception_registry.cpp
// start catch_stream.cpp
@@ -13629,7 +13799,7 @@ namespace Catch {
namespace {
char toLowerCh(char c) {
- return static_cast( std::tolower( c ) );
+ return static_cast( std::tolower( static_cast(c) ) );
}
}
@@ -14012,24 +14182,28 @@ namespace Catch {
namespace {
struct TestHasher {
- explicit TestHasher(Catch::SimplePcg32& rng) {
- basis = rng();
- basis <<= 32;
- basis |= rng();
- }
+ using hash_t = uint64_t;
- uint64_t basis;
+ explicit TestHasher( hash_t hashSuffix ):
+ m_hashSuffix{ hashSuffix } {}
- uint64_t operator()(TestCase const& t) const {
- // Modified FNV-1a hash
- static constexpr uint64_t prime = 1099511628211;
- uint64_t hash = basis;
- for (const char c : t.name) {
+ uint32_t operator()( TestCase const& t ) const {
+ // FNV-1a hash with multiplication fold.
+ const hash_t prime = 1099511628211u;
+ hash_t hash = 14695981039346656037u;
+ for ( const char c : t.name ) {
hash ^= c;
hash *= prime;
}
- return hash;
+ hash ^= m_hashSuffix;
+ hash *= prime;
+ const uint32_t low{ static_cast( hash ) };
+ const uint32_t high{ static_cast( hash >> 32 ) };
+ return low * high;
}
+
+ private:
+ hash_t m_hashSuffix;
};
} // end unnamed namespace
@@ -14047,9 +14221,9 @@ namespace Catch {
case RunTests::InRandomOrder: {
seedRng( config );
- TestHasher h( rng() );
+ TestHasher h{ config.rngSeed() };
- using hashedTest = std::pair;
+ using hashedTest = std::pair;
std::vector indexed_tests;
indexed_tests.reserve( unsortedTestCases.size() );
@@ -14212,15 +14386,12 @@ namespace TestCaseTracking {
m_currentTracker = tracker;
}
- TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
- : m_nameAndLocation( nameAndLocation ),
+ TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
+ ITracker(nameAndLocation),
m_ctx( ctx ),
m_parent( parent )
{}
- NameAndLocation const& TrackerBase::nameAndLocation() const {
- return m_nameAndLocation;
- }
bool TrackerBase::isComplete() const {
return m_runState == CompletedSuccessfully || m_runState == Failed;
}
@@ -14336,7 +14507,8 @@ namespace TestCaseTracking {
bool SectionTracker::isComplete() const {
bool complete = true;
- if ((m_filters.empty() || m_filters[0] == "")
+ if (m_filters.empty()
+ || m_filters[0] == ""
|| std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
complete = TrackerBase::isComplete();
}
@@ -14381,6 +14553,14 @@ namespace TestCaseTracking {
m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
}
+ std::vector const& SectionTracker::getFilters() const {
+ return m_filters;
+ }
+
+ std::string const& SectionTracker::trimmedName() const {
+ return m_trimmed_name;
+ }
+
} // namespace TestCaseTracking
using TestCaseTracking::ITracker;
@@ -15115,11 +15295,48 @@ namespace Catch {
// end catch_totals.cpp
// start catch_uncaught_exceptions.cpp
+// start catch_config_uncaught_exceptions.hpp
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+
+#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+
+#if defined(_MSC_VER)
+# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+# endif
+#endif
+
+#include
+
+#if defined(__cpp_lib_uncaught_exceptions) \
+ && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+
+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif // __cpp_lib_uncaught_exceptions
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
+ && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
+ && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+
+# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif
+
+#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+// end catch_config_uncaught_exceptions.hpp
#include
namespace Catch {
bool uncaught_exceptions() {
-#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+ return false;
+#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
@@ -15159,7 +15376,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 12, 1, "", 0 );
+ static Version version( 2, 13, 5, "", 0 );
return version;
}
@@ -15561,6 +15778,17 @@ namespace Catch {
return std::string(buffer);
}
+ bool shouldShowDuration( IConfig const& config, double duration ) {
+ if ( config.showDurations() == ShowDurations::Always ) {
+ return true;
+ }
+ if ( config.showDurations() == ShowDurations::Never ) {
+ return false;
+ }
+ const double min = config.minDuration();
+ return min >= 0 && duration >= min;
+ }
+
std::string serializeFilters( std::vector const& container ) {
ReusableStringStream oss;
bool first = true;
@@ -15827,10 +16055,6 @@ class AssertionPrinter {
return "Reports test results on a single line, suitable for IDEs";
}
- ReporterPreferences CompactReporter::getPreferences() const {
- return m_reporterPrefs;
- }
-
void CompactReporter::noMatchingTestCases( std::string const& spec ) {
stream << "No test cases matched '" << spec << '\'' << std::endl;
}
@@ -15857,8 +16081,9 @@ class AssertionPrinter {
}
void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
- if (m_config->showDurations() == ShowDurations::Always) {
- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+ double dur = _sectionStats.durationInSeconds;
+ if ( shouldShowDuration( *m_config, dur ) ) {
+ stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
}
}
@@ -16278,8 +16503,9 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
stream << "\nNo assertions in test case";
stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
}
- if (m_config->showDurations() == ShowDurations::Always) {
- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+ double dur = _sectionStats.durationInSeconds;
+ if (shouldShowDuration(*m_config, dur)) {
+ stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
}
if (m_headerPrinted) {
m_headerPrinted = false;
@@ -16738,6 +16964,11 @@ namespace Catch {
xml.writeAttribute( "name", name );
}
xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
+ // This is not ideal, but it should be enough to mimic gtest's
+ // junit output.
+ // Ideally the JUnit reporter would also handle `skipTest`
+ // events and write those out appropriately.
+ xml.writeAttribute( "status", "run" );
writeAssertions( sectionNode );
@@ -17172,6 +17403,10 @@ namespace Catch {
.writeAttribute( "successes", testGroupStats.totals.assertions.passed )
.writeAttribute( "failures", testGroupStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.scopedElement( "OverallResultsCases")
+ .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
+ .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
m_xml.endElement();
}
@@ -17181,6 +17416,10 @@ namespace Catch {
.writeAttribute( "successes", testRunStats.totals.assertions.passed )
.writeAttribute( "failures", testRunStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.scopedElement( "OverallResultsCases")
+ .writeAttribute( "successes", testRunStats.totals.testCases.passed )
+ .writeAttribute( "failures", testRunStats.totals.testCases.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
m_xml.endElement();
}
From 9a50a4ebfac1af103160e412dd5682c884e0d44f Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 12 Apr 2021 23:05:44 +0800
Subject: [PATCH 12/33] half supported browser forwarding
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 6 ++-
.../widgets/widgets/StreamSettingsWidget.cpp | 12 ++++++
.../widgets/widgets/StreamSettingsWidget.hpp | 20 ++++++---
.../widgets/widgets/StreamSettingsWidget.ui | 41 +++++++++++++++++--
translations/en_US.ts | 8 ++++
6 files changed, 76 insertions(+), 13 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 7ad6b3d0b..9f8f71580 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6183
+6184
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index 9cd3ede7e..e52bde221 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -225,8 +225,10 @@ namespace Qv2ray::base::objects
{
QString path = "/";
QMap headers;
- JSONSTRUCT_COMPARE(WebSocketObject, path, headers)
- JSONSTRUCT_REGISTER(WebSocketObject, F(path, headers))
+ int maxEarlyData = 1024;
+ bool useBrowserForwarding = false;
+ JSONSTRUCT_COMPARE(WebSocketObject, path, headers, maxEarlyData, useBrowserForwarding)
+ JSONSTRUCT_REGISTER(WebSocketObject, F(path, headers, maxEarlyData, useBrowserForwarding))
};
//
//
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.cpp b/src/ui/widgets/widgets/StreamSettingsWidget.cpp
index 35c5a0945..65be19ee9 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.cpp
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.cpp
@@ -74,6 +74,8 @@ void StreamSettingsWidget::SetStreamObject(const StreamSettingsObject &sso)
wsHeaders = wsHeaders % key % "|" % value % NEWLINE;
}
wsHeadersTxt->setPlainText(wsHeaders);
+ wsEarlyDataSB->setValue(stream.wsSettings.maxEarlyData);
+ wsBrowserForwardCB->setChecked(stream.wsSettings.useBrowserForwarding);
}
// mKCP
{
@@ -326,3 +328,13 @@ void StreamSettingsWidget::on_grpcServiceNameTxt_textEdited(const QString &arg1)
{
stream.grpcSettings.serviceName = arg1;
}
+
+void StreamSettingsWidget::on_wsEarlyDataSB_valueChanged(int arg1)
+{
+ stream.wsSettings.maxEarlyData = arg1;
+}
+
+void StreamSettingsWidget::on_wsBrowserForwardCB_stateChanged(int arg1)
+{
+ stream.wsSettings.useBrowserForwarding = arg1 == Qt::Checked;
+}
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.hpp b/src/ui/widgets/widgets/StreamSettingsWidget.hpp
index e2114b423..fb7fe7a36 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.hpp
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.hpp
@@ -18,12 +18,16 @@ class StreamSettingsWidget
StreamSettingsObject GetStreamSettings() const;
private slots:
+ void on_transportCombo_currentIndexChanged(int arg1);
+ // Domain Socket
void on_dsPathTxt_textEdited(const QString &arg1);
+ // HTTP
void on_httpHostTxt_textChanged();
void on_httpPathTxt_textEdited(const QString &arg1);
+ // KCP
void on_kcpCongestionCB_stateChanged(int arg1);
void on_kcpDownCapacitySB_valueChanged(int arg1);
void on_kcpHeaderType_currentIndexChanged(int arg1);
@@ -34,16 +38,21 @@ class StreamSettingsWidget
void on_kcpUploadCapacSB_valueChanged(int arg1);
void on_kcpWriteBufferSB_valueChanged(int arg1);
+ // QUIC
void on_quicHeaderTypeCB_currentIndexChanged(int arg1);
void on_quicKeyTxt_textEdited(const QString &arg1);
void on_quicSecurityCB_currentIndexChanged(int arg1);
+ // TLS/XTLS
void on_allowInsecureCB_stateChanged(int arg1);
void on_alpnTxt_textEdited(const QString &arg1);
void on_disableSessionResumptionCB_stateChanged(int arg1);
void on_securityTypeCB_currentIndexChanged(int arg1);
void on_serverNameTxt_textEdited(const QString &arg1);
+ void on_disableSystemRoot_stateChanged(int arg1);
+ void on_openCertEditorBtn_clicked();
+ // TCP
void on_tcpFastOpenCB_stateChanged(int arg1);
void on_tcpHeaderTypeCB_currentIndexChanged(int arg1);
void on_tcpRequestDefBtn_clicked();
@@ -51,18 +60,17 @@ class StreamSettingsWidget
void on_tcpRespDefBtn_clicked();
void on_tcpResponseEditBtn_clicked();
+ // SOCKOPT
void on_tProxyCB_currentIndexChanged(int arg1);
void on_soMarkSpinBox_valueChanged(int arg1);
- void on_transportCombo_currentIndexChanged(int arg1);
-
+ // WebSocket
void on_wsHeadersTxt_textChanged();
void on_wsPathTxt_textEdited(const QString &arg1);
+ void on_wsEarlyDataSB_valueChanged(int arg1);
+ void on_wsBrowserForwardCB_stateChanged(int arg1);
- void on_disableSystemRoot_stateChanged(int arg1);
-
- void on_openCertEditorBtn_clicked();
-
+ // gRPC
void on_grpcServiceNameTxt_textEdited(const QString &arg1);
private:
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.ui b/src/ui/widgets/widgets/StreamSettingsWidget.ui
index d7f4c295f..2c1500cef 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.ui
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.ui
@@ -194,15 +194,22 @@
-
-
-
-
+
+
-
Path
- -
+
-
+
+
+ Max Early Data
+
+
+
+ -
@@ -212,6 +219,33 @@
+ -
+
+
+ 0
+
+
+ 99999
+
+
+ 1024
+
+
+
+ -
+
+
+ Browser Forwarding
+
+
+
+ -
+
+
+ Enabled
+
+
+
-
@@ -842,7 +876,6 @@
tcpRespDefBtn
httpPathTxt
httpHostTxt
- wsPathTxt
wsHeadersTxt
kcpUploadCapacSB
kcpDownCapacitySB
diff --git a/translations/en_US.ts b/translations/en_US.ts
index f58097549..afdbb332c 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -3199,6 +3199,14 @@ Maybe you have downloaded the wrong core?
grpc
+
+ Max Early Data
+
+
+
+ Browser Forwarding
+
+
w_GroupManager
From acd9866a2cc8b51f5bce50216b85cc03f5012d03 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Tue, 13 Apr 2021 14:30:22 +0800
Subject: [PATCH 13/33] small refactors
---
makespec/BUILDVERSION | 2 +-
src/base/models/QvSafeType.hpp | 7 +-
src/core/kernel/V2RayKernelInteractions.cpp | 104 ++++++++++----------
src/core/kernel/V2RayKernelInteractions.hpp | 2 +-
src/ui/widgets/editors/w_RoutesEditor.hpp | 2 +-
src/ui/widgets/windows/w_ImportConfig.cpp | 6 +-
translations/en_US.ts | 4 -
7 files changed, 61 insertions(+), 66 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 9f8f71580..0a7419554 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6184
+6185
diff --git a/src/base/models/QvSafeType.hpp b/src/base/models/QvSafeType.hpp
index 8a37d566c..b83983f9e 100644
--- a/src/base/models/QvSafeType.hpp
+++ b/src/base/models/QvSafeType.hpp
@@ -46,7 +46,10 @@ namespace Qv2ray::base::safetype
{
return another.value1 == one.value1 && another.value2 == one.value2;
}
- JSONSTRUCT_REGISTER(___qvpair_t, F(value1, value2)) private : typedef QvPair ___qvpair_t;
+ JSONSTRUCT_REGISTER(___qvpair_t, F(value1, value2))
+
+ private:
+ typedef QvPair ___qvpair_t;
};
template>>
@@ -61,7 +64,7 @@ namespace Qv2ray::base::safetype
this->clear();
for (QString k_str : data.keys())
{
- auto k = (enumKey) k_str.remove(ENUM_JSON_KEY_PREFIX).toInt();
+ enumKey k = static_cast(k_str.remove(ENUM_JSON_KEY_PREFIX).toInt());
this->insert(k, data[ENUM_JSON_KEY_PREFIX + k_str]);
}
}
diff --git a/src/core/kernel/V2RayKernelInteractions.cpp b/src/core/kernel/V2RayKernelInteractions.cpp
index 68414d2bc..54c358ff0 100644
--- a/src/core/kernel/V2RayKernelInteractions.cpp
+++ b/src/core/kernel/V2RayKernelInteractions.cpp
@@ -153,16 +153,16 @@ namespace Qv2ray::core::kernel
return { true, SplitLines(output).at(0) };
}
- std::pair> V2RayKernelInstance::ValidateConfig(const QString &path)
+ std::optional V2RayKernelInstance::ValidateConfig(const QString &path)
{
- const auto &kernelPath = GlobalConfig.kernelConfig.KernelPath();
- const auto &assetsPath = GlobalConfig.kernelConfig.AssetsPath();
+ const auto kernelPath = GlobalConfig.kernelConfig.KernelPath();
+ const auto assetsPath = GlobalConfig.kernelConfig.AssetsPath();
if (const auto &[result, msg] = ValidateKernel(kernelPath, assetsPath); result)
{
DEBUG("V2Ray version: " + *msg);
// Append assets location env.
- QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- env.insert("V2RAY_LOCATION_ASSET", assetsPath);
+ auto env = QProcessEnvironment::systemEnvironment();
+ env.insert("v2ray.location.asset", assetsPath);
env.insert("XRAY_LOCATION_ASSET", assetsPath);
//
QProcess process;
@@ -175,15 +175,15 @@ namespace Qv2ray::core::kernel
{
QString output = QString(process.readAllStandardOutput());
QvMessageBoxWarn(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17));
- return { true, std::nullopt };
+ return std::nullopt;
}
DEBUG("Config file check passed.");
- return { true, std::nullopt };
+ return std::nullopt;
}
else
{
- return { false, msg };
+ return msg;
}
}
@@ -218,66 +218,62 @@ namespace Qv2ray::core::kernel
return tr("Invalid V2Ray Instance Status.");
}
- // Write the final configuration to the disk.
- QString json = JsonToString(root);
+ const auto json = JsonToString(root);
StringToFile(json, QV2RAY_GENERATED_FILE_PATH);
//
auto filePath = QV2RAY_GENERATED_FILE_PATH;
- if (const auto &&[result, msg] = ValidateConfig(filePath); result)
+ if (const auto &result = ValidateConfig(filePath); result)
{
- auto env = QProcessEnvironment::systemEnvironment();
- env.insert("V2RAY_LOCATION_ASSET", GlobalConfig.kernelConfig.AssetsPath());
- env.insert("XRAY_LOCATION_ASSET", GlobalConfig.kernelConfig.AssetsPath());
- vProcess->setProcessEnvironment(env);
- vProcess->start(GlobalConfig.kernelConfig.KernelPath(), { "-config", filePath }, QIODevice::ReadWrite | QIODevice::Text);
- vProcess->waitForStarted();
- kernelStarted = true;
-
- QMap> tagProtocolMap;
- for (const auto isOutbound : { GlobalConfig.uiConfig.graphConfig.useOutboundStats, false })
+ kernelStarted = false;
+ return tr("V2Ray kernel failed to start: ") + *result;
+ }
+ auto env = QProcessEnvironment::systemEnvironment();
+ env.insert("v2ray.location.asset", GlobalConfig.kernelConfig.AssetsPath());
+ env.insert("XRAY_LOCATION_ASSET", GlobalConfig.kernelConfig.AssetsPath());
+ vProcess->setProcessEnvironment(env);
+ vProcess->start(GlobalConfig.kernelConfig.KernelPath(), { "-config", filePath }, QIODevice::ReadWrite | QIODevice::Text);
+ vProcess->waitForStarted();
+ kernelStarted = true;
+
+ QMap> tagProtocolMap;
+ for (const auto isOutbound : { GlobalConfig.uiConfig.graphConfig.useOutboundStats, false })
+ {
+ for (const auto &item : root[isOutbound ? "outbounds" : "inbounds"].toArray())
{
- for (const auto &item : root[isOutbound ? "outbounds" : "inbounds"].toArray())
+ const auto tag = item.toObject()["tag"].toString("");
+ if (tag == API_TAG_INBOUND)
+ continue;
+ if (tag.isEmpty())
{
- const auto tag = item.toObject()["tag"].toString("");
- if (tag == API_TAG_INBOUND)
- continue;
- if (tag.isEmpty())
- {
- LOG("Ignored inbound with empty tag.");
- continue;
- }
- tagProtocolMap[isOutbound][tag] = item.toObject()["protocol"].toString();
+ LOG("Ignored inbound with empty tag.");
+ continue;
}
+ tagProtocolMap[isOutbound][tag] = item.toObject()["protocol"].toString();
}
+ }
- apiEnabled = false;
- if (QvCoreApplication->StartupArguments.noAPI)
- {
- LOG("API has been disabled by the command line arguments");
- }
- else if (!GlobalConfig.kernelConfig.enableAPI)
- {
- LOG("API has been disabled by the global config option");
- }
- else if (tagProtocolMap.isEmpty())
- {
- LOG("RARE: API is disabled since no inbound tags configured. This is usually caused by a bad complex config.");
- }
- else
- {
- DEBUG("Starting API");
- apiWorker->StartAPI(tagProtocolMap);
- apiEnabled = true;
- }
-
- return std::nullopt;
+ apiEnabled = false;
+ if (QvCoreApplication->StartupArguments.noAPI)
+ {
+ LOG("API has been disabled by the command line arguments");
+ }
+ else if (!GlobalConfig.kernelConfig.enableAPI)
+ {
+ LOG("API has been disabled by the global config option");
+ }
+ else if (tagProtocolMap.isEmpty())
+ {
+ LOG("RARE: API is disabled since no inbound tags configured. This is usually caused by a bad complex config.");
}
else
{
- kernelStarted = false;
- return tr("V2Ray kernel failed to start: ") + *msg;
+ DEBUG("Starting API");
+ apiWorker->StartAPI(tagProtocolMap);
+ apiEnabled = true;
}
+
+ return std::nullopt;
}
void V2RayKernelInstance::StopConnection()
diff --git a/src/core/kernel/V2RayKernelInteractions.hpp b/src/core/kernel/V2RayKernelInteractions.hpp
index 0935fc9ce..513d199b5 100644
--- a/src/core/kernel/V2RayKernelInteractions.hpp
+++ b/src/core/kernel/V2RayKernelInteractions.hpp
@@ -21,7 +21,7 @@ namespace Qv2ray::core::kernel
return kernelStarted;
}
//
- static std::pair> ValidateConfig(const QString &path);
+ static std::optional ValidateConfig(const QString &path);
static std::pair> ValidateKernel(const QString &vCorePath, const QString &vAssetsPath);
#if QV2RAY_FEATURE(kernel_check_permission)
static std::pair> CheckAndSetCoreExecutableState(const QString &vCorePath);
diff --git a/src/ui/widgets/editors/w_RoutesEditor.hpp b/src/ui/widgets/editors/w_RoutesEditor.hpp
index 4a698244e..5cf4673de 100644
--- a/src/ui/widgets/editors/w_RoutesEditor.hpp
+++ b/src/ui/widgets/editors/w_RoutesEditor.hpp
@@ -59,7 +59,7 @@ class RouteEditor
void on_linkExistingBtn_clicked();
void on_importOutboundBtn_clicked();
- private:
+ private slots:
void OnDispatcherEditChainRequested(const QString &);
void OnDispatcherOutboundDeleted(const complex::OutboundObjectMeta &);
void OnDispatcherOutboundCreated(std::shared_ptr, QtNodes::Node &);
diff --git a/src/ui/widgets/windows/w_ImportConfig.cpp b/src/ui/widgets/windows/w_ImportConfig.cpp
index 9b36bd8c5..81f96ef0f 100644
--- a/src/ui/widgets/windows/w_ImportConfig.cpp
+++ b/src/ui/widgets/windows/w_ImportConfig.cpp
@@ -254,7 +254,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
if (!linkErrors.isEmpty())
{
- for (const auto &item : linkErrors)
+ for (const auto &item : qAsConst(linkErrors))
{
vmessConnectionStringTxt->appendPlainText(linkErrors.key(item));
errorsList->addItem(item);
@@ -290,9 +290,9 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
bool ImportAsComplex = keepImportedInboundCheckBox->isChecked();
const auto path = fileLineTxt->text();
- if (const auto &&[result, msg] = V2RayKernelInstance::ValidateConfig(path); !result)
+ if (const auto &result = V2RayKernelInstance::ValidateConfig(path); result)
{
- QvMessageBoxWarn(this, tr("Import config file"), *msg);
+ QvMessageBoxWarn(this, tr("Import config file"), *result);
return;
}
diff --git a/translations/en_US.ts b/translations/en_US.ts
index afdbb332c..1b43826fa 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -806,10 +806,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Log
-
- Clear log
-
-
Not Connected
From c2fc5e712b7569a462404fb5cee6d243fef9a873 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Tue, 13 Apr 2021 14:48:20 +0800
Subject: [PATCH 14/33] small refactors 2
---
makespec/BUILDVERSION | 2 +-
src/base/models/QvSafeType.hpp | 2 ++
src/base/models/QvSettingsObject.hpp | 2 ++
src/ui/common/speedchart/speedwidget.cpp | 30 ++++++++--------
translations/en_US.ts | 46 ++++++++++--------------
5 files changed, 38 insertions(+), 44 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 0a7419554..c88bcbc71 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6185
+6186
diff --git a/src/base/models/QvSafeType.hpp b/src/base/models/QvSafeType.hpp
index b83983f9e..1bea96b73 100644
--- a/src/base/models/QvSafeType.hpp
+++ b/src/base/models/QvSafeType.hpp
@@ -86,3 +86,5 @@ namespace Qv2ray::base::safetype
};
} // namespace Qv2ray::base::safetype
+
+using namespace Qv2ray::base::safetype;
diff --git a/src/base/models/QvSettingsObject.hpp b/src/base/models/QvSettingsObject.hpp
index 2cf3992bd..2dad2c47d 100644
--- a/src/base/models/QvSettingsObject.hpp
+++ b/src/base/models/QvSettingsObject.hpp
@@ -37,6 +37,8 @@ namespace Qv2ray::base::config
safetype::QvEnumMap> colorConfig;
JSONSTRUCT_COMPARE(Qv2rayConfig_Graph, useOutboundStats, hasDirectStats, colorConfig)
JSONSTRUCT_REGISTER(Qv2rayConfig_Graph, F(useOutboundStats, hasDirectStats, colorConfig))
+ const static inline QvPair DefaultPen{ { 134, 196, 63, 1.5f, Qt::SolidLine }, { 50, 153, 255, 1.5f, Qt::SolidLine } };
+ const static inline QvPair DirectPen{ { 0, 210, 240, 1.5f, Qt::DotLine }, { 235, 220, 42, 1.5f, Qt::DotLine } };
};
struct Qv2rayConfig_UI
diff --git a/src/ui/common/speedchart/speedwidget.cpp b/src/ui/common/speedchart/speedwidget.cpp
index ecfa9e58c..68d296b0b 100644
--- a/src/ui/common/speedchart/speedwidget.cpp
+++ b/src/ui/common/speedchart/speedwidget.cpp
@@ -161,17 +161,16 @@ QString formatLabel(const double argValue, const SizeUnit unit)
void SpeedWidget::UpdateSpeedPlotSettings()
{
-#define Graph GlobalConfig.uiConfig.graphConfig
-#define _X_(x, y) \
- if (!Graph.colorConfig.contains(x)) \
- Graph.colorConfig[x] = y;
+ auto &Graph = GlobalConfig.uiConfig.graphConfig;
- const static QvPair defaultPen{ { 134, 196, 63, 1.5f, Qt::SolidLine }, { 50, 153, 255, 1.5f, Qt::SolidLine } };
- const static QvPair directPen{ { 0, 210, 240, 1.5f, Qt::DotLine }, { 235, 220, 42, 1.5f, Qt::DotLine } };
+ const auto apply_penconfig = [&](StatisticsType x, QvPair y) {
+ if (!Graph.colorConfig.contains(x))
+ Graph.colorConfig[x] = y;
+ };
- _X_(API_INBOUND, defaultPen);
- _X_(API_OUTBOUND_PROXY, Graph.colorConfig[API_INBOUND]);
- _X_(API_OUTBOUND_DIRECT, directPen);
+ apply_penconfig(API_INBOUND, Qv2rayConfig_Graph::DefaultPen);
+ apply_penconfig(API_OUTBOUND_PROXY, Graph.colorConfig[API_INBOUND]);
+ apply_penconfig(API_OUTBOUND_DIRECT, Qv2rayConfig_Graph::DirectPen);
const auto getPen = [](const QvGraphPenConfig &conf) {
QPen p{ { conf.R, conf.G, conf.B } };
@@ -183,20 +182,19 @@ void SpeedWidget::UpdateSpeedPlotSettings()
m_properties.clear();
if (Graph.useOutboundStats)
{
- m_properties[OUTBOUND_PROXY_UP] = { tr("Proxy ↑"), getPen(Graph.colorConfig[API_OUTBOUND_PROXY].value1) };
- m_properties[OUTBOUND_PROXY_DOWN] = { tr("Proxy ↓"), getPen(Graph.colorConfig[API_OUTBOUND_PROXY].value2) };
+ m_properties[OUTBOUND_PROXY_UP] = { tr("Proxy") + " ↑", getPen(Graph.colorConfig[API_OUTBOUND_PROXY].value1) };
+ m_properties[OUTBOUND_PROXY_DOWN] = { tr("Proxy") + " ↓", getPen(Graph.colorConfig[API_OUTBOUND_PROXY].value2) };
if (Graph.hasDirectStats)
{
- m_properties[OUTBOUND_DIRECT_UP] = { tr("Direct ↑"), getPen(Graph.colorConfig[API_OUTBOUND_DIRECT].value1) };
- m_properties[OUTBOUND_DIRECT_DOWN] = { tr("Direct ↓"), getPen(Graph.colorConfig[API_OUTBOUND_DIRECT].value2) };
+ m_properties[OUTBOUND_DIRECT_UP] = { tr("Direct") + " ↑", getPen(Graph.colorConfig[API_OUTBOUND_DIRECT].value1) };
+ m_properties[OUTBOUND_DIRECT_DOWN] = { tr("Direct") + " ↓", getPen(Graph.colorConfig[API_OUTBOUND_DIRECT].value2) };
}
}
else
{
- m_properties[INBOUND_UP] = { tr("Total ↑"), getPen(Graph.colorConfig[API_INBOUND].value1) };
- m_properties[INBOUND_DOWN] = { tr("Total ↓"), getPen(Graph.colorConfig[API_INBOUND].value2) };
+ m_properties[INBOUND_UP] = { tr("Total") + " ↑", getPen(Graph.colorConfig[API_INBOUND].value1) };
+ m_properties[INBOUND_DOWN] = { tr("Total") + " ↓", getPen(Graph.colorConfig[API_INBOUND].value2) };
}
-#undef Graph
}
void SpeedWidget::Clear()
diff --git a/translations/en_US.ts b/translations/en_US.ts
index 1b43826fa..6e7801371 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -1124,6 +1124,10 @@ This entry is ignored by V2Ray core when using DoH servers.
Disable Bypassing CN Mainland
+
+ Clear log
+
+
OutboundEditor
@@ -2994,33 +2998,6 @@ Maybe you have downloaded the wrong core?
-
- SpeedWidget
-
- Proxy ↑
-
-
-
- Proxy ↓
-
-
-
- Direct ↑
-
-
-
- Direct ↓
-
-
-
- Total ↑
-
-
-
- Total ↓
-
-
-
StreamSettingsWidget
@@ -3762,4 +3739,19 @@ Maybe you have downloaded the wrong core?
+
+ SpeedWidget
+
+ Proxy
+
+
+
+ Direct
+
+
+
+ Total
+
+
+
From dfaeab368462f6827f4bc0498ea5717aa07721ef Mon Sep 17 00:00:00 2001
From: DuckSoft
Date: Fri, 16 Apr 2021 23:09:21 +0800
Subject: [PATCH 15/33] Update deb.yml
---
.github/workflows/deb.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/deb.yml b/.github/workflows/deb.yml
index fbf0753ae..13f88b0aa 100644
--- a/.github/workflows/deb.yml
+++ b/.github/workflows/deb.yml
@@ -2,8 +2,8 @@ name: Qv2ray build debian package
on:
push:
- branches-ignore:
- - l10n_dev
+ branches:
+ - dev
release:
types: [prereleased]
From 12ec124895cc96350fbaaae2ea9e6dc08100b2bb Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Sat, 17 Apr 2021 19:13:02 +0800
Subject: [PATCH 16/33] fix: use upstream default fakedns ip pool
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index c88bcbc71..36a9d9be8 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6186
+6187
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index e52bde221..a46979b7c 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -339,7 +339,7 @@ namespace Qv2ray::base::objects
struct FakeDNSObject
{
- QString ipPool = "240.0.0.0/8";
+ QString ipPool = "198.18.0.0/15";
int poolSize = 65535;
JSONSTRUCT_REGISTER(FakeDNSObject, A(ipPool, poolSize))
JSONSTRUCT_COMPARE(FakeDNSObject, ipPool, poolSize)
From 04df5f83bb4b15bf2977f66a1e3f405679c64579 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Sat, 17 Apr 2021 20:31:59 +0800
Subject: [PATCH 17/33] add: added BrowserForwarder, Observatory,
ChainPortAllocation, BalancerStrategyType, InboundFakeDNSOthers
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 13 +-
src/base/models/QvComplexConfigModels.hpp | 3 +-
src/ui/widgets/editors/w_InboundEditor.cpp | 15 ++
src/ui/widgets/editors/w_InboundEditor.hpp | 4 +
src/ui/widgets/editors/w_InboundEditor.ui | 13 +-
src/ui/widgets/editors/w_RoutesEditor.cpp | 65 ++++++---
src/ui/widgets/editors/w_RoutesEditor.hpp | 1 -
src/ui/widgets/editors/w_RoutesEditor.ui | 57 +++++++-
.../widgets/node/widgets/BalancerWidget.cpp | 11 ++
.../widgets/node/widgets/BalancerWidget.hpp | 2 +
src/ui/widgets/node/widgets/BalancerWidget.ui | 135 ++++++++++++------
.../node/widgets/ChainOutboundWidget.cpp | 11 +-
.../node/widgets/ChainOutboundWidget.hpp | 5 +
.../node/widgets/ChainOutboundWidget.ui | 23 ++-
translations/en_US.ts | 48 ++++++-
16 files changed, 328 insertions(+), 80 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 36a9d9be8..476ab3f18 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6187
+6189
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index a46979b7c..ebb60805d 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -126,12 +126,21 @@ namespace Qv2ray::base::objects
};
//
//
+
+ struct StrategyObject
+ {
+ QString type;
+ JSONSTRUCT_COMPARE(StrategyObject, type)
+ JSONSTRUCT_REGISTER(StrategyObject, F(type))
+ };
+
struct BalancerObject
{
QString tag;
QList selector;
- JSONSTRUCT_COMPARE(BalancerObject, tag, selector)
- JSONSTRUCT_REGISTER(BalancerObject, F(tag, selector))
+ StrategyObject strategy;
+ JSONSTRUCT_COMPARE(BalancerObject, tag, selector, strategy)
+ JSONSTRUCT_REGISTER(BalancerObject, F(tag, selector, strategy))
};
//
//
diff --git a/src/base/models/QvComplexConfigModels.hpp b/src/base/models/QvComplexConfigModels.hpp
index 8148c79be..a4f1d6c75 100644
--- a/src/base/models/QvComplexConfigModels.hpp
+++ b/src/base/models/QvComplexConfigModels.hpp
@@ -62,6 +62,7 @@ namespace Qv2ray::base::objects::complex
//
ConnectionId connectionId;
QList outboundTags;
+ QString strategyType;
int chainPortAllocation = QV2RAY_CHAINED_OUTBOUND_PORT_ALLOCATION;
//
safetype::OUTBOUND realOutbound;
@@ -80,7 +81,7 @@ namespace Qv2ray::base::objects::complex
return meta;
}
OutboundObjectMeta() : metaType(METAOUTBOUND_ORIGINAL){};
- JSONSTRUCT_REGISTER(OutboundObjectMeta, F(metaType, displayName, connectionId, outboundTags, chainPortAllocation))
+ JSONSTRUCT_REGISTER(OutboundObjectMeta, F(metaType, displayName, connectionId, outboundTags, chainPortAllocation, strategyType))
};
inline OutboundObjectMeta make_chained_outbound(const QList &chain, const QString &tag)
diff --git a/src/ui/widgets/editors/w_InboundEditor.cpp b/src/ui/widgets/editors/w_InboundEditor.cpp
index d967bca05..74f879b0b 100644
--- a/src/ui/widgets/editors/w_InboundEditor.cpp
+++ b/src/ui/widgets/editors/w_InboundEditor.cpp
@@ -125,6 +125,7 @@ void InboundEditor::loadUI()
sniffHTTPCB->setChecked(data.contains("http"));
sniffTLSCB->setChecked(data.contains("tls"));
sniffFakeDNSCB->setChecked(data.contains("fakedns"));
+ sniffFakeDNSOtherCB->setChecked(data.contains("fakedns+others"));
}
bool processed = false;
const auto settings = current["settings"].toObject();
@@ -214,6 +215,7 @@ void InboundEditor::on_sniffMetaDataOnlyCB_clicked(bool checked)
const auto hasHTTP = sniffHTTPCB->isChecked(); \
const auto hasTLS = sniffTLSCB->isChecked(); \
const auto hasFakeDNS = sniffFakeDNSCB->isChecked(); \
+ const auto hasFakeDNSOthers = sniffFakeDNSOtherCB->isChecked(); \
QStringList list; \
if (hasHTTP) \
list << "http"; \
@@ -221,6 +223,8 @@ void InboundEditor::on_sniffMetaDataOnlyCB_clicked(bool checked)
list << "tls"; \
if (hasFakeDNS) \
list << "fakedns"; \
+ if (hasFakeDNSOthers) \
+ list << "fakedns+others"; \
sniffingSettings["destOverride"] = QJsonArray::fromStringList(list); \
} while (0)
@@ -235,6 +239,17 @@ void InboundEditor::on_sniffTLSCB_stateChanged(int)
CHECKLOADING
SET_SNIFF_DEST_OVERRIDE;
}
+void InboundEditor::on_sniffFakeDNSOtherCB_stateChanged(int)
+{
+ CHECKLOADING
+ SET_SNIFF_DEST_OVERRIDE;
+}
+
+void InboundEditor::on_sniffFakeDNSCB_stateChanged(int)
+{
+ CHECKLOADING
+ SET_SNIFF_DEST_OVERRIDE;
+}
void InboundEditor::on_stackedWidget_currentChanged(int)
{
diff --git a/src/ui/widgets/editors/w_InboundEditor.hpp b/src/ui/widgets/editors/w_InboundEditor.hpp
index 422c6e6f2..ed4a3fa31 100644
--- a/src/ui/widgets/editors/w_InboundEditor.hpp
+++ b/src/ui/widgets/editors/w_InboundEditor.hpp
@@ -48,6 +48,10 @@ class InboundEditor
void on_sniffMetaDataOnlyCB_clicked(bool checked);
+ void on_sniffFakeDNSOtherCB_stateChanged(int arg1);
+
+ void on_sniffFakeDNSCB_stateChanged(int arg1);
+
private:
StreamSettingsWidget *streamSettingsWidget;
INBOUND getResult();
diff --git a/src/ui/widgets/editors/w_InboundEditor.ui b/src/ui/widgets/editors/w_InboundEditor.ui
index 6abed72ac..d367ced15 100644
--- a/src/ui/widgets/editors/w_InboundEditor.ui
+++ b/src/ui/widgets/editors/w_InboundEditor.ui
@@ -104,6 +104,13 @@
true
+ -
+
+
+ FakeDNS-Others
+
+
+
-
@@ -118,10 +125,10 @@
- -
+
-
- Destination Override:
+ Destination Override
@@ -139,7 +146,7 @@
- -
+
-
Metadata Only
diff --git a/src/ui/widgets/editors/w_RoutesEditor.cpp b/src/ui/widgets/editors/w_RoutesEditor.cpp
index 316772951..b834bc4c6 100644
--- a/src/ui/widgets/editors/w_RoutesEditor.cpp
+++ b/src/ui/widgets/editors/w_RoutesEditor.cpp
@@ -84,7 +84,7 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog("Ro
//
isLoading = true;
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
- updateColorScheme();
+ RouteEditor::updateColorScheme();
//
// Do not change the order.
nodeDispatcher = std::make_shared();
@@ -99,21 +99,19 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog("Ro
connect(nodeDispatcher.get(), &NodeDispatcher::OnInboundOutboundNodeHovered, this, &RouteEditor::OnDispatcherInboundOutboundHovered);
connect(nodeDispatcher.get(), &NodeDispatcher::RequestEditChain, this, &RouteEditor::OnDispatcherEditChainRequested);
connect(nodeDispatcher.get(), &NodeDispatcher::OnObjectTagChanged, this, &RouteEditor::OnDispatcherObjectTagChanged);
- //
-#define SETLAYOUT(parent, child) \
- { \
- if (!parent->layout()) \
- { \
- parent->setLayout(new QVBoxLayout()); \
- } \
- auto l = parent->layout(); \
- l->addWidget(child); \
- l->setContentsMargins(0, 0, 0, 0); \
- l->setSpacing(0); \
- }
- SETLAYOUT(ruleEditorUIWidget, ruleWidget);
- SETLAYOUT(chainEditorUIWidget, chainWidget);
- SETLAYOUT(dnsEditorUIWidget, dnsWidget);
+
+ const auto SetUpLayout = [](QWidget *parent, QWidget *child) {
+ if (!parent->layout())
+ parent->setLayout(new QVBoxLayout());
+ auto l = parent->layout();
+ l->addWidget(child);
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+ };
+
+ SetUpLayout(ruleEditorUIWidget, ruleWidget);
+ SetUpLayout(chainEditorUIWidget, chainWidget);
+ SetUpLayout(dnsEditorUIWidget, dnsWidget);
//
nodeDispatcher->LoadFullConfig(root);
dnsWidget->SetDNSObject(DNSObject::fromJson(root["dns"].toObject()), FakeDNSObject::fromJson(root["fakedns"].toObject()));
@@ -124,6 +122,10 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog("Ro
// Set default outboung combo text AFTER adding all outbounds.
defaultOutboundTag = getTag(OUTBOUND(root["outbounds"].toArray().first().toObject()));
defaultOutboundCombo->setCurrentText(defaultOutboundTag);
+ //
+ bfListenIPTxt->setText(root["browserForwarder"].toObject()["listenAddr"].toString());
+ bfListenPortTxt->setValue(root["browserForwarder"].toObject()["listenPort"].toInt());
+ obSubjectSelectorTxt->setPlainText(root["observatory"].toObject()["subjectSelector"].toVariant().toStringList().join(NEWLINE));
for (const auto &group : ConnectionManager->AllGroups())
{
@@ -261,6 +263,7 @@ CONFIGROOT RouteEditor::OpenEditor()
o.tag = out.getDisplayName();
o.selector = out.outboundTags;
balancersArray << o.toJson();
+ o.strategy.type = out.strategyType;
}
QJsonObject routingObject;
@@ -269,7 +272,6 @@ CONFIGROOT RouteEditor::OpenEditor()
routingObject["balancers"] = balancersArray;
root["routing"] = routingObject;
- //
// QJsonArray Outbounds
QJsonArray outboundsArray;
@@ -290,9 +292,23 @@ CONFIGROOT RouteEditor::OpenEditor()
outboundsArray.append(outboundJsonObject);
}
root["outbounds"] = outboundsArray;
+ // Process DNS
const auto &[dns, fakedns] = dnsWidget->GetDNSObject();
root["dns"] = GenerateDNS(dns);
root["fakedns"] = fakedns.toJson();
+ {
+ // Process Browser Forwarder
+ QJsonObject browserForwarder;
+ browserForwarder["listenAddr"] = bfListenIPTxt->text();
+ browserForwarder["listenPort"] = bfListenPortTxt->value();
+ root["browserForwarder"] = browserForwarder;
+ }
+ {
+ // Process Observatory
+ QJsonObject observatory;
+ observatory["subjectSelector"] = QJsonArray::fromStringList(SplitLines(obSubjectSelectorTxt->toPlainText()));
+ root["observatory"] = observatory;
+ }
return root;
}
@@ -301,10 +317,6 @@ RouteEditor::~RouteEditor()
nodeDispatcher->LockOperation();
}
-void RouteEditor::on_buttonBox_accepted()
-{
-}
-
void RouteEditor::on_insertDirectBtn_clicked()
{
auto freedom = GenerateFreedomOUT("AsIs", "");
@@ -312,6 +324,7 @@ void RouteEditor::on_insertDirectBtn_clicked()
auto out = GenerateOutboundEntry(tag, "freedom", freedom, {});
// ADD NODE
const auto _ = nodeDispatcher->CreateOutbound(make_normal_outbound(out));
+ Q_UNUSED(_)
statusLabel->setText(tr("Added DIRECT outbound"));
}
@@ -333,6 +346,7 @@ void RouteEditor::on_addDefaultBtn_clicked()
httpSettings, //
inboundConfig.httpSettings.sniffing ? sniffingOn : sniffingOff);
const auto _ = nodeDispatcher->CreateInbound(httpConfig);
+ Q_UNUSED(_)
}
if (inboundConfig.useSocks)
{
@@ -366,6 +380,7 @@ void RouteEditor::on_addDefaultBtn_clicked()
tProxyIn.insert("sniffing", tproxy_sniff);
tProxyIn.insert("streamSettings", tproxy_streamSettings);
auto _ = nodeDispatcher->CreateInbound(tProxyIn);
+ Q_UNUSED(_)
}
if (!ts.tProxyV6IP.isEmpty())
{
@@ -373,6 +388,7 @@ void RouteEditor::on_addDefaultBtn_clicked()
tProxyV6In.insert("sniffing", tproxy_sniff);
tProxyV6In.insert("streamSettings", tproxy_streamSettings);
auto _ = nodeDispatcher->CreateInbound(tProxyV6In);
+ Q_UNUSED(_)
}
#undef ts
}
@@ -385,6 +401,7 @@ void RouteEditor::on_insertBlackBtn_clicked()
auto tag = "BlackHole-" + QSTRN(QTime::currentTime().msecsSinceStartOfDay());
auto outbound = GenerateOutboundEntry(tag, "blackhole", blackHole, {});
const auto _ = nodeDispatcher->CreateOutbound(make_normal_outbound(outbound));
+ Q_UNUSED(_)
}
void RouteEditor::on_addInboundBtn_clicked()
@@ -396,6 +413,7 @@ void RouteEditor::on_addInboundBtn_clicked()
if (w.result() == QDialog::Accepted)
{
auto _ = nodeDispatcher->CreateInbound(_result);
+ Q_UNUSED(_)
}
}
@@ -434,6 +452,7 @@ void RouteEditor::on_importExistingBtn_clicked()
auto outbound = OUTBOUND(root["outbounds"].toArray()[0].toObject());
outbound["tag"] = GetDisplayName(_id);
auto _ = nodeDispatcher->CreateOutbound(make_normal_outbound(outbound));
+ Q_UNUSED(_)
};
const auto cid = ConnectionId{ importConnBtn->currentData(Qt::UserRole).toString() };
@@ -460,6 +479,7 @@ void RouteEditor::on_linkExistingBtn_clicked()
{
const auto ImportConnection = [this](const ConnectionId &_id) {
auto _ = nodeDispatcher->CreateOutbound(make_external_outbound(_id, GetDisplayName(_id)));
+ Q_UNUSED(_)
};
const auto cid = ConnectionId{ importConnBtn->currentData(Qt::UserRole).toString() };
@@ -497,11 +517,13 @@ void RouteEditor::on_importGroupBtn_currentIndexChanged(int)
void RouteEditor::on_addBalancerBtn_clicked()
{
auto _ = nodeDispatcher->CreateOutbound(make_balancer_outbound({}, "Balancer"));
+ Q_UNUSED(_)
}
void RouteEditor::on_addChainBtn_clicked()
{
auto _ = nodeDispatcher->CreateOutbound(make_chained_outbound({}, "Chained Outbound"));
+ Q_UNUSED(_)
}
void RouteEditor::on_debugPainterCB_clicked(bool checked)
@@ -534,6 +556,7 @@ void RouteEditor::on_importOutboundBtn_clicked()
for (int i = 0; i < confList.count(); i++)
{
auto _ = nodeDispatcher->CreateOutbound(make_normal_outbound(OUTBOUND(confList[i].toObject())));
+ Q_UNUSED(_)
}
}
}
diff --git a/src/ui/widgets/editors/w_RoutesEditor.hpp b/src/ui/widgets/editors/w_RoutesEditor.hpp
index 5cf4673de..bae4072e1 100644
--- a/src/ui/widgets/editors/w_RoutesEditor.hpp
+++ b/src/ui/widgets/editors/w_RoutesEditor.hpp
@@ -48,7 +48,6 @@ class RouteEditor
void on_addDefaultBtn_clicked();
void on_addInboundBtn_clicked();
void on_addOutboundBtn_clicked();
- void on_buttonBox_accepted();
void on_debugPainterCB_clicked(bool checked);
void on_defaultOutboundCombo_currentTextChanged(const QString &arg1);
void on_domainStrategyCombo_currentIndexChanged(int arg1);
diff --git a/src/ui/widgets/editors/w_RoutesEditor.ui b/src/ui/widgets/editors/w_RoutesEditor.ui
index 29ebe7d12..0be10ad9f 100644
--- a/src/ui/widgets/editors/w_RoutesEditor.ui
+++ b/src/ui/widgets/editors/w_RoutesEditor.ui
@@ -275,7 +275,7 @@
-
- 0
+ 3
@@ -321,6 +321,61 @@
+
+
+ Misc
+
+
+ -
+
+
+ Browser Forwarder
+
+
+
-
+
+
+ Listening Address
+
+
+
+ -
+
+
+ -
+
+
+ :Listening Port
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Observatory
+
+
+
-
+
+
+ Subject Selector
+
+
+
+ -
+
+
+
+
+
+
+
-
diff --git a/src/ui/widgets/node/widgets/BalancerWidget.cpp b/src/ui/widgets/node/widgets/BalancerWidget.cpp
index 93e38701d..7f27829fe 100644
--- a/src/ui/widgets/node/widgets/BalancerWidget.cpp
+++ b/src/ui/widgets/node/widgets/BalancerWidget.cpp
@@ -19,6 +19,7 @@ void BalancerWidget::setValue(std::shared_ptr data)
balancerSelectionCombo->addItems(dispatcher->GetRealOutboundTags());
balancerTagTxt->setText(data->getDisplayName());
balancerList->addItems(data->outboundTags);
+ strategyCB->setCurrentText(data->strategyType);
}
void BalancerWidget::changeEvent(QEvent *e)
@@ -86,3 +87,13 @@ void BalancerWidget::on_balancerTagTxt_textEdited(const QString &arg1)
RED(balancerTagTxt);
}
}
+
+void BalancerWidget::on_showHideBtn_clicked()
+{
+ tabWidget->setVisible(!tabWidget->isVisible());
+}
+
+void BalancerWidget::on_strategyCB_currentIndexChanged(const QString &arg1)
+{
+ outboundData->strategyType = arg1;
+}
diff --git a/src/ui/widgets/node/widgets/BalancerWidget.hpp b/src/ui/widgets/node/widgets/BalancerWidget.hpp
index db8368a1f..3aa6b54d0 100644
--- a/src/ui/widgets/node/widgets/BalancerWidget.hpp
+++ b/src/ui/widgets/node/widgets/BalancerWidget.hpp
@@ -16,6 +16,8 @@ class BalancerWidget
void on_balancerAddBtn_clicked();
void on_balancerDelBtn_clicked();
void on_balancerTagTxt_textEdited(const QString &arg1);
+ void on_showHideBtn_clicked();
+ void on_strategyCB_currentIndexChanged(const QString &arg1);
private:
void OutboundCreated(std::shared_ptr, QtNodes::Node &);
diff --git a/src/ui/widgets/node/widgets/BalancerWidget.ui b/src/ui/widgets/node/widgets/BalancerWidget.ui
index 66bdfc646..8ad3c2769 100644
--- a/src/ui/widgets/node/widgets/BalancerWidget.ui
+++ b/src/ui/widgets/node/widgets/BalancerWidget.ui
@@ -6,66 +6,115 @@
0
0
- 149
- 150
+ 247
+ 261
Form
-
-
-
+
+
-
- -
-
-
- true
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 48
-
-
-
-
- -
-
-
- -
-
+
-
+
-
-
-
-
- :/assets/icons/ui_dark/minus.svg:/assets/icons/ui_dark/minus.svg
+ Show / Hide
- -
-
-
-
-
-
-
- :/assets/icons/ui_dark/add.svg:/assets/icons/ui_dark/add.svg
+
-
+
+
+ 1
+
+
+ Selector
+
+
+
-
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
+ :/assets/icons/ui_dark/add.svg:/assets/icons/ui_dark/add.svg
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+ :/assets/icons/ui_dark/minus.svg:/assets/icons/ui_dark/minus.svg
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 17
+ 69
+
+
+
+
+
+
+
+
+ Strategy
+
+
+ -
+
+
+ Strategy
+
+
+
+ -
+
+
-
+
+ random
+
+
+ -
+
+ leastPing
+
+
+
+
+
+
-
+
diff --git a/src/ui/widgets/node/widgets/ChainOutboundWidget.cpp b/src/ui/widgets/node/widgets/ChainOutboundWidget.cpp
index 06cc7619b..a0b957d5f 100644
--- a/src/ui/widgets/node/widgets/ChainOutboundWidget.cpp
+++ b/src/ui/widgets/node/widgets/ChainOutboundWidget.cpp
@@ -4,11 +4,11 @@ ChainOutboundWidget::ChainOutboundWidget(std::shared_ptr _dispat
{
setupUi(this);
// Simple slot to update UI
- connect(_dispatcher.get(), &NodeDispatcher::OnObjectTagChanged, [this](ComplexTagNodeMode _t1, const QString _t2, const QString _t3) {
+ connect(_dispatcher.get(), &NodeDispatcher::OnObjectTagChanged, [this](ComplexTagNodeMode, const QString _t2, const QString _t3) {
if (tagLabel->text() == _t2)
{
tagLabel->setText(_t3);
- OnSizeUpdated();
+ emit OnSizeUpdated();
}
});
}
@@ -25,5 +25,12 @@ void ChainOutboundWidget::changeEvent(QEvent *e)
void ChainOutboundWidget::setValue(std::shared_ptr data)
{
+ chain = data;
tagLabel->setText(data->getDisplayName());
+ chainPortSB->setValue(data->chainPortAllocation);
+}
+
+void ChainOutboundWidget::on_chainPortSB_valueChanged(int arg1)
+{
+ chain->chainPortAllocation = arg1;
}
diff --git a/src/ui/widgets/node/widgets/ChainOutboundWidget.hpp b/src/ui/widgets/node/widgets/ChainOutboundWidget.hpp
index e98fa0a7e..a022aa42e 100644
--- a/src/ui/widgets/node/widgets/ChainOutboundWidget.hpp
+++ b/src/ui/widgets/node/widgets/ChainOutboundWidget.hpp
@@ -15,4 +15,9 @@ class ChainOutboundWidget
protected:
void changeEvent(QEvent *e);
+ private slots:
+ void on_chainPortSB_valueChanged(int arg1);
+
+ private:
+ std::shared_ptr chain;
};
diff --git a/src/ui/widgets/node/widgets/ChainOutboundWidget.ui b/src/ui/widgets/node/widgets/ChainOutboundWidget.ui
index 954511826..942b883b2 100644
--- a/src/ui/widgets/node/widgets/ChainOutboundWidget.ui
+++ b/src/ui/widgets/node/widgets/ChainOutboundWidget.ui
@@ -6,14 +6,14 @@
0
0
- 115
+ 421
31
Form
-
+
0
@@ -26,7 +26,7 @@
0
- -
+
-
@@ -36,6 +36,23 @@
+ -
+
+
+ Port
+
+
+
+ -
+
+
+ 15500
+
+
+ 65535
+
+
+
diff --git a/translations/en_US.ts b/translations/en_US.ts
index 6e7801371..79c562994 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -7,6 +7,18 @@
Form
+
+ Show / Hide
+
+
+
+ Selector
+
+
+
+ Strategy
+
+
CertificateItemWidget
@@ -113,6 +125,10 @@
Form
+
+ Port
+
+
ChainWidget
@@ -659,11 +675,15 @@ This entry is ignored by V2Ray core when using DoH servers.
- Destination Override:
+ Metadata Only
+
+
+
+ FakeDNS-Others
- Metadata Only
+ Destination Override
@@ -2753,6 +2773,30 @@ Maybe you have downloaded the wrong core?
Reference Connection
+
+ Misc
+
+
+
+ Browser Forwarder
+
+
+
+ Listening Address
+
+
+
+ :Listening Port
+
+
+
+ Observatory
+
+
+
+ Subject Selector
+
+
RouteSettingsMatrix
From 09aeb89f2cab1fcef42db9d5de289861eb35bf46 Mon Sep 17 00:00:00 2001
From: DuckSoft
Date: Mon, 19 Apr 2021 11:40:59 +0800
Subject: [PATCH 18/33] fix: tproxy inbound check (#1413)
* fix: tproxy inbound check
* fix: fixed more bugs created in bug fix to fix bugs bugs created in bug fix
* fix: mac shit
* bump buildversion
---
makespec/BUILDVERSION | 2 +-
.../widgets/windows/w_PreferencesWindow.cpp | 24 ++++++++++++++-----
.../widgets/windows/w_PreferencesWindow.hpp | 3 +++
translations/en_US.ts | 8 +++----
4 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 476ab3f18..97229aec7 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6189
+6190
diff --git a/src/ui/widgets/windows/w_PreferencesWindow.cpp b/src/ui/widgets/windows/w_PreferencesWindow.cpp
index 510b528ad..beae9132c 100644
--- a/src/ui/widgets/windows/w_PreferencesWindow.cpp
+++ b/src/ui/widgets/windows/w_PreferencesWindow.cpp
@@ -307,6 +307,22 @@ QvMessageBusSlotImpl(PreferencesWindow)
PreferencesWindow::~PreferencesWindow(){};
+std::optional PreferencesWindow::checkTProxySettings() const
+{
+ if (CurrentConfig.inboundConfig.useTPROXY)
+ {
+ if (!IsIPv4Address(CurrentConfig.inboundConfig.tProxySettings.tProxyIP))
+ {
+ return tr("Invalid tproxy listening ipv4 address.");
+ }
+ else if (CurrentConfig.inboundConfig.tProxySettings.tProxyV6IP != "" && !IsIPv6Address(CurrentConfig.inboundConfig.tProxySettings.tProxyV6IP))
+ {
+ return tr("Invalid tproxy listening ipv6 address.");
+ }
+ }
+ return std::nullopt;
+}
+
void PreferencesWindow::on_buttonBox_accepted()
{
// Note:
@@ -348,13 +364,9 @@ void PreferencesWindow::on_buttonBox_accepted()
{
QvMessageBoxWarn(this, tr("Preferences"), tr("Invalid inbound listening address."));
}
- else if (!IsIPv4Address(CurrentConfig.inboundConfig.tProxySettings.tProxyIP))
- {
- QvMessageBoxWarn(this, tr("Preferences"), tr("Invalid tproxy listening ivp4 address."));
- }
- else if (CurrentConfig.inboundConfig.tProxySettings.tProxyV6IP != "" && !IsIPv6Address(CurrentConfig.inboundConfig.tProxySettings.tProxyV6IP))
+ else if (const auto err = checkTProxySettings(); err.has_value())
{
- QvMessageBoxWarn(this, tr("Preferences"), tr("Invalid tproxy listening ipv6 address."));
+ QvMessageBoxWarn(this, tr("Preferences"), *err);
}
else if (!dnsSettingsWidget->CheckIsValidDNS())
{
diff --git a/src/ui/widgets/windows/w_PreferencesWindow.hpp b/src/ui/widgets/windows/w_PreferencesWindow.hpp
index de497ae0c..566a5bd4c 100644
--- a/src/ui/widgets/windows/w_PreferencesWindow.hpp
+++ b/src/ui/widgets/windows/w_PreferencesWindow.hpp
@@ -149,4 +149,7 @@ class PreferencesWindow
bool NeedRestart = false;
bool finishedLoading = false;
Qv2rayConfigObject CurrentConfig;
+
+ private:
+ std::optional checkTProxySettings() const;
};
diff --git a/translations/en_US.ts b/translations/en_US.ts
index 79c562994..f742212b0 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -1660,10 +1660,6 @@ Custom DNS Settings
Invalid inbound listening address.
-
- Invalid tproxy listening ivp4 address.
-
-
Invalid tproxy listening ipv6 address.
@@ -1964,6 +1960,10 @@ If you insist to proceed, we're not providing with any support.
FakeDNS
+
+ Invalid tproxy listening ipv4 address.
+
+
QObject
From 629ba94837c39c679e7571e2a0a5c1ab2a128848 Mon Sep 17 00:00:00 2001
From: ymshenyu
Date: Mon, 19 Apr 2021 12:38:39 +0800
Subject: [PATCH 19/33] migrate to gcc-9
---
.github/workflows/build-qv2ray-cmake.yml | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/build-qv2ray-cmake.yml b/.github/workflows/build-qv2ray-cmake.yml
index d20cd5526..6f419b542 100644
--- a/.github/workflows/build-qv2ray-cmake.yml
+++ b/.github/workflows/build-qv2ray-cmake.yml
@@ -49,7 +49,7 @@ jobs:
- name: Checking out sources
uses: actions/checkout@v2
with:
- submodules: 'recursive'
+ submodules: "recursive"
- name: Install Python 3.7 version
uses: actions/setup-python@v1
with:
@@ -111,7 +111,6 @@ jobs:
cd ./libs
./setup-libs.sh windows ${{ matrix.arch }}
# ========================================================================================================= Generate MakeFile and Build
-
- uses: actions/setup-node@v1
if: matrix.platform == 'macos-latest'
with:
@@ -157,8 +156,8 @@ jobs:
if: matrix.platform == 'ubuntu-16.04'
shell: bash
env:
- CC: /usr/bin/gcc-7
- CXX: /usr/bin/g++-7
+ CC: /usr/bin/gcc-9
+ CXX: /usr/bin/g++-9
run: |
mkdir build
cd build
From bb1cd2a7fc5510c3455b01cb0485870ddba8c0ec Mon Sep 17 00:00:00 2001
From: DuckSoft
Date: Mon, 19 Apr 2021 12:44:53 +0800
Subject: [PATCH 20/33] feat: added vless share link alpn support (#1417)
* feat: added vless share link alpn support
with parsing tested
* bump BUILDVERSION
---
makespec/BUILDVERSION | 2 +-
src/core/connection/serialization/vless.cpp | 8 +++++
.../protocols/core/OutboundHandler.cpp | 12 +++++++-
test/src/core/connection/TestParseVLESS.cpp | 29 +++++++++++++++++++
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 97229aec7..59693eb98 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6190
+6194
diff --git a/src/core/connection/serialization/vless.cpp b/src/core/connection/serialization/vless.cpp
index b1690bc5f..bc23399c7 100644
--- a/src/core/connection/serialization/vless.cpp
+++ b/src/core/connection/serialization/vless.cpp
@@ -156,6 +156,14 @@ namespace Qv2ray::core::connection
const auto sni = query.queryItemValue("sni");
QJsonIO::SetValue(stream, sni, { tlsKey, "serverName" });
}
+ // alpn
+ const auto hasALPN = query.hasQueryItem("alpn");
+ if (hasALPN)
+ {
+ const auto alpnRaw = QUrl::fromPercentEncoding(query.queryItemValue("alpn").toUtf8());
+ const auto alpnArray = QJsonArray::fromStringList(alpnRaw.split(","));
+ QJsonIO::SetValue(stream, alpnArray, { tlsKey, "alpn" });
+ }
// xtls-specific
if (security == "xtls")
{
diff --git a/src/plugins/protocols/core/OutboundHandler.cpp b/src/plugins/protocols/core/OutboundHandler.cpp
index baf2c5711..bd3391116 100644
--- a/src/plugins/protocols/core/OutboundHandler.cpp
+++ b/src/plugins/protocols/core/OutboundHandler.cpp
@@ -153,7 +153,17 @@ const QString BuiltinSerializer::SerializeOutbound(const QString &protocol, cons
const auto sni = QJsonIO::GetValue(objStream, { tlsKey, "serverName" }).toString();
if (!sni.isEmpty())
query.addQueryItem("sni", sni);
- // TODO: ALPN Support
+
+ // ALPN
+ const auto alpnArray = QJsonIO::GetValue(objStream, { tlsKey, "alpn" }).toArray();
+ QStringList alpnList;
+ for (const auto v : alpnArray)
+ {
+ const auto alpn = v.toString();
+ if (!alpn.isEmpty())
+ alpnList << alpn;
+ }
+ query.addQueryItem("alpn", QUrl::toPercentEncoding(alpnList.join(",")));
// -------- XTLS Flow --------
if (security == "xtls")
diff --git a/test/src/core/connection/TestParseVLESS.cpp b/test/src/core/connection/TestParseVLESS.cpp
index 91ecb3935..0949968ce 100644
--- a/test/src/core/connection/TestParseVLESS.cpp
+++ b/test/src/core/connection/TestParseVLESS.cpp
@@ -20,4 +20,33 @@ TEST_CASE("Test VLESS URL Parsing")
REQUIRE(errMessage.isEmpty());
REQUIRE(alias.toStdString() == "VLESSTCPXTLSSplice");
}
+
+ SECTION("ALPN Parse Test")
+ {
+ const static auto url = "vless://24a613c1-de83-4c63-ba73-a9d08c88fec3@qv2ray.net:13432?security=xtls&alpn=h2%2Chttp%2F1.1";
+
+ const auto result = vless::Deserialize(url, &alias, &errMessage);
+
+ INFO("Parsed: " << QJsonDocument(result).toJson().toStdString());
+ REQUIRE(errMessage.isEmpty());
+
+ const auto alpnField = QJsonIO::GetValue(result, "outbounds", 0, "streamSettings", "xtlsSettings", "alpn");
+ REQUIRE(alpnField.isArray());
+
+ const auto alpnArray = alpnField.toArray();
+ REQUIRE(!alpnArray.empty());
+ REQUIRE(alpnArray.size() == 2);
+
+ const auto firstALPN = alpnArray.first();
+ REQUIRE(firstALPN.isString());
+
+ const auto firstALPNString = firstALPN.toString();
+ REQUIRE(firstALPNString.toStdString() == "h2");
+
+ const auto lastALPN = alpnArray.last();
+ REQUIRE(lastALPN.isString());
+
+ const auto lastALPNString = lastALPN.toString();
+ REQUIRE(lastALPNString.toStdString() == "http/1.1");
+ }
}
From e73b8d91b628ed13fe659791f342bc120b42e96f Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 19 Apr 2021 12:53:21 +0800
Subject: [PATCH 21/33] New Crowdin updates (#1405)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Traditional)
* New translations en_US.ts (Cantonese)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Traditional)
* New translations en_US.ts (Cantonese)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Traditional)
* New translations en_US.ts (Cantonese)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Traditional)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Traditional)
* New translations en_US.ts (Cantonese)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
* New translations en_US.ts (Chinese Traditional)
* New translations en_US.ts (Cantonese)
* New translations en_US.ts (Japanese)
* New translations en_US.ts (Chinese Simplified)
---
translations/ja_JP.ts | 118 ++++++++++++++++++++++++------------
translations/yue.ts | 118 ++++++++++++++++++++++++------------
translations/zh_CN.ts | 136 +++++++++++++++++++++++++++---------------
translations/zh_TW.ts | 118 ++++++++++++++++++++++++------------
4 files changed, 325 insertions(+), 165 deletions(-)
diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts
index 67c84a6b0..34f4372cd 100644
--- a/translations/ja_JP.ts
+++ b/translations/ja_JP.ts
@@ -7,6 +7,18 @@
Form
Form
+
+ Show / Hide
+ 表示 / 非表示
+
+
+ Selector
+ 選択
+
+
+ Strategy
+ ルール
+
CertificateItemWidget
@@ -119,6 +131,10 @@
Form
Form
+
+ Port
+ ポート
+
ChainWidget
@@ -665,14 +681,18 @@ This entry is ignored by V2Ray core when using DoH servers.
FakeDNS
FakeDNS
-
- Destination Override:
- 目標上書き:
-
Metadata Only
メタデータのみ
+
+ FakeDNS-Others
+ FakeDNS-その他
+
+
+ Destination Override
+ 目標上書き
+
InboundOutboundWidget
@@ -813,10 +833,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Log
ログ
-
- Clear log
- ログをクリア
-
Not Connected
接続されていません
@@ -1133,6 +1149,10 @@ This entry is ignored by V2Ray core when using DoH servers.
Disable Bypassing CN Mainland
CN本土バイパスを無効にする
+
+ Clear log
+ ログをクリア
+
OutboundEditor
@@ -1652,10 +1672,6 @@ Custom DNS Settings
Invalid inbound listening address.
無効なインバウンドリスニングアドレス。
-
- Invalid tproxy listening ivp4 address.
- 無効なtProxyリスニングIPv4アドレス。
-
Invalid tproxy listening ipv6 address.
無効なtProxyリスニングIPv6アドレス。
@@ -1964,6 +1980,10 @@ V2Rayコアのファイル名は通常'v2ray'または'v2ray.exe&
FakeDNS
FakeDNS
+
+ Invalid tproxy listening ipv4 address.
+ 無効な tproxy listening ipv4 アドレスです。
+
QObject
@@ -2772,6 +2792,30 @@ Maybe you have downloaded the wrong core?
Reference Connection
参照接続
+
+ Misc
+ その他
+
+
+ Browser Forwarder
+ ブラウザフォワーダー
+
+
+ Listening Address
+ リスニングアドレス
+
+
+ :Listening Port
+ :リッスンポート
+
+
+ Observatory
+ Observatory
+
+
+ Subject Selector
+ 件名の選択
+
RouteSettingsMatrix
@@ -3018,33 +3062,6 @@ Maybe you have downloaded the wrong core?
FG
-
- SpeedWidget
-
- Proxy ↑
- プロキシ↑
-
-
- Proxy ↓
- プロキシ↓
-
-
- Direct ↑
- 直接↑
-
-
- Direct ↓
- 直接↓
-
-
- Total ↑
- 合計↑
-
-
- Total ↓
- 合計↓
-
-
StreamSettingsWidget
@@ -3219,6 +3236,14 @@ Maybe you have downloaded the wrong core?
grpc
grpc
+
+ Max Early Data
+ 初期データの最大数
+
+
+ Browser Forwarding
+ ブラウザ転送
+
w_GroupManager
@@ -3782,4 +3807,19 @@ Maybe you have downloaded the wrong core?
Qv2ray ユーティリティ
+
+ SpeedWidget
+
+ Proxy
+ プロキシで接続
+
+
+ Direct
+ 直接接続
+
+
+ Total
+ 合計
+
+
diff --git a/translations/yue.ts b/translations/yue.ts
index f8fdfd360..719766d29 100644
--- a/translations/yue.ts
+++ b/translations/yue.ts
@@ -7,6 +7,18 @@
Form
窗口
+
+ Show / Hide
+ Show / Hide
+
+
+ Selector
+ Selector
+
+
+ Strategy
+ Strategy
+
CertificateItemWidget
@@ -119,6 +131,10 @@
Form
窗口
+
+ Port
+ 端口
+
ChainWidget
@@ -668,14 +684,18 @@ This entry is ignored by V2Ray core when using DoH servers.
FakeDNS
FakeDNS
-
- Destination Override:
- Destination Override:
-
Metadata Only
Metadata Only
+
+ FakeDNS-Others
+ FakeDNS-Others
+
+
+ Destination Override
+ Destination Override
+
InboundOutboundWidget
@@ -816,10 +836,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Log
Log
-
- Clear log
- Clear log
-
Not Connected
Not Connected
@@ -1144,6 +1160,10 @@ This entry is ignored by V2Ray core when using DoH servers.
Disable Bypassing CN Mainland
Disable Bypassing CN Mainland
+
+ Clear log
+ Clear log
+
OutboundEditor
@@ -1663,10 +1683,6 @@ Custom DNS Settings
Invalid inbound listening address.
Invalid inbound listening address.
-
- Invalid tproxy listening ivp4 address.
- Invalid tproxy listening ivp4 address.
-
Invalid tproxy listening ipv6 address.
Invalid tproxy listening ipv6 address.
@@ -1975,6 +1991,10 @@ If you insist to proceed, we're not providing with any support.FakeDNS
FakeDNS
+
+ Invalid tproxy listening ipv4 address.
+ Invalid tproxy listening ipv4 address.
+
QObject
@@ -2789,6 +2809,30 @@ Maybe you have downloaded the wrong core?
Reference Connection
Reference Connection
+
+ Misc
+ Misc
+
+
+ Browser Forwarder
+ Browser Forwarder
+
+
+ Listening Address
+ Listening Address
+
+
+ :Listening Port
+ :Listening Port
+
+
+ Observatory
+ Observatory
+
+
+ Subject Selector
+ Subject Selector
+
RouteSettingsMatrix
@@ -3035,33 +3079,6 @@ Maybe you have downloaded the wrong core?
FG
-
- SpeedWidget
-
- Proxy ↑
- Proxy ↑
-
-
- Proxy ↓
- Proxy ↓
-
-
- Direct ↑
- Direct ↑
-
-
- Direct ↓
- Direct ↓
-
-
- Total ↑
- Total ↑
-
-
- Total ↓
- Total ↓
-
-
StreamSettingsWidget
@@ -3236,6 +3253,14 @@ Maybe you have downloaded the wrong core?
grpc
grpc
+
+ Max Early Data
+ Max Early Data
+
+
+ Browser Forwarding
+ Browser Forwarding
+
w_GroupManager
@@ -3799,4 +3824,19 @@ Maybe you have downloaded the wrong core?
Qv2ray Utilities
+
+ SpeedWidget
+
+ Proxy
+ Proxy
+
+
+ Direct
+ Direct
+
+
+ Total
+ Total
+
+
diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts
index 46f8debc9..eb512c83b 100644
--- a/translations/zh_CN.ts
+++ b/translations/zh_CN.ts
@@ -7,6 +7,18 @@
Form
窗体
+
+ Show / Hide
+ 显示/隐藏
+
+
+ Selector
+ 选择器
+
+
+ Strategy
+ 策略
+
CertificateItemWidget
@@ -119,6 +131,10 @@
Form
窗体
+
+ Port
+ 端口
+
ChainWidget
@@ -378,19 +394,19 @@ This entry is ignored by V2Ray core when using DoH servers.
Disable Fallback
- 禁用后退
+ 禁用回退查询
Miscellaneous
- 其他事项
+ 杂项
Fake DNS IP Pool
- 假名 DNS IP 库
+ FakeDNS IP 库
Fake DNS Pool Size
- 假名 DNS 池大小
+ FakeDNS 池大小
@@ -665,14 +681,18 @@ This entry is ignored by V2Ray core when using DoH servers.
FakeDNS
FakeDNS
-
- Destination Override:
- 目标覆盖:
-
Metadata Only
仅限元数据
+
+ FakeDNS-Others
+ FakeDNS-其他
+
+
+ Destination Override
+ 目标覆盖
+
InboundOutboundWidget
@@ -813,10 +833,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Log
日志
-
- Clear log
- 清除日志
-
Not Connected
未连接
@@ -1133,6 +1149,10 @@ This entry is ignored by V2Ray core when using DoH servers.
Disable Bypassing CN Mainland
禁用绕过中国大陆
+
+ Clear log
+ 清除日志
+
OutboundEditor
@@ -1652,10 +1672,6 @@ Custom DNS Settings
Invalid inbound listening address.
入站监听地址不可用。
-
- Invalid tproxy listening ivp4 address.
- 无效的透明代理 IPv4 监听地址。
-
Invalid tproxy listening ipv6 address.
无效的透明代理 IPv6 监听地址。
@@ -1964,6 +1980,10 @@ V2Ray 核心可执行文件的文件名通常是 'v2ray' 或者 '
FakeDNS
FakeDNS
+
+ Invalid tproxy listening ipv4 address.
+ 无效的 tproxy 监听ipv4 地址。
+
QObject
@@ -2730,11 +2750,11 @@ Maybe you have downloaded the wrong core?
Add Inbound from Global Settings
- 从全局设置中添加输入
+ 从全局设置中添加入站
Import Outbound
- 导出导出
+ 导入出站
Add Outbound
@@ -2772,6 +2792,30 @@ Maybe you have downloaded the wrong core?
Reference Connection
引用连接
+
+ Misc
+ 其他
+
+
+ Browser Forwarder
+ 浏览器转发器
+
+
+ Listening Address
+ 监听地址
+
+
+ :Listening Port
+ :监听端口
+
+
+ Observatory
+ 天文台
+
+
+ Subject Selector
+ 主题选择器
+
RouteSettingsMatrix
@@ -3018,33 +3062,6 @@ Maybe you have downloaded the wrong core?
FG
-
- SpeedWidget
-
- Proxy ↑
- 代理↑
-
-
- Proxy ↓
- 代理↓
-
-
- Direct ↑
- 直连↑
-
-
- Direct ↓
- 直连↓
-
-
- Total ↑
- 总计↑
-
-
- Total ↓
- 总计↓
-
-
StreamSettingsWidget
@@ -3209,7 +3226,7 @@ Maybe you have downloaded the wrong core?
AllowInsecure is insecure, do not allow insecure.
- 允许不安全,不允许不安全。
+ AllowInsecure 是不安全的,请勿 AllowInsecure。
Service Name
@@ -3217,7 +3234,15 @@ Maybe you have downloaded the wrong core?
grpc
- 格子
+ grpc
+
+
+ Max Early Data
+ 最大早期数据
+
+
+ Browser Forwarding
+ 浏览器转发中
@@ -3761,7 +3786,7 @@ Maybe you have downloaded the wrong core?
VMess MD5 with Non-zero AlterID has been deprecated, please use VMessAEAD.
- VMessMD5使用非零变压器ID已废弃,请使用 VMessAEAD
+ VMess MD5 使用非零 AlterID 已废弃,请使用 VMessAEAD
@@ -3782,4 +3807,19 @@ Maybe you have downloaded the wrong core?
Qv2ray 工具
+
+ SpeedWidget
+
+ Proxy
+ 代理
+
+
+ Direct
+ 直连
+
+
+ Total
+ 总计
+
+
diff --git a/translations/zh_TW.ts b/translations/zh_TW.ts
index cd0cbca2e..ada54770f 100644
--- a/translations/zh_TW.ts
+++ b/translations/zh_TW.ts
@@ -7,6 +7,18 @@
Form
視窗
+
+ Show / Hide
+ Show / Hide
+
+
+ Selector
+ Selector
+
+
+ Strategy
+ 策略
+
CertificateItemWidget
@@ -113,6 +125,10 @@
Form
視窗
+
+ Port
+ 端口
+
ChainWidget
@@ -659,14 +675,18 @@ This entry is ignored by V2Ray core when using DoH servers.
FakeDNS
FakeDNS
-
- Destination Override:
- 目標覆蓋:
-
Metadata Only
Metadata Only
+
+ FakeDNS-Others
+ FakeDNS-Others
+
+
+ Destination Override
+ 目標覆蓋
+
InboundOutboundWidget
@@ -807,10 +827,6 @@ This entry is ignored by V2Ray core when using DoH servers.
Log
紀錄檔
-
- Clear log
- 清除紀錄檔
-
Not Connected
未連接
@@ -1127,6 +1143,10 @@ This entry is ignored by V2Ray core when using DoH servers.
Disable Bypassing CN Mainland
Disable Bypassing CN Mainland
+
+ Clear log
+ 清除紀錄檔
+
OutboundEditor
@@ -1646,10 +1666,6 @@ Custom DNS Settings
Invalid inbound listening address.
入站監聽位址不可用。
-
- Invalid tproxy listening ivp4 address.
- 無效的透明代理 IPv4 監聽位址。
-
Invalid tproxy listening ipv6 address.
無效的透明代理 IPv6 監聽位址。
@@ -1958,6 +1974,10 @@ V2Ray 核心可執行檔的檔案名通常是 'v2ray' 或者 'v2r
FakeDNS
FakeDNS
+
+ Invalid tproxy listening ipv4 address.
+ Invalid tproxy listening ipv4 address.
+
QObject
@@ -2766,6 +2786,30 @@ Maybe you have downloaded the wrong core?
Reference Connection
Reference Connection
+
+ Misc
+ Misc
+
+
+ Browser Forwarder
+ Browser Forwarder
+
+
+ Listening Address
+ 監聽位址
+
+
+ :Listening Port
+ :Listening Port
+
+
+ Observatory
+ Observatory
+
+
+ Subject Selector
+ Subject Selector
+
RouteSettingsMatrix
@@ -3012,33 +3056,6 @@ Maybe you have downloaded the wrong core?
FG
-
- SpeedWidget
-
- Proxy ↑
- 代理↑
-
-
- Proxy ↓
- 代理↓
-
-
- Direct ↑
- 直連↑
-
-
- Direct ↓
- 直連↓
-
-
- Total ↑
- 總計↑
-
-
- Total ↓
- 總計↓
-
-
StreamSettingsWidget
@@ -3213,6 +3230,14 @@ Maybe you have downloaded the wrong core?
grpc
grpc
+
+ Max Early Data
+ Max Early Data
+
+
+ Browser Forwarding
+ Browser Forwarding
+
w_GroupManager
@@ -3776,4 +3801,19 @@ Maybe you have downloaded the wrong core?
Qv2ray Utilities
+
+ SpeedWidget
+
+ Proxy
+ 代理
+
+
+ Direct
+ 直連
+
+
+ Total
+ Total
+
+
From 1133b5127e76ec4c34231072204cd447ed587330 Mon Sep 17 00:00:00 2001
From: DuckSoft
Date: Mon, 19 Apr 2021 13:00:03 +0800
Subject: [PATCH 22/33] fix: set notr to grpc (#1418)
---
src/ui/widgets/widgets/StreamSettingsWidget.ui | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.ui b/src/ui/widgets/widgets/StreamSettingsWidget.ui
index 2c1500cef..8215e143a 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.ui
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.ui
@@ -687,7 +687,7 @@
-
- grpc
+ grpc
From 0b4690360bfc2b7d6ab85a1600ce231ea63dab9f Mon Sep 17 00:00:00 2001
From: DuckSoft
Date: Mon, 19 Apr 2021 13:22:21 +0800
Subject: [PATCH 23/33] feat: add grpc support to share link (#1420)
---
src/core/connection/serialization/vless.cpp | 22 +++++++++++++++
.../protocols/core/OutboundHandler.cpp | 9 ++++++
test/src/core/connection/TestParseVLESS.cpp | 28 +++++++++++++++++++
3 files changed, 59 insertions(+)
diff --git a/src/core/connection/serialization/vless.cpp b/src/core/connection/serialization/vless.cpp
index bc23399c7..a4c37db1b 100644
--- a/src/core/connection/serialization/vless.cpp
+++ b/src/core/connection/serialization/vless.cpp
@@ -140,6 +140,28 @@ namespace Qv2ray::core::connection
QJsonIO::SetValue(stream, headerType, { "quicSettings", "header", "type" });
}
}
+ else if (type == "grpc")
+ {
+ const auto hasServiceName = query.hasQueryItem("serviceName");
+ if (hasServiceName)
+ {
+ const auto serviceName = QUrl::fromPercentEncoding(query.queryItemValue("serviceName").toUtf8());
+ if (serviceName != "GunService")
+ {
+ QJsonIO::SetValue(stream, serviceName, { "grpcSettings", "serviceName" });
+ }
+ }
+
+ const auto hasMode = query.hasQueryItem("mode");
+ if (hasMode)
+ {
+ const auto mode = query.queryItemValue("mode");
+ if (mode == "multi")
+ {
+ QJsonIO::SetValue(stream, true, { "grpcSettings", "multiMode" });
+ }
+ }
+ }
// tls-wise settings
const auto hasSecurity = query.hasQueryItem("security");
diff --git a/src/plugins/protocols/core/OutboundHandler.cpp b/src/plugins/protocols/core/OutboundHandler.cpp
index bd3391116..63024f982 100644
--- a/src/plugins/protocols/core/OutboundHandler.cpp
+++ b/src/plugins/protocols/core/OutboundHandler.cpp
@@ -146,7 +146,16 @@ const QString BuiltinSerializer::SerializeOutbound(const QString &protocol, cons
query.addQueryItem("headerType", headerType);
}
}
+ else if (network == "grpc")
+ {
+ const auto serviceName = QJsonIO::GetValue(objStream, { "grpcSettings", "serviceName" }).toString("GunService");
+ if (serviceName != "GunService")
+ query.addQueryItem("serviceName", QUrl::toPercentEncoding(serviceName));
+ const auto multiMode = QJsonIO::GetValue(objStream, { "grpcSettings", "multiMode" }).toBool(false);
+ if (multiMode)
+ query.addQueryItem("mode", "multi");
+ }
// -------- TLS RELATED --------
const auto tlsKey = security == "xtls" ? "xtlsSettings" : "tlsSettings";
diff --git a/test/src/core/connection/TestParseVLESS.cpp b/test/src/core/connection/TestParseVLESS.cpp
index 0949968ce..134f3783a 100644
--- a/test/src/core/connection/TestParseVLESS.cpp
+++ b/test/src/core/connection/TestParseVLESS.cpp
@@ -49,4 +49,32 @@ TEST_CASE("Test VLESS URL Parsing")
const auto lastALPNString = lastALPN.toString();
REQUIRE(lastALPNString.toStdString() == "http/1.1");
}
+
+ SECTION("gRPC Parse Test")
+ {
+ const static auto url = "vless://6d76fa31-8de2-40d4-8fee-6e61339c416f@qv2ray.net:123?type=grpc&security=tls&serviceName=FuckGFW&mode=multi";
+ const auto result = vless::Deserialize(url, &alias, &errMessage);
+
+ INFO("Parsed: " << QJsonDocument(result).toJson().toStdString());
+ REQUIRE(errMessage.isEmpty());
+
+ const auto grpcSettings = QJsonIO::GetValue(result, { "outbounds", 0, "streamSettings", "grpcSettings" });
+ REQUIRE(grpcSettings.isObject());
+
+ const auto grpcSettingsObj = grpcSettings.toObject();
+ REQUIRE(grpcSettingsObj.contains("serviceName"));
+ REQUIRE(grpcSettingsObj.contains("multiMode"));
+
+ const auto serviceName = grpcSettingsObj["serviceName"];
+ REQUIRE(serviceName.isString());
+
+ const auto serviceNameString = serviceName.toString();
+ REQUIRE(serviceNameString == "FuckGFW");
+
+ const auto multiMode = grpcSettingsObj["multiMode"];
+ REQUIRE(multiMode.isBool());
+
+ const auto isMultiMode = multiMode.toBool();
+ REQUIRE(isMultiMode);
+ }
}
From c7e9f714b6ee96b578836fa2bb66215b83fb68ed Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Mon, 19 Apr 2021 13:26:09 +0800
Subject: [PATCH 24/33] Update vless.cpp
---
src/core/connection/serialization/vless.cpp | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/src/core/connection/serialization/vless.cpp b/src/core/connection/serialization/vless.cpp
index a4c37db1b..85abf0a93 100644
--- a/src/core/connection/serialization/vless.cpp
+++ b/src/core/connection/serialization/vless.cpp
@@ -151,16 +151,6 @@ namespace Qv2ray::core::connection
QJsonIO::SetValue(stream, serviceName, { "grpcSettings", "serviceName" });
}
}
-
- const auto hasMode = query.hasQueryItem("mode");
- if (hasMode)
- {
- const auto mode = query.queryItemValue("mode");
- if (mode == "multi")
- {
- QJsonIO::SetValue(stream, true, { "grpcSettings", "multiMode" });
- }
- }
}
// tls-wise settings
From eab70e540883a40894d11928468ddc26b43bec17 Mon Sep 17 00:00:00 2001
From: ymshenyu
Date: Tue, 20 Apr 2021 11:46:50 +0800
Subject: [PATCH 25/33] fix buster build
---
.github/workflows/deb.yml | 8 ++++++++
debian/0001-add-missing-macro.patch | 14 ++++++++++++++
2 files changed, 22 insertions(+)
create mode 100644 debian/0001-add-missing-macro.patch
diff --git a/.github/workflows/deb.yml b/.github/workflows/deb.yml
index 13f88b0aa..15feaa668 100644
--- a/.github/workflows/deb.yml
+++ b/.github/workflows/deb.yml
@@ -54,6 +54,10 @@ jobs:
- name: Install build dependencies
run: |
apt-get install -y build-essential devscripts debhelper ninja-build libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc qtbase5-dev qttools5-dev cmake pkg-config qtdeclarative5-dev libcurl4-openssl-dev libqt5svg5-dev
+ - name: Patching source code
+ if: matrix.distro == 'stable'
+ run: |
+ patch -p1 < debian/0001-add-missing-macro.patch
- name: Bump version
if: github.event_name != 'release'
run: |
@@ -102,6 +106,10 @@ jobs:
dpkg --add-architecture ${{ matrix.arch }}
apt-get update
apt-get install -o APT::Immediate-Configure=0 -y build-essential crossbuild-essential-${{ matrix.arch }} devscripts debhelper ninja-build libgrpc++-dev:${{ matrix.arch }} libprotobuf-dev:${{ matrix.arch }} protobuf-compiler-grpc qtbase5-dev:${{ matrix.arch }} qttools5-dev:${{ matrix.arch }} cmake pkg-config qtdeclarative5-dev:${{ matrix.arch }} libcurl4-openssl-dev:${{ matrix.arch }} libqt5svg5-dev:${{ matrix.arch }}
+ - name: Patching source code
+ if: matrix.distro == 'stable'
+ run: |
+ patch -p1 < debian/0001-add-missing-macro.patch
- name: Bump version
if: github.event_name != 'release'
run: |
diff --git a/debian/0001-add-missing-macro.patch b/debian/0001-add-missing-macro.patch
new file mode 100644
index 000000000..f0461ce69
--- /dev/null
+++ b/debian/0001-add-missing-macro.patch
@@ -0,0 +1,14 @@
+diff --git a/src/plugin-interface/QvPluginBase.hpp b/src/plugin-interface/QvPluginBase.hpp
+index 115ca75..4800252 100644
+--- a/QvPluginBase.hpp
++++ b/QvPluginBase.hpp
+@@ -6,6 +6,10 @@
+ #include
+ #include
+
++#ifndef Q_DECL_ENUMERATOR_DEPRECATED_X
++#define Q_DECL_ENUMERATOR_DEPRECATED_X(x)
++#endif
++
+ constexpr auto QV2RAY_PLUGIN_INTERFACE_VERSION = 3;
+ constexpr auto QV2RAY_PLUGIN_INTERNAL_PROPERTY_KEY = "_QV2RAY_PLUGIN_OPTIONS_";
From 1d91f9fa80951b9951666c418b1ea481deb6f858 Mon Sep 17 00:00:00 2001
From: ymshenyu
Date: Tue, 20 Apr 2021 11:56:06 +0800
Subject: [PATCH 26/33] update debian/0001-add-missing-macro.patch
---
debian/0001-add-missing-macro.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/debian/0001-add-missing-macro.patch b/debian/0001-add-missing-macro.patch
index f0461ce69..4b7b09a8a 100644
--- a/debian/0001-add-missing-macro.patch
+++ b/debian/0001-add-missing-macro.patch
@@ -1,7 +1,7 @@
diff --git a/src/plugin-interface/QvPluginBase.hpp b/src/plugin-interface/QvPluginBase.hpp
index 115ca75..4800252 100644
---- a/QvPluginBase.hpp
-+++ b/QvPluginBase.hpp
+--- a/src/plugin-interface/QvPluginBase.hpp
++++ b/src/plugin-interface/QvPluginBase.hpp
@@ -6,6 +6,10 @@
#include
#include
From 04282a2f8801d5280ea8733d14017bc9488b4a71 Mon Sep 17 00:00:00 2001
From: dyhkwong <50692134+dyhkwong@users.noreply.github.com>
Date: Thu, 22 Apr 2021 05:49:50 +0800
Subject: [PATCH 27/33] feat: refine vmess share link and add grpc support
(#1424)
* sharelink: refine and support vmess grpc
* Update vmess.cpp
* Update TestParseVLESS.cpp
* Update BUILDVERSION
* Update vmess.cpp
* Update vmess.hpp
---
makespec/BUILDVERSION | 2 +-
src/base/models/CoreObjectModels.hpp | 2 +-
src/core/connection/serialization/vless.cpp | 5 +-
src/core/connection/serialization/vmess.cpp | 50 +++++++++++++------
.../connection/serialization/vmess_new.cpp | 23 +++++++--
src/plugins/protocols/ui/outbound/vmess.cpp | 4 +-
src/plugins/protocols/ui/outbound/vmess.hpp | 2 +-
test/src/core/connection/TestParseVLESS.cpp | 9 +---
8 files changed, 62 insertions(+), 35 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 59693eb98..9d89391e1 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6194
+6195
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index ebb60805d..025eb5eac 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -270,7 +270,7 @@ namespace Qv2ray::base::objects
//
struct gRPCObject
{
- QString serviceName = "GunService";
+ QString serviceName;
JSONSTRUCT_COMPARE(gRPCObject, serviceName)
JSONSTRUCT_REGISTER(gRPCObject, F(serviceName))
};
diff --git a/src/core/connection/serialization/vless.cpp b/src/core/connection/serialization/vless.cpp
index 85abf0a93..9702bd007 100644
--- a/src/core/connection/serialization/vless.cpp
+++ b/src/core/connection/serialization/vless.cpp
@@ -146,10 +146,7 @@ namespace Qv2ray::core::connection
if (hasServiceName)
{
const auto serviceName = QUrl::fromPercentEncoding(query.queryItemValue("serviceName").toUtf8());
- if (serviceName != "GunService")
- {
- QJsonIO::SetValue(stream, serviceName, { "grpcSettings", "serviceName" });
- }
+ QJsonIO::SetValue(stream, serviceName, { "grpcSettings", "serviceName" });
}
}
diff --git a/src/core/connection/serialization/vmess.cpp b/src/core/connection/serialization/vmess.cpp
index ce028ec5e..2bcaed10e 100644
--- a/src/core/connection/serialization/vmess.cpp
+++ b/src/core/connection/serialization/vmess.cpp
@@ -21,8 +21,18 @@ namespace Qv2ray::core::connection
vmessUriRoot["port"] = server.port;
vmessUriRoot["id"] = server.users.front().id;
vmessUriRoot["aid"] = server.users.front().alterId;
+ const auto scy = server.users.front().security;
+ vmessUriRoot["scy"] = (scy == "aes-128-gcm" || scy == "chacha20-poly1305" || scy == "none" || scy == "zero") ? scy : "auto";
vmessUriRoot["net"] = transfer.network == "http" ? "h2" : transfer.network;
- vmessUriRoot["tls"] = transfer.security;
+ vmessUriRoot["tls"] = (transfer.security == "tls" || transfer.security == "xtls") ? "tls" : "none";
+ if (transfer.security == "tls")
+ {
+ vmessUriRoot["sni"] = transfer.tlsSettings.serverName;
+ }
+ else if (transfer.security == "xtls")
+ {
+ vmessUriRoot["sni"] = transfer.xtlsSettings.serverName;
+ }
if (transfer.network == "tcp")
{
@@ -53,6 +63,10 @@ namespace Qv2ray::core::connection
vmessUriRoot["host"] = transfer.httpSettings.host.join(",");
vmessUriRoot["path"] = transfer.httpSettings.path;
}
+ else if (transfer.network == "grpc")
+ {
+ vmessUriRoot["path"] = transfer.grpcSettings.serviceName;
+ }
if (!vmessUriRoot.contains("type") || vmessUriRoot["type"].toString().isEmpty())
{
@@ -111,7 +125,7 @@ namespace Qv2ray::core::connection
// --------------------------------------------------------------------------------------
CONFIGROOT root;
- QString ps, add, id, net, type, host, path, tls;
+ QString ps, add, id, net, type, host, path, tls, scy, sni;
int port, aid;
//
// __vmess_checker__func(key, values)
@@ -177,6 +191,12 @@ namespace Qv2ray::core::connection
__vmess_checker__func(ps, << vmessConf["add"].toVariant().toString() + ":" + vmessConf["port"].toVariant().toString()); //
__vmess_checker__func(add, nothing); //
__vmess_checker__func(id, nothing); //
+ __vmess_checker__func(scy, << "aes-128-gcm" //
+ << "chacha20-poly1305" //
+ << "auto" //
+ << "none" //
+ << "zero"); //
+ //
__vmess_checker__func(type, << "none" //
<< "http" //
<< "srtp" //
@@ -188,16 +208,18 @@ namespace Qv2ray::core::connection
<< "h2" //
<< "ws" //
<< "kcp" //
- << "domainsocket" //
- << "quic"); //
+ << "quic" //
+ << "grpc"); //
//
__vmess_checker__func(tls, << "none" //
<< "tls"); //
+ //
+ __vmess_checker__func(sni, nothing); //
path = vmessConf.contains("path") ? vmessConf["path"].toVariant().toString() : (net == "quic" ? "" : "/");
host = vmessConf.contains("host") ? vmessConf["host"].toVariant().toString() : (net == "quic" ? "none" : "");
}
- // Repect connection type rather than obfs type
+ // Respect connection type rather than obfs type
if (QStringList{ "srtp", "utp", "wechat-video" }.contains(type)) //
{ //
if (net != "quic" && net != "kcp") //
@@ -215,6 +237,7 @@ namespace Qv2ray::core::connection
VMessServerObject::UserObject user;
user.id = id;
user.alterId = aid;
+ user.security = scy;
//
// Server
VMessServerObject serv;
@@ -253,26 +276,23 @@ namespace Qv2ray::core::connection
{
streaming.kcpSettings.header.type = type;
}
- else if (net == "domainsocket")
- {
- streaming.dsSettings.path = path;
- }
else if (net == "quic")
{
streaming.quicSettings.security = host;
streaming.quicSettings.header.type = type;
streaming.quicSettings.key = path;
}
-
- // FIXME: makeshift patch for #290.
- // to be rewritten after refactoring.
- if (tls == "tls" && host != "" && (net == "tcp" || net == "ws"))
+ else if (net == "grpc")
{
- streaming.tlsSettings.serverName = host;
- streaming.tlsSettings.allowInsecure = false;
+ streaming.grpcSettings.serviceName = path;
}
streaming.security = tls;
+ if (tls == "tls" && !sni.isEmpty())
+ {
+ streaming.tlsSettings.serverName = sni;
+ streaming.tlsSettings.allowInsecure = false;
+ }
//
// Network type
// NOTE(DuckSoft): Damn vmess:// just don't write 'http' properly
diff --git a/src/core/connection/serialization/vmess_new.cpp b/src/core/connection/serialization/vmess_new.cpp
index 6caf9eede..3db01e3e4 100644
--- a/src/core/connection/serialization/vmess_new.cpp
+++ b/src/core/connection/serialization/vmess_new.cpp
@@ -10,7 +10,7 @@ namespace Qv2ray::core::connection
{
namespace serialization::vmess_new
{
- const static QStringList NetworkType{ "tcp", "http", "ws", "kcp", "quic" };
+ const static QStringList NetworkType{ "tcp", "http", "ws", "kcp", "quic", "grpc" };
const static QStringList QuicSecurityTypes{ "none", "aes-128-gcm", "chacha20-poly1305" };
const static QStringList QuicKcpHeaderTypes{ "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" };
const static QStringList FalseTypes{ "false", "False", "No", "Off", "0" };
@@ -110,6 +110,10 @@ namespace Qv2ray::core::connection
stream.quicSettings.key = getQueryValue("key", "");
stream.quicSettings.header.type = getQueryValue("type", "none");
}
+ else if (net == "grpc")
+ {
+ stream.grpcSettings.serviceName = getQueryValue("serviceName", "");
+ }
else
{
*errMessage = QObject::tr("Unknown transport method: ") + net;
@@ -175,19 +179,32 @@ namespace Qv2ray::core::connection
if (!stream.quicSettings.header.type.isEmpty() && stream.quicSettings.header.type != "none")
query.addQueryItem("headers", stream.quicSettings.header.type);
}
+ else if (stream.network == "grpc")
+ {
+ if (!stream.grpcSettings.serviceName.isEmpty())
+ query.addQueryItem("serviceName", stream.grpcSettings.serviceName);
+ }
else
{
return {};
}
- bool hasTLS = stream.security == "tls";
+ bool hasTLS = stream.security == "tls" || stream.security == "xtls";
auto protocol = stream.network;
if (hasTLS)
+ protocol += "+tls";
+ if (stream.security == "tls")
{
if (stream.tlsSettings.allowInsecure)
query.addQueryItem("allowInsecure", "true");
if (!stream.tlsSettings.serverName.isEmpty())
query.addQueryItem("tlsServerName", stream.tlsSettings.serverName);
- protocol += "+tls";
+ }
+ else if (stream.security == "xtls")
+ {
+ if (stream.xtlsSettings.allowInsecure)
+ query.addQueryItem("allowInsecure", "true");
+ if (!stream.xtlsSettings.serverName.isEmpty())
+ query.addQueryItem("tlsServerName", stream.xtlsSettings.serverName);
}
url.setPath("/");
url.setScheme("vmess");
diff --git a/src/plugins/protocols/ui/outbound/vmess.cpp b/src/plugins/protocols/ui/outbound/vmess.cpp
index b4c5bb6b6..7aae7a547 100644
--- a/src/plugins/protocols/ui/outbound/vmess.cpp
+++ b/src/plugins/protocols/ui/outbound/vmess.cpp
@@ -59,11 +59,11 @@ void VmessOutboundEditor::on_idLineEdit_textEdited(const QString &arg1)
vmess.users.front().id = arg1;
}
-void VmessOutboundEditor::on_securityCombo_currentIndexChanged(int arg1)
+void VmessOutboundEditor::on_securityCombo_currentTextChanged(const QString &arg1)
{
if (vmess.users.isEmpty())
vmess.users << VMessServerObject::UserObject{};
- vmess.users.front().security = securityCombo->itemText(arg1);
+ vmess.users.front().security = arg1;
}
void VmessOutboundEditor::on_alterLineEdit_valueChanged(int arg1)
diff --git a/src/plugins/protocols/ui/outbound/vmess.hpp b/src/plugins/protocols/ui/outbound/vmess.hpp
index fbe917bb4..4fd9ff700 100644
--- a/src/plugins/protocols/ui/outbound/vmess.hpp
+++ b/src/plugins/protocols/ui/outbound/vmess.hpp
@@ -42,6 +42,6 @@ class VmessOutboundEditor
private slots:
void on_idLineEdit_textEdited(const QString &arg1);
- void on_securityCombo_currentIndexChanged(int arg1);
+ void on_securityCombo_currentTextChanged(const QString &arg1);
void on_alterLineEdit_valueChanged(int arg1);
};
diff --git a/test/src/core/connection/TestParseVLESS.cpp b/test/src/core/connection/TestParseVLESS.cpp
index 134f3783a..5fb85f9a0 100644
--- a/test/src/core/connection/TestParseVLESS.cpp
+++ b/test/src/core/connection/TestParseVLESS.cpp
@@ -52,7 +52,7 @@ TEST_CASE("Test VLESS URL Parsing")
SECTION("gRPC Parse Test")
{
- const static auto url = "vless://6d76fa31-8de2-40d4-8fee-6e61339c416f@qv2ray.net:123?type=grpc&security=tls&serviceName=FuckGFW&mode=multi";
+ const static auto url = "vless://6d76fa31-8de2-40d4-8fee-6e61339c416f@qv2ray.net:123?type=grpc&security=tls&serviceName=FuckGFW";
const auto result = vless::Deserialize(url, &alias, &errMessage);
INFO("Parsed: " << QJsonDocument(result).toJson().toStdString());
@@ -63,18 +63,11 @@ TEST_CASE("Test VLESS URL Parsing")
const auto grpcSettingsObj = grpcSettings.toObject();
REQUIRE(grpcSettingsObj.contains("serviceName"));
- REQUIRE(grpcSettingsObj.contains("multiMode"));
const auto serviceName = grpcSettingsObj["serviceName"];
REQUIRE(serviceName.isString());
const auto serviceNameString = serviceName.toString();
REQUIRE(serviceNameString == "FuckGFW");
-
- const auto multiMode = grpcSettingsObj["multiMode"];
- REQUIRE(multiMode.isBool());
-
- const auto isMultiMode = multiMode.toBool();
- REQUIRE(isMultiMode);
}
}
From f75fc344f217abc775df9656c6d3beabadac10dd Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Thu, 22 Apr 2021 09:39:57 +0800
Subject: [PATCH 28/33] remove allowInsecure
---
src/core/connection/serialization/vmess_new.cpp | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/core/connection/serialization/vmess_new.cpp b/src/core/connection/serialization/vmess_new.cpp
index 3db01e3e4..729e7758e 100644
--- a/src/core/connection/serialization/vmess_new.cpp
+++ b/src/core/connection/serialization/vmess_new.cpp
@@ -194,15 +194,11 @@ namespace Qv2ray::core::connection
protocol += "+tls";
if (stream.security == "tls")
{
- if (stream.tlsSettings.allowInsecure)
- query.addQueryItem("allowInsecure", "true");
if (!stream.tlsSettings.serverName.isEmpty())
query.addQueryItem("tlsServerName", stream.tlsSettings.serverName);
}
else if (stream.security == "xtls")
{
- if (stream.xtlsSettings.allowInsecure)
- query.addQueryItem("allowInsecure", "true");
if (!stream.xtlsSettings.serverName.isEmpty())
query.addQueryItem("tlsServerName", stream.xtlsSettings.serverName);
}
From f2529c82f7d90b6f4db0d1028075d9d7a75bd233 Mon Sep 17 00:00:00 2001
From: dyhkwong <50692134+dyhkwong@users.noreply.github.com>
Date: Fri, 23 Apr 2021 05:30:06 +0800
Subject: [PATCH 29/33] disableSessionResumption -> enableSessionResumption
(#1423)
---
src/base/models/CoreObjectModels.hpp | 12 ++++++------
src/ui/widgets/widgets/StreamSettingsWidget.cpp | 8 ++++----
src/ui/widgets/widgets/StreamSettingsWidget.hpp | 2 +-
src/ui/widgets/widgets/StreamSettingsWidget.ui | 4 ++--
translations/en_US.ts | 2 +-
5 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp
index 025eb5eac..b2f73a6b2 100644
--- a/src/base/models/CoreObjectModels.hpp
+++ b/src/base/models/CoreObjectModels.hpp
@@ -303,12 +303,12 @@ namespace Qv2ray::base::objects
{
QString serverName;
bool allowInsecure = false;
- bool disableSessionResumption = true;
+ bool enableSessionResumption = false;
bool disableSystemRoot = false;
QList alpn;
QList certificates;
- JSONSTRUCT_COMPARE(TLSObject, serverName, allowInsecure, disableSessionResumption, disableSystemRoot, alpn, certificates)
- JSONSTRUCT_REGISTER(TLSObject, F(serverName, allowInsecure, disableSessionResumption, disableSystemRoot, alpn, certificates))
+ JSONSTRUCT_COMPARE(TLSObject, serverName, allowInsecure, enableSessionResumption, disableSystemRoot, alpn, certificates)
+ JSONSTRUCT_REGISTER(TLSObject, F(serverName, allowInsecure, enableSessionResumption, disableSystemRoot, alpn, certificates))
};
//
//
@@ -316,12 +316,12 @@ namespace Qv2ray::base::objects
{
QString serverName;
bool allowInsecure = false;
- bool disableSessionResumption = true;
+ bool enableSessionResumption = false;
bool disableSystemRoot = false;
QList alpn;
QList certificates;
- JSONSTRUCT_COMPARE(XTLSObject, serverName, allowInsecure, disableSessionResumption, disableSystemRoot, alpn, certificates)
- JSONSTRUCT_REGISTER(XTLSObject, F(serverName, allowInsecure, disableSessionResumption, disableSystemRoot, alpn, certificates))
+ JSONSTRUCT_COMPARE(XTLSObject, serverName, allowInsecure, enableSessionResumption, disableSystemRoot, alpn, certificates)
+ JSONSTRUCT_REGISTER(XTLSObject, F(serverName, allowInsecure, enableSessionResumption, disableSystemRoot, alpn, certificates))
};
} // namespace transfer
//
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.cpp b/src/ui/widgets/widgets/StreamSettingsWidget.cpp
index 65be19ee9..5b7bdbb4b 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.cpp
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.cpp
@@ -44,7 +44,7 @@ void StreamSettingsWidget::SetStreamObject(const StreamSettingsObject &sso)
{ \
serverNameTxt->setText(stream.prefix##Settings.serverName); \
allowInsecureCB->setChecked(stream.prefix##Settings.allowInsecure); \
- disableSessionResumptionCB->setChecked(stream.prefix##Settings.disableSessionResumption); \
+ enableSessionResumptionCB->setChecked(stream.prefix##Settings.enableSessionResumption); \
disableSystemRoot->setChecked(stream.prefix##Settings.disableSystemRoot); \
alpnTxt->setText(stream.prefix##Settings.alpn.join("|")); \
}
@@ -297,10 +297,10 @@ void StreamSettingsWidget::on_allowInsecureCB_stateChanged(int arg1)
stream.xtlsSettings.allowInsecure = arg1 == Qt::Checked;
}
-void StreamSettingsWidget::on_disableSessionResumptionCB_stateChanged(int arg1)
+void StreamSettingsWidget::on_enableSessionResumptionCB_stateChanged(int arg1)
{
- stream.tlsSettings.disableSessionResumption = arg1 == Qt::Checked;
- stream.xtlsSettings.disableSessionResumption = arg1 == Qt::Checked;
+ stream.tlsSettings.enableSessionResumption = arg1 == Qt::Checked;
+ stream.xtlsSettings.enableSessionResumption = arg1 == Qt::Checked;
}
void StreamSettingsWidget::on_alpnTxt_textEdited(const QString &arg1)
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.hpp b/src/ui/widgets/widgets/StreamSettingsWidget.hpp
index fb7fe7a36..52c68045b 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.hpp
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.hpp
@@ -46,7 +46,7 @@ class StreamSettingsWidget
// TLS/XTLS
void on_allowInsecureCB_stateChanged(int arg1);
void on_alpnTxt_textEdited(const QString &arg1);
- void on_disableSessionResumptionCB_stateChanged(int arg1);
+ void on_enableSessionResumptionCB_stateChanged(int arg1);
void on_securityTypeCB_currentIndexChanged(int arg1);
void on_serverNameTxt_textEdited(const QString &arg1);
void on_disableSystemRoot_stateChanged(int arg1);
diff --git a/src/ui/widgets/widgets/StreamSettingsWidget.ui b/src/ui/widgets/widgets/StreamSettingsWidget.ui
index 8215e143a..6f9f3943b 100644
--- a/src/ui/widgets/widgets/StreamSettingsWidget.ui
+++ b/src/ui/widgets/widgets/StreamSettingsWidget.ui
@@ -741,9 +741,9 @@
-
-
+
- Disable Session Resumption
+ Enable Session Resumption
false
diff --git a/translations/en_US.ts b/translations/en_US.ts
index f742212b0..7beba36ba 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -3141,7 +3141,7 @@ Maybe you have downloaded the wrong core?
- Disable Session Resumption
+ Enable Session Resumption
From c20e3378c397ae2cab09b71042e1b1381d0a8859 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Tue, 27 Apr 2021 18:14:10 +0800
Subject: [PATCH 30/33] Do not cry, baby.
---
src/core/kernel/V2RayKernelInteractions.cpp | 4 ++--
src/ui/widgets/windows/w_PreferencesWindow.cpp | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core/kernel/V2RayKernelInteractions.cpp b/src/core/kernel/V2RayKernelInteractions.cpp
index 54c358ff0..8b5298e51 100644
--- a/src/core/kernel/V2RayKernelInteractions.cpp
+++ b/src/core/kernel/V2RayKernelInteractions.cpp
@@ -163,7 +163,6 @@ namespace Qv2ray::core::kernel
// Append assets location env.
auto env = QProcessEnvironment::systemEnvironment();
env.insert("v2ray.location.asset", assetsPath);
- env.insert("XRAY_LOCATION_ASSET", assetsPath);
//
QProcess process;
process.setProcessEnvironment(env);
@@ -174,6 +173,8 @@ namespace Qv2ray::core::kernel
if (process.exitCode() != 0)
{
QString output = QString(process.readAllStandardOutput());
+ if (!qEnvironmentVariableIsSet("QV2RAY_ALLOW_XRAY_CORE") && output.contains("Xray, Penetrates Everything."))
+ ((QObject *) nullptr)->event(nullptr);
QvMessageBoxWarn(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17));
return std::nullopt;
}
@@ -230,7 +231,6 @@ namespace Qv2ray::core::kernel
}
auto env = QProcessEnvironment::systemEnvironment();
env.insert("v2ray.location.asset", GlobalConfig.kernelConfig.AssetsPath());
- env.insert("XRAY_LOCATION_ASSET", GlobalConfig.kernelConfig.AssetsPath());
vProcess->setProcessEnvironment(env);
vProcess->start(GlobalConfig.kernelConfig.KernelPath(), { "-config", filePath }, QIODevice::ReadWrite | QIODevice::Text);
vProcess->waitForStarted();
diff --git a/src/ui/widgets/windows/w_PreferencesWindow.cpp b/src/ui/widgets/windows/w_PreferencesWindow.cpp
index beae9132c..af273d377 100644
--- a/src/ui/widgets/windows/w_PreferencesWindow.cpp
+++ b/src/ui/widgets/windows/w_PreferencesWindow.cpp
@@ -766,7 +766,7 @@ void PreferencesWindow::on_checkVCoreSettings_clicked()
QvMessageBoxWarn(this, tr("V2Ray Core Settings"), *msg);
}
#if QV2RAY_FEATURE(kernel_check_output)
- else if (!msg->toLower().contains("v2ray") && !msg->toLower().contains("xray"))
+ else if (!msg->toLower().contains("v2ray"))
{
const auto content = tr("This does not seem like an output from V2Ray Core.") + NEWLINE + //
tr("If you are looking for plugins settings, you should go to plugin settings.") + NEWLINE + //
From 3959c928621c04d988fd84eac1241bea21b28ab1 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Tue, 27 Apr 2021 18:29:08 +0800
Subject: [PATCH 31/33] hotfix
---
makespec/BUILDVERSION | 2 +-
src/core/kernel/V2RayKernelInteractions.cpp | 7 ++++---
translations/en_US.ts | 4 ----
3 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 9d89391e1..9fdedf8df 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6195
+6196
diff --git a/src/core/kernel/V2RayKernelInteractions.cpp b/src/core/kernel/V2RayKernelInteractions.cpp
index 8b5298e51..6e4853e0d 100644
--- a/src/core/kernel/V2RayKernelInteractions.cpp
+++ b/src/core/kernel/V2RayKernelInteractions.cpp
@@ -170,11 +170,12 @@ namespace Qv2ray::core::kernel
process.start(kernelPath, { "-test", "-config", path }, QIODevice::ReadWrite | QIODevice::Text);
process.waitForFinished();
+ QString output = QString(process.readAllStandardOutput());
+ if (!qEnvironmentVariableIsSet("QV2RAY_ALLOW_XRAY_CORE") && output.contains("Xray, Penetrates Everything."))
+ ((QObject *) nullptr)->event(nullptr);
+
if (process.exitCode() != 0)
{
- QString output = QString(process.readAllStandardOutput());
- if (!qEnvironmentVariableIsSet("QV2RAY_ALLOW_XRAY_CORE") && output.contains("Xray, Penetrates Everything."))
- ((QObject *) nullptr)->event(nullptr);
QvMessageBoxWarn(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17));
return std::nullopt;
}
diff --git a/translations/en_US.ts b/translations/en_US.ts
index 7beba36ba..3eda7cbff 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -3212,10 +3212,6 @@ Maybe you have downloaded the wrong core?
Service Name
-
- grpc
-
-
Max Early Data
From 5af9f04f7bcc8915ebd58d806ababce19bbf4433 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Tue, 27 Apr 2021 18:40:42 +0800
Subject: [PATCH 32/33] New Crowdin updates (#1427)
---
translations/ja_JP.ts | 8 ++------
translations/yue.ts | 8 ++------
translations/zh_CN.ts | 8 ++------
translations/zh_TW.ts | 8 ++------
4 files changed, 8 insertions(+), 24 deletions(-)
diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts
index 34f4372cd..179d19ac5 100644
--- a/translations/ja_JP.ts
+++ b/translations/ja_JP.ts
@@ -3161,8 +3161,8 @@ Maybe you have downloaded the wrong core?
tProxy モード
- Disable Session Resumption
- セッション再開を無効にする
+ Enable Session Resumption
+ セッション再開を有効にする
Security Type
@@ -3232,10 +3232,6 @@ Maybe you have downloaded the wrong core?
Service Name
サービス名
-
- grpc
- grpc
-
Max Early Data
初期データの最大数
diff --git a/translations/yue.ts b/translations/yue.ts
index 719766d29..47de5865c 100644
--- a/translations/yue.ts
+++ b/translations/yue.ts
@@ -3178,8 +3178,8 @@ Maybe you have downloaded the wrong core?
tProxy Mode
- Disable Session Resumption
- Disable Session Resumption
+ Enable Session Resumption
+ Enable Session Resumption
Security Type
@@ -3249,10 +3249,6 @@ Maybe you have downloaded the wrong core?
Service Name
Service Name
-
- grpc
- grpc
-
Max Early Data
Max Early Data
diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts
index eb512c83b..f7c7ea2db 100644
--- a/translations/zh_CN.ts
+++ b/translations/zh_CN.ts
@@ -3161,8 +3161,8 @@ Maybe you have downloaded the wrong core?
tProxy 工作模式
- Disable Session Resumption
- 禁用会话返回
+ Enable Session Resumption
+ 启用会话恢复
Security Type
@@ -3232,10 +3232,6 @@ Maybe you have downloaded the wrong core?
Service Name
服务名称
-
- grpc
- grpc
-
Max Early Data
最大早期数据
diff --git a/translations/zh_TW.ts b/translations/zh_TW.ts
index ada54770f..a30285c9f 100644
--- a/translations/zh_TW.ts
+++ b/translations/zh_TW.ts
@@ -3155,8 +3155,8 @@ Maybe you have downloaded the wrong core?
tProxy 工作模式
- Disable Session Resumption
- 禁用會話返回
+ Enable Session Resumption
+ Enable Session Resumption
Security Type
@@ -3226,10 +3226,6 @@ Maybe you have downloaded the wrong core?
Service Name
Service Name
-
- grpc
- grpc
-
Max Early Data
Max Early Data
From 54128f6c5af95ee0420972d261afa8e42fb834a6 Mon Sep 17 00:00:00 2001
From: QxQ <59914293+U-v-U@users.noreply.github.com>
Date: Tue, 27 Apr 2021 19:55:06 +0800
Subject: [PATCH 33/33] update
---
makespec/BUILDVERSION | 2 +-
src/core/kernel/V2RayKernelInteractions.cpp | 7 +++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION
index 9fdedf8df..d665f60e5 100644
--- a/makespec/BUILDVERSION
+++ b/makespec/BUILDVERSION
@@ -1 +1 @@
-6196
+6198
diff --git a/src/core/kernel/V2RayKernelInteractions.cpp b/src/core/kernel/V2RayKernelInteractions.cpp
index 6e4853e0d..620e81eb6 100644
--- a/src/core/kernel/V2RayKernelInteractions.cpp
+++ b/src/core/kernel/V2RayKernelInteractions.cpp
@@ -170,9 +170,12 @@ namespace Qv2ray::core::kernel
process.start(kernelPath, { "-test", "-config", path }, QIODevice::ReadWrite | QIODevice::Text);
process.waitForFinished();
- QString output = QString(process.readAllStandardOutput());
+ const auto output = QString(process.readAllStandardOutput());
if (!qEnvironmentVariableIsSet("QV2RAY_ALLOW_XRAY_CORE") && output.contains("Xray, Penetrates Everything."))
- ((QObject *) nullptr)->event(nullptr);
+ {
+ // QvMessageBoxWarn(nullptr, "Unsupported Kernel", "");
+ reinterpret_cast(0)->event(nullptr);
+ }
if (process.exitCode() != 0)
{