├── .clang-format ├── .github ├── dependabot.yml └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── 3rdparty └── uistyles │ ├── LICENSE.mulan │ ├── flatwhite │ ├── flatwhite.css │ ├── flatwhite.qrc │ └── flatwhite │ │ ├── add_bottom.png │ │ ├── add_left.png │ │ ├── add_right.png │ │ ├── add_top.png │ │ ├── branch_close.png │ │ ├── branch_open.png │ │ ├── calendar_nextmonth.png │ │ ├── calendar_prevmonth.png │ │ ├── checkbox_checked.png │ │ ├── checkbox_checked_disable.png │ │ ├── checkbox_parcial.png │ │ ├── checkbox_parcial_disable.png │ │ ├── checkbox_unchecked.png │ │ ├── checkbox_unchecked_disable.png │ │ ├── radiobutton_checked.png │ │ ├── radiobutton_checked_disable.png │ │ ├── radiobutton_unchecked.png │ │ └── radiobutton_unchecked_disable.png │ ├── psblack │ ├── psblack.css │ ├── psblack.qrc │ └── psblack │ │ ├── add_bottom.png │ │ ├── add_left.png │ │ ├── add_right.png │ │ ├── add_top.png │ │ ├── branch_close.png │ │ ├── branch_open.png │ │ ├── calendar_nextmonth.png │ │ ├── calendar_prevmonth.png │ │ ├── checkbox_checked.png │ │ ├── checkbox_checked_disable.png │ │ ├── checkbox_parcial.png │ │ ├── checkbox_parcial_disable.png │ │ ├── checkbox_unchecked.png │ │ ├── checkbox_unchecked_disable.png │ │ ├── radiobutton_checked.png │ │ ├── radiobutton_checked_disable.png │ │ ├── radiobutton_unchecked.png │ │ └── radiobutton_unchecked_disable.png │ └── uistyles.cmake ├── CMakeLists.txt ├── LICENSE ├── README.md ├── assets ├── MacOSXBundleInfo.plist.in ├── ProtocolSchemes.txt ├── QvRoute.schema.json ├── icons │ ├── Applogo_bird_b.png │ ├── Applogo_bird_colorful.png │ ├── Applogo_bird_g.png │ ├── IconSource.txt │ ├── convert.sh │ ├── designs │ │ ├── Applogo_Bird_b.svg │ │ ├── Applogo_Bird_colorful.svg │ │ ├── Applogo_Bird_g.svg │ │ ├── Applogo_Bird_r.svg │ │ ├── Applogo_Circle.svg │ │ ├── Applogo_Frameless.svg │ │ ├── Applogo_Square.svg │ │ ├── banner.svg │ │ └── banner.svg.png │ ├── iconconv.nim │ ├── qv2ray.1024.png │ ├── qv2ray.128.png │ ├── qv2ray.16.png │ ├── qv2ray.22.png │ ├── qv2ray.256.png │ ├── qv2ray.32.png │ ├── qv2ray.48.png │ ├── qv2ray.512.png │ ├── qv2ray.64.png │ ├── qv2ray.icns │ ├── qv2ray.ico │ ├── qv2ray.png │ ├── qv2ray.svg │ ├── resources.qrc │ ├── ui_dark │ │ ├── add.svg │ │ ├── adjust.svg │ │ ├── arrow-down-filling.svg │ │ ├── arrow-down.svg │ │ ├── arrow-right.svg │ │ ├── arrow-up-filling.svg │ │ ├── arrow-up.svg │ │ ├── ashbin.svg │ │ ├── close.svg │ │ ├── code.svg │ │ ├── copy.svg │ │ ├── data-view.svg │ │ ├── edit.svg │ │ ├── export.svg │ │ ├── file-open.svg │ │ ├── glyph-tray-connected.png │ │ ├── glyph-tray-connected.svg │ │ ├── glyph-tray-systemproxy.png │ │ ├── glyph-tray-systemproxy.svg │ │ ├── glyph-tray.png │ │ ├── glyph-tray.svg │ │ ├── link.svg │ │ ├── map.svg │ │ ├── minus.svg │ │ ├── netspeed_arrow.svg │ │ ├── ping_gauge.svg │ │ ├── save.svg │ │ ├── share.svg │ │ ├── start.svg │ │ ├── stop.svg │ │ ├── tray-connected.png │ │ ├── tray-systemproxy.png │ │ └── tray.png │ └── ui_light │ │ ├── add.svg │ │ ├── adjust.svg │ │ ├── arrow-down-filling.svg │ │ ├── arrow-down.svg │ │ ├── arrow-right.svg │ │ ├── arrow-up-filling.svg │ │ ├── arrow-up.svg │ │ ├── ashbin.svg │ │ ├── close.svg │ │ ├── code.svg │ │ ├── copy.svg │ │ ├── data-view.svg │ │ ├── edit.svg │ │ ├── export.svg │ │ ├── file-open.svg │ │ ├── glyph-tray-connected.png │ │ ├── glyph-tray-connected.svg │ │ ├── glyph-tray-systemproxy.png │ │ ├── glyph-tray-systemproxy.svg │ │ ├── glyph-tray.png │ │ ├── glyph-tray.svg │ │ ├── link.svg │ │ ├── map.svg │ │ ├── minus.svg │ │ ├── netspeed_arrow.svg │ │ ├── ping_gauge.svg │ │ ├── save.svg │ │ ├── share.svg │ │ ├── start.svg │ │ ├── stop.svg │ │ ├── tray-connected.png │ │ ├── tray-systemproxy.png │ │ └── tray.png └── qv2ray.desktop ├── cmake ├── deployment-linux.cmake ├── deployment-macos.cmake ├── deployment-windows.cmake ├── qrencode.cmake ├── qv2ray-sources.cmake └── versioninfo │ ├── VersionInfo.in │ ├── VersionResource.rc │ └── generate_product_version.cmake ├── docs ├── Compilation-Guidance.md ├── Platform-Specific-Compilation-Notices.md └── Query-Syntax-in-Search-Bar.md ├── src ├── Qv2rayApplication.cpp ├── Qv2rayApplication.hpp ├── components │ ├── AutoLaunchHelper │ │ ├── AutoLaunchHelper.cpp │ │ └── AutoLaunchHelper.hpp │ ├── ConnectionModelHelper │ │ ├── ConnectionModelHelper.cpp │ │ └── ConnectionModelHelper.hpp │ ├── FlowLayout │ │ ├── FlowLayout.cpp │ │ └── FlowLayout.hpp │ ├── GeositeReader │ │ ├── GeositeReader.cpp │ │ ├── GeositeReader.hpp │ │ ├── picoproto.cpp │ │ └── picoproto.hpp │ ├── GuiPluginHost │ │ ├── GuiPluginHost.cpp │ │ └── GuiPluginHost.hpp │ ├── LogHighlighter │ │ ├── LogHighlighter.cpp │ │ └── LogHighlighter.hpp │ ├── MessageBus │ │ ├── MessageBus.cpp │ │ └── MessageBus.hpp │ ├── QJsonModel │ │ ├── QJsonModel.cpp │ │ └── QJsonModel.hpp │ ├── QRCodeHelper │ │ ├── QRCodeHelper.cpp │ │ └── QRCodeHelper.hpp │ ├── QueryParser │ │ ├── QueryParser.cpp │ │ └── QueryParser.hpp │ ├── RouteSchemeIO │ │ ├── RouteSchemeIO.cpp │ │ └── RouteSchemeIO.hpp │ ├── SpeedWidget │ │ ├── SpeedWidget.cpp │ │ └── SpeedWidget.hpp │ ├── StyleManager │ │ ├── StyleManager.cpp │ │ └── StyleManager.hpp │ └── UpdateChecker │ │ ├── UpdateChecker.cpp │ │ ├── UpdateChecker.hpp │ │ └── semver.hpp ├── main.cpp ├── models │ └── SettingsModels.hpp ├── plugins │ ├── CMakeLists.txt │ ├── PluginsCommon │ │ └── V2RayModels.hpp │ ├── internal │ │ ├── InternalPlugin.cpp │ │ ├── InternalPlugin.hpp │ │ ├── InternalProfilePreprocessor.cpp │ │ └── InternalProfilePreprocessor.hpp │ ├── protocols │ │ ├── BuiltinProtocolPlugin.cpp │ │ ├── BuiltinProtocolPlugin.hpp │ │ ├── CMakeLists.txt │ │ ├── assets │ │ │ └── qv2ray.png │ │ ├── core │ │ │ ├── OutboundHandler.cpp │ │ │ └── OutboundHandler.hpp │ │ ├── resx.qrc │ │ └── ui │ │ │ ├── Interface.hpp │ │ │ ├── PluginSettingsWidget.cpp │ │ │ ├── PluginSettingsWidget.hpp │ │ │ ├── PluginSettingsWidget.ui │ │ │ ├── inbound │ │ │ ├── dokodemo-door.cpp │ │ │ ├── dokodemo-door.hpp │ │ │ ├── dokodemo-door.ui │ │ │ ├── httpin.cpp │ │ │ ├── httpin.hpp │ │ │ ├── httpin.ui │ │ │ ├── shadowsocks.cpp │ │ │ ├── shadowsocks.hpp │ │ │ ├── shadowsocks.ui │ │ │ ├── socksin.cpp │ │ │ ├── socksin.hpp │ │ │ ├── socksin.ui │ │ │ ├── vless.cpp │ │ │ ├── vless.hpp │ │ │ ├── vless.ui │ │ │ ├── vmess.cpp │ │ │ ├── vmess.hpp │ │ │ └── vmess.ui │ │ │ └── outbound │ │ │ ├── blackhole.cpp │ │ │ ├── blackhole.hpp │ │ │ ├── blackhole.ui │ │ │ ├── dns.cpp │ │ │ ├── dns.hpp │ │ │ ├── dns.ui │ │ │ ├── freedom.cpp │ │ │ ├── freedom.hpp │ │ │ ├── freedom.ui │ │ │ ├── httpout.cpp │ │ │ ├── httpout.hpp │ │ │ ├── httpout.ui │ │ │ ├── loopback.cpp │ │ │ ├── loopback.hpp │ │ │ ├── loopback.ui │ │ │ ├── mtproto.cpp │ │ │ ├── mtproto.hpp │ │ │ ├── mtproto.ui │ │ │ ├── shadowsocks.cpp │ │ │ ├── shadowsocks.hpp │ │ │ ├── shadowsocks.ui │ │ │ ├── socksout.cpp │ │ │ ├── socksout.hpp │ │ │ ├── socksout.ui │ │ │ ├── trojan.cpp │ │ │ ├── trojan.hpp │ │ │ ├── trojan.ui │ │ │ ├── vmess.cpp │ │ │ ├── vmess.hpp │ │ │ └── vmess.ui │ ├── routingA │ │ ├── CMakeLists.txt │ │ ├── RoutingAPlugin.cpp │ │ ├── RoutingAPlugin.hpp │ │ ├── RoutingA_GuiInterface.hpp │ │ ├── common │ │ │ ├── RoutingAConverter.cpp │ │ │ └── RoutingAConverter.hpp │ │ └── ui │ │ │ ├── RoutingAEditor.cpp │ │ │ ├── RoutingAEditor.hpp │ │ │ └── RoutingAEditor.ui │ ├── subscription-adapters │ │ ├── BuiltinSubscriptionAdapter.cpp │ │ ├── BuiltinSubscriptionAdapter.hpp │ │ ├── CMakeLists.txt │ │ ├── assets │ │ │ └── qv2ray.png │ │ ├── core │ │ │ ├── SubscriptionAdapter.cpp │ │ │ └── SubscriptionAdapter.hpp │ │ └── resx.qrc │ └── v2ray │ │ ├── CMakeLists.txt │ │ ├── V2RayCorePluginTemplate.cpp │ │ ├── V2RayCorePluginTemplate.hpp │ │ ├── assets │ │ ├── V2Ray-Stats.proto │ │ ├── V2Ray5-Stats.proto │ │ ├── V2RayRust-Stats.proto │ │ └── V2RaySN-Stats.proto │ │ ├── common │ │ ├── CommonHelpers.cpp │ │ ├── CommonHelpers.hpp │ │ └── SettingsModels.hpp │ │ ├── core │ │ ├── V2Ray │ │ │ ├── Kernel.cpp │ │ │ ├── Kernel.hpp │ │ │ ├── ProfileGenerator.cpp │ │ │ └── ProfileGenerator.hpp │ │ ├── V2Ray5 │ │ │ ├── Kernel.cpp │ │ │ ├── Kernel.hpp │ │ │ ├── ProfileGenerator.cpp │ │ │ └── ProfileGenerator.hpp │ │ ├── V2RayAPIStats.cpp │ │ ├── V2RayAPIStats.hpp │ │ ├── V2RayRust │ │ │ ├── Kernel.cpp │ │ │ ├── Kernel.hpp │ │ │ ├── ProfileGenerator.cpp │ │ │ ├── ProfileGenerator.hpp │ │ │ └── toml.hpp │ │ ├── V2RaySN │ │ │ ├── Kernel.cpp │ │ │ ├── Kernel.hpp │ │ │ ├── ProfileGenerator.cpp │ │ │ └── ProfileGenerator.hpp │ │ ├── api.pb.c │ │ ├── api.pb.h │ │ ├── pb.h │ │ ├── pb_common.c │ │ ├── pb_common.h │ │ ├── pb_decode.c │ │ ├── pb_decode.h │ │ ├── pb_encode.c │ │ └── pb_encode.h │ │ └── ui │ │ ├── w_V2RayKernelSettings.cpp │ │ ├── w_V2RayKernelSettings.hpp │ │ └── w_V2RayKernelSettings.ui └── ui │ ├── TrayManager.cpp │ ├── TrayManager.hpp │ ├── WidgetUIBase.hpp │ ├── widgets │ ├── AutoCompleteTextEdit.cpp │ ├── AutoCompleteTextEdit.hpp │ ├── ConfigurableEditorWidget.cpp │ ├── ConfigurableEditorWidget.hpp │ ├── ConnectionInfoWidget.cpp │ ├── ConnectionInfoWidget.hpp │ ├── ConnectionInfoWidget.ui │ ├── ConnectionItemWidget.cpp │ ├── ConnectionItemWidget.hpp │ ├── ConnectionItemWidget.ui │ ├── TagLineEditorWidget.cpp │ ├── TagLineEditorWidget.hpp │ └── editors │ │ ├── CertificateItemWidget.ui │ │ ├── DnsSettingsWidget.cpp │ │ ├── DnsSettingsWidget.hpp │ │ ├── DnsSettingsWidget.ui │ │ ├── RouteSettingsMatrix.cpp │ │ ├── RouteSettingsMatrix.hpp │ │ ├── RouteSettingsMatrix.ui │ │ ├── StreamSettingsWidget.cpp │ │ ├── StreamSettingsWidget.hpp │ │ └── StreamSettingsWidget.ui │ └── windows │ ├── editors │ ├── w_JsonEditor.cpp │ ├── w_JsonEditor.hpp │ ├── w_JsonEditor.ui │ ├── w_OutboundEditor.cpp │ ├── w_OutboundEditor.hpp │ └── w_OutboundEditor.ui │ ├── w_AboutWindow.cpp │ ├── w_AboutWindow.hpp │ ├── w_AboutWindow.ui │ ├── w_GroupManager.cpp │ ├── w_GroupManager.hpp │ ├── w_GroupManager.ui │ ├── w_ImportConfig.cpp │ ├── w_ImportConfig.hpp │ ├── w_ImportConfig.ui │ ├── w_MainWindow.cpp │ ├── w_MainWindow.hpp │ ├── w_MainWindow.ui │ ├── w_MainWindow_extra.cpp │ ├── w_PluginManager.cpp │ ├── w_PluginManager.hpp │ ├── w_PluginManager.ui │ ├── w_PreferencesWindow.cpp │ ├── w_PreferencesWindow.hpp │ └── w_PreferencesWindow.ui └── vcpkg.json /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Microsoft 3 | AccessModifierOffset: -2 4 | AlignAfterOpenBracket: Align 5 | AllowAllArgumentsOnNextLine: false 6 | AllowAllConstructorInitializersOnNextLine: false 7 | AllowAllParametersOfDeclarationOnNextLine: false 8 | AllowShortBlocksOnASingleLine: Never 9 | AllowShortCaseLabelsOnASingleLine: true 10 | AllowShortFunctionsOnASingleLine: None 11 | AllowShortIfStatementsOnASingleLine: Never 12 | AllowShortLambdasOnASingleLine: All 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakAfterDefinitionReturnType: None 15 | AlwaysBreakAfterReturnType: None 16 | AlwaysBreakBeforeMultilineStrings: false 17 | AlwaysBreakTemplateDeclarations: Yes 18 | BinPackArguments: true 19 | BinPackParameters: true 20 | BreakBeforeBraces: Allman 21 | BreakBeforeTernaryOperators: false 22 | BreakInheritanceList: BeforeComma 23 | BreakStringLiterals: false 24 | ColumnLimit: 170 25 | CompactNamespaces: false 26 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 27 | Cpp11BracedListStyle: false 28 | ExperimentalAutoDetectBinPacking: false 29 | FixNamespaceComments: true 30 | IncludeBlocks: Regroup 31 | IndentCaseLabels: true 32 | IndentPPDirectives: None 33 | IndentWidth: 4 34 | Language: Cpp 35 | MaxEmptyLinesToKeep: 1 36 | NamespaceIndentation: All 37 | ReflowComments: true 38 | SortIncludes: true 39 | SortUsingDeclarations: true 40 | SpaceAfterCStyleCast: true 41 | SpaceAfterTemplateKeyword: false 42 | SpaceBeforeParens: ControlStatements 43 | SpaceBeforeRangeBasedForLoopColon: true 44 | SpacesInParentheses: false 45 | Standard: c++17 46 | StatementMacros: [ Q_UNUSED LOG DEBUG ] 47 | TabWidth: 4 48 | UseTab: Never 49 | 50 | ... 51 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compilation Database 2 | compile_commands.json 3 | 4 | # macOS 5 | .DS_Store 6 | 7 | # Qt / Qt Creator 8 | *.user 9 | *.qm 10 | 11 | # Visual Studio 12 | .vs/ 13 | CMakeSettings.json 14 | out/ 15 | build**/ 16 | *build/ 17 | 18 | # IntelliJ-based IDE Trash 19 | .idea/ 20 | *.iml 21 | cmake-build-debug/ 22 | cmake-build-release/ 23 | 24 | # OSS VSCode 25 | .vscode/ 26 | .cache 27 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rdparty/SingleApplication"] 2 | path = 3rdparty/SingleApplication 3 | url = https://github.com/itay-grudev/SingleApplication 4 | [submodule "3rdparty/QCodeEditor"] 5 | path = 3rdparty/QCodeEditor 6 | url = https://github.com/cpeditor/QCodeEditor 7 | [submodule "3rdparty/qt-qrcode"] 8 | path = 3rdparty/qt-qrcode 9 | url = https://github.com/danielsanfr/qt-qrcode 10 | [submodule "src/Qv2rayBase"] 11 | path = src/Qv2rayBase 12 | url = https://github.com/Shadowsocks-NET/Qv2rayBase.git 13 | [submodule "src/plugins/routingA/core"] 14 | path = src/plugins/routingA/core 15 | url = https://github.com/moodyhunter/libRoutingA.git 16 | -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | flatwhite.css 4 | flatwhite/add_bottom.png 5 | flatwhite/add_left.png 6 | flatwhite/add_right.png 7 | flatwhite/add_top.png 8 | flatwhite/branch_close.png 9 | flatwhite/branch_open.png 10 | flatwhite/calendar_nextmonth.png 11 | flatwhite/calendar_prevmonth.png 12 | flatwhite/checkbox_checked.png 13 | flatwhite/checkbox_checked_disable.png 14 | flatwhite/checkbox_parcial.png 15 | flatwhite/checkbox_parcial_disable.png 16 | flatwhite/checkbox_unchecked.png 17 | flatwhite/checkbox_unchecked_disable.png 18 | flatwhite/radiobutton_checked.png 19 | flatwhite/radiobutton_checked_disable.png 20 | flatwhite/radiobutton_unchecked.png 21 | flatwhite/radiobutton_unchecked_disable.png 22 | 23 | 24 | -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/add_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/add_bottom.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/add_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/add_left.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/add_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/add_right.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/add_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/add_top.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/branch_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/branch_close.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/branch_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/branch_open.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/calendar_nextmonth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/calendar_nextmonth.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/calendar_prevmonth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/calendar_prevmonth.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/checkbox_checked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/checkbox_checked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/checkbox_checked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/checkbox_parcial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/checkbox_parcial.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/checkbox_parcial_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/checkbox_parcial_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/checkbox_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/checkbox_unchecked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/checkbox_unchecked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/checkbox_unchecked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/radiobutton_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/radiobutton_checked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/radiobutton_checked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/radiobutton_checked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/radiobutton_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/radiobutton_unchecked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/flatwhite/flatwhite/radiobutton_unchecked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/flatwhite/flatwhite/radiobutton_unchecked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | psblack.css 4 | psblack/add_bottom.png 5 | psblack/add_left.png 6 | psblack/add_right.png 7 | psblack/add_top.png 8 | psblack/branch_close.png 9 | psblack/branch_open.png 10 | psblack/calendar_nextmonth.png 11 | psblack/calendar_prevmonth.png 12 | psblack/checkbox_checked.png 13 | psblack/checkbox_checked_disable.png 14 | psblack/checkbox_parcial.png 15 | psblack/checkbox_parcial_disable.png 16 | psblack/checkbox_unchecked.png 17 | psblack/checkbox_unchecked_disable.png 18 | psblack/radiobutton_checked.png 19 | psblack/radiobutton_checked_disable.png 20 | psblack/radiobutton_unchecked.png 21 | psblack/radiobutton_unchecked_disable.png 22 | 23 | 24 | -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/add_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/add_bottom.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/add_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/add_left.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/add_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/add_right.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/add_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/add_top.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/branch_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/branch_close.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/branch_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/branch_open.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/calendar_nextmonth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/calendar_nextmonth.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/calendar_prevmonth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/calendar_prevmonth.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/checkbox_checked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/checkbox_checked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/checkbox_checked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/checkbox_parcial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/checkbox_parcial.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/checkbox_parcial_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/checkbox_parcial_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/checkbox_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/checkbox_unchecked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/checkbox_unchecked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/checkbox_unchecked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/radiobutton_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/radiobutton_checked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/radiobutton_checked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/radiobutton_checked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/radiobutton_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/radiobutton_unchecked.png -------------------------------------------------------------------------------- /3rdparty/uistyles/psblack/psblack/radiobutton_unchecked_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/3rdparty/uistyles/psblack/psblack/radiobutton_unchecked_disable.png -------------------------------------------------------------------------------- /3rdparty/uistyles/uistyles.cmake: -------------------------------------------------------------------------------- 1 | set(UISTYLE_QRCS 2 | ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/uistyles/flatwhite/flatwhite.qrc 3 | ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/uistyles/psblack/psblack.qrc 4 | ) 5 | -------------------------------------------------------------------------------- /assets/MacOSXBundleInfo.plist.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${MACOSX_BUNDLE_EXECUTABLE_NAME} 9 | CFBundleGetInfoString 10 | ${MACOSX_BUNDLE_INFO_STRING} 11 | CFBundleIconFile 12 | ${MACOSX_BUNDLE_ICON_FILE} 13 | CFBundleIdentifier 14 | ${MACOSX_BUNDLE_GUI_IDENTIFIER} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleLongVersionString 18 | ${MACOSX_BUNDLE_LONG_VERSION_STRING} 19 | CFBundleName 20 | ${MACOSX_BUNDLE_BUNDLE_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | ${MACOSX_BUNDLE_SHORT_VERSION_STRING} 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | ${MACOSX_BUNDLE_BUNDLE_VERSION} 29 | CSResourcesFileMapped 30 | 31 | NSHumanReadableCopyright 32 | ${MACOSX_BUNDLE_COPYRIGHT} 33 | NSPrincipalClass 34 | NSApplication 35 | NSHighResolutionCapable 36 | True 37 | CFBundleURLTypes 38 | 39 | 40 | CFBundleTypeRole 41 | Editor 42 | CFBundleURLIconFile 43 | Icon 44 | CFBundleURLName 45 | com.qv2ray.qv2ray 46 | CFBundleURLSchemes 47 | 48 | qv2ray 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /assets/ProtocolSchemes.txt: -------------------------------------------------------------------------------- 1 | qv2ray://open/preference/general 2 | qv2ray://open/preference/kernel 3 | qv2ray://open/preference/inbound 4 | qv2ray://open/preference/connection 5 | qv2ray://open/preference/route 6 | qv2ray://open/preference/about 7 | 8 | qv2ray://open/group/connection 9 | qv2ray://open/group/subscription 10 | qv2ray://open/group/dns 11 | qv2ray://open/group/route 12 | 13 | qv2ray://open/import/link?name= 14 | qv2ray://open/import/qr?name= 15 | qv2ray://open/import/manual?name= 16 | qv2ray://open/import/advanced?name= 17 | 18 | qv2ray://open/plugin/plugindir 19 | qv2ray://open/plugin/metadata 20 | qv2ray://open/plugin/settings 21 | -------------------------------------------------------------------------------- /assets/icons/Applogo_bird_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/Applogo_bird_b.png -------------------------------------------------------------------------------- /assets/icons/Applogo_bird_colorful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/Applogo_bird_colorful.png -------------------------------------------------------------------------------- /assets/icons/Applogo_bird_g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/Applogo_bird_g.png -------------------------------------------------------------------------------- /assets/icons/IconSource.txt: -------------------------------------------------------------------------------- 1 | https://www.iconfont.cn/collections/detail?cid=22664 2 | -------------------------------------------------------------------------------- /assets/icons/convert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #sed -i "s/#dbdbdb/#707070/g" *.svg 3 | -------------------------------------------------------------------------------- /assets/icons/designs/banner.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/designs/banner.svg.png -------------------------------------------------------------------------------- /assets/icons/iconconv.nim: -------------------------------------------------------------------------------- 1 | # Qv2ray Icon Converter 2 | # Author: DuckSoft 3 | # Licensed under The Star And Thank Author License (SATA License) & GPL 3.0. 4 | 5 | import os 6 | import strformat 7 | import asyncdispatch 8 | import strutils 9 | import sequtils 10 | 11 | const linuxIconSizes = [16, 22, 32, 48, 64, 128, 256, 512, 1024] 12 | const windowsIconSizes = [32, 64, 128, 256] 13 | const windowsPackForVistaThreshold = 128 14 | const windowsIconBitDepth = 32 15 | const macOSIconSizes = [16, 32, 128, 256, 512, 1024] 16 | 17 | proc svg2PngWithSize(sz: int): Future[int] {.async.} = 18 | let targetFilename = fmt"qv2ray.{sz}.png" 19 | if os.existsFile(targetFilename): 20 | echo fmt" => Skipped: {targetFilename}..." 21 | return 0 22 | 23 | let cmdline = fmt"convert -background none -geometry {sz}x{sz} -density {4*sz} qv2ray.svg {targetFilename}" 24 | echo fmt" => Converting: {targetFilename}..." 25 | return os.execShellCmd(cmdline) 26 | 27 | proc generateLinuxIcon(): Future[void] {.async.} = 28 | echo "Generating Linux Icons..." 29 | let sizeFutures = map(linuxIconSizes, svg2PngWithSize) 30 | discard waitFor all(sizeFutures) 31 | 32 | proc generateWindowsIcon(): Future[void] {.async.} = 33 | echo "Generating Windows Icon..." 34 | var cmdline = "icotool --create " 35 | 36 | var idx = 1 37 | for size in windowsIconSizes: 38 | cmdline &= fmt"--index={idx} --width={size} --height={size} --bit-depth={windowsIconBitDepth} --palette-size=0 " 39 | if size > windowsPackForVistaThreshold: 40 | cmdline &= "--raw=" 41 | cmdline &= fmt"qv2ray.{size}.png " 42 | idx.inc() 43 | 44 | cmdline &= "--output=qv2ray.ico" 45 | 46 | let result = os.execShellCmd(cmdline) 47 | if result == 0: 48 | echo " => Success!" 49 | else: 50 | echo " => Failed!" 51 | 52 | proc generateMacOSIcon(): Future[void] {.async.} = 53 | var cmdline = "png2icns qv2ray.icns " 54 | let macOSIconFilenames = map(macOSIconSizes, proc (size: int): string = fmt"qv2ray.{size}.png") 55 | cmdline &= join(macOSIconFilenames, " ") 56 | discard os.execShellCmd(cmdline) 57 | 58 | proc main() {.async.} = 59 | echo "Qv2ray Icon Converter" 60 | waitFor generateLinuxIcon() 61 | waitFor generateWindowsIcon() 62 | waitFor generateMacOSIcon() 63 | 64 | waitFor main() 65 | -------------------------------------------------------------------------------- /assets/icons/qv2ray.1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.1024.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.128.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.16.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.22.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.256.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.32.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.48.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.512.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.64.png -------------------------------------------------------------------------------- /assets/icons/qv2ray.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.icns -------------------------------------------------------------------------------- /assets/icons/qv2ray.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.ico -------------------------------------------------------------------------------- /assets/icons/qv2ray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/qv2ray.png -------------------------------------------------------------------------------- /assets/icons/ui_dark/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/adjust.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/arrow-down-filling.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/arrow-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/arrow-up-filling.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 31 | 51 | 55 | 56 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/ashbin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/data-view.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/export.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/file-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/glyph-tray-connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_dark/glyph-tray-connected.png -------------------------------------------------------------------------------- /assets/icons/ui_dark/glyph-tray-connected.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/glyph-tray-systemproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_dark/glyph-tray-systemproxy.png -------------------------------------------------------------------------------- /assets/icons/ui_dark/glyph-tray-systemproxy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/glyph-tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_dark/glyph-tray.png -------------------------------------------------------------------------------- /assets/icons/ui_dark/glyph-tray.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/map.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/minus.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 31 | 51 | 56 | 57 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/save.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/share.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_dark/tray-connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_dark/tray-connected.png -------------------------------------------------------------------------------- /assets/icons/ui_dark/tray-systemproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_dark/tray-systemproxy.png -------------------------------------------------------------------------------- /assets/icons/ui_dark/tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_dark/tray.png -------------------------------------------------------------------------------- /assets/icons/ui_light/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/adjust.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/arrow-down-filling.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/arrow-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/arrow-up-filling.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 31 | 51 | 55 | 56 | -------------------------------------------------------------------------------- /assets/icons/ui_light/ashbin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/data-view.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/export.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/file-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/glyph-tray-connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_light/glyph-tray-connected.png -------------------------------------------------------------------------------- /assets/icons/ui_light/glyph-tray-connected.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/icons/ui_light/glyph-tray-systemproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_light/glyph-tray-systemproxy.png -------------------------------------------------------------------------------- /assets/icons/ui_light/glyph-tray-systemproxy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/icons/ui_light/glyph-tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_light/glyph-tray.png -------------------------------------------------------------------------------- /assets/icons/ui_light/glyph-tray.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/icons/ui_light/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/map.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/minus.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 31 | 51 | 56 | 57 | -------------------------------------------------------------------------------- /assets/icons/ui_light/save.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/share.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/ui_light/tray-connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_light/tray-connected.png -------------------------------------------------------------------------------- /assets/icons/ui_light/tray-systemproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_light/tray-systemproxy.png -------------------------------------------------------------------------------- /assets/icons/ui_light/tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/assets/icons/ui_light/tray.png -------------------------------------------------------------------------------- /assets/qv2ray.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=Qv2ray 4 | Type=Application 5 | GenericName=V2Ray Graphical Frontend 6 | GenericName[zh_CN]=V2Ray 图形前端 7 | GenericName[zh_TW]=V2Ray 圖形前端 8 | GenericName[ja]=V2Rayグラフィックフロントエンド 9 | Comment=A Cross-Platform V2Ray Qt GUI Client 10 | Comment[zh_CN]=跨平台的 V2Ray Qt 图形客户端 11 | Comment[zh_TW]=跨平臺的 V2Ray Qt 圖形用戶端 12 | Comment[ja]=とあるクロスプラットフォームV2Rayグラフィックフロントエンド 13 | Keywords=Internet;VPN;Proxy;v2ray;Qt;qv; 14 | Keywords[zh_CN]=Internet;VPN;Proxy;v2ray;Qt;qv;代理; 15 | Keywords[zh_TW]=Internet;VPN;Proxy;v2ray;Qt;qv;代理; 16 | Keywords[ja]=インターネット;VPN;プロキシ;Qt;v2ray;qv; 17 | Categories=Network;Qt; 18 | Terminal=false 19 | Icon=qv2ray 20 | Exec=qv2ray %u 21 | MimeType=x-scheme-handler/qv2ray; 22 | Actions=debug;noPlugin;noScaleFactor;noAPI;noAutoConnection; 23 | 24 | [Desktop Action debug] 25 | Name=Start with Debug Mode 26 | Name[zh_CN]=以调试模式运行 27 | Name[zh_TW]=以調試模式運行 28 | Name[ja]=デバッグモードで起動 29 | Exec=qv2ray --debug 30 | 31 | [Desktop Action noPlugin] 32 | Name=Start without Plugins 33 | Name[zh_CN]=不使用插件启动 34 | Name[zh_TW]=不使用外掛程式啟動 35 | Name[ja]=プラグイン使用せずに起動 36 | Exec=qv2ray --noPlugin 37 | 38 | [Desktop Action noScaleFactor] 39 | Name=Start without Scaling Factor 40 | Name[zh_CN]=禁用界面缩放启动 41 | Name[zh_TW]=禁用介面縮放啟動 42 | Name[ja]=インターフェーススケーリング使用せずに起動 43 | Exec=qv2ray --noScaleFactor 44 | 45 | [Desktop Action noAPI] 46 | Name=Start without gRPC API 47 | Name[zh_CN]=不使用 gRPC API 启动 48 | Name[zh_TW]=不使用 gRPC API 啟動 49 | Name[ja]=gRPC使用せずに起動 50 | Exec=qv2ray --noAPI 51 | 52 | [Desktop Action noAutoConnection] 53 | Name=Start without automatic connection 54 | Name[zh_CN]=不自动连接节点启动 55 | Name[zh_TW]=不自動連接節點啟動 56 | Name[ja]=自動接続使用せずに起動 57 | Exec=qv2ray --noAutoConnection 58 | 59 | -------------------------------------------------------------------------------- /cmake/deployment-linux.cmake: -------------------------------------------------------------------------------- 1 | install(TARGETS qv2ray RUNTIME DESTINATION bin) 2 | install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/qv2ray.desktop DESTINATION share/applications) 3 | install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/qv2ray.svg DESTINATION share/icons/hicolor/scalable/apps) 4 | 5 | if(BUILD_SHARED_LIBS) 6 | if(QV2RAY_QV2RAYBASE_PROVIDER STREQUAL "module") 7 | install(TARGETS Qv2rayBase) 8 | endif() 9 | endif() 10 | 11 | foreach(d 16 22 32 48 64 128 256 512 1024) 12 | install(FILES assets/icons/qv2ray.${d}.png 13 | DESTINATION share/icons/hicolor/${d}x${d}/apps 14 | RENAME qv2ray.png) 15 | endforeach(d) 16 | 17 | if(NOT QV2RAY_EMBED_TRANSLATIONS) 18 | install(FILES ${QV2RAY_QM_FILES} 19 | DESTINATION share/qv2ray/lang) 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/deployment-windows.cmake: -------------------------------------------------------------------------------- 1 | target_link_libraries(qv2ray PRIVATE wininet wsock32 ws2_32 user32 Rasapi32 Iphlpapi Dbghelp) 2 | 3 | install(TARGETS qv2ray RUNTIME DESTINATION .) 4 | 5 | # For Global Target 6 | list(APPEND DIRS "${CMAKE_BINARY_DIR}") 7 | 8 | # For Qv2rayBase 9 | list(APPEND DIRS "${CMAKE_BINARY_DIR}/src/Qv2rayBase") 10 | list(APPEND DIRS "${CMAKE_CURRENT_BINARY_DIR}") 11 | list(APPEND DIRS "${Qt6Core_DIR}/../../") 12 | list(APPEND DIRS "${Qt6Core_DIR}/../../../bin/") 13 | 14 | if(CMAKE_PREFIX_PATH) 15 | foreach(dir ${CMAKE_PREFIX_PATH}) 16 | list(APPEND DIRS "${dir}/bin" "${dir}/lib") 17 | endforeach() 18 | endif() 19 | 20 | list(APPEND DIRS "${Qt6Core_DIR}/../..") 21 | 22 | foreach(d ${DIRS}) 23 | string(REPLACE "\\" "/" newd ${d}) 24 | list(APPEND NEW_DIRS ${newd}) 25 | endforeach() 26 | set(DIRS ${NEW_DIRS}) 27 | 28 | set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) 29 | 30 | set(APP "${CMAKE_INSTALL_PREFIX}/qv2ray.exe") 31 | install(CODE "include(BundleUtilities)") 32 | install(CODE "fixup_bundle(\"${APP}\" \"\" \"${DIRS}\")") 33 | install(CODE "message(\"\")") 34 | install(CODE "execute_process(COMMAND \"${Qt6_DIR}/../../../bin/windeployqt.exe\" \"${APP}\" --no-compiler-runtime --no-opengl-sw)") 35 | install(CODE "message(\"Completed\")") 36 | -------------------------------------------------------------------------------- /cmake/qrencode.cmake: -------------------------------------------------------------------------------- 1 | set(QT_QRENCODE_BASEDIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qt-qrcode/lib) 2 | 3 | include_directories(${QT_QRENCODE_BASEDIR}) 4 | 5 | set(QT_QRENCODE_SOURCES 6 | ${QT_QRENCODE_BASEDIR}/libqrencode/bitstream.c 7 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrencode.c 8 | ${QT_QRENCODE_BASEDIR}/libqrencode/mqrspec.c 9 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrinput.c 10 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrspec.c 11 | ${QT_QRENCODE_BASEDIR}/libqrencode/split.c 12 | ${QT_QRENCODE_BASEDIR}/libqrencode/rsecc.c 13 | ${QT_QRENCODE_BASEDIR}/libqrencode/mmask.c 14 | ${QT_QRENCODE_BASEDIR}/libqrencode/mask.c 15 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrencode_inner.h 16 | ${QT_QRENCODE_BASEDIR}/libqrencode/bitstream.h 17 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrencode.h 18 | ${QT_QRENCODE_BASEDIR}/libqrencode/mqrspec.h 19 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrinput.h 20 | ${QT_QRENCODE_BASEDIR}/libqrencode/qrspec.h 21 | ${QT_QRENCODE_BASEDIR}/libqrencode/split.h 22 | ${QT_QRENCODE_BASEDIR}/libqrencode/rsecc.h 23 | ${QT_QRENCODE_BASEDIR}/libqrencode/mmask.h 24 | ${QT_QRENCODE_BASEDIR}/libqrencode/mask.h 25 | ${QT_QRENCODE_BASEDIR}/QtQrCode 26 | ${QT_QRENCODE_BASEDIR}/qtqrcode_global.h 27 | ${QT_QRENCODE_BASEDIR}/QtQrCodePainter 28 | ${QT_QRENCODE_BASEDIR}/qtqrcodepainter.h 29 | ${QT_QRENCODE_BASEDIR}/qtqrcode.cpp 30 | ${QT_QRENCODE_BASEDIR}/qtqrcode.h 31 | ${QT_QRENCODE_BASEDIR}/qtqrcodepainter.cpp 32 | ) 33 | 34 | find_package(Qt6 COMPONENTS Core Gui Svg REQUIRED) 35 | 36 | add_library(qv2ray_qrencode STATIC ${QT_QRENCODE_SOURCES}) 37 | 38 | target_compile_definitions(qv2ray_qrencode PRIVATE 39 | -DSTATIC_IN_RELEASE=static 40 | -D__STATIC=static 41 | -DMAJOR_VERSION=3 42 | -DMINOR_VERSION=9 43 | -DMICRO_VERSION=0 44 | -DVERSION="0.0.0") 45 | 46 | target_link_libraries(qv2ray_qrencode 47 | Qt::Core 48 | Qt::Gui 49 | Qt::Svg) 50 | 51 | add_library(Qv2ray::QREncode ALIAS qv2ray_qrencode) 52 | -------------------------------------------------------------------------------- /cmake/versioninfo/VersionResource.rc: -------------------------------------------------------------------------------- 1 | #include "VersionInfo.h" 2 | 3 | #if defined(__MINGW64__) || defined(__MINGW32__) 4 | // MinGW-w64, MinGW 5 | #if defined(__has_include) && __has_include() 6 | #include 7 | #else 8 | #include 9 | #include 10 | #endif 11 | #else 12 | // MSVC, Windows SDK 13 | #include 14 | #endif 15 | 16 | IDI_ICON1 ICON PRODUCT_ICON 17 | 18 | LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT 19 | 20 | VS_VERSION_INFO VERSIONINFO 21 | FILEVERSION FILE_VERSION_RESOURCE 22 | PRODUCTVERSION PRODUCT_VERSION_RESOURCE 23 | FILEFLAGSMASK 0x3fL 24 | #ifdef _DEBUG 25 | FILEFLAGS 0x1L 26 | #else 27 | FILEFLAGS 0x0L 28 | #endif 29 | FILEOS 0x4L 30 | FILETYPE 0x1L 31 | FILESUBTYPE 0x0L 32 | BEGIN 33 | BLOCK "StringFileInfo" 34 | BEGIN 35 | BLOCK "000904b0" 36 | BEGIN 37 | VALUE "Comments", PRODUCT_COMMENTS 38 | VALUE "CompanyName", PRODUCT_COMPANY_NAME 39 | VALUE "FileDescription", PRODUCT_FILE_DESCRIPTION 40 | VALUE "FileVersion", FILE_VERSION_RESOURCE_STR 41 | VALUE "InternalName", PRODUCT_INTERNAL_NAME 42 | VALUE "LegalCopyright", PRODUCT_COMPANY_COPYRIGHT 43 | VALUE "OriginalFilename", PRODUCT_ORIGINAL_FILENAME 44 | VALUE "ProductName", PRODUCT_BUNDLE 45 | VALUE "ProductVersion", PRODUCT_VERSION_RESOURCE_STR 46 | END 47 | END 48 | BLOCK "VarFileInfo" 49 | BEGIN 50 | VALUE "Translation", 0x9, 1200 51 | END 52 | END 53 | -------------------------------------------------------------------------------- /docs/Platform-Specific-Compilation-Notices.md: -------------------------------------------------------------------------------- 1 | # Linux (libuv, uvw) 2 | 3 | - The CMake support provided by `uvw` is not complete and lacks `libdl` linkage when configuring using `USE_SYSTEM_LIBUV` option. 4 | 5 | # Linux (Qt) 6 | 7 | - As a regression of Qt 6.2 beta2, Vulkan must be installed when configuring a Qt GUI application, so install vulkan and set `VULKAN_SDK` properly. (See [QTBUG-95391](https://bugreports.qt.io/browse/QTBUG-95391)) 8 | 9 | # macOS (Qt) 10 | 11 | - `macdeployqt` is malfunctioning when it sees `libabsl_debugging_internal.dylib` (See [QTBUG-90982](https://bugreports.qt.io/browse/QTBUG-90982)) 12 | - QvPersonal uses static linking (provided by vcpkg) so this won't cause a problem. 13 | - Pay special attention when using shared(dynamic) gRPC libraries (which depends on libabsl) from homebrew. 14 | - **Qt Network OpenSSL TLS backend plugin** is not shipped Qt, causing TLS 1.3 to be unavailable. (See [QTBUG-95249](https://bugreports.qt.io/browse/QTBUG-95249)) 15 | 16 | # Windows (Qt) 17 | 18 | - `windeployqt` will not copy **Qt Network TLS backend plugins**, so they're copied by CMake, as a result, debugging libraries may be copied. 19 | - As a regression of Qt 6.2 beta2, Vulkan must be installed when configuring a Qt GUI application, so install vulkan and set `VULKAN_SDK` properly. (See [QTBUG-95391](https://bugreports.qt.io/browse/QTBUG-95391)) -------------------------------------------------------------------------------- /docs/Query-Syntax-in-Search-Bar.md: -------------------------------------------------------------------------------- 1 | - You can now search for connections by group, connection name, tags, latency, outbound count, inbound count, protocol, port and server address using the new searching syntax. 2 | - The new query syntax is prefixed with a `>` character. 3 | 4 | ### e.g. 5 | - Searching for connections with tags, AND relation: `> tags=onetag,"another tag", anotherTag2` 6 | - Searching for connections with tags, OR relation: `> tags=onetag|"another tag"| anotherTag2` 7 | - Comma will be replaced with the default relation: `AND` for `Equals`, `OR` for `NotEquals` 8 | - Searching for connections without tags: `> tags!= excludedTag` 9 | - Searching for connections with latency no more than 50ms: `> latency<=50` 10 | - Searching for connections to a specific server: `> address=my.server.com` 11 | - and many more... 12 | 13 | ### Multiple searching criteria can be joined by a semicolon char (`;`) 14 | - Searching for connections tagged with `JP` and `Direct`, where the latency is less than 40ms, while exclude the currently-connected one: `> tags=JP,Direct; latency<40; !connected` 15 | 16 | ### All searching criteria 17 | - `group`: Group Name (string) 18 | - `Name`: Connection Name (string) 19 | - `tags`: Connection Tags (list) 20 | - `latency`: Connection Latency (int) 21 | - `inbounds`: Inbounds count (int) 22 | - `outbounds`: Outbounds count (int) 23 | - `connected`: Is current connection? (bool) 24 | - `protocol`: First outbound protocol (string) 25 | - `address`: First outbound address (string) 26 | - `port`: First outbound port (int) 27 | -------------------------------------------------------------------------------- /src/components/AutoLaunchHelper/AutoLaunchHelper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Qv2ray::components::autolaunch 4 | { 5 | bool GetLaunchAtLoginStatus(); 6 | void SetLaunchAtLoginStatus(bool enable); 7 | } // namespace Qv2ray::components::autolaunch 8 | 9 | using namespace Qv2ray::components; 10 | using namespace Qv2ray::components::autolaunch; 11 | -------------------------------------------------------------------------------- /src/components/ConnectionModelHelper/ConnectionModelHelper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/PluginInterface.hpp" 4 | #include "components/QueryParser/QueryParser.hpp" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Qv2ray::ui::widgets::models 11 | { 12 | enum ConnectionInfoRole 13 | { 14 | // 10 -> Magic value. 15 | ROLE_DISPLAYNAME = Qt::UserRole + 10, 16 | ROLE_LATENCY, 17 | ROLE_IMPORTTIME, 18 | ROLE_LAST_CONNECTED_TIME, 19 | ROLE_DATA_USAGE 20 | }; 21 | 22 | class ConnectionListHelper : public QObject 23 | { 24 | Q_OBJECT 25 | public: 26 | ConnectionListHelper(QTreeView *parentView, QObject *parent = nullptr); 27 | ~ConnectionListHelper(); 28 | void Sort(ConnectionInfoRole, Qt::SortOrder); 29 | void Filter(const QString &); 30 | void Filter(const Qv2ray::components::QueryParser::SemanticAnalyzer::Program &program); 31 | 32 | inline QModelIndex GetConnectionPairIndex(const ProfileId &id) const 33 | { 34 | return model->indexFromItem(pairs.value(id)); 35 | } 36 | 37 | inline QModelIndex GetGroupIndex(const GroupId &id) const 38 | { 39 | return model->indexFromItem(groups[id]); 40 | } 41 | 42 | private: 43 | QStandardItem *addConnectionItem(const ProfileId &id); 44 | QStandardItem *addGroupItem(const GroupId &groupId); 45 | void OnGroupDeleted(const GroupId &id, const QList &connections); 46 | void OnConnectionDeleted(const ProfileId &id); 47 | 48 | private: 49 | QTreeView *parentView; 50 | QStandardItemModel *model; 51 | 52 | QHash groups; 53 | QHash pairs; 54 | QHash> connections; 55 | }; 56 | 57 | } // namespace Qv2ray::ui::widgets::models 58 | 59 | using namespace Qv2ray::ui::widgets::models; 60 | -------------------------------------------------------------------------------- /src/components/FlowLayout/FlowLayout.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Qv2ray::components 8 | { 9 | class FlowLayout : public QLayout 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1, QWidget *parent = nullptr); 15 | ~FlowLayout(); 16 | 17 | int count() const override; 18 | int horizontalSpacing() const; 19 | int verticalSpacing() const; 20 | Qt::Orientations expandingDirections() const override; 21 | bool hasHeightForWidth() const override; 22 | int heightForWidth(int) const override; 23 | QLayoutItem *itemAt(int index) const override; 24 | QSize minimumSize() const override; 25 | void setGeometry(const QRect &rect) override; 26 | QSize sizeHint() const override; 27 | QLayoutItem *takeAt(int index) override; 28 | void addItem(QLayoutItem *item) override; 29 | void addWidgetAt(QWidget *item, int index); 30 | 31 | private: 32 | int doLayout(QRect rect, bool testOnly) const; 33 | int smartSpacing(QStyle::PixelMetric pm) const; 34 | 35 | QList itemList; 36 | int m_hSpace; 37 | int m_vSpace; 38 | }; 39 | } // namespace Qv2ray::components 40 | -------------------------------------------------------------------------------- /src/components/GeositeReader/GeositeReader.cpp: -------------------------------------------------------------------------------- 1 | #include "GeositeReader.hpp" 2 | 3 | #include "Qv2rayBase/Qv2rayBaseFeatures.hpp" 4 | #include "picoproto.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace Qv2ray::components::GeositeReader 10 | { 11 | QMap GeositeEntries; 12 | 13 | QStringList ReadGeoSiteFromFile(const QString &filepath, bool allowCache) 14 | { 15 | if (GeositeEntries.contains(filepath) && allowCache) 16 | return GeositeEntries.value(filepath); 17 | 18 | QStringList list; 19 | qInfo() << "Reading geosites from:" << filepath; 20 | QFile f(filepath); 21 | bool opened = f.open(QFile::OpenModeFlag::ReadOnly); 22 | 23 | if (!opened) 24 | { 25 | qInfo() << "File cannot be opened:" << filepath; 26 | return list; 27 | } 28 | 29 | const auto content = f.readAll(); 30 | f.close(); 31 | { 32 | picoproto::Message root; 33 | root.ParseFromBytes((unsigned char *) content.data(), content.size()); 34 | 35 | list.reserve(root.GetMessageArray(1).size()); 36 | for (const auto &geosite : root.GetMessageArray(1)) 37 | list << QString::fromStdString(geosite->GetString(1)); 38 | } 39 | 40 | qInfo() << "Loaded" << list.count() << "geosite entries from data file."; 41 | list.sort(); 42 | GeositeEntries[filepath] = list; 43 | return list; 44 | } 45 | } // namespace Qv2ray::components::geosite 46 | -------------------------------------------------------------------------------- /src/components/GeositeReader/GeositeReader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Qv2ray::components::GeositeReader 6 | { 7 | QStringList ReadGeoSiteFromFile(const QString &filepath, bool allowCache = true); 8 | } // namespace Qv2ray::components::GeositeReader 9 | -------------------------------------------------------------------------------- /src/components/GuiPluginHost/GuiPluginHost.cpp: -------------------------------------------------------------------------------- 1 | #include "GuiPluginHost.hpp" 2 | 3 | #include "Qv2rayBase/Plugin/PluginManagerCore.hpp" 4 | #include "Qv2rayBase/Qv2rayBaseLibrary.hpp" 5 | 6 | using namespace Qv2rayPlugin; 7 | 8 | namespace Qv2ray::components::GuiPluginHost 9 | { 10 | GuiPluginAPIHost::GuiPluginAPIHost() 11 | { 12 | } 13 | 14 | QList> GuiPluginAPIHost::QueryByGuiComponent(PLUGIN_GUI_COMPONENT_TYPE c) const 15 | { 16 | QList> guiInterfaces; 17 | for (const auto &plugin : QvPluginManagerCore->GetPlugins(Qv2rayPlugin::COMPONENT_GUI)) 18 | { 19 | const auto guiInterface = plugin->pinterface->GetGUIInterface(); 20 | if (guiInterface->GetComponents().contains(c)) 21 | guiInterfaces << std::make_pair(plugin->metadata(), guiInterface); 22 | } 23 | return guiInterfaces; 24 | } 25 | } // namespace Qv2ray::components::GuiPluginHost 26 | -------------------------------------------------------------------------------- /src/components/GuiPluginHost/GuiPluginHost.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Qv2rayBase/Plugin/PluginAPIHost.hpp" 4 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 5 | 6 | namespace Qv2ray::components::GuiPluginHost 7 | { 8 | class GuiPluginAPIHost 9 | { 10 | public: 11 | GuiPluginAPIHost(); 12 | QList> QueryByGuiComponent(Qv2rayPlugin::PLUGIN_GUI_COMPONENT_TYPE c) const; 13 | }; 14 | } // namespace Qv2ray::components::GuiPluginHost 15 | 16 | inline Qv2ray::components::GuiPluginHost::GuiPluginAPIHost *GUIPluginHost; 17 | -------------------------------------------------------------------------------- /src/components/MessageBus/MessageBus.cpp: -------------------------------------------------------------------------------- 1 | #include "MessageBus.hpp" 2 | -------------------------------------------------------------------------------- /src/components/MessageBus/MessageBus.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define QvMessageBusConnect() connect(UIMessageBus, &std::decay_t::QvSendMessage, this, &std::decay_t::on_QvMessageReceived) 5 | 6 | #define QvMessageBusSlotSig Qv2ray::components::MessageBus::QvMBMessage msg 7 | #define QvMessageBusSlotIdentifier on_QvMessageReceived 8 | 9 | #define QvMessageBusSlotDecl void QvMessageBusSlotIdentifier(QvMessageBusSlotSig) 10 | #define QvMessageBusSlotImpl(CLASSNAME) void CLASSNAME::QvMessageBusSlotIdentifier(QvMessageBusSlotSig) 11 | 12 | #define MBUpdateColorSchemeDefaultImpl \ 13 | case Qv2ray::components::MessageBus::UPDATE_COLORSCHEME: \ 14 | { \ 15 | this->updateColorScheme(); \ 16 | break; \ 17 | } 18 | 19 | namespace Qv2ray::components::MessageBus 20 | { 21 | Q_NAMESPACE 22 | enum QvMBMessage 23 | { 24 | UPDATE_COLORSCHEME 25 | }; 26 | Q_ENUM_NS(QvMBMessage) 27 | 28 | class QvMessageBusObject : public QObject 29 | { 30 | Q_OBJECT 31 | public: 32 | explicit QvMessageBusObject(){}; 33 | void EmitGlobalSignal(const QvMBMessage &msg) 34 | { 35 | emit QvSendMessage(msg); 36 | } 37 | signals: 38 | void QvSendMessage(const QvMBMessage &msg); 39 | }; 40 | 41 | } // namespace Qv2ray::components::MessageBus 42 | 43 | inline Qv2ray::components::MessageBus::QvMessageBusObject *UIMessageBus; 44 | -------------------------------------------------------------------------------- /src/components/QRCodeHelper/QRCodeHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "QRCodeHelper.hpp" 2 | 3 | #include "QtQrCode" 4 | #include "QtQrCodePainter" 5 | 6 | #include 7 | 8 | namespace Qv2ray::ui 9 | { 10 | QString DecodeQRCode(const QImage &) 11 | { 12 | return ""; 13 | } 14 | 15 | QImage EncodeQRCode(const QString content, int size) 16 | { 17 | QtQrCode c; 18 | c.setData(content.toUtf8()); 19 | return QtQrCodePainter(2.0).toImage(c, size); 20 | } 21 | } // namespace Qv2ray::ui 22 | -------------------------------------------------------------------------------- /src/components/QRCodeHelper/QRCodeHelper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class QImage; 4 | class QSize; 5 | class QString; 6 | 7 | namespace Qv2ray::ui 8 | { 9 | QString DecodeQRCode(const QImage &img); 10 | QImage EncodeQRCode(const QString content, int size); 11 | } // namespace Qv2ray::ui 12 | using namespace Qv2ray::ui; 13 | -------------------------------------------------------------------------------- /src/components/RouteSchemeIO/RouteSchemeIO.cpp: -------------------------------------------------------------------------------- 1 | #include "RouteSchemeIO.hpp" 2 | -------------------------------------------------------------------------------- /src/components/RouteSchemeIO/RouteSchemeIO.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "plugins/PluginsCommon/V2RayModels.hpp" 4 | 5 | #include 6 | 7 | namespace Qv2ray::components::RouteSchemeIO 8 | { 9 | const static inline Qv2ray::Models::RouteMatrixConfig EmptyScheme; 10 | const static inline Qv2ray::Models::RouteMatrixConfig NoAdsScheme({ {}, { "geosite:category-ads-all" }, {} }, { {}, {}, {} }, "AsIs"); 11 | 12 | /** 13 | * @brief The Qv2rayRouteScheme struct 14 | * @author DuckSoft 15 | */ 16 | struct Qv2rayRouteScheme : Qv2ray::Models::RouteMatrixConfig 17 | { 18 | /** 19 | * @brief the name of the scheme. 20 | * @example "Untitled Scheme" 21 | */ 22 | Bindable name; 23 | /** 24 | * @brief the author of the scheme. 25 | * @example "DuckSoft " 26 | */ 27 | Bindable author; 28 | /** 29 | * @brief details of this scheme. 30 | * @example "A scheme to bypass China mainland, while allowing bilibili to go through proxy." 31 | */ 32 | Bindable description; 33 | QJS_JSON(P(name, author, description), B(RouteMatrixConfig)) 34 | }; 35 | } // namespace Qv2ray::components::RouteSchemeIO 36 | -------------------------------------------------------------------------------- /src/components/StyleManager/StyleManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Qv2ray::components::QvStyleManager 8 | { 9 | struct QvStyle 10 | { 11 | enum StyleType 12 | { 13 | QVSTYLE_FACTORY, 14 | QVSTYLE_QSS 15 | } Type; 16 | QString Name; 17 | QString qssPath; 18 | }; 19 | 20 | class QvStyleManager : QObject 21 | { 22 | public: 23 | QvStyleManager(QObject *parent = nullptr); 24 | inline QStringList AllStyles() const 25 | { 26 | return styles.keys(); 27 | } 28 | bool ApplyStyle(const QString &); 29 | bool isDarkMode() const; 30 | 31 | private: 32 | void ReloadStyles(); 33 | QMap styles; 34 | }; 35 | 36 | } // namespace Qv2ray::components::StyleManager 37 | 38 | inline Qv2ray::components::QvStyleManager::QvStyleManager *StyleManager = nullptr; 39 | -------------------------------------------------------------------------------- /src/components/UpdateChecker/UpdateChecker.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Qv2ray::components::UpdateChecker 6 | { 7 | void CheckUpdate(); 8 | } // namespace Qv2ray::components::UpdateChecker 9 | -------------------------------------------------------------------------------- /src/plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(protocols) 2 | add_subdirectory(subscription-adapters) 3 | add_subdirectory(v2ray) 4 | add_subdirectory(routingA) 5 | -------------------------------------------------------------------------------- /src/plugins/internal/InternalPlugin.cpp: -------------------------------------------------------------------------------- 1 | #include "InternalPlugin.hpp" 2 | 3 | #include "InternalProfilePreprocessor.hpp" 4 | 5 | const Qv2rayPlugin::QvPluginMetadata Qv2rayInternalPlugin::GetMetadata() const 6 | { 7 | return Qv2rayPlugin::QvPluginMetadata{ 8 | u"Qv2ray Internal Plugin"_qs, // 9 | u"Moody"_qs, // 10 | PluginId{ u"qvinternal"_qs }, // 11 | u"Apply your globally configured inbounds and routing rules for simple connections."_qs, // 12 | u""_qs, // 13 | { Qv2rayPlugin::COMPONENT_PROFILE_PREPROCESSOR } // 14 | }; 15 | } 16 | 17 | bool Qv2rayInternalPlugin::InitializePlugin() 18 | { 19 | m_ProfilePreprocessor = std::make_shared(); 20 | return true; 21 | } 22 | 23 | void Qv2rayInternalPlugin::SettingsUpdated() 24 | { 25 | // No settings related. 26 | } 27 | -------------------------------------------------------------------------------- /src/plugins/internal/InternalPlugin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "QvPlugin/PluginInterface.hpp" 3 | 4 | #ifndef QT_STATICPLUGIN 5 | #define QT_STATICPLUGIN 6 | #endif 7 | 8 | #include 9 | 10 | class Qv2rayInternalPlugin 11 | : public QObject 12 | , public Qv2rayPlugin::Qv2rayInterface 13 | { 14 | Q_OBJECT 15 | QV2RAY_PLUGIN(Qv2rayInternalPlugin) 16 | 17 | public: 18 | virtual const Qv2rayPlugin::QvPluginMetadata GetMetadata() const override; 19 | virtual bool InitializePlugin() override; 20 | virtual void SettingsUpdated() override; 21 | }; 22 | -------------------------------------------------------------------------------- /src/plugins/internal/InternalProfilePreprocessor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "QvPlugin/Handlers/IProfilePreprocessor.hpp" 3 | 4 | class InternalProfilePreprocessor : public Qv2rayPlugin::Profile::IProfilePreprocessor 5 | { 6 | public: 7 | virtual ~InternalProfilePreprocessor() = default; 8 | virtual ProfileContent PreprocessProfile(const ProfileContent &) override; 9 | }; 10 | -------------------------------------------------------------------------------- /src/plugins/protocols/BuiltinProtocolPlugin.cpp: -------------------------------------------------------------------------------- 1 | #include "BuiltinProtocolPlugin.hpp" 2 | 3 | #include "core/OutboundHandler.hpp" 4 | #include "ui/Interface.hpp" 5 | 6 | bool InternalProtocolSupportPlugin::InitializePlugin() 7 | { 8 | m_OutboundHandler = std::make_shared(); 9 | m_GUIInterface = new ProtocolGUIInterface(); 10 | return true; 11 | } 12 | -------------------------------------------------------------------------------- /src/plugins/protocols/BuiltinProtocolPlugin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/PluginInterface.hpp" 4 | 5 | #include 6 | #include 7 | 8 | using namespace Qv2rayPlugin; 9 | 10 | class InternalProtocolSupportPlugin 11 | : public QObject 12 | , public Qv2rayInterface 13 | { 14 | Q_OBJECT 15 | QV2RAY_PLUGIN(InternalProtocolSupportPlugin) 16 | 17 | public: 18 | // 19 | // Basic metainfo of this plugin 20 | const QvPluginMetadata GetMetadata() const override 21 | { 22 | return { 23 | "Builtin Protocol Support", 24 | "Qv2ray Core Workgroup", 25 | PluginId("qv2ray_builtin_protocol"), 26 | "VMess, SOCKS, HTTP, Shadowsocks, DNS, Dokodemo-door editor support", 27 | QUrl{ "Qv2ray Repository" }, 28 | { 29 | COMPONENT_OUTBOUND_HANDLER, 30 | COMPONENT_GUI, 31 | }, 32 | }; 33 | } 34 | 35 | bool InitializePlugin() override; 36 | void SettingsUpdated() override{}; 37 | }; 38 | -------------------------------------------------------------------------------- /src/plugins/protocols/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROTOCOL_PLUGIN_TARGET QvPlugin-BuiltinProtocolSupport) 2 | 3 | macro(ADD_SOURCE mode name) 4 | list(APPEND PLUGIN_UI_SOURCE "${CMAKE_CURRENT_LIST_DIR}/ui/${mode}/${name}.ui") 5 | list(APPEND PLUGIN_UI_SOURCE "${CMAKE_CURRENT_LIST_DIR}/ui/${mode}/${name}.cpp") 6 | list(APPEND PLUGIN_UI_SOURCE "${CMAKE_CURRENT_LIST_DIR}/ui/${mode}/${name}.hpp") 7 | endmacro() 8 | 9 | ADD_SOURCE(outbound blackhole) 10 | ADD_SOURCE(outbound dns) 11 | ADD_SOURCE(outbound freedom) 12 | ADD_SOURCE(outbound httpout) 13 | ADD_SOURCE(outbound socksout) 14 | ADD_SOURCE(outbound shadowsocks) 15 | ADD_SOURCE(outbound vmess) 16 | ADD_SOURCE(outbound loopback) 17 | ADD_SOURCE(outbound trojan) 18 | 19 | ADD_SOURCE(inbound dokodemo-door) 20 | ADD_SOURCE(inbound httpin) 21 | ADD_SOURCE(inbound socksin) 22 | 23 | qv2ray_add_plugin(${PROTOCOL_PLUGIN_TARGET} Widgets 24 | INSTALL_PREFIX_MACOS "${CMAKE_INSTALL_PREFIX}/qv2ray.app/Contents/Resources/plugins" 25 | CLASS_NAME "InternalProtocolSupportPlugin") 26 | 27 | target_sources(${PROTOCOL_PLUGIN_TARGET} PRIVATE 28 | ${PLUGIN_UI_SOURCE} 29 | ${CMAKE_CURRENT_LIST_DIR}/resx.qrc 30 | ${CMAKE_CURRENT_LIST_DIR}/BuiltinProtocolPlugin.hpp 31 | ${CMAKE_CURRENT_LIST_DIR}/BuiltinProtocolPlugin.cpp 32 | ${CMAKE_CURRENT_LIST_DIR}/core/OutboundHandler.cpp 33 | ${CMAKE_CURRENT_LIST_DIR}/core/OutboundHandler.hpp 34 | ${CMAKE_CURRENT_LIST_DIR}/ui/Interface.hpp 35 | ${CMAKE_CURRENT_LIST_DIR}/ui/PluginSettingsWidget.cpp 36 | ${CMAKE_CURRENT_LIST_DIR}/ui/PluginSettingsWidget.hpp 37 | ${CMAKE_CURRENT_LIST_DIR}/ui/PluginSettingsWidget.ui 38 | ) 39 | 40 | target_include_directories(${PROTOCOL_PLUGIN_TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../PluginsCommon) 41 | -------------------------------------------------------------------------------- /src/plugins/protocols/assets/qv2ray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/src/plugins/protocols/assets/qv2ray.png -------------------------------------------------------------------------------- /src/plugins/protocols/core/OutboundHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Handlers/OutboundHandler.hpp" 4 | 5 | class BuiltinSerializer : public Qv2rayPlugin::Outbound::IOutboundProcessor 6 | { 7 | public: 8 | explicit BuiltinSerializer() : Qv2rayPlugin::Outbound::IOutboundProcessor(){}; 9 | 10 | virtual std::optional Serialize(const QString &name, const IOConnectionSettings &outbound) const override; 11 | virtual std::optional> Deserialize(const QString &link) const override; 12 | 13 | virtual std::optional GetOutboundInfo(const IOConnectionSettings &) const override; 14 | virtual bool SetOutboundInfo(IOConnectionSettings &, const PluginIOBoundData &) const override; 15 | 16 | QList SupportedLinkPrefixes() const override 17 | { 18 | return { "http", "socks", "vmess", "ss", "trojan" }; 19 | } 20 | 21 | QList SupportedProtocols() const override 22 | { 23 | return { "http", "socks", "shadowsocks", "vmess", "trojan" }; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /src/plugins/protocols/resx.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | assets/qv2ray.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/PluginSettingsWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginSettingsWidget.hpp" 2 | 3 | SimplePluginSettingsWidget::SimplePluginSettingsWidget(QWidget *parent) : Qv2rayPlugin::Gui::PluginSettingsWidget(parent) 4 | { 5 | setupUi(this); 6 | } 7 | 8 | void SimplePluginSettingsWidget::Load() 9 | { 10 | } 11 | 12 | void SimplePluginSettingsWidget::Store() 13 | { 14 | } 15 | 16 | void SimplePluginSettingsWidget::changeEvent(QEvent *e) 17 | { 18 | QWidget::changeEvent(e); 19 | switch (e->type()) 20 | { 21 | case QEvent::LanguageChange: retranslateUi(this); break; 22 | default: break; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/PluginSettingsWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_PluginSettingsWidget.h" 5 | class SimplePluginSettingsWidget 6 | : public Qv2rayPlugin::Gui::PluginSettingsWidget 7 | , private Ui::PluginSettingsWidget 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | explicit SimplePluginSettingsWidget(QWidget *parent = nullptr); 13 | 14 | virtual void Load() override; 15 | virtual void Store() override; 16 | 17 | protected: 18 | void changeEvent(QEvent *e) override; 19 | }; 20 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/PluginSettingsWidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | PluginSettingsWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/dokodemo-door.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_dokodemo-door.h" 5 | 6 | class DokodemoDoorInboundEditor 7 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 8 | , private Ui::dokodemodoorInEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit DokodemoDoorInboundEditor(QWidget *parent = nullptr); 14 | 15 | virtual void Load() override; 16 | virtual void Store() override; 17 | 18 | protected: 19 | void changeEvent(QEvent *e) override; 20 | 21 | private slots: 22 | void on_dokoFollowRedirectCB_stateChanged(int arg1); 23 | void on_dokoIPAddrTxt_textEdited(const QString &arg1); 24 | void on_dokoPortSB_valueChanged(int arg1); 25 | void on_dokoTCPCB_stateChanged(int arg1); 26 | void on_dokoUDPCB_stateChanged(int arg1); 27 | void on_dokoTimeoutSB_valueChanged(int arg1); 28 | 29 | private: 30 | bool isLoading = false; 31 | }; 32 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/httpin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_httpin.h" 5 | 6 | #include 7 | 8 | class HTTPInboundEditor 9 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 10 | , private Ui::httpInEditor 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit HTTPInboundEditor(QWidget *parent = nullptr); 16 | 17 | virtual void Load() override; 18 | virtual void Store() override; 19 | 20 | protected: 21 | void changeEvent(QEvent *e) override; 22 | 23 | private slots: 24 | void on_httpTimeoutSpinBox_valueChanged(int arg1); 25 | void on_httpTransparentCB_stateChanged(int arg1); 26 | void on_httpRemoveUserBtn_clicked(); 27 | void on_httpAddUserBtn_clicked(); 28 | 29 | private: 30 | bool isLoading = false; 31 | }; 32 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/shadowsocks.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginInboundEditor.hpp" 2 | 3 | SimplePluginInboundEditor::SimplePluginInboundEditor(QWidget *parent) : Qv2rayPlugin::QvPluginEditor(parent) 4 | { 5 | setupUi(this); 6 | } 7 | 8 | void SimplePluginInboundEditor::changeEvent(QEvent *e) 9 | { 10 | QWidget::changeEvent(e); 11 | switch (e->type()) 12 | { 13 | case QEvent::LanguageChange: retranslateUi(this); break; 14 | default: break; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/shadowsocks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvGUIPluginInterface.hpp" 4 | #include "ui_PluginInboundEditor.h" 5 | 6 | class SimplePluginInboundEditor 7 | : public Qv2rayPlugin::QvPluginEditor 8 | , private Ui::PluginInboundEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit SimplePluginInboundEditor(QWidget *parent = nullptr); 14 | 15 | void SetHostAddress(const QString &, int) override{}; 16 | QPair GetHostAddress() const override 17 | { 18 | return {}; 19 | }; 20 | 21 | void SetContent(const QJsonObject &content) override 22 | { 23 | this->content = content; 24 | }; 25 | const QJsonObject GetContent() const override 26 | { 27 | return content; 28 | }; 29 | 30 | protected: 31 | void changeEvent(QEvent *e) override; 32 | }; 33 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/shadowsocks.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | PluginInboundEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/socksin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_socksin.h" 5 | 6 | #include 7 | 8 | class SocksInboundEditor 9 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 10 | , private Ui::socksInEditor 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit SocksInboundEditor(QWidget *parent = nullptr); 16 | 17 | void Load() override; 18 | void Store() override{}; 19 | 20 | private slots: 21 | void on_socksUDPCB_stateChanged(int arg1); 22 | void on_socksUDPIPAddrTxt_textEdited(const QString &arg1); 23 | void on_socksRemoveUserBtn_clicked(); 24 | void on_socksAddUserBtn_clicked(); 25 | void on_socksAuthCombo_currentIndexChanged(int arg1); 26 | 27 | protected: 28 | void changeEvent(QEvent *e) override; 29 | 30 | private: 31 | bool isLoading = false; 32 | }; 33 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/vless.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginInboundEditor.hpp" 2 | 3 | SimplePluginInboundEditor::SimplePluginInboundEditor(QWidget *parent) : Qv2rayPlugin::QvPluginEditor(parent) 4 | { 5 | setupUi(this); 6 | } 7 | 8 | void SimplePluginInboundEditor::changeEvent(QEvent *e) 9 | { 10 | QWidget::changeEvent(e); 11 | switch (e->type()) 12 | { 13 | case QEvent::LanguageChange: retranslateUi(this); break; 14 | default: break; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/vless.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvGUIPluginInterface.hpp" 4 | #include "ui_PluginInboundEditor.h" 5 | 6 | class SimplePluginInboundEditor 7 | : public Qv2rayPlugin::QvPluginEditor 8 | , private Ui::PluginInboundEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit SimplePluginInboundEditor(QWidget *parent = nullptr); 14 | 15 | void SetHostAddress(const QString &, int) override{}; 16 | QPair GetHostAddress() const override 17 | { 18 | return {}; 19 | }; 20 | 21 | void SetContent(const QJsonObject &content) override 22 | { 23 | this->content = content; 24 | }; 25 | const QJsonObject GetContent() const override 26 | { 27 | return content; 28 | }; 29 | 30 | protected: 31 | void changeEvent(QEvent *e) override; 32 | }; 33 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/vless.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | PluginInboundEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/vmess.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginInboundEditor.hpp" 2 | 3 | SimplePluginInboundEditor::SimplePluginInboundEditor(QWidget *parent) : Qv2rayPlugin::QvPluginEditor(parent) 4 | { 5 | setupUi(this); 6 | } 7 | 8 | void SimplePluginInboundEditor::changeEvent(QEvent *e) 9 | { 10 | QWidget::changeEvent(e); 11 | switch (e->type()) 12 | { 13 | case QEvent::LanguageChange: retranslateUi(this); break; 14 | default: break; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/vmess.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvGUIPluginInterface.hpp" 4 | #include "ui_PluginInboundEditor.h" 5 | 6 | class SimplePluginInboundEditor 7 | : public Qv2rayPlugin::QvPluginEditor 8 | , private Ui::PluginInboundEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit SimplePluginInboundEditor(QWidget *parent = nullptr); 14 | 15 | void SetHostAddress(const QString &, int) override{}; 16 | QPair GetHostAddress() const override 17 | { 18 | return {}; 19 | }; 20 | 21 | void SetContent(const QJsonObject &content) override 22 | { 23 | this->content = content; 24 | }; 25 | const QJsonObject GetContent() const override 26 | { 27 | return content; 28 | }; 29 | 30 | protected: 31 | void changeEvent(QEvent *e) override; 32 | }; 33 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/inbound/vmess.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | PluginInboundEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/blackhole.cpp: -------------------------------------------------------------------------------- 1 | #include "blackhole.hpp" 2 | 3 | BlackholeOutboundEditor::BlackholeOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", false); 7 | } 8 | 9 | void BlackholeOutboundEditor::changeEvent(QEvent *e) 10 | { 11 | QWidget::changeEvent(e); 12 | switch (e->type()) 13 | { 14 | case QEvent::LanguageChange: retranslateUi(this); break; 15 | default: break; 16 | } 17 | } 18 | 19 | void BlackholeOutboundEditor::Load() 20 | { 21 | isLoading = true; 22 | if (settings.contains("response") && settings["response"].toObject().contains("type")) 23 | responseTypeCB->setCurrentText(settings["response"].toObject()["type"].toString()); 24 | isLoading = false; 25 | } 26 | 27 | void BlackholeOutboundEditor::Store() 28 | { 29 | } 30 | 31 | void BlackholeOutboundEditor::on_responseTypeCB_currentTextChanged(const QString &arg1) 32 | { 33 | if (isLoading) 34 | return; 35 | settings = IOProtocolSettings{ QJsonObject{ { "response", QJsonObject{ { "type", arg1 } } } } }; 36 | } 37 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/blackhole.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_blackhole.h" 5 | 6 | class BlackholeOutboundEditor 7 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 8 | , private Ui::blackholeOutEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit BlackholeOutboundEditor(QWidget *parent = nullptr); 14 | 15 | virtual void Load() override; 16 | virtual void Store() override; 17 | 18 | protected: 19 | void changeEvent(QEvent *e) override; 20 | 21 | private slots: 22 | void on_responseTypeCB_currentTextChanged(const QString &arg1); 23 | 24 | private: 25 | bool isLoading = false; 26 | }; 27 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/blackhole.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | blackholeOutEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Response 21 | 22 | 23 | 24 | 25 | 26 | Type 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | none 35 | 36 | 37 | 38 | 39 | http 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/dns.cpp: -------------------------------------------------------------------------------- 1 | #include "dns.hpp" 2 | 3 | DnsOutboundEditor::DnsOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", false); 7 | } 8 | 9 | void DnsOutboundEditor::Load() 10 | { 11 | isLoading = true; 12 | if (settings.contains("network")) 13 | { 14 | tcpCB->setChecked(settings["network"] == "tcp"); 15 | udpCB->setChecked(settings["network"] == "udp"); 16 | } 17 | else 18 | { 19 | originalCB->setChecked(true); 20 | } 21 | if (settings.contains("address")) 22 | addressTxt->setText(settings["address"].toString()); 23 | if (settings.contains("port")) 24 | portSB->setValue(settings["port"].toInt()); 25 | isLoading = false; 26 | } 27 | 28 | void DnsOutboundEditor::Store() 29 | { 30 | } 31 | 32 | void DnsOutboundEditor::changeEvent(QEvent *e) 33 | { 34 | QWidget::changeEvent(e); 35 | switch (e->type()) 36 | { 37 | case QEvent::LanguageChange: retranslateUi(this); break; 38 | default: break; 39 | } 40 | } 41 | 42 | void DnsOutboundEditor::on_tcpCB_clicked() 43 | { 44 | settings["network"] = "tcp"; 45 | } 46 | 47 | void DnsOutboundEditor::on_udpCB_clicked() 48 | { 49 | settings["network"] = "udp"; 50 | } 51 | 52 | void DnsOutboundEditor::on_originalCB_clicked() 53 | { 54 | settings.remove("network"); 55 | } 56 | 57 | void DnsOutboundEditor::on_addressTxt_textEdited(const QString &arg1) 58 | { 59 | if (arg1.isEmpty()) 60 | settings.remove("network"); 61 | else 62 | settings["network"] = arg1; 63 | } 64 | 65 | void DnsOutboundEditor::on_portSB_valueChanged(int arg1) 66 | { 67 | if (arg1 < 0) 68 | settings.remove("port"); 69 | else 70 | settings["port"] = arg1; 71 | } 72 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/dns.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_dns.h" 5 | 6 | class DnsOutboundEditor 7 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 8 | , private Ui::dnsOutEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit DnsOutboundEditor(QWidget *parent = nullptr); 14 | 15 | virtual void Load() override; 16 | virtual void Store() override; 17 | 18 | protected: 19 | void changeEvent(QEvent *e) override; 20 | 21 | private slots: 22 | void on_tcpCB_clicked(); 23 | void on_udpCB_clicked(); 24 | void on_originalCB_clicked(); 25 | void on_addressTxt_textEdited(const QString &arg1); 26 | void on_portSB_valueChanged(int arg1); 27 | 28 | private: 29 | bool isLoading = false; 30 | }; 31 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/freedom.cpp: -------------------------------------------------------------------------------- 1 | #include "freedom.hpp" 2 | 3 | FreedomOutboundEditor::FreedomOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | // Should freedom outbound use StreamSettings? 7 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", false); 8 | } 9 | 10 | void FreedomOutboundEditor::changeEvent(QEvent *e) 11 | { 12 | QWidget::changeEvent(e); 13 | switch (e->type()) 14 | { 15 | case QEvent::LanguageChange: retranslateUi(this); break; 16 | default: break; 17 | } 18 | } 19 | 20 | void FreedomOutboundEditor::on_DSCB_currentTextChanged(const QString &arg1) 21 | { 22 | settings["domainStrategy"] = arg1; 23 | } 24 | 25 | void FreedomOutboundEditor::on_redirectTxt_textEdited(const QString &arg1) 26 | { 27 | settings["redirect"] = arg1; 28 | } 29 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/freedom.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_freedom.h" 5 | 6 | class FreedomOutboundEditor 7 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 8 | , private Ui::freedomOutEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit FreedomOutboundEditor(QWidget *parent = nullptr); 14 | 15 | void Load() override 16 | { 17 | isLoading = true; 18 | DSCB->setCurrentText(settings["domainStrategy"].toString()); 19 | redirectTxt->setText(settings["redirect"].toString()); 20 | isLoading = false; 21 | }; 22 | void Store() override{}; 23 | 24 | protected: 25 | void changeEvent(QEvent *e) override; 26 | 27 | private slots: 28 | void on_DSCB_currentTextChanged(const QString &arg1); 29 | void on_redirectTxt_textEdited(const QString &arg1); 30 | 31 | private: 32 | bool isLoading = false; 33 | }; 34 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/freedom.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | freedomOutEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 257 10 | 134 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Domain Strategy 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | AsIs 29 | 30 | 31 | 32 | 33 | UseIP 34 | 35 | 36 | 37 | 38 | UseIPv4 39 | 40 | 41 | 42 | 43 | UseIPv6 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Redirect 52 | 53 | 54 | 55 | 56 | 57 | 58 | :0 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/httpout.cpp: -------------------------------------------------------------------------------- 1 | #include "httpout.hpp" 2 | 3 | HttpOutboundEditor::HttpOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", true); 7 | } 8 | 9 | void HttpOutboundEditor::changeEvent(QEvent *e) 10 | { 11 | QWidget::changeEvent(e); 12 | switch (e->type()) 13 | { 14 | case QEvent::LanguageChange: retranslateUi(this); break; 15 | default: break; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/httpout.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "V2RayModels.hpp" 5 | #include "ui_httpout.h" 6 | 7 | class HttpOutboundEditor 8 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 9 | , private Ui::httpOutEditor 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit HttpOutboundEditor(QWidget *parent = nullptr); 15 | 16 | void Load() override 17 | { 18 | http.loadJson(settings); 19 | http.user.ReadWriteBind(http_UserNameTxt, "text", &QLineEdit::textEdited); 20 | http.pass.ReadWriteBind(http_PasswordTxt, "text", &QLineEdit::textEdited); 21 | } 22 | 23 | void Store() override 24 | { 25 | settings = IOProtocolSettings{ http.toJson() }; 26 | } 27 | 28 | protected: 29 | void changeEvent(QEvent *e) override; 30 | 31 | private: 32 | Qv2ray::Models::HTTPSOCKSObject http; 33 | }; 34 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/httpout.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | httpOutEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 299 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Username 21 | 22 | 23 | 24 | 25 | 26 | 27 | Username 28 | 29 | 30 | 31 | 32 | 33 | 34 | Password 35 | 36 | 37 | 38 | 39 | 40 | 41 | p@ssw0rd 42 | 43 | 44 | 45 | 46 | 47 | 48 | Qt::Vertical 49 | 50 | 51 | 52 | 20 53 | 217 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/loopback.cpp: -------------------------------------------------------------------------------- 1 | #include "loopback.hpp" 2 | 3 | LoopbackSettingsEditor::LoopbackSettingsEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | } 7 | 8 | void LoopbackSettingsEditor::changeEvent(QEvent *e) 9 | { 10 | QWidget::changeEvent(e); 11 | switch (e->type()) 12 | { 13 | case QEvent::LanguageChange: retranslateUi(this); break; 14 | default: break; 15 | } 16 | } 17 | 18 | void LoopbackSettingsEditor::on_inboundTagTxt_textEdited(const QString &arg1) 19 | { 20 | settings["inboundTag"] = arg1; 21 | } 22 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/loopback.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_loopback.h" 5 | 6 | class LoopbackSettingsEditor 7 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 8 | , private Ui::loopback 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit LoopbackSettingsEditor(QWidget *parent = nullptr); 14 | 15 | void Load() override 16 | { 17 | inboundTagTxt->setText(settings["inboundTag"].toString()); 18 | } 19 | 20 | void Store() override 21 | { 22 | } 23 | 24 | protected: 25 | void changeEvent(QEvent *e) override; 26 | 27 | private slots: 28 | void on_inboundTagTxt_textEdited(const QString &arg1); 29 | }; 30 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/loopback.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | loopback 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Inbound Tag 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/mtproto.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginOutboundEditor.hpp" 2 | 3 | SimplePluginOutboundEditor::SimplePluginOutboundEditor(QWidget *parent) : Qv2rayPlugin::QvPluginEditor(parent) 4 | { 5 | setupUi(this); 6 | } 7 | 8 | void SimplePluginOutboundEditor::changeEvent(QEvent *e) 9 | { 10 | QWidget::changeEvent(e); 11 | switch (e->type()) 12 | { 13 | case QEvent::LanguageChange: retranslateUi(this); break; 14 | default: break; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/mtproto.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvGUIPluginInterface.hpp" 4 | #include "ui_PluginOutboundEditor.h" 5 | 6 | class SimplePluginOutboundEditor 7 | : public Qv2rayPlugin::QvPluginEditor 8 | , private Ui::PluginOutboundEditor 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit SimplePluginOutboundEditor(QWidget *parent = nullptr); 14 | 15 | void SetHostAddress(const QString &, int) override{}; 16 | QPair GetHostAddress() const override 17 | { 18 | return {}; 19 | }; 20 | 21 | void SetContent(const QJsonObject &content) override 22 | { 23 | this->content = content; 24 | }; 25 | const QJsonObject GetContent() const override 26 | { 27 | return content; 28 | }; 29 | 30 | protected: 31 | void changeEvent(QEvent *e) override; 32 | }; 33 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/mtproto.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PluginOutboundEditor 6 | 7 | 8 | 9 | 0 10 | 0 11 | 400 12 | 300 13 | 14 | 15 | 16 | Form 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/shadowsocks.cpp: -------------------------------------------------------------------------------- 1 | #include "shadowsocks.hpp" 2 | 3 | ShadowsocksOutboundEditor::ShadowsocksOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", true); 7 | shadowsocks.method.ReadWriteBind(ss_encryptionMethod, "currentText", &QComboBox::currentTextChanged); 8 | shadowsocks.password.ReadWriteBind(ss_passwordTxt, "text", &QLineEdit::textEdited); 9 | } 10 | 11 | void ShadowsocksOutboundEditor::changeEvent(QEvent *e) 12 | { 13 | QWidget::changeEvent(e); 14 | switch (e->type()) 15 | { 16 | case QEvent::LanguageChange: retranslateUi(this); break; 17 | default: break; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/shadowsocks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "V2RayModels.hpp" 5 | #include "ui_shadowsocks.h" 6 | 7 | class ShadowsocksOutboundEditor 8 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 9 | , private Ui::shadowsocksOutEditor 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit ShadowsocksOutboundEditor(QWidget *parent = nullptr); 15 | 16 | void Load() override 17 | { 18 | shadowsocks.loadJson(settings); 19 | } 20 | 21 | void Store() override 22 | { 23 | settings = IOProtocolSettings{ shadowsocks.toJson() }; 24 | } 25 | 26 | protected: 27 | void changeEvent(QEvent *e) override; 28 | 29 | private: 30 | Qv2ray::Models::ShadowSocksClientObject shadowsocks; 31 | }; 32 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/socksout.cpp: -------------------------------------------------------------------------------- 1 | #include "socksout.hpp" 2 | 3 | SocksOutboundEditor::SocksOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", true); 7 | } 8 | 9 | void SocksOutboundEditor::changeEvent(QEvent *e) 10 | { 11 | QWidget::changeEvent(e); 12 | switch (e->type()) 13 | { 14 | case QEvent::LanguageChange: retranslateUi(this); break; 15 | default: break; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/socksout.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "V2RayModels.hpp" 5 | #include "ui_socksout.h" 6 | 7 | class SocksOutboundEditor 8 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 9 | , private Ui::socksOutEditor 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit SocksOutboundEditor(QWidget *parent = nullptr); 15 | 16 | virtual void Load() override 17 | { 18 | socks.loadJson(settings); 19 | socks.user.ReadWriteBind(socks_UserNameTxt, "text", &QLineEdit::textEdited); 20 | socks.pass.ReadWriteBind(socks_PasswordTxt, "text", &QLineEdit::textEdited); 21 | } 22 | 23 | virtual void Store() override 24 | { 25 | settings = IOProtocolSettings{ socks.toJson() }; 26 | } 27 | 28 | protected: 29 | void changeEvent(QEvent *e) override; 30 | 31 | private: 32 | Qv2ray::Models::HTTPSOCKSObject socks; 33 | }; 34 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/socksout.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | socksOutEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 226 10 | 169 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Username 21 | 22 | 23 | 24 | 25 | 26 | 27 | Username 28 | 29 | 30 | 31 | 32 | 33 | 34 | Password 35 | 36 | 37 | 38 | 39 | 40 | 41 | p@ssw0rd 42 | 43 | 44 | 45 | 46 | 47 | 48 | Qt::Vertical 49 | 50 | 51 | 52 | 20 53 | 86 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/trojan.cpp: -------------------------------------------------------------------------------- 1 | #include "trojan.hpp" 2 | 3 | TrojanOutboundEditor::TrojanOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 4 | { 5 | setupUi(this); 6 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", true); 7 | trojan.password.ReadWriteBind(passwdTxt, "text", &QLineEdit::textEdited); 8 | } 9 | 10 | void TrojanOutboundEditor::changeEvent(QEvent *e) 11 | { 12 | QWidget::changeEvent(e); 13 | switch (e->type()) 14 | { 15 | case QEvent::LanguageChange: retranslateUi(this); break; 16 | default: break; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/trojan.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "V2RayModels.hpp" 5 | #include "ui_trojan.h" 6 | 7 | class TrojanOutboundEditor 8 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 9 | , private Ui::TrojanOutEditor 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit TrojanOutboundEditor(QWidget *parent = nullptr); 15 | 16 | protected: 17 | void changeEvent(QEvent *e) override; 18 | virtual void Load() override 19 | { 20 | trojan.loadJson(settings); 21 | } 22 | void Store() override 23 | { 24 | settings = IOProtocolSettings{ trojan.toJson() }; 25 | } 26 | 27 | private: 28 | Qv2ray::Models::TrojanClientObject trojan; 29 | }; 30 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/trojan.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TrojanOutEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Password 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/vmess.cpp: -------------------------------------------------------------------------------- 1 | #include "vmess.hpp" 2 | 3 | #include "BuiltinProtocolPlugin.hpp" 4 | 5 | VmessOutboundEditor::VmessOutboundEditor(QWidget *parent) : Qv2rayPlugin::Gui::PluginProtocolEditor(parent) 6 | { 7 | setupUi(this); 8 | setProperty("QV2RAY_INTERNAL_HAS_STREAMSETTINGS", true); 9 | } 10 | 11 | void VmessOutboundEditor::changeEvent(QEvent *e) 12 | { 13 | QWidget::changeEvent(e); 14 | switch (e->type()) 15 | { 16 | case QEvent::LanguageChange: retranslateUi(this); break; 17 | default: break; 18 | } 19 | } 20 | 21 | void VmessOutboundEditor::Load() 22 | { 23 | vmess.loadJson(settings); 24 | 25 | vmess.security.ReadWriteBind(securityCombo, "currentText", &QComboBox::currentIndexChanged); 26 | vmess.id.ReadWriteBind(idLineEdit, "text", &QLineEdit::textEdited); 27 | vmess.experiments.ReadWriteBind(experimentsTxt, "text", &QLineEdit::textEdited); 28 | } 29 | -------------------------------------------------------------------------------- /src/plugins/protocols/ui/outbound/vmess.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "V2RayModels.hpp" 5 | #include "ui_vmess.h" 6 | 7 | class VmessOutboundEditor 8 | : public Qv2rayPlugin::Gui::PluginProtocolEditor 9 | , private Ui::vmessOutEditor 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit VmessOutboundEditor(QWidget *parent = nullptr); 15 | 16 | void Load() override; 17 | void Store() override 18 | { 19 | settings = IOProtocolSettings{ vmess.toJson() }; 20 | } 21 | 22 | private: 23 | Qv2ray::Models::VMessClientObject vmess; 24 | 25 | protected: 26 | void changeEvent(QEvent *e) override; 27 | }; 28 | -------------------------------------------------------------------------------- /src/plugins/routingA/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 2 | 3 | qv2ray_add_plugin(QvPlugin-RoutingAEditor Widgets 4 | INSTALL_PREFIX_MACOS "${CMAKE_INSTALL_PREFIX}/qv2ray.app/Contents/Resources/plugins" 5 | CLASS_NAME "RoutingAPlugin" 6 | DEV_INTERFACE) 7 | 8 | target_sources(QvPlugin-RoutingAEditor PRIVATE 9 | ${CMAKE_CURRENT_LIST_DIR}/RoutingAPlugin.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/RoutingAPlugin.hpp 11 | ${CMAKE_CURRENT_LIST_DIR}/RoutingA_GuiInterface.hpp 12 | ${CMAKE_CURRENT_LIST_DIR}/core/libRoutingA-ActionTable.cpp 13 | ${CMAKE_CURRENT_LIST_DIR}/core/libRoutingA.cpp 14 | ${CMAKE_CURRENT_LIST_DIR}/core/libRoutingA.hpp 15 | ${CMAKE_CURRENT_LIST_DIR}/common/RoutingAConverter.cpp 16 | ${CMAKE_CURRENT_LIST_DIR}/common/RoutingAConverter.hpp 17 | ${CMAKE_CURRENT_LIST_DIR}/ui/RoutingAEditor.cpp 18 | ${CMAKE_CURRENT_LIST_DIR}/ui/RoutingAEditor.ui 19 | ${CMAKE_CURRENT_LIST_DIR}/ui/RoutingAEditor.hpp 20 | ) 21 | 22 | target_include_directories(QvPlugin-RoutingAEditor PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../PluginsCommon) 23 | -------------------------------------------------------------------------------- /src/plugins/routingA/RoutingAPlugin.cpp: -------------------------------------------------------------------------------- 1 | #include "RoutingAPlugin.hpp" 2 | 3 | #include "RoutingA_GuiInterface.hpp" 4 | 5 | bool RoutingAPlugin::InitializePlugin() 6 | { 7 | m_GUIInterface = new RoutingAGuiInterface; 8 | return true; 9 | } 10 | 11 | void RoutingAPlugin::SettingsUpdated() 12 | { 13 | } 14 | -------------------------------------------------------------------------------- /src/plugins/routingA/RoutingAPlugin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/PluginInterface.hpp" 4 | 5 | #include 6 | 7 | using namespace Qv2rayPlugin; 8 | 9 | class RoutingAPlugin 10 | : public QObject 11 | , public Qv2rayInterface 12 | { 13 | Q_OBJECT 14 | QV2RAY_PLUGIN(RoutingAPlugin) 15 | 16 | public: 17 | const QvPluginMetadata GetMetadata() const override 18 | { 19 | return { 20 | "RoutingA Editor Plugin", 21 | "Moody", 22 | PluginId("RoutingA_Plugin"), 23 | "Allowing edit complex configurations in RoutingA syntax.", 24 | QUrl{}, 25 | { 26 | COMPONENT_GUI, 27 | }, 28 | }; 29 | } 30 | 31 | bool InitializePlugin() override; 32 | void SettingsUpdated() override; 33 | }; 34 | -------------------------------------------------------------------------------- /src/plugins/routingA/RoutingA_GuiInterface.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui/RoutingAEditor.hpp" 5 | 6 | class RoutingAGuiInterface : public Qv2rayPlugin::Gui::Qv2rayGUIInterface 7 | { 8 | public: 9 | virtual QIcon Icon() const override 10 | { 11 | return {}; 12 | } 13 | virtual QList GetComponents() const override 14 | { 15 | return { Qv2rayPlugin::GUI_COMPONENT_MAIN_WINDOW_ACTIONS }; 16 | } 17 | virtual std::unique_ptr GetSettingsWidget() const override 18 | { 19 | return nullptr; 20 | } 21 | virtual PluginEditorDescriptor GetInboundEditors() const override 22 | { 23 | return {}; 24 | } 25 | virtual PluginEditorDescriptor GetOutboundEditors() const override 26 | { 27 | return {}; 28 | } 29 | virtual std::unique_ptr GetMainWindowWidget() const override 30 | { 31 | return std::make_unique(); 32 | } 33 | virtual QList GetTrayMenus() const override 34 | { 35 | return {}; 36 | } 37 | virtual ProfileEditorDescriptor GetProfileEditors() const override 38 | { 39 | return {}; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /src/plugins/routingA/common/RoutingAConverter.cpp: -------------------------------------------------------------------------------- 1 | #include "RoutingAConverter.hpp" 2 | 3 | namespace RoutingA::Converter 4 | { 5 | QPair, QList> FromRADefines(const QList &defines) 6 | { 7 | QList inbounds; 8 | QList outbounds; 9 | 10 | QString defaultOutbound; 11 | 12 | for (const auto &def : defines) 13 | { 14 | if (def.type == u"inbound"_qs) 15 | { 16 | const auto indef = def.content; 17 | InboundObject in; 18 | in.name = indef.name; 19 | in.inboundSettings.protocol = indef.function.name; 20 | 21 | // Only the first value is supported. 22 | for (const auto &[key, val] : indef.function.namedParams.toStdMap()) 23 | if (!val.isEmpty()) 24 | in.inboundSettings.protocolSettings.insert(key, val.first()); 25 | } 26 | else if (def.type == u"outbound"_qs) 27 | { 28 | const auto outdef = def.content; 29 | } 30 | else if (def.type == u"default"_qs) 31 | defaultOutbound = def.value; 32 | else 33 | throw ParsingErrorException(u"Unexpected defination: "_qs + def.type, 0, {}); 34 | } 35 | 36 | return { inbounds, outbounds }; 37 | } 38 | 39 | QList FromRARouting(const QList &) 40 | { 41 | QList rules; 42 | 43 | return rules; 44 | } 45 | 46 | QString ToRoutingA(const QList &, const QList &, const QList &) 47 | { 48 | return {}; 49 | } 50 | 51 | } // namespace RoutingA::Converter 52 | -------------------------------------------------------------------------------- /src/plugins/routingA/common/RoutingAConverter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Common/CommonTypes.hpp" 4 | #include "core/libRoutingA.hpp" 5 | 6 | namespace RoutingA::Converter 7 | { 8 | QPair, QList> FromRADefines(const QList &); 9 | QList FromRARouting(const QList &); 10 | 11 | QString ToRoutingA(const QList &, const QList &, const QList &); 12 | } // namespace RoutingA::Converter 13 | -------------------------------------------------------------------------------- /src/plugins/routingA/ui/RoutingAEditor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "ui_RoutingAEditor.h" 5 | 6 | #include 7 | #include 8 | 9 | class RoutingAHighlighter : public QSyntaxHighlighter 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit RoutingAHighlighter(QTextDocument *parent = nullptr); 15 | 16 | protected: 17 | void highlightBlock(const QString &text) override; 18 | 19 | private: 20 | struct HighlightingRule 21 | { 22 | QRegularExpression pattern; 23 | QTextCharFormat format; 24 | }; 25 | QList highlightingRules; 26 | 27 | QTextCharFormat keywordsFormat; 28 | QTextCharFormat builtinTagFormat; 29 | QTextCharFormat geoIPSiteFormat; 30 | QTextCharFormat commentFormat; 31 | QTextCharFormat literalFormat; 32 | QTextCharFormat quotedFormat; 33 | }; 34 | 35 | class RoutingAEditor 36 | : public Qv2rayPlugin::Gui::PluginMainWindowWidget 37 | , private Ui::RoutingAEditor 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | explicit RoutingAEditor(QWidget *parent = nullptr); 43 | 44 | protected: 45 | void changeEvent(QEvent *e); 46 | 47 | private slots: 48 | void on_routingAText_textChanged(); 49 | void on_showLogBtn_clicked(); 50 | void on_checkBtn_clicked(); 51 | }; 52 | -------------------------------------------------------------------------------- /src/plugins/subscription-adapters/BuiltinSubscriptionAdapter.cpp: -------------------------------------------------------------------------------- 1 | #include "BuiltinSubscriptionAdapter.hpp" 2 | 3 | #include "core/SubscriptionAdapter.hpp" 4 | 5 | bool InternalSubscriptionSupportPlugin::InitializePlugin() 6 | { 7 | m_SubscriptionInterface = std::make_shared(); 8 | return true; 9 | } 10 | -------------------------------------------------------------------------------- /src/plugins/subscription-adapters/BuiltinSubscriptionAdapter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/PluginInterface.hpp" 4 | 5 | #include 6 | #include 7 | 8 | using namespace Qv2rayPlugin; 9 | 10 | class InternalSubscriptionSupportPlugin 11 | : public QObject 12 | , public Qv2rayInterface 13 | { 14 | Q_OBJECT 15 | QV2RAY_PLUGIN(InternalSubscriptionSupportPlugin) 16 | 17 | public: 18 | // Basic metainfo of this plugin 19 | const QvPluginMetadata GetMetadata() const override 20 | { 21 | return QvPluginMetadata{ 22 | "Builtin Subscription Support", 23 | "Qv2ray Core Workgroup", 24 | PluginId{ "builtin_subscription" }, 25 | "Basic subscription support for Qv2ray", 26 | QUrl{}, 27 | { 28 | COMPONENT_SUBSCRIPTION_ADAPTER, 29 | }, 30 | }; 31 | } 32 | 33 | bool InitializePlugin() override; 34 | void SettingsUpdated() override{}; 35 | }; 36 | -------------------------------------------------------------------------------- /src/plugins/subscription-adapters/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | qv2ray_add_plugin(QvPlugin-BuiltinSubscriptionSupport Widgets 2 | INSTALL_PREFIX_MACOS "${CMAKE_INSTALL_PREFIX}/qv2ray.app/Contents/Resources/plugins" 3 | CLASS_NAME "InternalSubscriptionSupportPlugin") 4 | 5 | target_sources(QvPlugin-BuiltinSubscriptionSupport PRIVATE 6 | ${CMAKE_CURRENT_LIST_DIR}/resx.qrc 7 | ${CMAKE_CURRENT_LIST_DIR}/BuiltinSubscriptionAdapter.cpp 8 | ${CMAKE_CURRENT_LIST_DIR}/BuiltinSubscriptionAdapter.hpp 9 | ${CMAKE_CURRENT_LIST_DIR}/core/SubscriptionAdapter.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/core/SubscriptionAdapter.hpp 11 | ) 12 | 13 | target_include_directories(QvPlugin-BuiltinSubscriptionSupport PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../PluginsCommon) 14 | -------------------------------------------------------------------------------- /src/plugins/subscription-adapters/assets/qv2ray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shadowsocks-NET/Qv2ray/8213f99d88aedc4fa0ea23dc85a3de00ce3e4397/src/plugins/subscription-adapters/assets/qv2ray.png -------------------------------------------------------------------------------- /src/plugins/subscription-adapters/core/SubscriptionAdapter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/PluginInterface.hpp" 4 | 5 | using namespace Qv2rayPlugin; 6 | using namespace Qv2rayPlugin::Common::EditorCreator; 7 | 8 | class SIP008Decoder : public SubscriptionProvider 9 | { 10 | public: 11 | SubscriptionResult DecodeSubscription(const QByteArray &data) const override; 12 | }; 13 | 14 | class SimpleBase64Decoder : public SubscriptionProvider 15 | { 16 | public: 17 | SubscriptionResult DecodeSubscription(const QByteArray &data) const override; 18 | }; 19 | 20 | class OOCProvider : public SubscriptionProvider 21 | { 22 | public: 23 | SubscriptionResult FetchDecodeSubscription(const SubscriptionProviderOptions &) const override; 24 | }; 25 | 26 | class BuiltinSubscriptionAdapterInterface final : public IPluginSubscriptionInterface 27 | { 28 | 29 | public: 30 | explicit BuiltinSubscriptionAdapterInterface() = default; 31 | 32 | const static inline Qv2rayPlugin::Common::EditorCreator::EditorInfoList oocv1_options{ 33 | #ifdef OOCv1_DETAIL_CONFIGURATION 34 | EditorInfo::Create("version", "OOC version"), 35 | EditorInfo::Create("baseUrl", "Base URL"), 36 | EditorInfo::Create("secret", "Secret"), 37 | EditorInfo::Create("userId", "User ID"), 38 | EditorInfo::Create("certSha256", "Certification SHA256"), 39 | #else 40 | EditorInfo::Create("token", "Token/URL"), 41 | #endif 42 | }; 43 | 44 | QList GetInfo() const override 45 | { 46 | return { 47 | SubscriptionProviderInfo::CreateDecoder(SubscriptionProviderId{ "sip008" }, "SIP008"), 48 | SubscriptionProviderInfo::CreateDecoder(SubscriptionProviderId{ "simple_base64" }, "Base64 Links"), 49 | SubscriptionProviderInfo::CreateFetcherDecoder(SubscriptionProviderId{ "ooc" }, "Open Online Config", oocv1_options), 50 | }; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /src/plugins/subscription-adapters/resx.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | assets/qv2ray.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/plugins/v2ray/V2RayCorePluginTemplate.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "QvPlugin/PluginInterface.hpp" 5 | #include "common/SettingsModels.hpp" 6 | 7 | #include 8 | 9 | using namespace Qv2rayPlugin; 10 | 11 | #define CORETYPE_V2Ray 0x01 12 | #define CORETYPE_V2RaySN 0x02 13 | #define CORETYPE_V2Ray5 0x03 14 | #define CORETYPE_V2RayRust 0x04 15 | 16 | #if !defined(V2RayCorePluginClass) || !defined(V2RayCoreType) 17 | #error either V2RayCorePluginClass or V2RayCoreType is not defined. 18 | #endif 19 | 20 | class V2RayCorePluginClass 21 | : public QObject 22 | , public Qv2rayInterface 23 | { 24 | Q_OBJECT 25 | QV2RAY_PLUGIN(V2RayCorePluginClass) 26 | 27 | public: 28 | V2RayCorePluginSettings settings; 29 | 30 | const QvPluginMetadata GetMetadata() const override; 31 | bool InitializePlugin() override; 32 | void SettingsUpdated() override; 33 | }; 34 | 35 | namespace V2RayPluginNamespace 36 | { 37 | class V2RayKernelInterface : public Qv2rayPlugin::Kernel::IKernelHandler 38 | { 39 | public: 40 | V2RayKernelInterface() = default; 41 | 42 | public: 43 | virtual QList PluginKernels() const override; 44 | Q_DISABLE_COPY(V2RayKernelInterface) 45 | }; 46 | 47 | class GuiInterface : public Qv2rayPlugin::Gui::Qv2rayGUIInterface 48 | { 49 | public: 50 | GuiInterface() = default; 51 | 52 | public: 53 | virtual QIcon Icon() const override; 54 | virtual QList GetComponents() const override; 55 | 56 | protected: 57 | virtual std::unique_ptr GetSettingsWidget() const override; 58 | virtual PluginEditorDescriptor GetInboundEditors() const override; 59 | virtual PluginEditorDescriptor GetOutboundEditors() const override; 60 | virtual std::unique_ptr GetMainWindowWidget() const override; 61 | 62 | private: 63 | Q_DISABLE_COPY(GuiInterface) 64 | }; 65 | } // namespace V2RayPluginNamespace 66 | -------------------------------------------------------------------------------- /src/plugins/v2ray/assets/V2Ray-Stats.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.stats.command; 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | message GetStatsRequest 8 | { 9 | // Name of the stat counter. 10 | string name = 1; 11 | // Whether or not to reset the counter to fetching its value. 12 | bool reset = 2; 13 | } 14 | 15 | message Stat 16 | { 17 | string name = 1; 18 | int64 value = 2; 19 | } 20 | 21 | message GetStatsResponse 22 | { 23 | Stat stat = 1; 24 | } 25 | 26 | message QueryStatsRequest 27 | { 28 | string pattern = 1; 29 | bool reset = 2; 30 | } 31 | 32 | message QueryStatsResponse 33 | { 34 | repeated Stat stat = 1; 35 | } 36 | 37 | service StatsService 38 | { 39 | rpc GetStats(GetStatsRequest) returns (GetStatsResponse); 40 | rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse); 41 | } 42 | -------------------------------------------------------------------------------- /src/plugins/v2ray/assets/V2Ray5-Stats.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.stats.command; 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | message GetStatsRequest 8 | { 9 | // Name of the stat counter. 10 | string name = 1; 11 | // Whether or not to reset the counter to fetching its value. 12 | bool reset = 2; 13 | } 14 | 15 | message Stat 16 | { 17 | string name = 1; 18 | int64 value = 2; 19 | } 20 | 21 | message GetStatsResponse 22 | { 23 | Stat stat = 1; 24 | } 25 | 26 | message QueryStatsRequest 27 | { 28 | reserved 1; 29 | bool reset = 2; 30 | repeated string patterns = 3; 31 | bool regexp = 4; 32 | } 33 | 34 | message QueryStatsResponse 35 | { 36 | repeated Stat stat = 1; 37 | } 38 | 39 | service StatsService 40 | { 41 | rpc GetStats(GetStatsRequest) returns (GetStatsResponse); 42 | rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse); 43 | } 44 | -------------------------------------------------------------------------------- /src/plugins/v2ray/assets/V2RayRust-Stats.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.stats.command; 4 | 5 | message GetStatsRequest 6 | { 7 | // Name of the stat counter. 8 | string name = 1; 9 | // Whether or not to reset the counter to fetching its value. 10 | bool reset = 2; 11 | } 12 | 13 | message Stat 14 | { 15 | string name = 1; 16 | int64 value = 2; 17 | } 18 | 19 | message GetStatsResponse 20 | { 21 | Stat stat = 1; 22 | } 23 | 24 | // message QueryStatsRequest { 25 | // string pattern = 1; 26 | // bool reset = 2; 27 | // } 28 | 29 | message QueryStatsResponse 30 | { 31 | repeated Stat stat = 1; 32 | } 33 | 34 | service StatsService 35 | { 36 | rpc GetStats(GetStatsRequest) returns (GetStatsResponse) 37 | { 38 | } 39 | // rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {} 40 | } 41 | -------------------------------------------------------------------------------- /src/plugins/v2ray/assets/V2RaySN-Stats.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.stats.command; 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | message GetStatsRequest 8 | { 9 | // Name of the stat counter. 10 | string name = 1; 11 | // Whether or not to reset the counter to fetching its value. 12 | bool reset = 2; 13 | } 14 | 15 | message Stat 16 | { 17 | string name = 1; 18 | int64 value = 2; 19 | } 20 | 21 | message GetStatsResponse 22 | { 23 | Stat stat = 1; 24 | } 25 | 26 | message QueryStatsRequest 27 | { 28 | reserved 1; 29 | bool reset = 2; 30 | repeated string patterns = 3; 31 | bool regexp = 4; 32 | } 33 | 34 | message QueryStatsResponse 35 | { 36 | repeated Stat stat = 1; 37 | } 38 | 39 | service StatsService 40 | { 41 | rpc GetStats(GetStatsRequest) returns (GetStatsResponse); 42 | rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse); 43 | } 44 | -------------------------------------------------------------------------------- /src/plugins/v2ray/common/CommonHelpers.cpp: -------------------------------------------------------------------------------- 1 | #include "CommonHelpers.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | std::pair> ValidateKernel(const QString &corePath, const QString &assetsPath, const QStringList &arguments) 9 | { 10 | QFile coreFile(corePath); 11 | 12 | if (!coreFile.exists()) 13 | return { false, QObject::tr("V2Ray core executable not found.") }; 14 | 15 | // Use open() here to prevent `executing` a folder, which may have the 16 | // same name as the V2Ray core. 17 | if (!coreFile.open(QFile::ReadOnly)) 18 | return { false, QObject::tr("V2Ray core file cannot be opened, please ensure there's a file instead of a folder.") }; 19 | 20 | coreFile.close(); 21 | 22 | // 23 | // Check file existance. 24 | // From: https://www.v2fly.org/chapter_02/env.html#asset-location 25 | bool hasGeoIP = QDir(assetsPath).entryList().contains(u"geoip.dat"_qs); 26 | bool hasGeoSite = QDir(assetsPath).entryList().contains(u"geosite.dat"_qs); 27 | 28 | if (!hasGeoIP && !hasGeoSite) 29 | return { false, QObject::tr("V2Ray assets path is not valid.") }; 30 | 31 | if (!hasGeoIP) 32 | return { false, QObject::tr("No geoip.dat in assets path.") }; 33 | 34 | if (!hasGeoSite) 35 | return { false, QObject::tr("No geosite.dat in assets path.") }; 36 | 37 | // Check if V2Ray core returns a version number correctly. 38 | QProcess proc; 39 | //#ifdef Q_OS_WIN32 40 | // // nativeArguments are required for Windows platform, without a reason... 41 | // proc.setProcessChannelMode(QProcess::MergedChannels); 42 | // proc.setProgram(corePath); 43 | // proc.setNativeArguments(u"--version"_qs); 44 | // proc.start(); 45 | //#else 46 | proc.start(corePath, arguments); 47 | //#endif 48 | proc.waitForStarted(); 49 | proc.waitForFinished(); 50 | auto exitCode = proc.exitCode(); 51 | 52 | if (exitCode != 0) 53 | return { false, QObject::tr("V2Ray core failed with an exit code: ") + QString::number(exitCode) }; 54 | 55 | const auto output = proc.readAllStandardOutput(); 56 | 57 | if (output.split('\n').isEmpty()) 58 | return { false, QObject::tr("V2Ray core returns empty string.") }; 59 | 60 | return { true, QString::fromUtf8(output.split('\n').first()) }; 61 | } 62 | -------------------------------------------------------------------------------- /src/plugins/v2ray/common/CommonHelpers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | std::pair> ValidateKernel(const QString &corePath, const QString &assetsPath, const QStringList &arguments); 7 | -------------------------------------------------------------------------------- /src/plugins/v2ray/common/SettingsModels.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "QvPlugin/Utils/BindableProps.hpp" 3 | #include "QvPlugin/Utils/JsonConversion.hpp" 4 | 5 | #ifndef QV2RAY_DEFAULT_VCORE_PATH 6 | #define QV2RAY_DEFAULT_VCORE_PATH "" 7 | #endif 8 | 9 | #ifndef QV2RAY_DEFAULT_VASSETS_PATH 10 | #define QV2RAY_DEFAULT_VASSETS_PATH "" 11 | #endif 12 | 13 | struct BrowserForwarderConfig 14 | { 15 | Bindable listenAddr; 16 | Bindable listenPort{ 18888 }; 17 | QJS_JSON(P(listenAddr, listenPort)) 18 | }; 19 | 20 | struct ObservatoryConfig 21 | { 22 | QStringList subjectSelector; 23 | QJS_JSON(F(subjectSelector)) 24 | }; 25 | 26 | struct V2RayCorePluginSettings 27 | { 28 | enum V2RayLogLevel 29 | { 30 | None, 31 | Error, 32 | Warning, 33 | Info, 34 | Debug 35 | }; 36 | 37 | Bindable LogLevel{ Warning }; 38 | 39 | Bindable CorePath{ QString::fromUtf8(QV2RAY_DEFAULT_VCORE_PATH) }; 40 | Bindable AssetsPath{ QString::fromUtf8(QV2RAY_DEFAULT_VASSETS_PATH) }; 41 | 42 | Bindable OutboundMark{ 255 }; 43 | 44 | Bindable APIEnabled{ true }; 45 | Bindable APIPort{ 15480 }; 46 | 47 | BrowserForwarderConfig BrowserForwarderSettings; 48 | ObservatoryConfig ObservatorySettings; 49 | 50 | QJS_JSON(P(LogLevel, CorePath, AssetsPath, APIEnabled, APIPort, OutboundMark), F(BrowserForwarderSettings, ObservatorySettings)) 51 | }; 52 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/V2Ray/Kernel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Handlers/KernelHandler.hpp" 4 | 5 | class QProcess; 6 | 7 | namespace V2RayPluginNamespace 8 | { 9 | class APIWorker; 10 | } 11 | 12 | const inline KernelId v2ray_kernel_id{ u"v2ray_kernel"_qs }; 13 | 14 | class V2RayKernel : public Qv2rayPlugin::Kernel::PluginKernel 15 | { 16 | Q_OBJECT 17 | public: 18 | V2RayKernel(); 19 | ~V2RayKernel(); 20 | 21 | public: 22 | virtual void SetConnectionSettings(const QMap &, const IOConnectionSettings &) override{}; 23 | virtual void SetProfileContent(const ProfileContent &) override; 24 | virtual bool PrepareConfigurations() override; 25 | virtual void Start() override; 26 | virtual bool Stop() override; 27 | virtual KernelId GetKernelId() const override 28 | { 29 | return v2ray_kernel_id; 30 | } 31 | 32 | signals: 33 | void OnCrashed(const QString &); 34 | void OnLog(const QString &); 35 | void OnStatsAvailable(StatisticsObject); 36 | 37 | private: 38 | std::optional ValidateConfig(const QString &path); 39 | 40 | private: 41 | ProfileContent profile; 42 | V2RayPluginNamespace::APIWorker *apiWorker; 43 | QProcess *vProcess; 44 | bool apiEnabled; 45 | bool kernelStarted = false; 46 | QMap tagProtocolMap; 47 | QString configFilePath; 48 | }; 49 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/V2Ray5/Kernel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Handlers/KernelHandler.hpp" 4 | 5 | class QProcess; 6 | 7 | namespace V2RayPluginNamespace 8 | { 9 | class APIWorker; 10 | } 11 | 12 | const inline KernelId v2ray_5_kernel_id{ u"v2ray5_kernel"_qs }; 13 | 14 | class V2Ray5Kernel : public Qv2rayPlugin::Kernel::PluginKernel 15 | { 16 | Q_OBJECT 17 | public: 18 | V2Ray5Kernel(); 19 | ~V2Ray5Kernel(); 20 | 21 | public: 22 | virtual void SetConnectionSettings(const QMap &, const IOConnectionSettings &) override{}; 23 | virtual void SetProfileContent(const ProfileContent &) override; 24 | virtual bool PrepareConfigurations() override; 25 | virtual void Start() override; 26 | virtual bool Stop() override; 27 | virtual KernelId GetKernelId() const override 28 | { 29 | return v2ray_5_kernel_id; 30 | } 31 | 32 | signals: 33 | void OnCrashed(const QString &); 34 | void OnLog(const QString &); 35 | void OnStatsAvailable(StatisticsObject); 36 | 37 | private: 38 | std::optional ValidateConfig(const QString &path); 39 | 40 | private: 41 | ProfileContent profile; 42 | V2RayPluginNamespace::APIWorker *apiWorker; 43 | QProcess *vProcess; 44 | bool apiEnabled; 45 | bool kernelStarted = false; 46 | QMap tagProtocolMap; 47 | QString configFilePath; 48 | }; 49 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/V2RayAPIStats.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Common/CommonTypes.hpp" 4 | 5 | #ifndef QV2RAY_NO_GRPC 6 | #include V2RayCoreStatsHeaderName 7 | 8 | #include 9 | #endif 10 | 11 | // Check 10 times before telling user that API has failed. 12 | constexpr auto QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD = 30; 13 | 14 | typedef std::map QvAPITagProtocolConfig; 15 | 16 | namespace V2RayPluginNamespace 17 | { 18 | #ifdef QV2RAY_NO_GRPC 19 | struct Http2GrpcChannelPrivate; 20 | #endif 21 | class APIWorker : public QObject 22 | { 23 | Q_OBJECT 24 | public: 25 | APIWorker(); 26 | ~APIWorker(); 27 | void StartAPI(const QMap &tagProtocolPair); 28 | void StopAPI(); 29 | 30 | signals: 31 | void OnAPIDataReady(const StatisticsObject &data); 32 | void OnAPIErrored(const QString &err); 33 | 34 | private slots: 35 | void process(); 36 | 37 | private: 38 | qint64 CallStatsAPIByName(const QString &name); 39 | QvAPITagProtocolConfig tagProtocolConfig; 40 | QThread *workThread; 41 | 42 | bool started = false; 43 | bool running = false; 44 | #ifndef QV2RAY_NO_GRPC 45 | std::shared_ptr<::grpc::Channel> grpc_channel; 46 | std::unique_ptr<::v2ray::core::app::stats::command::StatsService::Stub> stats_service_stub; 47 | #else 48 | std::unique_ptr grpc_channel; 49 | #endif 50 | }; 51 | } // namespace V2RayPluginNamespace 52 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/V2RayRust/Kernel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Handlers/KernelHandler.hpp" 4 | 5 | class QProcess; 6 | 7 | namespace V2RayPluginNamespace 8 | { 9 | class APIWorker; 10 | } 11 | 12 | const inline KernelId v2ray_rust_kernel_id{ u"v2ray_rust_kernel"_qs }; 13 | 14 | class V2RayRustKernel : public Qv2rayPlugin::Kernel::PluginKernel 15 | { 16 | Q_OBJECT 17 | public: 18 | V2RayRustKernel(); 19 | ~V2RayRustKernel(); 20 | 21 | public: 22 | virtual void SetConnectionSettings(const QMap &, const IOConnectionSettings &) override{}; 23 | virtual void SetProfileContent(const ProfileContent &) override; 24 | virtual bool PrepareConfigurations() override; 25 | virtual void Start() override; 26 | virtual bool Stop() override; 27 | virtual KernelId GetKernelId() const override 28 | { 29 | return v2ray_rust_kernel_id; 30 | } 31 | 32 | signals: 33 | void OnCrashed(const QString &); 34 | void OnLog(const QString &); 35 | void OnStatsAvailable(StatisticsObject); 36 | 37 | private: 38 | std::optional ValidateConfig(const QString &path); 39 | 40 | private: 41 | ProfileContent profile; 42 | V2RayPluginNamespace::APIWorker *apiWorker; 43 | QProcess *vProcess; 44 | bool apiEnabled; 45 | bool kernelStarted = false; 46 | QMap tagProtocolMap; 47 | QString configFilePath; 48 | }; 49 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/V2RaySN/Kernel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Handlers/KernelHandler.hpp" 4 | 5 | class QProcess; 6 | 7 | namespace V2RayPluginNamespace 8 | { 9 | class APIWorker; 10 | } // namespace V2RayPluginNamespace 11 | 12 | const inline KernelId v2ray_sn_kernel_id{ u"v2ray_sagernet_kernel"_qs }; 13 | class V2RaySNKernel : public Qv2rayPlugin::Kernel::PluginKernel 14 | { 15 | Q_OBJECT 16 | public: 17 | V2RaySNKernel(); 18 | ~V2RaySNKernel(); 19 | 20 | public: 21 | virtual void SetConnectionSettings(const QMap &, const IOConnectionSettings &) override{}; 22 | virtual void SetProfileContent(const ProfileContent &) override; 23 | virtual bool PrepareConfigurations() override; 24 | virtual void Start() override; 25 | virtual bool Stop() override; 26 | virtual KernelId GetKernelId() const override 27 | { 28 | return v2ray_sn_kernel_id; 29 | } 30 | 31 | signals: 32 | void OnCrashed(const QString &); 33 | void OnLog(const QString &); 34 | void OnStatsAvailable(StatisticsObject); 35 | 36 | private: 37 | std::optional ValidateConfig(const QString &path); 38 | 39 | private: 40 | ProfileContent profile; 41 | V2RayPluginNamespace::APIWorker *apiWorker; 42 | QProcess *vProcess; 43 | bool apiEnabled; 44 | bool kernelStarted = false; 45 | QMap tagProtocolMap; 46 | QString configFilePath; 47 | }; 48 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/api.pb.c: -------------------------------------------------------------------------------- 1 | /* Automatically generated nanopb constant definitions */ 2 | /* Generated by nanopb-0.4.6-dev */ 3 | 4 | #include "api.pb.h" 5 | #if PB_PROTO_HEADER_VERSION != 40 6 | #error Regenerate this file with the current version of nanopb generator. 7 | #endif 8 | 9 | PB_BIND(v2ray_core_app_stats_command_GetStatsRequest, v2ray_core_app_stats_command_GetStatsRequest, AUTO) 10 | 11 | 12 | PB_BIND(v2ray_core_app_stats_command_Stat, v2ray_core_app_stats_command_Stat, AUTO) 13 | 14 | 15 | PB_BIND(v2ray_core_app_stats_command_GetStatsResponse, v2ray_core_app_stats_command_GetStatsResponse, AUTO) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/plugins/v2ray/core/pb_common.h: -------------------------------------------------------------------------------- 1 | /* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. 2 | * These functions are rarely needed by applications directly. 3 | */ 4 | 5 | #ifndef PB_COMMON_H_INCLUDED 6 | #define PB_COMMON_H_INCLUDED 7 | 8 | #include "pb.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* Initialize the field iterator structure to beginning. 15 | * Returns false if the message type is empty. */ 16 | bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message); 17 | 18 | /* Get a field iterator for extension field. */ 19 | bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension); 20 | 21 | /* Same as pb_field_iter_begin(), but for const message pointer. 22 | * Note that the pointers in pb_field_iter_t will be non-const but shouldn't 23 | * be written to when using these functions. */ 24 | bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message); 25 | bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension); 26 | 27 | /* Advance the iterator to the next field. 28 | * Returns false when the iterator wraps back to the first field. */ 29 | bool pb_field_iter_next(pb_field_iter_t *iter); 30 | 31 | /* Advance the iterator until it points at a field with the given tag. 32 | * Returns false if no such field exists. */ 33 | bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); 34 | 35 | /* Find a field with type PB_LTYPE_EXTENSION, or return false if not found. 36 | * There can be only one extension range field per message. */ 37 | bool pb_field_iter_find_extension(pb_field_iter_t *iter); 38 | 39 | #ifdef PB_VALIDATE_UTF8 40 | /* Validate UTF-8 text string */ 41 | bool pb_validate_utf8(const char *s); 42 | #endif 43 | 44 | #ifdef __cplusplus 45 | } /* extern "C" */ 46 | #endif 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /src/plugins/v2ray/ui/w_V2RayKernelSettings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 4 | #include "common/SettingsModels.hpp" 5 | #include "ui_w_V2RayKernelSettings.h" 6 | 7 | namespace V2RayPluginNamespace 8 | { 9 | class V2RayKernelSettings 10 | : public Qv2rayPlugin::Gui::PluginSettingsWidget 11 | , private Ui::V2RayKernelSettings 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit V2RayKernelSettings(QWidget *parent = nullptr); 17 | 18 | protected: 19 | void changeEvent(QEvent *e) override; 20 | 21 | public: 22 | virtual void Load() override; 23 | virtual void Store() override; 24 | 25 | private slots: 26 | void on_selectVCoreBtn_clicked(); 27 | void on_selectVAssetBtn_clicked(); 28 | void on_checkVCoreSettings_clicked(); 29 | void on_detectCoreBtn_clicked(); 30 | void on_resetVCoreBtn_clicked(); 31 | void on_resetVAssetBtn_clicked(); 32 | 33 | private: 34 | V2RayCorePluginSettings settingsObject; 35 | }; 36 | } // namespace V2RayPluginNamespace 37 | -------------------------------------------------------------------------------- /src/ui/TrayManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Common/CommonTypes.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Qv2ray::ui 10 | { 11 | enum class MainWindowState 12 | { 13 | State_Shown, 14 | State_Hidden 15 | }; 16 | 17 | class TrayManager : public QObject 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | TrayManager(QObject *parent = nullptr); 23 | ~TrayManager(); 24 | 25 | void HideTrayIcon(); 26 | void ShowTrayIcon(); 27 | void SetTrayIcon(const QIcon &icon); 28 | void SetTrayTooltip(const QString &tooltip); 29 | void ShowTrayMessage(const QString &m, int msecs = 10000); 30 | void SetMainWindowCurrentState(MainWindowState s); 31 | void UpdateColorScheme(); 32 | void Retranslate(); 33 | 34 | signals: 35 | void TrayActivated(QSystemTrayIcon::ActivationReason); 36 | void VisibilityToggled(); 37 | 38 | private: 39 | void ReloadRecentConnectionList(); 40 | 41 | // Slots 42 | void OnConnected(const ProfileId &); 43 | void OnDisconnected(const ProfileId &); 44 | 45 | private: 46 | QSystemTrayIcon *hTray; 47 | QMenu *tray_RootMenu; 48 | QAction *tray_action_ToggleVisibility; 49 | QAction *tray_action_Preferences; 50 | QAction *tray_action_Quit; 51 | QAction *tray_action_Start; 52 | QAction *tray_action_Restart; 53 | QAction *tray_action_Stop; 54 | 55 | QMenu *tray_RecentConnectionsMenu; 56 | QAction *tray_ClearRecentConnectionsAction; 57 | }; 58 | } // namespace Qv2ray::ui 59 | -------------------------------------------------------------------------------- /src/ui/widgets/ConfigurableEditorWidget.hpp: -------------------------------------------------------------------------------- 1 | #include "QvPlugin/Common/EditorCreatorDefs.hpp" 2 | 3 | #include 4 | 5 | QT_BEGIN_NAMESPACE 6 | class QListWidget; 7 | QT_END_NAMESPACE 8 | 9 | class ConfigurableEditor : public QWidget 10 | { 11 | Q_OBJECT 12 | 13 | using _ElementType = Qv2rayPlugin::Common::EditorCreator::ElementType; 14 | using _EditorInfo = Qv2rayPlugin::Common::EditorCreator::EditorInfo; 15 | 16 | public: 17 | explicit ConfigurableEditor(_ElementType arrayType, const QList<_EditorInfo> &subObjects, QWidget *parent = nullptr); 18 | explicit ConfigurableEditor(const QList<_EditorInfo> &_info, QWidget *parent = nullptr); 19 | void SetContent(const QVariant &c); 20 | QVariant GetContent() const; 21 | 22 | private: 23 | const bool isArrayType; 24 | 25 | // For objects 26 | QVariantMap contentObject; 27 | const QList<_EditorInfo> info; 28 | 29 | // For arrays 30 | QListWidget *arrayItemListView; 31 | QVariantList arrayContentList; 32 | }; 33 | -------------------------------------------------------------------------------- /src/ui/widgets/ConnectionInfoWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MessageBus/MessageBus.hpp" 4 | #include "QvPlugin/PluginInterface.hpp" 5 | #include "ui_ConnectionInfoWidget.h" 6 | 7 | #include 8 | 9 | class TagsLineEdit; 10 | 11 | class ConnectionInfoWidget 12 | : public QWidget 13 | , private Ui::ConnectionInfoWidget 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit ConnectionInfoWidget(QWidget *parent = nullptr); 19 | void ShowDetails(const ProfileId &_identifier); 20 | ~ConnectionInfoWidget(); 21 | 22 | signals: 23 | void OnEditRequested(const ConnectionId &id); 24 | void OnJsonEditRequested(const ConnectionId &id); 25 | void OnTagSearchRequested(const QString &tag); 26 | 27 | protected: 28 | bool eventFilter(QObject *object, QEvent *event) override; 29 | 30 | private slots: 31 | void on_connectBtn_clicked(); 32 | void on_editBtn_clicked(); 33 | void on_editJsonBtn_clicked(); 34 | void on_deleteBtn_clicked(); 35 | void on_latencyBtn_clicked(); 36 | 37 | void OnGroupRenamed(const GroupId &id, const QString &oldName, const QString &newName); 38 | void OnConnected(const ProfileId &id); 39 | void OnDisConnected(const ProfileId &id); 40 | void OnConnectionModified(const ConnectionId &id); 41 | void OnConnectionModified_Pair(const ProfileId &id); 42 | 43 | private: 44 | TagsLineEdit *tagsEditor; 45 | void updateColorScheme(); 46 | QvMessageBusSlotDecl; 47 | ConnectionId connectionId; 48 | GroupId groupId; 49 | // 50 | bool isRealPixmapShown; 51 | QPixmap qrPixmap; 52 | QPixmap qrPixmapBlured; 53 | }; 54 | -------------------------------------------------------------------------------- /src/ui/widgets/ConnectionItemWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QvPlugin/Common/CommonTypes.hpp" 4 | #include "QvPlugin/Handlers/LatencyTestHandler.hpp" 5 | #include "ui_ConnectionItemWidget.h" 6 | 7 | #include 8 | 9 | class ConnectionItemWidget 10 | : public QWidget 11 | , private Ui::ConnectionWidget 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit ConnectionItemWidget(const ProfileId &id, QWidget *parent = nullptr); 16 | explicit ConnectionItemWidget(const GroupId &groupId, QWidget *parent = nullptr); 17 | ~ConnectionItemWidget() = default; 18 | 19 | void BeginConnection() const; 20 | void BeginRename(); 21 | void CancelRename(); 22 | 23 | inline const ProfileId Profile() const 24 | { 25 | return { this->connectionId, this->groupId }; 26 | } 27 | inline bool IsRenaming() const 28 | { 29 | return stackedWidget->currentIndex() == 1; 30 | } 31 | inline bool IsConnection() const 32 | { 33 | return !connectionId.isNull(); 34 | } 35 | 36 | private slots: 37 | void OnConnected(const ProfileId &id); 38 | void OnDisConnected(const ProfileId &id); 39 | void OnConnectionStatsArrived(const ProfileId &id, const StatisticsObject &data); 40 | void OnLatencyTestStart(const ConnectionId &id); 41 | void OnConnectionModified(const ConnectionId &id); 42 | void OnLatencyTestFinished(const ConnectionId &id, const Qv2rayPlugin::Latency::LatencyTestResponse &average); 43 | void RecalculateConnections(); 44 | void OnConnectionItemRenamed(const ConnectionId &id, const QString &, const QString &newName); 45 | void OnGroupItemRenamed(const GroupId &id, const QString &, const QString &newName); 46 | void on_doRenameBtn_clicked(); 47 | 48 | private: 49 | explicit ConnectionItemWidget(QWidget *parent = nullptr); 50 | QString originalItemName; 51 | ConnectionId connectionId; 52 | GroupId groupId; 53 | }; 54 | -------------------------------------------------------------------------------- /src/ui/widgets/TagLineEditorWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "components/FlowLayout/FlowLayout.hpp" 4 | 5 | #include 6 | #include 7 | 8 | class QLabel; 9 | class QLineEdit; 10 | 11 | class TagEntryWidget : public QFrame 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit TagEntryWidget(const QString &name, QWidget *parent = nullptr); 17 | ~TagEntryWidget() = default; 18 | 19 | QString GetTag() const; 20 | 21 | protected: 22 | virtual bool event(QEvent *event) override; 23 | 24 | signals: 25 | void OnTagClicked(const QString &); 26 | void OnTagDeleted(const QString &, QPrivateSignal); 27 | 28 | private: 29 | QLabel *label; 30 | QString text; 31 | }; 32 | 33 | class TagsLineEdit : public QWidget 34 | { 35 | Q_OBJECT 36 | 37 | public: 38 | explicit TagsLineEdit(QWidget *parent = nullptr); 39 | ~TagsLineEdit() = default; 40 | 41 | void SetTags(const QSet &); 42 | QStringList GetTags(); 43 | 44 | signals: 45 | void OnTagClicked(const QString &); 46 | void OnTagsChanged(const QStringList &); 47 | 48 | protected: 49 | virtual bool eventFilter(QObject *target, QEvent *event) override; 50 | 51 | private: 52 | void DeleteTag(const QString &s); 53 | void AddTag(const QString &str); 54 | 55 | private: 56 | QLineEdit *lineEdit; 57 | Qv2ray::components::FlowLayout *_layout; 58 | QSet tagsSet; 59 | }; 60 | -------------------------------------------------------------------------------- /src/ui/widgets/editors/DnsSettingsWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MessageBus/MessageBus.hpp" 4 | #include "plugins/PluginsCommon/V2RayModels.hpp" 5 | #include "ui_DnsSettingsWidget.h" 6 | 7 | namespace Qv2ray::ui::widgets 8 | { 9 | class AutoCompleteTextEdit; 10 | } 11 | 12 | class DnsSettingsWidget 13 | : public QWidget 14 | , private Ui::DnsSettingsWidget 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit DnsSettingsWidget(QWidget *parent = nullptr); 20 | void SetDNSObject(const Qv2ray::Models::V2RayDNSObject &dns, const QList &fakeDNS); 21 | std::pair> GetDNSObject(); 22 | bool CheckIsValidDNS() const; 23 | 24 | private slots: 25 | void on_dnsClientIPTxt_textEdited(const QString &arg1); 26 | void on_dnsTagTxt_textEdited(const QString &arg1); 27 | void on_addServerBtn_clicked(); 28 | void on_removeServerBtn_clicked(); 29 | void on_serversListbox_currentRowChanged(int currentRow); 30 | void on_moveServerUpBtn_clicked(); 31 | void on_moveServerDownBtn_clicked(); 32 | void on_serverAddressTxt_textEdited(const QString &arg1); 33 | void on_serverPortSB_valueChanged(int arg1); 34 | void on_addStaticHostBtn_clicked(); 35 | void on_removeStaticHostBtn_clicked(); 36 | void on_detailsSettingsGB_toggled(bool arg1); 37 | void on_staticResolvedDomainsTable_cellChanged(int row, int column); 38 | void on_dnsDisableCacheCB_stateChanged(int arg1); 39 | void on_dnsDisableFallbackCB_stateChanged(int arg1); 40 | void on_dnsQueryStrategyCB_currentTextChanged(const QString &arg1); 41 | 42 | private: 43 | void updateColorScheme(); 44 | void ShowCurrentDnsServerDetails(); 45 | void ProcessDnsPortEnabledState(); 46 | QvMessageBusSlotDecl; 47 | Qv2ray::Models::V2RayDNSObject dns; 48 | // int currentServerIndex; 49 | // 50 | Qv2ray::ui::widgets::AutoCompleteTextEdit *domainListTxt; 51 | Qv2ray::ui::widgets::AutoCompleteTextEdit *ipListTxt; 52 | }; 53 | -------------------------------------------------------------------------------- /src/ui/widgets/editors/RouteSettingsMatrix.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RouteSchemeIO/RouteSchemeIO.hpp" 4 | #include "ui/widgets/AutoCompleteTextEdit.hpp" 5 | #include "ui_RouteSettingsMatrix.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | class RouteSettingsMatrixWidget 12 | : public QWidget 13 | , private Ui::RouteSettingsMatrix 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | RouteSettingsMatrixWidget(QWidget *parent = nullptr); 19 | void SetRoute(const Qv2ray::Models::RouteMatrixConfig &conf); 20 | Qv2ray::Models::RouteMatrixConfig GetRouteConfig() const; 21 | ~RouteSettingsMatrixWidget(); 22 | 23 | private: 24 | std::optional openFileDialog(); 25 | std::optional saveFileDialog(); 26 | 27 | private slots: 28 | void on_importSchemeBtn_clicked(); 29 | void on_exportSchemeBtn_clicked(); 30 | 31 | private: 32 | Qv2ray::ui::widgets::AutoCompleteTextEdit *directDomainTxt; 33 | Qv2ray::ui::widgets::AutoCompleteTextEdit *proxyDomainTxt; 34 | Qv2ray::ui::widgets::AutoCompleteTextEdit *blockDomainTxt; 35 | 36 | Qv2ray::ui::widgets::AutoCompleteTextEdit *directIPTxt; 37 | Qv2ray::ui::widgets::AutoCompleteTextEdit *blockIPTxt; 38 | Qv2ray::ui::widgets::AutoCompleteTextEdit *proxyIPTxt; 39 | 40 | private: 41 | QMenu *builtInSchemesMenu; 42 | }; 43 | -------------------------------------------------------------------------------- /src/ui/windows/editors/w_JsonEditor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MessageBus/MessageBus.hpp" 4 | #include "QJsonModel/QJsonModel.hpp" 5 | #include "ui_w_JsonEditor.h" 6 | 7 | #include 8 | #include 9 | 10 | class JSONHighlighter : public QSyntaxHighlighter 11 | { 12 | Q_OBJECT 13 | enum Mode 14 | { 15 | MString, 16 | MNumber, 17 | MKeyword 18 | }; 19 | 20 | public: 21 | explicit JSONHighlighter(QTextDocument *document = nullptr) : QSyntaxHighlighter(document){}; 22 | static QTextCharFormat getFormat(const Mode name); 23 | 24 | protected: 25 | void highlightBlock(const QString &text) override; 26 | }; 27 | 28 | class JsonEditor 29 | : public QDialog 30 | , private Ui::JsonEditor 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | explicit JsonEditor(QJsonObject rootObject = {}, QWidget *parent = nullptr); 36 | ~JsonEditor(); 37 | QJsonObject OpenEditor(); 38 | 39 | private: 40 | QvMessageBusSlotDecl; 41 | 42 | private slots: 43 | void on_jsonEditor_textChanged(); 44 | 45 | void on_formatJsonBtn_clicked(); 46 | 47 | private: 48 | QJsonModel model; 49 | QJsonObject original; 50 | QJsonObject final; 51 | }; 52 | -------------------------------------------------------------------------------- /src/ui/windows/editors/w_OutboundEditor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GuiPluginHost/GuiPluginHost.hpp" 3 | #include "MessageBus/MessageBus.hpp" 4 | #include "ui_w_OutboundEditor.h" 5 | 6 | #include 7 | 8 | class StreamSettingsWidget; 9 | 10 | class OutboundEditor 11 | : public QDialog 12 | , private Ui::OutboundEditor 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit OutboundEditor(QWidget *parent = nullptr); 17 | explicit OutboundEditor(const OutboundObject &outboundEntry, QWidget *parent = nullptr); 18 | ~OutboundEditor(); 19 | OutboundObject OpenEditor(); 20 | QString GetFriendlyName(); 21 | 22 | private: 23 | QvMessageBusSlotDecl; 24 | 25 | private slots: 26 | void on_buttonBox_accepted(); 27 | void on_ipLineEdit_textEdited(const QString &arg1); 28 | void on_muxConcurrencyTxt_valueChanged(int arg1); 29 | void on_muxEnabledCB_stateChanged(int arg1); 30 | void on_outBoundTypeCombo_currentIndexChanged(int index); 31 | void on_portLineEdit_textEdited(const QString &arg1); 32 | void on_tagTxt_textEdited(const QString &arg1); 33 | 34 | private: 35 | QString outboundTag; 36 | void reloadGUI(); 37 | OutboundObject generateConnectionJson(); 38 | OutboundObject originalConfig; 39 | OutboundObject resultConfig; 40 | MultiplexerObject muxConfig; 41 | QString serverAddress; 42 | int serverPort; 43 | // 44 | // Connection Configs 45 | QString outboundProtocol = "vmess"; 46 | // 47 | StreamSettingsWidget *streamSettingsWidget; 48 | // 49 | QMap pluginWidgets; 50 | }; 51 | -------------------------------------------------------------------------------- /src/ui/windows/w_AboutWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "w_AboutWindow.hpp" 2 | 3 | #include "Qv2rayBase/Common/Utils.hpp" 4 | #include "Qv2rayBase/Interfaces/IStorageProvider.hpp" 5 | #include "Qv2rayBase/Qv2rayBaseLibrary.hpp" 6 | #include "QvPlugin/Common/QvPluginBase.hpp" 7 | #include "ui_w_AboutWindow.h" 8 | 9 | #include 10 | #include 11 | 12 | AboutWindow::AboutWindow(QWidget *parent) : QDialog(parent), ui(new Ui::w_AboutWindow) 13 | { 14 | ui->setupUi(this); 15 | ui->configdirLabel->setText(QvStorageProvider->StorageLocation()); 16 | ui->qvVersion->setText(QString::fromUtf8(QV2RAY_VERSION_STRING)); 17 | ui->qvBuildInfo->setText(QString::fromUtf8(QV2RAY_BUILD_INFO)); 18 | ui->qvBuildExInfo->setText(QString::fromUtf8(QV2RAY_BUILD_EXTRA_INFO)); 19 | ui->qvPluginInterfaceVersionLabel->setText(QString::number(Qv2rayPlugin::QV2RAY_PLUGIN_INTERFACE_VERSION)); 20 | ui->tlsBackendLabel->setText(QSslSocket::activeBackend() + " (" + QSslSocket::sslLibraryVersionString() + ")"); 21 | // ui->textBrowser->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); 22 | } 23 | 24 | AboutWindow::~AboutWindow() 25 | { 26 | delete ui; 27 | } 28 | 29 | void AboutWindow::on_openConfigDirCB_clicked() 30 | { 31 | QvBaselib->OpenURL(QvStorageProvider->StorageLocation()); 32 | } 33 | 34 | void AboutWindow::on_aboutQt_clicked() 35 | { 36 | QApplication::aboutQt(); 37 | } 38 | -------------------------------------------------------------------------------- /src/ui/windows/w_AboutWindow.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Ui { 6 | class w_AboutWindow; 7 | } 8 | 9 | class AboutWindow : public QDialog 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit AboutWindow(QWidget *parent = nullptr); 15 | ~AboutWindow(); 16 | 17 | private slots: 18 | void on_openConfigDirCB_clicked(); 19 | void on_aboutQt_clicked(); 20 | 21 | private: 22 | Ui::w_AboutWindow *ui; 23 | }; 24 | -------------------------------------------------------------------------------- /src/ui/windows/w_ImportConfig.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ui/WidgetUIBase.hpp" 4 | #include "ui_w_ImportConfig.h" 5 | 6 | class ImportConfigWindow 7 | : public QvDialog 8 | , private Ui::ImportConfigWindow 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit ImportConfigWindow(QWidget *parent = nullptr); 14 | ~ImportConfigWindow(); 15 | std::pair> DoImportConnections(); 16 | void processCommands(QString command, QStringList commands, QMap args) override; 17 | 18 | private: 19 | QvMessageBusSlotDecl override; 20 | 21 | private slots: 22 | void on_beginImportBtn_clicked(); 23 | void on_cancelImportBtn_clicked(); 24 | void on_jsonEditBtn_clicked(); 25 | void on_groupCombo_currentIndexChanged(int index); 26 | 27 | private: 28 | void updateColorScheme() override{}; 29 | 30 | // Use hash here since the order is not important. 31 | GroupId selectedGroup = DefaultGroupId; 32 | QMultiMap connections; 33 | }; 34 | -------------------------------------------------------------------------------- /src/ui/windows/w_PluginManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Qv2rayBase/Plugin/PluginManagerCore.hpp" 4 | #include "QvPlugin/Gui/QvGUIPluginInterface.hpp" 5 | #include "ui/WidgetUIBase.hpp" 6 | #include "ui_w_PluginManager.h" 7 | 8 | #include 9 | 10 | class PluginManageWindow 11 | : public QvDialog 12 | , private Ui::w_PluginManager 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit PluginManageWindow(QWidget *parent = nullptr); 18 | ~PluginManageWindow(); 19 | void processCommands(QString command, QStringList commands, QMap) override 20 | { 21 | if (commands.isEmpty()) 22 | return; 23 | if (command == "open") 24 | { 25 | const auto c = commands.takeFirst(); 26 | if (c == "plugindir") 27 | on_openPluginFolder_clicked(); 28 | } 29 | } 30 | QvMessageBusSlotDecl override; 31 | 32 | private slots: 33 | void on_pluginListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); 34 | void on_pluginListWidget_itemChanged(QListWidgetItem *item); 35 | void on_openPluginFolder_clicked(); 36 | 37 | private: 38 | void updateColorScheme() override{}; 39 | 40 | std::shared_ptr currentSettingsWidget; 41 | const Qv2rayBase::Plugin::PluginInfo *currentPluginInfo = nullptr; 42 | QHash plugins; 43 | bool isLoading = true; 44 | }; 45 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qv2ray", 3 | "version-string": "0.0.1", 4 | "dependencies": [ 5 | "openssl", 6 | "protobuf", 7 | "grpc", 8 | "libuv", 9 | "uvw" 10 | ] 11 | } 12 | --------------------------------------------------------------------------------