From eaf274a23205a5a44f429d6dc13e289eca0c8d02 Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 20:55:11 +0800 Subject: [PATCH 01/42] update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 59026963..8ced4e91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ env: addons: snaps: - name: snapcraft - channel: stable + channel: edge confinement: classic - name: lxd channel: stable From fc69cfbf7b31271ed1f17cf7c006f7bb1a7fc9c5 Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 20:55:25 +0800 Subject: [PATCH 02/42] Revert "NYI: Revert "snap: testing new feature"" This reverts commit 6b12dd8d73ce732c5c1f8b4c34eebece909ea865. --- snap/snapcraft.yaml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index c1959052..e3e60a72 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -84,7 +84,6 @@ parts: sed -i 's|^Icon=.*|Icon=/usr/share/icons/hicolor/256x256/apps/qv2ray.png|g' assets/qv2ray.desktop after: - desktop-qt5 - - ppa desktop-qt5: source: https://github.com/ubuntu/snapcraft-desktop-helpers.git @@ -110,21 +109,12 @@ parts: - locales-all - xdg-user-dirs - fcitx-frontend-qt5 - after: - - ppa qt5-gtk-platform: plugin: nil stage-packages: - qt5-gtk-platformtheme - after: - - ppa - ppa: - plugin: nil - build-packages: - - software-properties-common - - dirmngr - override-build: | - sudo add-apt-repository -y ppa:ymshenyu/qv2ray-deps - sudo apt-get dist-upgrade -y \ No newline at end of file +package-repositories: + - type: apt + ppa: ymshenyu/qv2ray-deps \ No newline at end of file From 45a74812d8102194d3bfd919382a27a247a3e00b Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 20:55:52 +0800 Subject: [PATCH 03/42] switch from core18 to core20 --- snap/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index e3e60a72..912fa340 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: qv2ray -base: core18 +base: core20 adopt-info: qv2ray icon: assets/icons/qv2ray.png From bdb22ff9e64bdcd4dd29df539e2a1640921b1737 Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 20:57:05 +0800 Subject: [PATCH 04/42] remove PPA --- snap/snapcraft.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 912fa340..147b1286 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -113,8 +113,4 @@ parts: qt5-gtk-platform: plugin: nil stage-packages: - - qt5-gtk-platformtheme - -package-repositories: - - type: apt - ppa: ymshenyu/qv2ray-deps \ No newline at end of file + - qt5-gtk-platformtheme \ No newline at end of file From 00e012f19b9f5b4429a9b5e04f40fbbf1709770d Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 21:37:18 +0800 Subject: [PATCH 05/42] update snapcraft.yaml --- snap/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 147b1286..670baea5 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -70,7 +70,7 @@ parts: - libqt5network5 - libqt5widgets5 - libglib2.0-bin - configflags: + cmake-parameters: - -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_BUILD_TYPE=Release - -GNinja From b911e0d335ea37f41fa328e53b09d04d773b9c63 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sun, 3 May 2020 21:36:53 +0800 Subject: [PATCH 06/42] updating translations --- translations/en_US.ts | 128 ++++++++++++++++++++++++++++++------------ translations/ja_JP.ts | 111 +++++++++++++++++++++++++++++++++--- translations/ru_RU.ts | 126 +++++++++++++++++++++++++++++++---------- translations/zh_CN.ts | 111 +++++++++++++++++++++++++++++++++--- 4 files changed, 391 insertions(+), 85 deletions(-) diff --git a/translations/en_US.ts b/translations/en_US.ts index 9c04c324..c67ec840 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -115,6 +115,13 @@ + + ConnectionSettingsWidget + + Form + + + ConnectionWidget @@ -142,6 +149,45 @@ + + GroupManager + + Connection Management + + + + Reload Subscription + + + + Would you like to reload the subscription? + + + + Deleting a subscription + + + + All connections will be moved to default group, do you want to continue? + + + + Export Connection(s) + + + + Delete Connection(s) + + + + Copy to... + + + + Move to... + + + ImportConfigWindow @@ -516,6 +562,13 @@ + + InboundSettingsWidget + + Form + + + JsonEditor @@ -569,10 +622,6 @@ Qv2ray - - Add - - Preferences @@ -851,6 +900,10 @@ Groups + + Add Connection + + OutboundEditor @@ -1903,14 +1956,6 @@ But could damage your server if improperly used. Invalid ssd link: rc4-md5 encryption is not supported by v2ray-core - - Not connected - - - - Connected - - Custom Text @@ -2871,25 +2916,6 @@ Maybe you have downloaded the wrong core? - - SubscriptionEditor - - Reload Subscription - - - - Would you like to reload the subscription? - - - - Deleting a subscription - - - - All connections will be moved to default group, do you want to continue? - - - misc @@ -2951,10 +2977,6 @@ Maybe you have downloaded the wrong core? Remove Subscription - - Group Details - - Group Name @@ -2976,11 +2998,43 @@ Maybe you have downloaded the wrong core? - Connection List + Update Subscription Data - Update Subscription Data + Group Info + + + + Created At + + + + Connections + + + + Delete Selection + + + + Export Selection + + + + Subscription Settings + + + + This group is a subscription + + + + Connection Settings + + + + Route Settings diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 7814bea0..4683fe89 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -150,6 +150,13 @@ + + ConnectionSettingsWidget + + Form + Form + + ConnectionWidget @@ -219,6 +226,45 @@ フローシーンファイル (*.flow) + + GroupManager + + Connection Management + 項目管理 + + + Reload Subscription + サブスクリプションを更新 + + + Would you like to reload the subscription? + サブスクリプションを更新しますか? + + + Deleting a subscription + サブスクリプションを削除する + + + All connections will be moved to default group, do you want to continue? + すべての項目がデフォルトグループに移動します。続行しますか? + + + Export Connection(s) + 項目をエクスポート + + + Delete Connection(s) + 項目を削除 + + + Copy to... + コピーして... + + + Move to... + 移動して... + + ImportConfigWindow @@ -645,6 +691,13 @@ このユーザーは既に存在します. + + InboundSettingsWidget + + Form + Form + + JsonEditor @@ -792,7 +845,7 @@ Add - 追加 + 追加 Preferences @@ -1314,6 +1367,10 @@ Groups グループ + + Add Connection + 項目を作成 + OutboundEditor @@ -2536,11 +2593,11 @@ But could damage your server if improperly used. Not connected - 接続されていません + 接続されていません Connected - 接続済み + 接続済み Disconnected @@ -3775,19 +3832,19 @@ Maybe you have downloaded the wrong core? SubscriptionEditor Reload Subscription - サブスクリプションを更新 + サブスクリプションを更新 Would you like to reload the subscription? - サブスクリプションを更新しますか? + サブスクリプションを更新しますか? Deleting a subscription - サブスクリプションを削除する + サブスクリプションを削除する All connections will be moved to default group, do you want to continue? - すべての項目がデフォルトグループに移動します。続行しますか? + すべての項目がデフォルトグループに移動します。続行しますか? @@ -3853,7 +3910,7 @@ Maybe you have downloaded the wrong core? Group Details - 詳細 + 詳細 Group Name @@ -3877,12 +3934,48 @@ Maybe you have downloaded the wrong core? Connection List - 項目リスト + 項目リスト Update Subscription Data サブスクリプションデータの更新 + + Group Info + グループ情報 + + + Created At + 作成日 + + + Connections + 項目 + + + Delete Selection + 選択したものを削除 + + + Export Selection + 選択したものをエクスポート + + + Subscription Settings + サブスクリプション設定 + + + This group is a subscription + このグループはサブスクリプションです。 + + + Connection Settings + 接続設定 + + + Route Settings + ルート設定 + w_PluginManager diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index f9b036a4..c075d080 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -134,6 +134,13 @@ + + ConnectionSettingsWidget + + Form + + + ConnectionWidget @@ -203,6 +210,45 @@ Файл сцены потока (*.flow) + + GroupManager + + Connection Management + + + + Reload Subscription + + + + Would you like to reload the subscription? + + + + Deleting a subscription + + + + All connections will be moved to default group, do you want to continue? + + + + Export Connection(s) + + + + Delete Connection(s) + + + + Copy to... + + + + Move to... + + + ImportConfigWindow @@ -629,6 +675,13 @@ Этот пользователь уже существует. + + InboundSettingsWidget + + Form + + + JsonEditor @@ -776,7 +829,7 @@ Add - Добавить + Добавить Preferences @@ -1294,6 +1347,10 @@ Groups + + Add Connection + + OutboundEditor @@ -2438,13 +2495,9 @@ But could damage your server if improperly used. Technical Details Технические детали - - Not connected - - Connected - Подключено + Подключено Disconnected @@ -3612,25 +3665,6 @@ Maybe you have downloaded the wrong core? Не удалось обработать результат из апстрима, проверьте ваш URL. - - SubscriptionEditor - - Reload Subscription - - - - Would you like to reload the subscription? - - - - Deleting a subscription - - - - All connections will be moved to default group, do you want to continue? - - - misc @@ -3692,10 +3726,6 @@ Maybe you have downloaded the wrong core? Remove Subscription Удалить подписку - - Group Details - - Group Name @@ -3718,12 +3748,48 @@ Maybe you have downloaded the wrong core? Connection List - Список подключений + Список подключений Update Subscription Data Обновить данные подписки + + Group Info + + + + Created At + + + + Connections + + + + Delete Selection + Удалить выделение + + + Export Selection + + + + Subscription Settings + + + + This group is a subscription + + + + Connection Settings + Настройки соединения + + + Route Settings + + w_PluginManager diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 8b6137d3..bbe3d706 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -122,6 +122,13 @@ + + ConnectionSettingsWidget + + Form + 窗体 + + ConnectionWidget @@ -149,6 +156,45 @@ + + GroupManager + + Connection Management + 连接管理 + + + Reload Subscription + 更新订阅 + + + Would you like to reload the subscription? + 您要更新此订阅吗? + + + Deleting a subscription + 删除订阅 + + + All connections will be moved to default group, do you want to continue? + 本订阅中的所有连接都将移动到默认分组,您确定要继续吗? + + + Export Connection(s) + 导出连接 + + + Delete Connection(s) + 删除连接 + + + Copy to... + 复制到... + + + Move to... + 移动到... + + ImportConfigWindow @@ -555,6 +601,13 @@ 此用户已存在。 + + InboundSettingsWidget + + Form + 窗体 + + JsonEditor @@ -618,7 +671,7 @@ Add - 添加 + 添加 Preferences @@ -952,6 +1005,10 @@ Groups 分组 + + Add Connection + 添加连接 + OutboundEditor @@ -2270,11 +2327,11 @@ But could damage your server if improperly used. Not connected - 未连接 + 未连接 Connected - 已连接 + 已连接 Custom Text @@ -3317,19 +3374,19 @@ Maybe you have downloaded the wrong core? SubscriptionEditor Reload Subscription - 更新订阅 + 更新订阅 Would you like to reload the subscription? - 您要更新此订阅吗? + 您要更新此订阅吗? Deleting a subscription - 删除订阅 + 删除订阅 All connections will be moved to default group, do you want to continue? - 本订阅中的所有连接都将移动到默认分组,您确定要继续吗? + 本订阅中的所有连接都将移动到默认分组,您确定要继续吗? @@ -3395,7 +3452,7 @@ Maybe you have downloaded the wrong core? Group Details - 分组细节 + 分组细节 Group Name @@ -3419,12 +3476,48 @@ Maybe you have downloaded the wrong core? Connection List - 连接列表 + 连接列表 Update Subscription Data 更新订阅数据 + + Group Info + 分组信息 + + + Created At + 创建于 + + + Connections + 连接 + + + Delete Selection + 删除所选项 + + + Export Selection + 导出所选项 + + + Subscription Settings + 订阅设置 + + + This group is a subscription + 此分组是是一个订阅 + + + Connection Settings + 连接设置 + + + Route Settings + 路由设定 + w_PluginManager From 75c9b448dd2efd293cec3be3e68fcb5ccc8156ff Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sun, 3 May 2020 21:38:16 +0800 Subject: [PATCH 07/42] adopting urlsafe parsers --- src/common/QvHelpers.cpp | 25 +++++++++++++++++++++ src/common/QvHelpers.hpp | 4 ++++ src/core/connection/Serialization.cpp | 2 +- src/core/connection/Serialization_ss.cpp | 2 +- src/core/connection/Serialization_vmess.cpp | 2 +- 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/common/QvHelpers.cpp b/src/common/QvHelpers.cpp index f951357e..1c98e760 100644 --- a/src/common/QvHelpers.cpp +++ b/src/common/QvHelpers.cpp @@ -111,6 +111,31 @@ namespace Qv2ray::common return doc.object(); } + // backported from QvPlugin-SSR. + QString SafeBase64Encode(QString string) { + QByteArray ba = string.replace(QChar('-'), QChar('+')).replace(QChar('_'), QChar('/')).toUtf8(); + return QByteArray::fromBase64(ba, QByteArray::Base64Option::OmitTrailingEquals); + } + + // backported from QvPlugin-SSR. + QString SafeBase64Encode(const QString &string, bool trim) + { + QString base64 = string.toUtf8().toBase64(); + if (trim) + { + auto tmp = base64.replace(QChar('+'), QChar('-')).replace(QChar('/'), QChar('_')); + auto crbedin = tmp.crbegin(); + auto idx = tmp.length(); + while (crbedin != tmp.crend() && (*crbedin) == '=') idx -= 1, crbedin++; + return idx != tmp.length() ? tmp.remove(idx, tmp.length() - idx) : tmp; + } + else + { + return base64.replace(QChar('+'), QChar('-')).replace(QChar('/'), QChar('_')); + } + } + + QString Base64Encode(const QString &string) { QByteArray ba = string.toUtf8(); diff --git a/src/common/QvHelpers.hpp b/src/common/QvHelpers.hpp index c4214d22..a271678b 100644 --- a/src/common/QvHelpers.hpp +++ b/src/common/QvHelpers.hpp @@ -18,6 +18,10 @@ namespace Qv2ray::common { QStringList GetFileList(const QDir &dir); + + QString SafeBase64Decode(QString string); + QString SafeBase64Encode(const QString &string, bool trim); + QString Base64Encode(const QString &string); QString Base64Decode(const QString &string); QStringList SplitLines(const QString &str); diff --git a/src/core/connection/Serialization.cpp b/src/core/connection/Serialization.cpp index 56d2bc2c..291a7a01 100644 --- a/src/core/connection/Serialization.cpp +++ b/src/core/connection/Serialization.cpp @@ -122,7 +122,7 @@ namespace Qv2ray::core::connection // Some subscription providers may use plain vmess:// saperated by // lines But others may use base64 of above. auto result = QString::fromUtf8(arr).trimmed(); - return result.contains("://") ? result : Base64Decode(result); + return result.contains("://") ? result : SafeBase64Decode(result); } } // namespace Serialization } // namespace Qv2ray::core::connection diff --git a/src/core/connection/Serialization_ss.cpp b/src/core/connection/Serialization_ss.cpp index 86259b59..3bcf4561 100644 --- a/src/core/connection/Serialization_ss.cpp +++ b/src/core/connection/Serialization_ss.cpp @@ -81,7 +81,7 @@ namespace Qv2ray::core::connection auto x = QUrl::fromUserInput(uri); server.address = x.host(); server.port = x.port(); - QString userInfo = Base64Decode(x.userName()); + QString userInfo = SafeBase64Decode(x.userName()); auto userInfoSp = userInfo.indexOf(':'); // DEBUG(MODULE_CONNECTION, "Userinfo splitter position: " + QSTRN(userInfoSp)) diff --git a/src/core/connection/Serialization_vmess.cpp b/src/core/connection/Serialization_vmess.cpp index 034f7247..ebcdded3 100644 --- a/src/core/connection/Serialization_vmess.cpp +++ b/src/core/connection/Serialization_vmess.cpp @@ -88,7 +88,7 @@ namespace Qv2ray::core::connection return default; } - auto vmessString = Base64Decode(b64Str); + auto vmessString = SafeBase64Decode(b64Str); auto jsonErr = VerifyJsonString(vmessString); if (!jsonErr.isEmpty()) From d1553a1f31789afee87ee2e199cf96c6b1478446 Mon Sep 17 00:00:00 2001 From: ymshenyu <39402395+ymshenyu@users.noreply.github.com> Date: Sun, 3 May 2020 21:41:04 +0800 Subject: [PATCH 08/42] Update w_PluginManager.cpp (#572) Co-authored-by: Qv2ray-dev <59914293+Qv2ray-dev@users.noreply.github.com> --- src/ui/w_PluginManager.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ui/w_PluginManager.cpp b/src/ui/w_PluginManager.cpp index 19e46094..6fc51526 100644 --- a/src/ui/w_PluginManager.cpp +++ b/src/ui/w_PluginManager.cpp @@ -122,11 +122,7 @@ void PluginManageWindow::on_openPluginFolder_clicked() { pluginPath.mkpath(QV2RAY_CONFIG_DIR + "plugins/"); } -#ifdef Q_OS_LINUX - QProcess::execute("xdg-open", { pluginPath.absolutePath() }); -#else QDesktopServices::openUrl(QUrl::fromLocalFile(pluginPath.absolutePath())); -#endif } void PluginManageWindow::on_toolButton_clicked() From dacd98689b3aa5f70ca3d11cbfa5a1e79178d120 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sun, 3 May 2020 21:44:29 +0800 Subject: [PATCH 09/42] fix typo --- src/common/QvHelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/QvHelpers.cpp b/src/common/QvHelpers.cpp index 1c98e760..ea35a3df 100644 --- a/src/common/QvHelpers.cpp +++ b/src/common/QvHelpers.cpp @@ -112,7 +112,7 @@ namespace Qv2ray::common } // backported from QvPlugin-SSR. - QString SafeBase64Encode(QString string) { + QString SafeBase64Decode(QString string) { QByteArray ba = string.replace(QChar('-'), QChar('+')).replace(QChar('_'), QChar('/')).toUtf8(); return QByteArray::fromBase64(ba, QByteArray::Base64Option::OmitTrailingEquals); } From bdc6ea4688979053668a207d5bc19aea5750efd9 Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 22:01:32 +0800 Subject: [PATCH 10/42] update snapcraft.yaml --- snap/snapcraft.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 670baea5..60e41f38 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -57,7 +57,6 @@ parts: - libgrpc++-dev - libprotobuf-dev - protobuf-compiler-grpc - - ninja-build - pkg-config stage-packages: - libgcc1 @@ -73,7 +72,6 @@ parts: cmake-parameters: - -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_BUILD_TYPE=Release - - -GNinja - -DEMBED_TRANSLATIONS=ON override-pull: | snapcraftctl pull From 28e4664f356c62a05b7ffb9ac6463e35d232e762 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sun, 3 May 2020 22:27:07 +0800 Subject: [PATCH 11/42] adjusting preferencewindow 1. fixed the initial tab pos problem 2. fixed a typo on the preference window 3. added an explanation for network settings --- src/ui/w_PreferencesWindow.ui | 45 +++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/ui/w_PreferencesWindow.ui b/src/ui/w_PreferencesWindow.ui index f00a6b9d..87a1fe5c 100644 --- a/src/ui/w_PreferencesWindow.ui +++ b/src/ui/w_PreferencesWindow.ui @@ -33,7 +33,7 @@ - 3 + 0 @@ -274,28 +274,28 @@ Network Settings - + User-Agent - + - + Qv2ray Proxy - + @@ -320,14 +320,14 @@ - + - Curtom Proxy + Custom Proxy - + @@ -341,14 +341,7 @@ - - - - Curtom Proxy - - - - + @@ -375,6 +368,22 @@ + + + + + true + + + + These settings are for Qv2ray itself. +For example, for updating subscriptions. + + + Qt::PlainText + + + @@ -725,8 +734,8 @@ Custom DNS Settings 0 0 - 818 - 558 + 824 + 516 From 780bce46a14ed1fc21adf2add0e9850a107f03ef Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sun, 3 May 2020 22:30:37 +0800 Subject: [PATCH 12/42] updating translations --- translations/en_US.ts | 9 +++++---- translations/ja_JP.ts | 8 +++++++- translations/ru_RU.ts | 9 +++++---- translations/zh_CN.ts | 8 +++++++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/translations/en_US.ts b/translations/en_US.ts index c67ec840..50c7fdb9 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -1681,10 +1681,6 @@ But could damage your server if improperly used. Custom Proxy - - Curtom Proxy - - Network Options @@ -1733,6 +1729,11 @@ But could damage your server if improperly used. tproxy inbound's sniffing is enabled by default. + + These settings are for Qv2ray itself. +For example, for updating subscriptions. + + QObject diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 4683fe89..2bef7e70 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -2394,7 +2394,7 @@ But could damage your server if improperly used. Curtom Proxy - カスタムプロキシ + カスタムプロキシ Network Options @@ -2444,6 +2444,12 @@ But could damage your server if improperly used. tproxy inbound's sniffing is enabled by default. tProxyインバウンドのスニッフィングはデフォルトで有効になっています。 + + These settings are for Qv2ray itself. +For example, for updating subscriptions. + これらの設定はQv2ray自体のためのものです。 +例えば、サブスクリプションの更新などです。 + QObject diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index c075d080..0a979c06 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -2296,10 +2296,6 @@ But could damage your server if improperly used. Custom Proxy - - Curtom Proxy - - Network Options @@ -2348,6 +2344,11 @@ But could damage your server if improperly used. tproxy inbound's sniffing is enabled by default. + + These settings are for Qv2ray itself. +For example, for updating subscriptions. + + QObject diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index bbe3d706..105023ed 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -2024,7 +2024,7 @@ But could damage your server if improperly used. Curtom Proxy - 自定义代理 + 自定义代理 Network Options @@ -2074,6 +2074,12 @@ But could damage your server if improperly used. tproxy inbound's sniffing is enabled by default. tProxy 入站的嗅探选项默认开启。 + + These settings are for Qv2ray itself. +For example, for updating subscriptions. + 这些设定是针对 Qv2ray 本身的。 +例如,用在更新订阅时。 + QObject From ebe6736bba4903459e7d09290b0b029eb0e720a6 Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Sun, 3 May 2020 23:27:14 +0800 Subject: [PATCH 13/42] allow fallback to xdg-open --- CMakeLists.txt | 4 ++++ snap/snapcraft.yaml | 1 + src/ui/w_PluginManager.cpp | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ebb3f24b..e07cb39a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,6 +145,10 @@ if(QV2RAY_DISABLE_AUTO_UPDATE) add_definitions(-DDISABLE_AUTO_UPDATE) endif() +if(FALL_BACK_TO_XDG_OPEN) + add_definitions(-DFALL_BACK_TO_XDG_OPEN) +endif() + set(QVPLUGIN_INTERFACE_INCLUDE_DIR "src/components/plugins/interface") include(src/components/plugins/interface/QvPluginInterface.cmake) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 60e41f38..27eb5fdb 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -73,6 +73,7 @@ parts: - -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_BUILD_TYPE=Release - -DEMBED_TRANSLATIONS=ON + - -DFALL_BACK_TO_XDG_OPEN=ON override-pull: | snapcraftctl pull build_number=$(cat makespec/BUILDVERSION) diff --git a/src/ui/w_PluginManager.cpp b/src/ui/w_PluginManager.cpp index 6fc51526..5309f88a 100644 --- a/src/ui/w_PluginManager.cpp +++ b/src/ui/w_PluginManager.cpp @@ -122,7 +122,11 @@ void PluginManageWindow::on_openPluginFolder_clicked() { pluginPath.mkpath(QV2RAY_CONFIG_DIR + "plugins/"); } +#ifdef FALL_BACK_TO_XDG_OPEN + QProcess::execute("xdg-open", { pluginPath.absolutePath() }); +#else QDesktopServices::openUrl(QUrl::fromLocalFile(pluginPath.absolutePath())); +#endif } void PluginManageWindow::on_toolButton_clicked() From 5c66b29879b49643fcb7c3e6df47898077def03b Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Mon, 4 May 2020 15:11:51 +0800 Subject: [PATCH 14/42] adopting url-safe base64 decode for ssd this shall resolve #577 --- src/core/connection/Serialization_ssd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/connection/Serialization_ssd.cpp b/src/core/connection/Serialization_ssd.cpp index f207c3d4..5d694684 100644 --- a/src/core/connection/Serialization_ssd.cpp +++ b/src/core/connection/Serialization_ssd.cpp @@ -84,7 +84,7 @@ namespace Qv2ray::core::connection::Serialization // decode base64 const auto ssdURIBody = QStringRef(&uri, 6, uri.length() - 6); - const auto decodedJSON = QByteArray::fromBase64(ssdURIBody.toUtf8()); + const auto decodedJSON = SafeBase64Decode(ssdURIBody.toString()).toUtf8(); if (decodedJSON.length() == 0) { From ec17b27afa96893b9b13a0161e5d0d5c1e81e3e8 Mon Sep 17 00:00:00 2001 From: tleydxdy Date: Tue, 5 May 2020 02:35:29 -0400 Subject: [PATCH 15/42] make vmess link parsing more robust --- src/core/connection/Serialization_vmess.cpp | 30 +++++---------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/src/core/connection/Serialization_vmess.cpp b/src/core/connection/Serialization_vmess.cpp index ebcdded3..4f47cbf8 100644 --- a/src/core/connection/Serialization_vmess.cpp +++ b/src/core/connection/Serialization_vmess.cpp @@ -111,28 +111,10 @@ namespace Qv2ray::core::connection *errMessage = QObject::tr("seems like a v1 vmess, we don't support it"); return default; } - bool flag = true; - // C is a quick hack... -#define C(k) (flag = (vmessConf.contains(k) ? (errMessage->clear(), true) : (*errMessage += (k " does not exist"), false))) - // id, aid, port and add are mandatory fields of a vmess:// - // link. - flag = flag && C("id") && (C("aid") || C("alterId")) && C("port") && C("add"); - // Stream Settings - auto net = vmessConf["net"].toString(); - - if (net == "http" || net == "ws") - flag = flag && C("host") && C("path"); - else if (net == "domainsocket") - flag = flag && C("path"); - else if (net == "quic") - flag = flag && C("host") && C("type") && C("path"); - -#undef C - // return flag ? 0 : 1; // -------------------------------------------------------------------------------------- CONFIGROOT root; - QString ps, add, id, /*net,*/ type, host, path, tls; + QString ps, add, id, net, type, host, path, tls; int port, aid; // // __vmess_checker__func(key, values) @@ -194,9 +176,10 @@ namespace Qv2ray::core::connection << "domainsocket" // << "quic"); // // - __vmess_checker__func(path, << ""); // - __vmess_checker__func(host, << ""); // - __vmess_checker__func(tls, << ""); // + __vmess_checker__func(tls, << "none" // + << "tls"); // + 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 // if (QStringList{ "srtp", "utp", "wechat-video" }.contains(type)) // @@ -250,7 +233,8 @@ namespace Qv2ray::core::connection } else if (net == "ws") { - streaming.wsSettings.headers["Host"] = host; + if (!host.isEmpty()) + streaming.wsSettings.headers["Host"] = host; streaming.wsSettings.path = path; } else if (net == "kcp") From 48cf6ffef698d7c3a7aaf76fb6cdf8d89060ca86 Mon Sep 17 00:00:00 2001 From: tleydxdy Date: Tue, 5 May 2020 02:59:57 -0400 Subject: [PATCH 16/42] fix typo --- src/core/connection/Serialization_vmess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/connection/Serialization_vmess.cpp b/src/core/connection/Serialization_vmess.cpp index 4f47cbf8..04f18661 100644 --- a/src/core/connection/Serialization_vmess.cpp +++ b/src/core/connection/Serialization_vmess.cpp @@ -179,7 +179,7 @@ namespace Qv2ray::core::connection __vmess_checker__func(tls, << "none" // << "tls"); // path = vmessConf.contains("path") ? vmessConf["path"].toVariant().toString() : (net == "quic" ? "" : "/"); - host = vmessConf.contains("host") ? vmessConf["host"].toVariant().toString() : (net == "quic" ? "none" : "/"); + host = vmessConf.contains("host") ? vmessConf["host"].toVariant().toString() : (net == "quic" ? "none" : ""); } // Repect connection type rather than obfs type // if (QStringList{ "srtp", "utp", "wechat-video" }.contains(type)) // From 8e63a11c57e2b830f7afce3c1222b9ab675b1c0d Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 5 May 2020 20:14:04 +0800 Subject: [PATCH 17/42] updating translations --- translations/ja_JP.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 2bef7e70..78a855d2 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -3972,7 +3972,7 @@ Maybe you have downloaded the wrong core? This group is a subscription - このグループはサブスクリプションです。 + このグループはサブスクリプションです Connection Settings From 7cce0cd40ff49aa58e42fb746474ff9ff8ded66b Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 5 May 2020 21:13:01 +0800 Subject: [PATCH 18/42] trying to resolve GNOME HTTPS Proxy Problem --- src/components/proxy/QvProxyConfigurator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index f6fad937..cea25886 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -242,9 +242,9 @@ namespace Qv2ray::components::proxy { actions << QString("gsettings set org.gnome.system.proxy.http host '%1'").arg(address); actions << QString("gsettings set org.gnome.system.proxy.http port %1").arg(httpPort); - // - actions << QString("gsettings set org.gnome.system.proxy.https host '%1'").arg(address); - actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort); + // GNOME HTTPS is problematic. disabling. + // actions << QString("gsettings set org.gnome.system.proxy.https host '%1'").arg(address); + // actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort); if (isKDE) { // FTP here should be scheme: ftp:// From 407436ffba0329f3d6a0f42ac52b30f5c6432bdf Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Tue, 5 May 2020 22:09:46 +0800 Subject: [PATCH 19/42] Revert "trying to resolve GNOME HTTPS Proxy Problem" This reverts commit 7cce0cd40ff49aa58e42fb746474ff9ff8ded66b. --- src/components/proxy/QvProxyConfigurator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index cea25886..f6fad937 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -242,9 +242,9 @@ namespace Qv2ray::components::proxy { actions << QString("gsettings set org.gnome.system.proxy.http host '%1'").arg(address); actions << QString("gsettings set org.gnome.system.proxy.http port %1").arg(httpPort); - // GNOME HTTPS is problematic. disabling. - // actions << QString("gsettings set org.gnome.system.proxy.https host '%1'").arg(address); - // actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort); + // + actions << QString("gsettings set org.gnome.system.proxy.https host '%1'").arg(address); + actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort); if (isKDE) { // FTP here should be scheme: ftp:// From a3ce8015d6483d03ca5a3dcf6bb317678fe37af7 Mon Sep 17 00:00:00 2001 From: Qv2ray-dev <59914293+Qv2ray-dev@users.noreply.github.com> Date: Wed, 6 May 2020 17:27:14 +0800 Subject: [PATCH 20/42] add: added default vmess "type" field --- src/core/connection/Serialization_vmess.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/connection/Serialization_vmess.cpp b/src/core/connection/Serialization_vmess.cpp index 04f18661..42f59376 100644 --- a/src/core/connection/Serialization_vmess.cpp +++ b/src/core/connection/Serialization_vmess.cpp @@ -52,6 +52,11 @@ namespace Qv2ray::core::connection vmessUriRoot["host"] = transfer.httpSettings.host.join(","); vmessUriRoot["path"] = transfer.httpSettings.path; } + + if(!vmessUriRoot.contains("type") || vmessUriRoot["type"].toString().isEmpty()) + { + vmessUriRoot["type"] = "none"; + } // auto vmessPart = Base64Encode(JsonToString(vmessUriRoot, QJsonDocument::JsonFormat::Compact)); From b5ec43c0df349747b80da2bbeb3a6bf02a73df4c Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Wed, 6 May 2020 22:03:52 +0800 Subject: [PATCH 21/42] refactor: system-proxy/linux/set --- src/components/proxy/QvProxyConfigurator.cpp | 69 ++++++++++++-------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index f6fad937..c38839b1 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -233,46 +233,62 @@ namespace Qv2ray::components::proxy actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg("manual"); bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE"; const auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); - if (isKDE) + + // Setting Proxy Mode to Manual { - LOG(MODULE_PROXY, "KDE detected") - actions << QString("kwriteconfig5 --file " + configPath + "/kioslaverc --group \"Proxy Settings\" --key ProxyType 1"); - } - if (hasHTTP) - { - actions << QString("gsettings set org.gnome.system.proxy.http host '%1'").arg(address); - actions << QString("gsettings set org.gnome.system.proxy.http port %1").arg(httpPort); - // - actions << QString("gsettings set org.gnome.system.proxy.https host '%1'").arg(address); - actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort); + // for GNOME: + { + actions << "gsettings set org.gnome.system.proxy mode 'manual'"; + } + + // for KDE: if (isKDE) { - // FTP here should be scheme: ftp:// - for (auto protocol : { "http", "ftp", "https" }) + LOG(MODULE_PROXY, "KDE detected") + actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key ProxyType 1").arg(configPath); + } + } + + // Configure HTTP Proxies for HTTP, FTP and HTTPS + if (hasHTTP) + { + // iterate over protocols... + for (const auto protocol : { "http", "ftp", "https" }) + { + // for GNOME: { - auto str = - QString("kwriteconfig5 --file " + configPath + "/kioslaverc --group \"Proxy Settings\" --key %1Proxy \"http://%2 %3\"") - .arg(protocol) - .arg(address) - .arg(QSTRN(httpPort)); - actions << str; + actions << QString("gsettings set org.gnome.system.proxy.%1 host '%2'").arg(protocol, address); + actions << QString("gsettings set org.gnome.system.proxy.%1 port %2").arg(protocol, QSTRN(httpPort)); + } + + // for KDE: + if (isKDE) + { + actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key %2Proxy 'http://%3 %4'") + .arg(configPath, protocol, address, QSTRN(httpPort)); } } } + // Configure SOCKS5 Proxies if (hasSOCKS) { - actions << QString("gsettings set org.gnome.system.proxy.socks host '%1'").arg(address); - actions << QString("gsettings set org.gnome.system.proxy.socks port %1").arg(socksPort); + // for GNOME: + { + actions << QString("gsettings set org.gnome.system.proxy.socks host '%1'").arg(address); + actions << QString("gsettings set org.gnome.system.proxy.socks port %1").arg(socksPort); + } + + // for KDE: if (isKDE) { - actions << QString("kwriteconfig5 --file " + configPath + - "/kioslaverc --group \"Proxy Settings\" --key socksProxy \"socks://%1 %2\"") - .arg(address) - .arg(QSTRN(socksPort)); + actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key socksProxy 'socks://%2 %3'") + .arg(configPath, address, QSTRN(socksPort)); } } + // Execute them all! + // // note: do not use std::all_of / any_of / none_of, // because those are short-circuit and cannot guarantee atomicity. auto result = std::count_if(actions.cbegin(), actions.cend(), [](const QString &action) { @@ -286,7 +302,8 @@ namespace Qv2ray::components::proxy LOG(MODULE_PROXY, "It may happen if you are using KDE with no gsettings support.") } - Q_UNUSED(result); + // TODO: Post-settings for DDE + #else for (auto service : macOSgetNetworkServices()) From 0db5ae89a4dd91189c380cd711ec9eaa5a5e2b37 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Wed, 6 May 2020 23:04:17 +0800 Subject: [PATCH 22/42] more system proxy tweaks --- src/components/proxy/QvProxyConfigurator.cpp | 76 ++++++++++++-------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index c38839b1..23dfc7fc 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -234,21 +234,6 @@ namespace Qv2ray::components::proxy bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE"; const auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); - // Setting Proxy Mode to Manual - { - // for GNOME: - { - actions << "gsettings set org.gnome.system.proxy mode 'manual'"; - } - - // for KDE: - if (isKDE) - { - LOG(MODULE_PROXY, "KDE detected") - actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key ProxyType 1").arg(configPath); - } - } - // Configure HTTP Proxies for HTTP, FTP and HTTPS if (hasHTTP) { @@ -287,19 +272,37 @@ namespace Qv2ray::components::proxy } } + // Setting Proxy Mode to Manual + { + // for GNOME: + { + actions << "gsettings set org.gnome.system.proxy mode 'manual'"; + } + + // for KDE: + if (isKDE) + { + LOG(MODULE_PROXY, "KDE detected") + actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key ProxyType 1").arg(configPath); + } + } + // Execute them all! // // note: do not use std::all_of / any_of / none_of, // because those are short-circuit and cannot guarantee atomicity. auto result = std::count_if(actions.cbegin(), actions.cend(), [](const QString &action) { - DEBUG(MODULE_PROXY, action) - return QProcess::execute(action) == QProcess::NormalExit; + // execute and get the code + const auto returnCode = QProcess::execute(action); + // print out the commands and result codes + DEBUG(MODULE_PROXY, QString("[%1] %2").arg(QSTRN(returnCode), action)) + // give the code back + return returnCode == QProcess::NormalExit; }) == actions.size(); if (!result) { - LOG(MODULE_PROXY, "There was something wrong when setting proxies.") - LOG(MODULE_PROXY, "It may happen if you are using KDE with no gsettings support.") + LOG(MODULE_PROXY, "Something wrong when setting proxies.") } // TODO: Post-settings for DDE @@ -340,6 +343,7 @@ namespace Qv2ray::components::proxy void ClearSystemProxy() { LOG(MODULE_PROXY, "Clearing System Proxy") + #ifdef Q_OS_WIN LOG(MODULE_PROXY, "Cleaning system proxy settings.") INTERNET_PER_CONN_OPTION_LIST list; @@ -370,21 +374,33 @@ namespace Qv2ray::components::proxy InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0); InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0); #elif defined(Q_OS_LINUX) - if (qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE") + QStringList actions; + const bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE"; + const auto configRoot = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); + + // Setting System Proxy Mode to: None { - QProcess::execute("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + - "/kioslaverc --group \"Proxy Settings\" --key ProxyType 0"); - for (auto protocol : { "http", "ftp", "https" }) + // for GNOME: { - auto str = QString("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + - "/kioslaverc --group \"Proxy Settings\" --key %1Proxy ''") - .arg(protocol); - QProcess::execute(str); + actions << QString("gsettings set org.gnome.system.proxy mode 'none'"); + } + + // for KDE: + if (isKDE) + { + actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key ProxyType 0").arg(configRoot); } - QProcess::execute("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + - "/kioslaverc --group \"Proxy Settings\" --key socksProxy ''"); } - QProcess::execute("gsettings set org.gnome.system.proxy mode 'none'"); + + // Execute the Actions + for (const auto &action : actions) + { + // execute and get the code + const auto returnCode = QProcess::execute(action); + // print out the commands and result codes + DEBUG(MODULE_PROXY, QString("[%1] %2").arg(QSTRN(returnCode), action)) + } + #else for (auto service : macOSgetNetworkServices()) { From a224bc98c50bafe4b8aa2304ac463b84993d1b9b Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Thu, 7 May 2020 00:07:22 +0800 Subject: [PATCH 23/42] working around poisonous deepin proxy settings --- src/base/models/QvRuntimeConfig.hpp | 1 + src/components/proxy/QvProxyConfigurator.cpp | 22 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/base/models/QvRuntimeConfig.hpp b/src/base/models/QvRuntimeConfig.hpp index d1dd033c..f572f88b 100644 --- a/src/base/models/QvRuntimeConfig.hpp +++ b/src/base/models/QvRuntimeConfig.hpp @@ -8,6 +8,7 @@ namespace Qv2ray::base struct Qv2rayRuntimeConfig { bool screenShotHideQv2ray = false; + bool deepinHorribleProxyHint = false; }; inline base::Qv2rayRuntimeConfig RuntimeConfig = base::Qv2rayRuntimeConfig(); } // namespace Qv2ray::base diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index 23dfc7fc..514b816d 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -232,6 +232,7 @@ namespace Qv2ray::components::proxy QStringList actions; actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg("manual"); bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE"; + bool isDDE = isKDE ? false : qEnvironmentVariable("XDG_SESSION_DESKTOP") == "DDE"; const auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); // Configure HTTP Proxies for HTTP, FTP and HTTPS @@ -305,7 +306,26 @@ namespace Qv2ray::components::proxy LOG(MODULE_PROXY, "Something wrong when setting proxies.") } - // TODO: Post-settings for DDE + // Post-Actions for HTTP on Deepin Desktop Environment. + if (isDDE && hasHTTP) + { + if (!RuntimeConfig.deepinHorribleProxyHint) + { + RuntimeConfig.deepinHorribleProxyHint = true; + + const auto deepinWarnTitle = QObject::tr("Deepin Detected"); + const auto deepinWarnMessage = + QObject::tr("Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. ") + NEWLINE + // + QObject::tr("The original scheme should be http://, but he will replace with https://, causing the problem. ") + NEWLINE + // + QObject::tr("Qv2ray will help you change it back and make things work again. "); + QvMessageBoxWarn(nullptr, deepinWarnTitle, deepinWarnMessage); + } + + // set them back! + const auto httpProxyURL = QString("http://%1:%2").arg(address, QSTRN(httpPort)).toStdString(); + setenv("https_proxy", httpProxyURL.c_str(), true); + setenv("ftp_proxy", httpProxyURL.c_str(), true); + } #else From 57ffa703a0c1c2a37335fb6c963c109cc82a1318 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Thu, 7 May 2020 00:44:08 +0800 Subject: [PATCH 24/42] updating translations for the deepin hint --- translations/en_US.ts | 16 ++++++++++++++++ translations/ja_JP.ts | 16 ++++++++++++++++ translations/ru_RU.ts | 16 ++++++++++++++++ translations/zh_CN.ts | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/translations/en_US.ts b/translations/en_US.ts index 50c7fdb9..7bcc9616 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -2109,6 +2109,22 @@ For example, for updating subscriptions. Unknown + + Deepin Detected + + + + Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. + + + + The original scheme should be http://, but he will replace with https://, causing the problem. + + + + Qv2ray will help you change it back and make things work again. + + Qv2ray::common::QvCommandArgParser diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 2bef7e70..a0ec5922 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -2913,6 +2913,22 @@ For example, for updating subscriptions. Unknown 不明 + + Deepin Detected + Deepin検出 + + + Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. + Deepinのバカ、間違ったHTTPS_PROXY環境変数を設定します。 + + + The original scheme should be http://, but he will replace with https://, causing the problem. + 本来のスキームは http:// であるべきなのですが、彼は https:// に置き換えて問題を引き起こします。 + + + Qv2ray will help you change it back and make things work again. + Qv2rayはそれを元に戻して、またうまくいくようにしてくれます。 + Qv2ray::common::QvCommandArgParser diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index 0a979c06..1ccbdfcf 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -2796,6 +2796,22 @@ For example, for updating subscriptions. Unknown + + Deepin Detected + + + + Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. + + + + The original scheme should be http://, but he will replace with https://, causing the problem. + + + + Qv2ray will help you change it back and make things work again. + + Qv2ray::common::QvCommandArgParser diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 105023ed..ed8cbf39 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -2491,6 +2491,22 @@ For example, for updating subscriptions. Unknown 未知 + + Deepin Detected + 检测到 Deepin + + + Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. + 默认情况下,Deepin 自作聪明,会给你设置错误的 HTTPS_PROXY 环境变量。 + + + The original scheme should be http://, but he will replace with https://, causing the problem. + 原 scheme 应为 http://,但 Deepin 将其替换成了 https://,导致 HTTPS 代理无法正常使用。 + + + Qv2ray will help you change it back and make things work again. + Qv2ray 会尝试帮你改回去,以期解决此问题。 + Qv2ray::common::QvCommandArgParser From 2622664c617b0c9572c44afebf4bcc51935f8f2f Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Thu, 7 May 2020 10:08:20 +0800 Subject: [PATCH 25/42] D E E P I N --- src/components/proxy/QvProxyConfigurator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index 514b816d..8c496f0a 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -232,7 +232,7 @@ namespace Qv2ray::components::proxy QStringList actions; actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg("manual"); bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE"; - bool isDDE = isKDE ? false : qEnvironmentVariable("XDG_SESSION_DESKTOP") == "DDE"; + bool isDDE = isKDE ? false : qEnvironmentVariable("XDG_SESSION_DESKTOP") == "deepin"; const auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); // Configure HTTP Proxies for HTTP, FTP and HTTPS From a086db44323172cffcb0c5acf05fcfbcc3c37f15 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Fri, 8 May 2020 11:00:03 +0800 Subject: [PATCH 26/42] =?UTF-8?q?=E6=B2=A1=E6=95=91=E4=BA=86=EF=BC=8C?= =?UTF-8?q?=E7=AD=89=E6=AD=BB=E5=90=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/proxy/QvProxyConfigurator.cpp | 14 +++++++------- translations/en_US.ts | 6 +++--- translations/ja_JP.ts | 18 +++++++++++++++--- translations/ru_RU.ts | 6 +++--- translations/zh_CN.ts | 18 +++++++++++++++--- 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index 8c496f0a..9c0b4895 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -315,16 +315,16 @@ namespace Qv2ray::components::proxy const auto deepinWarnTitle = QObject::tr("Deepin Detected"); const auto deepinWarnMessage = - QObject::tr("Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. ") + NEWLINE + // - QObject::tr("The original scheme should be http://, but he will replace with https://, causing the problem. ") + NEWLINE + // - QObject::tr("Qv2ray will help you change it back and make things work again. "); + QObject::tr("Deepin plays smart and sets you the wrong HTTPS_PROXY, FTP_PROXY environment variable.") + NEWLINE + // + QObject::tr("The origin scheme http is wrongly replaced by https and ftp, causing the problem.") + NEWLINE + // + QObject::tr("Qv2ray cannot help you change them back. Please don't blame us if things go wrong."); // QvMessageBoxWarn(nullptr, deepinWarnTitle, deepinWarnMessage); } - // set them back! - const auto httpProxyURL = QString("http://%1:%2").arg(address, QSTRN(httpPort)).toStdString(); - setenv("https_proxy", httpProxyURL.c_str(), true); - setenv("ftp_proxy", httpProxyURL.c_str(), true); + // set them back! - NOPE. setenv only works within your little program. + // const auto httpProxyURL = QString("http://%1:%2").arg(address, QSTRN(httpPort)).toStdString(); + // setenv("https_proxy", httpProxyURL.c_str(), true); + // setenv("ftp_proxy", httpProxyURL.c_str(), true); } #else diff --git a/translations/en_US.ts b/translations/en_US.ts index 7bcc9616..ebfea120 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -2114,15 +2114,15 @@ For example, for updating subscriptions. - Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. + Deepin plays smart and sets you the wrong HTTPS_PROXY, FTP_PROXY environment variable. - The original scheme should be http://, but he will replace with https://, causing the problem. + The origin scheme http is wrongly replaced by https and ftp, causing the problem. - Qv2ray will help you change it back and make things work again. + Qv2ray cannot help you change them back. Please don't blame us if things go wrong. diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index a0ec5922..a55747b8 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -2919,15 +2919,27 @@ For example, for updating subscriptions. Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. - Deepinのバカ、間違ったHTTPS_PROXY環境変数を設定します。 + Deepinのバカ、間違ったHTTPS_PROXY環境変数を設定します。 The original scheme should be http://, but he will replace with https://, causing the problem. - 本来のスキームは http:// であるべきなのですが、彼は https:// に置き換えて問題を引き起こします。 + 本来のスキームは http:// であるべきなのですが、彼は https:// に置き換えて問題を引き起こします。 Qv2ray will help you change it back and make things work again. - Qv2rayはそれを元に戻して、またうまくいくようにしてくれます。 + Qv2rayはそれを元に戻して、またうまくいくようにしてくれます。 + + + Deepin plays smart and sets you the wrong HTTPS_PROXY, FTP_PROXY environment variable. + Deepinのバカ、間違ったHTTPS_PROXYとFTP_PROXYの環境変数を設定します。 + + + The origin scheme http is wrongly replaced by https and ftp, causing the problem. + 元のスキームのhttpがhttpsとftpに間違って置き換えられてしまい、問題が発生しています。 + + + Qv2ray cannot help you change them back. Please don't blame us if things go wrong. + Qv2rayでは元に戻すことはできません。何かあっても私たちのせいにしないでください。 diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index 1ccbdfcf..b82073f9 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -2801,15 +2801,15 @@ For example, for updating subscriptions. - Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. + Deepin plays smart and sets you the wrong HTTPS_PROXY, FTP_PROXY environment variable. - The original scheme should be http://, but he will replace with https://, causing the problem. + The origin scheme http is wrongly replaced by https and ftp, causing the problem. - Qv2ray will help you change it back and make things work again. + Qv2ray cannot help you change them back. Please don't blame us if things go wrong. diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index ed8cbf39..c2b03b9c 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -2497,15 +2497,27 @@ For example, for updating subscriptions. Deepin plays smart and sets you the wrong HTTPS_PROXY environment variable. - 默认情况下,Deepin 自作聪明,会给你设置错误的 HTTPS_PROXY 环境变量。 + 默认情况下,Deepin 自作聪明,会给你设置错误的 HTTPS_PROXY 环境变量。 The original scheme should be http://, but he will replace with https://, causing the problem. - 原 scheme 应为 http://,但 Deepin 将其替换成了 https://,导致 HTTPS 代理无法正常使用。 + 原 scheme 应为 http://,但 Deepin 将其替换成了 https://,导致 HTTPS 代理无法正常使用。 Qv2ray will help you change it back and make things work again. - Qv2ray 会尝试帮你改回去,以期解决此问题。 + Qv2ray 会尝试帮你改回去,以期解决此问题。 + + + Deepin plays smart and sets you the wrong HTTPS_PROXY, FTP_PROXY environment variable. + Deepin可能自作聪明,为你设置了错误的 HTTPS_PROXY 和 FTP_PROXY 环境变量。 + + + The origin scheme http is wrongly replaced by https and ftp, causing the problem. + 原来正确的 http:// 可能被错误地替换为 https:// 和 ftp://,导致这个问题。 + + + Qv2ray cannot help you change them back. Please don't blame us if things go wrong. + Qv2ray 很遗憾无法帮你改回来。若因此遇到问题,请勿指责吾等。 From 4ed028d77aa4275d0186343305b2073aab9c1610 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Fri, 8 May 2020 11:11:49 +0800 Subject: [PATCH 27/42] Deepin you win --- src/components/proxy/QvProxyConfigurator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index 9c0b4895..7ba75e93 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -232,7 +232,7 @@ namespace Qv2ray::components::proxy QStringList actions; actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg("manual"); bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE"; - bool isDDE = isKDE ? false : qEnvironmentVariable("XDG_SESSION_DESKTOP") == "deepin"; + bool isDDE = isKDE ? false : qEnvironmentVariable("XDG_CURRENT_DESKTOP").toLower() == "deepin"; const auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); // Configure HTTP Proxies for HTTP, FTP and HTTPS From 39e2adfabd87cf28375e4161c9fd1e3f1ae3d563 Mon Sep 17 00:00:00 2001 From: ymshenyu Date: Fri, 8 May 2020 13:29:07 +0800 Subject: [PATCH 28/42] Update CMakeLists.txt --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e07cb39a..a3789ce7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,10 +29,12 @@ add_definitions(-DQV2RAY_VERSION_BUGFIX=${CPACK_PACKAGE_VERSION_PATCH}) add_definitions(-DQV2RAY_VERSION_BUILD=${QV2RAY_BUILD_VERSION}) add_definitions(-DQV2RAY_VERSION_STRING="${QV2RAY_VERSION_STRING}") -add_definitions(-DXTOSTRUCT_QT) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +if(MSVC) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() find_package(Qt5 5.11 COMPONENTS Core Gui Widgets Network REQUIRED) From 79d61d3309f530032ee0dc39882fe806cf012271 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sat, 9 May 2020 14:14:34 +0800 Subject: [PATCH 29/42] fixing KDE system proxy settings damn kwriteconfig5 needs you to use double quote --- src/components/proxy/QvProxyConfigurator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index 7ba75e93..cb301468 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -250,7 +250,7 @@ namespace Qv2ray::components::proxy // for KDE: if (isKDE) { - actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key %2Proxy 'http://%3 %4'") + actions << QString(R"(kwriteconfig5 --file "%1/kioslaverc" --group "Proxy Settings" --key %2Proxy "http://%3 %4")") .arg(configPath, protocol, address, QSTRN(httpPort)); } } @@ -268,7 +268,7 @@ namespace Qv2ray::components::proxy // for KDE: if (isKDE) { - actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key socksProxy 'socks://%2 %3'") + actions << QString(R"(kwriteconfig5 --file "%1/kioslaverc" --group "Proxy Settings" --key socksProxy "socks://%2 %3")") .arg(configPath, address, QSTRN(socksPort)); } } @@ -284,7 +284,7 @@ namespace Qv2ray::components::proxy if (isKDE) { LOG(MODULE_PROXY, "KDE detected") - actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key ProxyType 1").arg(configPath); + actions << QString(R"(kwriteconfig5 --file "%1/kioslaverc" --group "Proxy Settings" --key ProxyType 1)").arg(configPath); } } @@ -408,7 +408,7 @@ namespace Qv2ray::components::proxy // for KDE: if (isKDE) { - actions << QString("kwriteconfig5 --file %1/kioslaverc --group 'Proxy Settings' --key ProxyType 0").arg(configRoot); + actions << QString(R"(kwriteconfig5 --file "%1/kioslaverc" --group "Proxy Settings" --key ProxyType 0)").arg(configRoot); } } From f9b4813b8dc52f2be70c108e589c73e405aafa71 Mon Sep 17 00:00:00 2001 From: DuckVador Date: Mon, 11 May 2020 00:45:20 +0800 Subject: [PATCH 30/42] add nonblocking TCPing --- makespec/BUILDVERSION | 2 +- src/components/latency/QvTCPing.cpp | 109 ++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION index 2f114b59..80969167 100644 --- a/makespec/BUILDVERSION +++ b/makespec/BUILDVERSION @@ -1 +1 @@ -5366 \ No newline at end of file +5367 \ No newline at end of file diff --git a/src/components/latency/QvTCPing.cpp b/src/components/latency/QvTCPing.cpp index 77046fec..b511c10b 100644 --- a/src/components/latency/QvTCPing.cpp +++ b/src/components/latency/QvTCPing.cpp @@ -4,13 +4,113 @@ #else #include #include + #include #include + #include #include #endif #include "QtConcurrent/QtConcurrent" #include "QvTCPing.hpp" #include "core/handler/ConfigHandler.hpp" + +#ifdef _WIN32 + using qv_socket_t=SOCKET; +#else + using qv_socket_t=int; +#endif +namespace +{ + inline int setnonblocking(qv_socket_t sockno,int &opt) + { +#ifdef _WIN32 + ULONG block = 1; + if (ioctlsocket(sockno, FIONBIO, &block) == SOCKET_ERROR) + { + return -1; + } +#else + if ((opt = fcntl (sockno, F_GETFL, NULL)) < 0) { + //get socket flags + return -1; + } + if (fcntl (sockno, F_SETFL, opt | O_NONBLOCK) < 0) { + //set socket non-blocking + return -1; + } +#endif + return 0; + } + + inline int setblocking(qv_socket_t sockno,int &opt) + { +#ifdef _WIN32 + ULONG block = 0; + if (ioctlsocket(sockno, FIONBIO, &block) == SOCKET_ERROR) + { + return -1; + } +#else + if (fcntl (sockno, F_SETFL, opt) < 0) { + //reset socket flags + return -1; + } +#endif + return 0; + } + + + int connect_wait ( + qv_socket_t sockno, + struct sockaddr * addr, + size_t addrlen, + int timeout_sec=5) + { + int res; + int opt; + timeval tv = {0}; + tv.tv_sec = timeout_sec; + tv.tv_usec = 0; + if ((res = setnonblocking(sockno,opt))!=0) + return -1; + if ((res = ::connect (sockno, addr, addrlen)) < 0) { +#ifdef _WIN32 + if (WSAGetLastError() != WSAEWOULDBLOCK) { +#else + if (errno == EINPROGRESS) { +#endif + //connecting + fd_set wait_set; + FD_ZERO (&wait_set); + FD_SET (sockno, &wait_set); + res = select (sockno + 1, NULL, &wait_set, NULL, &tv); + } + } + else { + //connect immediately + res = 1; + } + if (setblocking(sockno,opt)!=0){ + return -1; + } + if (res < 0) { + //an error occured + return -1; + } + else if (res == 0) { + //timeout + return 1; + } + else { + socklen_t len = sizeof (opt); + if (getsockopt (sockno, SOL_SOCKET, SO_ERROR, reinterpret_cast(&opt), &len) < 0) { + return -1; + } + } + return 0; + } +} + namespace Qv2ray::components::tcping { static int resolveHost(const std::string &host, int portnr, struct addrinfo **res); @@ -159,11 +259,8 @@ namespace Qv2ray::components::tcping int testLatency(struct addrinfo *addr, std::chrono::system_clock::time_point *start, std::chrono::system_clock::time_point *end) { -#ifdef _WIN32 - SOCKET fd; -#else - int fd; -#endif + qv_socket_t fd; + const int on = 1; /* int flags; */ int rv = 0; @@ -198,7 +295,7 @@ namespace Qv2ray::components::tcping /* connect to peer */ // Qt has its own connect() function in QObject.... // So we add "::" here - if (::connect(fd, addr->ai_addr, addr->ai_addrlen) == 0) + if (connect_wait(fd, addr->ai_addr, addr->ai_addrlen)==0) { *end = system_clock::now(); #ifdef Q_OS_WIN From f4b694ff6bc9a873b0497278e6a16aeae0d9d0af Mon Sep 17 00:00:00 2001 From: DuckVador Date: Mon, 11 May 2020 09:40:21 +0800 Subject: [PATCH 31/42] format code --- src/components/latency/QvTCPing.cpp | 90 +++++++++++++++-------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/src/components/latency/QvTCPing.cpp b/src/components/latency/QvTCPing.cpp index b511c10b..69c732f0 100644 --- a/src/components/latency/QvTCPing.cpp +++ b/src/components/latency/QvTCPing.cpp @@ -2,26 +2,25 @@ #include #include #else - #include - #include - #include - #include #include + #include + #include + #include + #include #include #endif #include "QtConcurrent/QtConcurrent" #include "QvTCPing.hpp" #include "core/handler/ConfigHandler.hpp" - #ifdef _WIN32 - using qv_socket_t=SOCKET; +using qv_socket_t = SOCKET; #else - using qv_socket_t=int; +using qv_socket_t = int; #endif namespace { - inline int setnonblocking(qv_socket_t sockno,int &opt) + inline int setnonblocking(qv_socket_t sockno, int &opt) { #ifdef _WIN32 ULONG block = 1; @@ -30,19 +29,21 @@ namespace return -1; } #else - if ((opt = fcntl (sockno, F_GETFL, NULL)) < 0) { - //get socket flags + if ((opt = fcntl(sockno, F_GETFL, NULL)) < 0) + { + // get socket flags return -1; } - if (fcntl (sockno, F_SETFL, opt | O_NONBLOCK) < 0) { - //set socket non-blocking + if (fcntl(sockno, F_SETFL, opt | O_NONBLOCK) < 0) + { + // set socket non-blocking return -1; } #endif return 0; } - inline int setblocking(qv_socket_t sockno,int &opt) + inline int setblocking(qv_socket_t sockno, int &opt) { #ifdef _WIN32 ULONG block = 0; @@ -51,65 +52,70 @@ namespace return -1; } #else - if (fcntl (sockno, F_SETFL, opt) < 0) { - //reset socket flags + if (fcntl(sockno, F_SETFL, opt) < 0) + { + // reset socket flags return -1; } #endif return 0; } - - int connect_wait ( - qv_socket_t sockno, - struct sockaddr * addr, - size_t addrlen, - int timeout_sec=5) + int connect_wait(qv_socket_t sockno, struct sockaddr *addr, size_t addrlen, int timeout_sec = 5) { int res; int opt; - timeval tv = {0}; + timeval tv = { 0 }; tv.tv_sec = timeout_sec; tv.tv_usec = 0; - if ((res = setnonblocking(sockno,opt))!=0) + if ((res = setnonblocking(sockno, opt)) != 0) return -1; - if ((res = ::connect (sockno, addr, addrlen)) < 0) { + if ((res = ::connect(sockno, addr, addrlen)) < 0) + { #ifdef _WIN32 - if (WSAGetLastError() != WSAEWOULDBLOCK) { + if (WSAGetLastError() != WSAEWOULDBLOCK) + { #else - if (errno == EINPROGRESS) { + if (errno == EINPROGRESS) + { #endif - //connecting + // connecting fd_set wait_set; - FD_ZERO (&wait_set); - FD_SET (sockno, &wait_set); - res = select (sockno + 1, NULL, &wait_set, NULL, &tv); + FD_ZERO(&wait_set); + FD_SET(sockno, &wait_set); + res = select(sockno + 1, NULL, &wait_set, NULL, &tv); } } - else { - //connect immediately + else + { + // connect immediately res = 1; } - if (setblocking(sockno,opt)!=0){ + if (setblocking(sockno, opt) != 0) + { return -1; } - if (res < 0) { - //an error occured + if (res < 0) + { + // an error occured return -1; } - else if (res == 0) { - //timeout + else if (res == 0) + { + // timeout return 1; } - else { - socklen_t len = sizeof (opt); - if (getsockopt (sockno, SOL_SOCKET, SO_ERROR, reinterpret_cast(&opt), &len) < 0) { + else + { + socklen_t len = sizeof(opt); + if (getsockopt(sockno, SOL_SOCKET, SO_ERROR, reinterpret_cast(&opt), &len) < 0) + { return -1; } } return 0; } -} +} // namespace namespace Qv2ray::components::tcping { @@ -295,7 +301,7 @@ namespace Qv2ray::components::tcping /* connect to peer */ // Qt has its own connect() function in QObject.... // So we add "::" here - if (connect_wait(fd, addr->ai_addr, addr->ai_addrlen)==0) + if (connect_wait(fd, addr->ai_addr, addr->ai_addrlen) == 0) { *end = system_clock::now(); #ifdef Q_OS_WIN From 7b7374a09b5f4a0f1a38fb85cdf55839bcc34793 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Mon, 11 May 2020 13:20:36 +0800 Subject: [PATCH 32/42] naive port detector implementation --- CMakeLists.txt | 2 ++ src/components/port/QvPortDetector.cpp | 13 +++++++++++++ src/components/port/QvPortDetector.hpp | 7 +++++++ 3 files changed, 22 insertions(+) create mode 100644 src/components/port/QvPortDetector.cpp create mode 100644 src/components/port/QvPortDetector.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a3789ce7..d20dc152 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,6 +174,7 @@ set(QV2RAY_SOURCES src/components/plugins/toolbar/QvToolbar_linux.cpp src/components/plugins/toolbar/QvToolbar_win.cpp src/components/plugins/QvPluginHost.cpp + src/components/port/QvPortDetector.cpp src/components/proxy/QvProxyConfigurator.cpp src/components/route/RouteSchemeIO.cpp src/components/speedchart/speedplotview.cpp @@ -269,6 +270,7 @@ set(QV2RAY_SOURCES src/components/speedchart/speedplotview.hpp src/components/speedchart/speedwidget.hpp src/components/update/UpdateChecker.hpp + src/components/port/QvPortDetector.hpp src/core/connection/ConnectionIO.hpp src/core/connection/Generation.hpp src/core/connection/Serialization.hpp diff --git a/src/components/port/QvPortDetector.cpp b/src/components/port/QvPortDetector.cpp new file mode 100644 index 00000000..eca0de22 --- /dev/null +++ b/src/components/port/QvPortDetector.cpp @@ -0,0 +1,13 @@ +#include "QvPortDetector.hpp" + +#include + +namespace Qv2ray::components::port +{ + bool detectPortTCP(quint16 port) + { + QTcpServer server; + return server.listen(QHostAddress::LocalHost, port); + } + +} // namespace Qv2ray::components::port diff --git a/src/components/port/QvPortDetector.hpp b/src/components/port/QvPortDetector.hpp new file mode 100644 index 00000000..dd50c6ff --- /dev/null +++ b/src/components/port/QvPortDetector.hpp @@ -0,0 +1,7 @@ +#pragma once +#include + +namespace Qv2ray::components::port +{ + bool detectPortTCP(quint16 port); +} From 7d2bbd9e7b68e398044fe24294e45e903181e56c Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 20:12:49 +0800 Subject: [PATCH 33/42] add warning when users switch off api subsystem --- src/ui/w_PreferencesWindow.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ui/w_PreferencesWindow.cpp b/src/ui/w_PreferencesWindow.cpp index a83ae8a9..6af797ce 100644 --- a/src/ui/w_PreferencesWindow.cpp +++ b/src/ui/w_PreferencesWindow.cpp @@ -1157,7 +1157,15 @@ void PreferencesWindow::on_enableAPI_stateChanged(int arg1) { LOADINGCHECK NEEDRESTART + CurrentConfig.apiConfig.enableAPI = arg1 == Qt::Checked; + if (arg1 == Qt::Unchecked) + { + const auto msgAPIDisableTitle = tr("Disabling API Subsystem"); + const auto msgAPIDisableMsg = tr("Disabling API subsystem will also disable the statistics function of Qv2ray.") + NEWLINE + // + tr("Speed chart and traffic statistics will be disabled."); + QvMessageBoxWarn(this, msgAPIDisableTitle, msgAPIDisableMsg); + } } void PreferencesWindow::on_updateChannelCombo_currentIndexChanged(int index) From 78aa2f645d083d98956970a2f692f303a8174b11 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 20:20:54 +0800 Subject: [PATCH 34/42] updating translations --- translations/en_US.ts | 12 ++++++++++++ translations/ja_JP.ts | 12 ++++++++++++ translations/ru_RU.ts | 12 ++++++++++++ translations/zh_CN.ts | 12 ++++++++++++ 4 files changed, 48 insertions(+) diff --git a/translations/en_US.ts b/translations/en_US.ts index ebfea120..41df5f9f 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -1734,6 +1734,18 @@ But could damage your server if improperly used. For example, for updating subscriptions. + + Disabling API Subsystem + + + + Disabling API subsystem will also disable the statistics function of Qv2ray. + + + + Speed chart and traffic statistics will be disabled. + + QObject diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 729473ae..288224b2 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -2450,6 +2450,18 @@ For example, for updating subscriptions. これらの設定はQv2ray自体のためのものです。 例えば、サブスクリプションの更新などです。 + + Disabling API Subsystem + APIサブシステムを無効 + + + Disabling API subsystem will also disable the statistics function of Qv2ray. + APIサブシステムを無効にすると、Qv2rayの統計機能も無効になります。 + + + Speed chart and traffic statistics will be disabled. + スピードチャートや交通統計は無効になります。 + QObject diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index b82073f9..425a6614 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -2349,6 +2349,18 @@ But could damage your server if improperly used. For example, for updating subscriptions. + + Disabling API Subsystem + + + + Disabling API subsystem will also disable the statistics function of Qv2ray. + + + + Speed chart and traffic statistics will be disabled. + + QObject diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index c2b03b9c..c1a9d3cc 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -2080,6 +2080,18 @@ For example, for updating subscriptions. 这些设定是针对 Qv2ray 本身的。 例如,用在更新订阅时。 + + Disabling API Subsystem + 禁用 API 子系统 + + + Disabling API subsystem will also disable the statistics function of Qv2ray. + 如果禁用 API 子系统,Qv2ray 的统计功能也会被一同禁用。 + + + Speed chart and traffic statistics will be disabled. + 速度图表和流量统计功能将不再可用。 + QObject From f7a92257542a010eee6e30323063555282f63bc0 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 20:53:15 +0800 Subject: [PATCH 35/42] add trusted abi --- src/core/kernel/QvKernelABIChecker.cpp | 10 ++++++++++ src/core/kernel/QvKernelABIChecker.hpp | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/kernel/QvKernelABIChecker.cpp b/src/core/kernel/QvKernelABIChecker.cpp index d2c57b5f..a6749f80 100644 --- a/src/core/kernel/QvKernelABIChecker.cpp +++ b/src/core/kernel/QvKernelABIChecker.cpp @@ -6,6 +6,7 @@ namespace Qv2ray::core::kernel::abi { QvKernelABICompatibility checkCompatibility(QvKernelABIType hostType, QvKernelABIType targetType) { +#ifndef QV2RAY_TRUSTED_ABI switch (hostType) { case ABI_WIN32: @@ -15,12 +16,19 @@ namespace Qv2ray::core::kernel::abi case ABI_ELF_X86: return targetType == hostType ? ABI_PERFECT : ABI_NOPE; case ABI_ELF_X86_64: return targetType == hostType ? ABI_PERFECT : targetType == ABI_ELF_X86 ? ABI_MAYBE : ABI_NOPE; case ABI_ELF_OTHER: return targetType == hostType ? ABI_PERFECT : ABI_MAYBE; + case ABI_TRUSTED: return ABI_PERFECT; default: return ABI_MAYBE; } +#else + return ABI_PERFECT; +#endif } std::pair, std::optional> deduceKernelABI(const QString &pathCoreExecutable) { +#ifdef QV2RAY_TRUSTED_ABI + return QvKernelABIType::ABI_TRUSTED; +#else QFile file(pathCoreExecutable); if (!file.exists()) return { std::nullopt, QObject::tr("core executable file %1 does not exist").arg(pathCoreExecutable) }; @@ -55,6 +63,7 @@ namespace Qv2ray::core::kernel::abi return { QvKernelABIType::ABI_MACH_O, std::nullopt }; else return { std::nullopt, QObject::tr("cannot deduce the type of core executable file %1").arg(pathCoreExecutable) }; +#endif } QString abiToString(QvKernelABIType abi) @@ -68,6 +77,7 @@ namespace Qv2ray::core::kernel::abi case ABI_ELF_AARCH64: return QObject::tr("ELF arm64 executable"); case ABI_ELF_ARM: return QObject::tr("ELF arm executable"); case ABI_ELF_OTHER: return QObject::tr("other ELF executable"); + case ABI_TRUSTED: return QObject::tr("trusted abi"); default: return QObject::tr("unknown abi"); } } diff --git a/src/core/kernel/QvKernelABIChecker.hpp b/src/core/kernel/QvKernelABIChecker.hpp index d0346388..5e166f13 100644 --- a/src/core/kernel/QvKernelABIChecker.hpp +++ b/src/core/kernel/QvKernelABIChecker.hpp @@ -19,6 +19,7 @@ namespace Qv2ray::core::kernel ABI_ELF_AARCH64, ABI_ELF_ARM, ABI_ELF_OTHER, + ABI_TRUSTED, }; enum QvKernelABICompatibility @@ -42,7 +43,8 @@ namespace Qv2ray::core::kernel #elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_V7) QvKernelABIType::ABI_ELF_ARM; #else - #error "unknown architecture" + QvKernelABIType::ABI_TRUSTED; + #define QV2RAY_TRUSTED_ABI #endif std::pair, std::optional> deduceKernelABI(const QString &pathCoreExecutable); From 128c4bc9cb4a30b659b62e10da83caea4e15ae65 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 22:57:36 +0800 Subject: [PATCH 36/42] update translations --- translations/en_US.ts | 4 ++++ translations/ja_JP.ts | 4 ++++ translations/ru_RU.ts | 4 ++++ translations/zh_CN.ts | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/translations/en_US.ts b/translations/en_US.ts index 41df5f9f..8a1e1f74 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -2137,6 +2137,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. + + trusted abi + + Qv2ray::common::QvCommandArgParser diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 288224b2..35de90c9 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -2953,6 +2953,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. Qv2rayでは元に戻すことはできません。何かあっても私たちのせいにしないでください。 + + trusted abi + 信頼できるABI + Qv2ray::common::QvCommandArgParser diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index 425a6614..ce25df9f 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -2824,6 +2824,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. + + trusted abi + + Qv2ray::common::QvCommandArgParser diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index c1a9d3cc..dabc3a9f 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -2531,6 +2531,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. Qv2ray 很遗憾无法帮你改回来。若因此遇到问题,请勿指责吾等。 + + trusted abi + 受信 ABI + Qv2ray::common::QvCommandArgParser From fbf8d071c72ae61a9d56d2c70e9e5b025e05d0ef Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 20:53:15 +0800 Subject: [PATCH 37/42] add trusted abi --- src/core/kernel/QvKernelABIChecker.cpp | 10 ++++++++++ src/core/kernel/QvKernelABIChecker.hpp | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/kernel/QvKernelABIChecker.cpp b/src/core/kernel/QvKernelABIChecker.cpp index d2c57b5f..a6749f80 100644 --- a/src/core/kernel/QvKernelABIChecker.cpp +++ b/src/core/kernel/QvKernelABIChecker.cpp @@ -6,6 +6,7 @@ namespace Qv2ray::core::kernel::abi { QvKernelABICompatibility checkCompatibility(QvKernelABIType hostType, QvKernelABIType targetType) { +#ifndef QV2RAY_TRUSTED_ABI switch (hostType) { case ABI_WIN32: @@ -15,12 +16,19 @@ namespace Qv2ray::core::kernel::abi case ABI_ELF_X86: return targetType == hostType ? ABI_PERFECT : ABI_NOPE; case ABI_ELF_X86_64: return targetType == hostType ? ABI_PERFECT : targetType == ABI_ELF_X86 ? ABI_MAYBE : ABI_NOPE; case ABI_ELF_OTHER: return targetType == hostType ? ABI_PERFECT : ABI_MAYBE; + case ABI_TRUSTED: return ABI_PERFECT; default: return ABI_MAYBE; } +#else + return ABI_PERFECT; +#endif } std::pair, std::optional> deduceKernelABI(const QString &pathCoreExecutable) { +#ifdef QV2RAY_TRUSTED_ABI + return QvKernelABIType::ABI_TRUSTED; +#else QFile file(pathCoreExecutable); if (!file.exists()) return { std::nullopt, QObject::tr("core executable file %1 does not exist").arg(pathCoreExecutable) }; @@ -55,6 +63,7 @@ namespace Qv2ray::core::kernel::abi return { QvKernelABIType::ABI_MACH_O, std::nullopt }; else return { std::nullopt, QObject::tr("cannot deduce the type of core executable file %1").arg(pathCoreExecutable) }; +#endif } QString abiToString(QvKernelABIType abi) @@ -68,6 +77,7 @@ namespace Qv2ray::core::kernel::abi case ABI_ELF_AARCH64: return QObject::tr("ELF arm64 executable"); case ABI_ELF_ARM: return QObject::tr("ELF arm executable"); case ABI_ELF_OTHER: return QObject::tr("other ELF executable"); + case ABI_TRUSTED: return QObject::tr("trusted abi"); default: return QObject::tr("unknown abi"); } } diff --git a/src/core/kernel/QvKernelABIChecker.hpp b/src/core/kernel/QvKernelABIChecker.hpp index d0346388..5e166f13 100644 --- a/src/core/kernel/QvKernelABIChecker.hpp +++ b/src/core/kernel/QvKernelABIChecker.hpp @@ -19,6 +19,7 @@ namespace Qv2ray::core::kernel ABI_ELF_AARCH64, ABI_ELF_ARM, ABI_ELF_OTHER, + ABI_TRUSTED, }; enum QvKernelABICompatibility @@ -42,7 +43,8 @@ namespace Qv2ray::core::kernel #elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_V7) QvKernelABIType::ABI_ELF_ARM; #else - #error "unknown architecture" + QvKernelABIType::ABI_TRUSTED; + #define QV2RAY_TRUSTED_ABI #endif std::pair, std::optional> deduceKernelABI(const QString &pathCoreExecutable); From 7dabdd66e5d197d4ab4591965bb0bc588688d5c2 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 22:57:36 +0800 Subject: [PATCH 38/42] update translations --- translations/en_US.ts | 4 ++++ translations/ja_JP.ts | 4 ++++ translations/ru_RU.ts | 4 ++++ translations/zh_CN.ts | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/translations/en_US.ts b/translations/en_US.ts index 41df5f9f..8a1e1f74 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -2137,6 +2137,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. + + trusted abi + + Qv2ray::common::QvCommandArgParser diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts index 288224b2..35de90c9 100644 --- a/translations/ja_JP.ts +++ b/translations/ja_JP.ts @@ -2953,6 +2953,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. Qv2rayでは元に戻すことはできません。何かあっても私たちのせいにしないでください。 + + trusted abi + 信頼できるABI + Qv2ray::common::QvCommandArgParser diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index 425a6614..ce25df9f 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -2824,6 +2824,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. + + trusted abi + + Qv2ray::common::QvCommandArgParser diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index c1a9d3cc..dabc3a9f 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -2531,6 +2531,10 @@ For example, for updating subscriptions. Qv2ray cannot help you change them back. Please don't blame us if things go wrong. Qv2ray 很遗憾无法帮你改回来。若因此遇到问题,请勿指责吾等。 + + trusted abi + 受信 ABI + Qv2ray::common::QvCommandArgParser From 5cc9f7293e4eff0cc085f58bad97d4cf9194bb3f Mon Sep 17 00:00:00 2001 From: Qv2ray-dev <59914293+Qv2ray-dev@users.noreply.github.com> Date: Tue, 12 May 2020 23:30:43 +0800 Subject: [PATCH 39/42] fix: prevent API fastfail when vCore starts slowly --- src/core/kernel/APIBackend.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/kernel/APIBackend.hpp b/src/core/kernel/APIBackend.hpp index b8929633..9e1a605c 100644 --- a/src/core/kernel/APIBackend.hpp +++ b/src/core/kernel/APIBackend.hpp @@ -9,7 +9,7 @@ #endif // Check 10 times before telling user that API has failed. -constexpr auto QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD = 10; +constexpr auto QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD = 30; namespace Qv2ray::core::kernel { From 04114e06414d8733f50bec758048d76912d3b896 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Tue, 12 May 2020 23:32:41 +0800 Subject: [PATCH 40/42] Added NTP Client from retgone/qntp (#606) * getting fucked by qt signal system * removing test code * adding license --- CMakeLists.txt | 4 +- src/components/ntp/QvNTPClient.cpp | 216 +++++++++++++++++++++++++++++ src/components/ntp/QvNTPClient.hpp | 165 ++++++++++++++++++++++ src/main.cpp | 2 + 4 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 src/components/ntp/QvNTPClient.cpp create mode 100644 src/components/ntp/QvNTPClient.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d20dc152..99608306 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,7 @@ set(QV2RAY_SOURCES src/components/speedchart/speedplotview.cpp src/components/speedchart/speedwidget.cpp src/components/darkmode/DarkmodeDetector.cpp + src/components/ntp/QvNTPClient.cpp src/components/update/UpdateChecker.cpp src/core/connection/ConnectionIO.cpp src/core/connection/Generation.cpp @@ -264,13 +265,14 @@ set(QV2RAY_SOURCES src/components/latency/QvTCPing.hpp src/components/plugins/toolbar/QvToolbar.hpp src/components/plugins/QvPluginHost.hpp + src/components/port/QvPortDetector.hpp src/components/proxy/QvProxyConfigurator.hpp + src/components/ntp/QvNTPClient.hpp src/components/route/RouteSchemeIO.hpp src/components/route/presets/RouteScheme_V2rayN.hpp src/components/speedchart/speedplotview.hpp src/components/speedchart/speedwidget.hpp src/components/update/UpdateChecker.hpp - src/components/port/QvPortDetector.hpp src/core/connection/ConnectionIO.hpp src/core/connection/Generation.hpp src/core/connection/Serialization.hpp diff --git a/src/components/ntp/QvNTPClient.cpp b/src/components/ntp/QvNTPClient.cpp new file mode 100644 index 00000000..9611d4ce --- /dev/null +++ b/src/components/ntp/QvNTPClient.cpp @@ -0,0 +1,216 @@ +/* This file from part of QNtp, a library that implements NTP protocol. + * + * Copyright (C) 2011 Alexander Fokin + * + * QNtp is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * QNtp is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with QNtp. If not, see . */ + +#include "QvNTPClient.hpp" + +#include + +namespace Qv2ray::components::ntp +{ + + NtpTimestamp NtpTimestamp::fromDateTime(const QDateTime &dateTime) + { + qint64 ntpMSecs = dateTime.toMSecsSinceEpoch() - january_1_1900; + + quint32 seconds = ntpMSecs / 1000; + quint32 fraction = 0x100000000ll * (ntpMSecs % 1000) / 1000; + + NtpTimestamp result; + result.seconds = qToBigEndian(seconds); + result.fraction = qToBigEndian(fraction); + return result; + } + + QDateTime NtpTimestamp::toDateTime(const NtpTimestamp &ntpTime) + { + /* Convert to local-endian. */ + quint32 seconds = qFromBigEndian(ntpTime.seconds); + quint32 fraction = qFromBigEndian(ntpTime.fraction); + + /* Convert NTP timestamp to number of milliseconds passed since Jan 1 1900. */ + qint64 ntpMSecs = seconds * 1000ll + fraction * 1000ll / 0x100000000ll; + + /* Construct Qt date time. */ + return QDateTime::fromMSecsSinceEpoch(ntpMSecs + january_1_1900); + } + + NtpReply::NtpReply() : d(new NtpReplyPrivate()) + { + /* We don't use shared null because NtpReplyPrivate isn't a POD type and + * allocation overhead is negligible here. */ + memset(&d->packet, 0, sizeof(d->packet)); + } + + NtpReply::NtpReply(NtpReplyPrivate *dd) : d(dd) + { + Q_ASSERT(dd != NULL); + } + + NtpReply::NtpReply(const NtpReply &other) : d(other.d) + { + } + + NtpReply::~NtpReply() + { + } + + NtpReply &NtpReply::operator=(const NtpReply &other) + { + d = other.d; + + return *this; + } + + NtpLeapIndicator NtpReply::leapIndicator() const + { + return static_cast(d->packet.basic.flags.leapIndicator); + } + + quint8 NtpReply::versionNumber() const + { + return d->packet.basic.flags.versionNumber; + } + + NtpMode NtpReply::mode() const + { + return static_cast(d->packet.basic.flags.mode); + } + + quint8 NtpReply::stratum() const + { + return d->packet.basic.stratum; + } + + qreal NtpReply::pollInterval() const + { + return std::pow(static_cast(2), static_cast(d->packet.basic.poll)); + } + + qreal NtpReply::precision() const + { + return std::pow(static_cast(2), static_cast(d->packet.basic.precision)); + } + + QDateTime NtpReply::referenceTime() const + { + return NtpTimestamp::toDateTime(d->packet.basic.referenceTimestamp); + } + + QDateTime NtpReply::originTime() const + { + return NtpTimestamp::toDateTime(d->packet.basic.originateTimestamp); + } + + QDateTime NtpReply::receiveTime() const + { + return NtpTimestamp::toDateTime(d->packet.basic.receiveTimestamp); + } + + QDateTime NtpReply::transmitTime() const + { + return NtpTimestamp::toDateTime(d->packet.basic.transmitTimestamp); + } + + QDateTime NtpReply::destinationTime() const + { + return d->destinationTime; + } + + qint64 NtpReply::roundTripDelay() const + { + return originTime().msecsTo(destinationTime()) - receiveTime().msecsTo(transmitTime()); + } + + qint64 NtpReply::localClockOffset() const + { + return (originTime().msecsTo(receiveTime()) + destinationTime().msecsTo(transmitTime())) / 2; + } + + bool NtpReply::isNull() const + { + return d->destinationTime.isNull(); + } + + NtpClient::NtpClient(QObject *parent) : QObject(parent) + { + init(QHostAddress::Any, 0); + } + + NtpClient::NtpClient(const QHostAddress &bindAddress, quint16 bindPort, QObject *parent) : QObject(parent) + { + init(bindAddress, bindPort); + } + + void NtpClient::init(const QHostAddress &bindAddress, quint16 bindPort) + { + mSocket = new QUdpSocket(this); + mSocket->bind(bindAddress, bindPort); + + connect(mSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); + } + + NtpClient::~NtpClient() + { + return; + } + + bool NtpClient::sendRequest(const QHostAddress &address, quint16 port) + { + if (mSocket->state() != QAbstractSocket::BoundState) + return false; + + /* Initialize the NTP packet. */ + NtpPacket packet; + memset(&packet, 0, sizeof(packet)); + packet.flags.mode = ClientMode; + packet.flags.versionNumber = 4; + packet.transmitTimestamp = NtpTimestamp::fromDateTime(QDateTime::currentDateTimeUtc()); + + /* Send it. */ + if (mSocket->writeDatagram(reinterpret_cast(&packet), sizeof(packet), address, port) < 0) + return false; + + return true; + } + + void NtpClient::readPendingDatagrams() + { + while (mSocket->hasPendingDatagrams()) + { + NtpFullPacket packet; + memset(&packet, 0, sizeof(packet)); + + QHostAddress address; + quint16 port; + + if (mSocket->readDatagram(reinterpret_cast(&packet), sizeof(packet), &address, &port) < (qint64) sizeof(NtpPacket)) + continue; + + QDateTime now = QDateTime::currentDateTime(); + + /* Prepare reply. */ + NtpReplyPrivate *replyPrivate = new NtpReplyPrivate(); + replyPrivate->packet = packet; + replyPrivate->destinationTime = now; + NtpReply reply(replyPrivate); + + /* Notify. */ + Q_EMIT replyReceived(address, port, reply); + } + } + +} // namespace Qv2ray::components::ntp diff --git a/src/components/ntp/QvNTPClient.hpp b/src/components/ntp/QvNTPClient.hpp new file mode 100644 index 00000000..ff8ac5f1 --- /dev/null +++ b/src/components/ntp/QvNTPClient.hpp @@ -0,0 +1,165 @@ +/* This file from part of QNtp, a library that implements NTP protocol. + * + * Copyright (C) 2011 Alexander Fokin + * + * QNtp is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * QNtp is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with QNtp. If not, see . */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Qv2ray::components::ntp +{ + const qint64 january_1_1900 = -2208988800000ll; + + enum NtpLeapIndicator + { + NoWarning = 0, /**< No warning. */ + LastMinute61Warning = 1, /**< Last minute has 61 seconds. */ + LastMinute59Warning = 2, /**< Last minute has 59 seconds. */ + UnsynchronizedWarning = 3, /**< Alarm condition (clock not synchronized). */ + }; + + enum NtpMode + { + ReservedMode = 0, /**< Reserved. */ + SymmetricActiveMode = 1, /**< Symmetric active. */ + SymmetricPassiveMode = 2, /**< Symmetric passive. */ + ClientMode = 3, /**< Client. */ + ServerMode = 4, /**< Server. */ + BroadcastMode = 5, /**< Broadcast. */ + ControlMode = 6, /**< NTP control message. */ + PrivateMode = 7, /**< Reserved for private use. */ + }; + + enum NtpStratum + { + UnspecifiedStratum = 0, /**< Unspecified or unavailable. */ + PrimaryStratum = 1, /**< Primary reference (e.g. radio-clock). */ + SecondaryStratumFirst = 2, /**< Secondary reference (via NTP or SNTP). */ + SecondaryStratumLast = 15, + UnsynchronizedStratum = 16, /**< Unsynchronized. */ + /* 17-255 are reserved. */ + }; + + struct NtpPacketFlags + { + unsigned char mode : 3; + unsigned char versionNumber : 3; + unsigned char leapIndicator : 2; + }; + +#pragma pack(push, 1) + + struct NtpTimestamp + { + quint32 seconds; + quint32 fraction; + static inline NtpTimestamp fromDateTime(const QDateTime &dateTime); + static inline QDateTime toDateTime(const NtpTimestamp &ntpTime); + }; + + struct NtpPacket + { + NtpPacketFlags flags; + quint8 stratum; + qint8 poll; + qint8 precision; + qint32 rootDelay; + qint32 rootDispersion; + qint8 referenceID[4]; + NtpTimestamp referenceTimestamp; + NtpTimestamp originateTimestamp; + NtpTimestamp receiveTimestamp; + NtpTimestamp transmitTimestamp; + }; + + struct NtpAuthenticationInfo + { + quint32 keyId; + quint8 messageDigest[16]; + }; + + struct NtpFullPacket + { + NtpPacket basic; + NtpAuthenticationInfo auth; + }; + +#pragma pack(pop) + + class NtpReplyPrivate : public QSharedData + { + public: + NtpFullPacket packet; + QDateTime destinationTime; + }; + + class NtpReply + { + public: + NtpReply(); + NtpReply(const NtpReply &other); + ~NtpReply(); + NtpReply &operator=(const NtpReply &other); + NtpLeapIndicator leapIndicator() const; + quint8 versionNumber() const; + NtpMode mode() const; + quint8 stratum() const; + qreal pollInterval() const; + qreal precision() const; + QDateTime referenceTime() const; + QDateTime originTime() const; + QDateTime receiveTime() const; + QDateTime transmitTime() const; + QDateTime destinationTime() const; + qint64 roundTripDelay() const; + qint64 localClockOffset() const; + bool isNull() const; + + protected: + friend class NtpClient; + NtpReply(NtpReplyPrivate *dd); + + private: + QSharedDataPointer d; + }; + + class NtpClient : public QObject + { + Q_OBJECT; + + public: + NtpClient(QObject *parent = NULL); + NtpClient(const QHostAddress &bindAddress, quint16 bindPort, QObject *parent = NULL); + virtual ~NtpClient(); + bool sendRequest(const QHostAddress &address, quint16 port); + + Q_SIGNALS: + void replyReceived(const QHostAddress &address, quint16 port, const NtpReply &reply); + + private Q_SLOTS: + void readPendingDatagrams(); + + private: + void init(const QHostAddress &bindAddress, quint16 bindPort); + + QUdpSocket *mSocket; + }; +} // namespace Qv2ray::components::ntp diff --git a/src/main.cpp b/src/main.cpp index d76b82cc..1012e58c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -196,6 +196,7 @@ int main(int argc, char *argv[]) case CommandLineHelpRequested: std::cout << parser.Parser()->helpText().toStdString() << std::endl; return 0; } } + #ifdef Q_OS_UNIX // Unix OS root user check. @@ -419,6 +420,7 @@ int main(int argc, char *argv[]) // Initialise Connection Handler PluginHost = new QvPluginHost(); ConnectionManager = new QvConfigHandler(); + // Show MainWindow MainWindow w; QObject::connect(&_qApp, &SingleApplication::instanceStarted, [&]() { From 8bfcbd3cb26aa7632862fc6679871a8431ada61f Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Wed, 13 May 2020 14:12:33 +0800 Subject: [PATCH 41/42] fix equality of routing schemes --- src/base/models/QvSettingsObject.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/base/models/QvSettingsObject.hpp b/src/base/models/QvSettingsObject.hpp index 3ba65190..9b50711f 100644 --- a/src/base/models/QvSettingsObject.hpp +++ b/src/base/models/QvSettingsObject.hpp @@ -135,9 +135,11 @@ namespace Qv2ray::base::config QList block; QList proxy; Qv2rayRouteConfig_Impl(){}; - friend bool operator==(const Qv2rayRouteConfig_Impl &left, const Qv2rayRouteConfig_Impl &right) + friend bool operator==(const Qv2rayRouteConfig_Impl &lhs, const Qv2rayRouteConfig_Impl &rhs) { - return left.direct == right.direct && left.block == right.block && left.proxy == left.proxy; + return lhs.block == rhs.block && // + lhs.proxy == rhs.proxy && // + lhs.direct == rhs.direct; } Qv2rayRouteConfig_Impl(const QList &_direct, const QList &_block, const QList &_proxy) : direct(_direct), block(_block), proxy(_proxy){}; From 7c1d9b05eb2c8173136a444ee4d60eac9dfb29f5 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Thu, 14 May 2020 14:15:20 +0800 Subject: [PATCH 42/42] fixing a return typo --- src/core/kernel/QvKernelABIChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/kernel/QvKernelABIChecker.cpp b/src/core/kernel/QvKernelABIChecker.cpp index a6749f80..7f05bdb4 100644 --- a/src/core/kernel/QvKernelABIChecker.cpp +++ b/src/core/kernel/QvKernelABIChecker.cpp @@ -27,7 +27,7 @@ namespace Qv2ray::core::kernel::abi std::pair, std::optional> deduceKernelABI(const QString &pathCoreExecutable) { #ifdef QV2RAY_TRUSTED_ABI - return QvKernelABIType::ABI_TRUSTED; + return { QvKernelABIType::ABI_TRUSTED, std::nullopt }; #else QFile file(pathCoreExecutable); if (!file.exists())