diff --git a/Qv2ray.astylerc b/Qv2ray.astylerc deleted file mode 100644 index 781c3ac5..00000000 --- a/Qv2ray.astylerc +++ /dev/null @@ -1,306 +0,0 @@ -# ~/.astylerc -# -# Courtesy of HN's super_mario: http://news.ycombinator.com/item?id=5348401 -# - -# Use K&R formatting style -style=kr - -# Indent class and struct blocks so that the blocks 'public', 'private' and -# 'protected' are indented. This option is effective in C++ files only -indent-classes - -# Indent 'switch' blocks so that the 'case X:' statements are indented with -# the switch block. The entire case block is indented. -# -# For example: -# switch (foo) -# { -# case 1: -# a += 1; -# break; -# -# case 2: -# { -# a += 2; -# break; -# } -# } -# -# becomes -# -# switch (foo) -# { -# case 1: -# a += 1; -# break; -# -# case 2: -# { -# a += 2; -# break; -# } -# } -indent-switches - -# Indent C++ namespaces (this option has no effect on other file types) -# Add extra indentation to namespace blocks. -# For example: -# namespace foospace -# { -# class Foo -# { -# public: -# Foo(); -# virtual ~Foo(); -# }; -# } -# -# becomes -# -# namespace foospace -# { -# class Foo -# { -# public: -# Foo(); -# virtual ~Foo(); -# }; -# } -indent-namespaces - -# Indent multi line preprocessor definitions ending with a backslash -# For example: -# -# #define Is_Bar(arg,a,b) \ -# (Is_Foo((arg), (a)) \ -# || Is_Foo((arg), (b))) -# -# becomes: -# -# #define Is_Bar(arg,a,b) \ -# (Is_Foo((arg), (a)) \ -# || Is_Foo((arg), (b))) -# -indent-preprocessor - -# Indent C++ comments beginning in column one. -# For example -# -# void Foo()\n" -# { -# // comment -# if (isFoo) -# bar(); -# } -# -# becomes: -# -# void Foo()\n" -# { -# // comment -# if (isFoo) -# bar(); -# } -# -indent-col1-comments - -# Pad empty lines around header blocks (e.g. 'if', 'for', 'while'...). -# -# isFoo = true; -# if (isFoo) { -# bar(); -# } else { -# anotherBar(); -# } -# isBar = false; -# -# becomes: -# -# isFoo = true; -# -# if (isFoo) { -# bar(); -# } else { -# anotherBar(); -# } -# -# isBar = false; -# -break-blocks - -# Insert space padding around operators. Any end of line comments will remain -# in the original column, if possible. Note that there is no option to unpad. -# Once padded, they stay padded. -# -# if (foo==2) -# a=bar((b-c)*a,d--); -# -# becomes: -# -# if (foo == 2) -# a = bar((b - c) * a, d--); -# -pad-oper - - -# Insert space padding after paren headers only (e.g. 'if', 'for', 'while'...). -# Any end of line comments will remain in the original column, if possible. -# This can be used with unpad-paren to remove unwanted spaces. -# -# if(isFoo(a, b)) -# bar(a, b); -# -# becomes: -# -# if (isFoo(a, b)) -# bar(a, b); -# -pad-header - -# Remove extra space padding around parenthesis on the inside and outside. Any -# end of line comments will remain in the original column, if possible. This -# option can be used in combination with the paren padding options pad‑paren, -# pad‑paren‑out, pad‑paren‑in, and pad‑header above. Only padding that has not -# been requested by other options will be removed. -# -# For example, if a source has parens padded on both the inside and outside, -# and you want inside only. You need to use unpad-paren to remove the outside -# padding, and pad‑paren‑in to retain the inside padding. Using only -# pad‑paren‑in would not remove the outside padding. -# -# if ( isFoo( a, b ) ) -# bar ( a, b ); -# -# becomes (with no padding option requested): -# -# if(isFoo(a, b)) -# bar(a, b); -# -unpad-paren - -# Delete empty lines within a function or method. Empty lines outside of -# functions or methods are NOT deleted. If used with break-blocks or -# break-blocks=all it will delete all lines EXCEPT the lines added by the -# break-blocks options. -# -# void Foo() -# { -# -# foo1 = 1; -# -# foo2 = 2; -# -# } -# -# becomes: -# -# void Foo() -# { -# foo1 = 1; -# foo2 = 2; -# } -# -delete-empty-lines - -# Attach a pointer or reference operator (* or &) to either the variable type -# (left) or variable name (right), or place it between the type and name -# (middle). The spacing between the type and name will be preserved, if -# possible. To format references separately use the following align-reference -# option. -# -# char *foo1; -# char &foo2; -# -# becomes (with align-pointer=type): -# -# char* foo1; -# char& foo2; -# -# char* foo1; -# char& foo2; -# -# becomes (with align-pointer=middle): -# -# char * foo1; -# char & foo2; -# -# char* foo1; -# char& foo2; -# -# becomes (with align-pointer=name): -# -# char *foo1; -# char &foo2; -# -align-pointer=name - -# Set the minimal indent that is added when a header is built of multiple -# lines. This indent helps to easily separate the header from the command -# statements that follow. The value for # indicates a number of indents and is -# a minimum value. The indent may be greater to align with the data on the -# previous line. -# The valid values are: -# 0 - no minimal indent. The lines will be aligned with the paren on the -# preceding line. -# 1 - indent at least one additional indent. -# 2 - indent at least two additional indents. -# 3 - indent at least one-half an additional indent. This is intended for large -# indents (e.g. 8). -# -# The default value is 2, two additional indents. -# -# // default setting makes this non-bracketed code clear -# if (a < b -# || c > d) -# foo++; -# -# // but creates an exaggerated indent in this bracketed code -# if (a < b -# || c > d) -# { -# foo++; -# } -# -# becomes (when setting --min-conditional-indent=0): -# -# // setting makes this non-bracketed code less clear -# if (a < b -# || c > d) -# foo++; -# -# // but makes this bracketed code clearer -# if (a < b -# || c > d) -# { -# foo++; -# } -# -min-conditional-indent=0 - -# Set the maximum of # spaces to indent a continuation line. The # indicates -# a number of columns and must not be greater than 120. If no # is set, the -# default value of 40 will be used. A maximum of less than two indent lengths -# will be ignored. This option will prevent continuation lines from extending -# too far to the right. Setting a larger value will allow the code to be -# extended further to the right. -# -# fooArray[] = { red, -# green, -# blue }; -# -# fooFunction(barArg1, -# barArg2, -# barArg3); -# -# becomes (with larger value): -# -# fooArray[] = { red, -# green, -# blue }; -# -# fooFunction(barArg1, -# barArg2, -# barArg3); -# -#max-instatement-indent=9 diff --git a/_clang-format b/_clang-format new file mode 100644 index 00000000..76d7dab8 --- /dev/null +++ b/_clang-format @@ -0,0 +1,50 @@ +--- +BasedOnStyle: Microsoft +AccessModifierOffset: '-2' +AlignAfterOpenBracket: Align +AllowAllArgumentsOnNextLine: 'false' +AllowAllConstructorInitializersOnNextLine: 'false' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AllowShortBlocksOnASingleLine: 'true' +AllowShortCaseLabelsOnASingleLine: 'true' +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: Inline +AllowShortLoopsOnASingleLine: 'true' +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: 'false' +AlwaysBreakTemplateDeclarations: 'Yes' +BinPackArguments: 'true' +BinPackParameters: 'true' +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: 'false' +BreakInheritanceList: BeforeComma +BreakStringLiterals: 'false' +ColumnLimit: '145' +CompactNamespaces: 'false' +ConstructorInitializerAllOnOneLineOrOnePerLine: 'false' +Cpp11BracedListStyle: 'false' +ExperimentalAutoDetectBinPacking: 'false' +FixNamespaceComments: 'true' +IncludeBlocks: Regroup +IndentCaseLabels: 'true' +IndentPPDirectives: BeforeHash +IndentWidth: '4' +Language: Cpp +MaxEmptyLinesToKeep: '1' +NamespaceIndentation: All +ReflowComments: 'true' +SortIncludes: 'true' +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'true' +SpaceAfterTemplateKeyword: 'false' +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: 'true' +SpacesInParentheses: 'false' +Standard: Cpp11 +StatementMacros: [ Q_UNUSED LOG DEBUG ] +TabWidth: '4' +UseTab: Never + +... diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION index 31678c37..1a9e10d9 100644 --- a/makespec/BUILDVERSION +++ b/makespec/BUILDVERSION @@ -1 +1 @@ -4014 +4031 diff --git a/src/base/GlobalInstances.hpp b/src/base/GlobalInstances.hpp index 494e3b93..114a9ccf 100644 --- a/src/base/GlobalInstances.hpp +++ b/src/base/GlobalInstances.hpp @@ -1,8 +1,8 @@ #pragma once +#include "base/models/QvConfigModel.hpp" #include "base/models/QvRuntimeConfig.hpp" #include "base/models/QvStartupConfig.hpp" -#include "base/models/QvConfigModel.hpp" #include @@ -18,4 +18,4 @@ namespace Qv2ray inline base::QvStartupOptions StartupOption = base::QvStartupOptions(); // inline std::unique_ptr Qv2rayTranslator; -} +} // namespace Qv2ray diff --git a/src/base/JsonHelpers.hpp b/src/base/JsonHelpers.hpp index 7977fa4e..38114f90 100644 --- a/src/base/JsonHelpers.hpp +++ b/src/base/JsonHelpers.hpp @@ -1,42 +1,42 @@ #pragma once -#define STRINGIZE(arg) STRINGIZE1(arg) +#define STRINGIZE(arg) STRINGIZE1(arg) #define STRINGIZE1(arg) STRINGIZE2(arg) #define STRINGIZE2(arg) #arg -#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2) -#define CONCATENATE2(arg1, arg2) arg1##arg2 +#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2) +#define CONCATENATE2(arg1, arg2) arg1##arg2 #define EXPAND(x) x #define FOR_EACH_1(what, x, ...) what(x) -#define FOR_EACH_2(what, x, ...)\ - what(x);\ - EXPAND(FOR_EACH_1(what, __VA_ARGS__)) -#define FOR_EACH_3(what, x, ...)\ - what(x);\ +#define FOR_EACH_2(what, x, ...) \ + what(x); \ + EXPAND(FOR_EACH_1(what, __VA_ARGS__)) +#define FOR_EACH_3(what, x, ...) \ + what(x); \ EXPAND(FOR_EACH_2(what, __VA_ARGS__)) -#define FOR_EACH_4(what, x, ...)\ - what(x);\ - EXPAND(FOR_EACH_3(what, __VA_ARGS__)) -#define FOR_EACH_5(what, x, ...)\ - what(x);\ - EXPAND(FOR_EACH_4(what, __VA_ARGS__)) -#define FOR_EACH_6(what, x, ...)\ - what(x);\ - EXPAND(FOR_EACH_5(what, __VA_ARGS__)) -#define FOR_EACH_7(what, x, ...)\ - what(x);\ - EXPAND(FOR_EACH_6(what, __VA_ARGS__)) -#define FOR_EACH_8(what, x, ...)\ - what(x);\ - EXPAND(FOR_EACH_7(what, __VA_ARGS__)) +#define FOR_EACH_4(what, x, ...) \ + what(x); \ + EXPAND(FOR_EACH_3(what, __VA_ARGS__)) +#define FOR_EACH_5(what, x, ...) \ + what(x); \ + EXPAND(FOR_EACH_4(what, __VA_ARGS__)) +#define FOR_EACH_6(what, x, ...) \ + what(x); \ + EXPAND(FOR_EACH_5(what, __VA_ARGS__)) +#define FOR_EACH_7(what, x, ...) \ + what(x); \ + EXPAND(FOR_EACH_6(what, __VA_ARGS__)) +#define FOR_EACH_8(what, x, ...) \ + what(x); \ + EXPAND(FOR_EACH_7(what, __VA_ARGS__)) #define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N()) #define FOR_EACH_NARG_(...) EXPAND(FOR_EACH_ARG_N(__VA_ARGS__)) #define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N #define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 -#define CONCATENATE(x,y) x##y +#define CONCATENATE(x, y) x##y #define FOR_EACH_(N, what, ...) EXPAND(CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__)) #define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) #define JADDEx_(jsonObj, field) jsonObj.insert(#field, field); diff --git a/src/base/Qv2rayBase.hpp b/src/base/Qv2rayBase.hpp index 0180a0e4..0cbfda18 100644 --- a/src/base/Qv2rayBase.hpp +++ b/src/base/Qv2rayBase.hpp @@ -1,30 +1,30 @@ #pragma once // #ifndef XTOSTRUCT_QT -# define XTOSTRUCT_QT + #define XTOSTRUCT_QT #endif // -#include -#include #include #include -#include +#include +#include #include -#include #include +#include #include +#include // Base support. -#include "base/Qv2rayLog.hpp" -#include "base/Qv2rayFeatures.hpp" -#include "base/JsonHelpers.hpp" #include "base/GlobalInstances.hpp" +#include "base/JsonHelpers.hpp" +#include "base/Qv2rayFeatures.hpp" +#include "base/Qv2rayLog.hpp" // Code Models -#include "base/models/QvSafeType.hpp" #include "base/models/CoreObjectModels.hpp" -#include "base/models/QvConfigModel.hpp" #include "base/models/QvConfigIdentifier.hpp" -#include "base/models/QvStartupConfig.hpp" +#include "base/models/QvConfigModel.hpp" #include "base/models/QvRuntimeConfig.hpp" +#include "base/models/QvSafeType.hpp" +#include "base/models/QvStartupConfig.hpp" using namespace std; using namespace std::chrono; @@ -38,9 +38,9 @@ using namespace Qv2ray::base::objects::transfer; // Linux users and DEs should handle the darkMode UI themselves. #ifndef QV2RAY_USE_BUILTIN_DARKTHEME -# ifndef Q_OS_LINUX -# define QV2RAY_USE_BUILTIN_DARKTHEME -# endif + #ifndef Q_OS_LINUX + #define QV2RAY_USE_BUILTIN_DARKTHEME + #endif #endif #define QV2RAY_BUILD_INFO QString(_QV2RAY_BUILD_INFO_STR_) @@ -48,9 +48,9 @@ using namespace Qv2ray::base::objects::transfer; // Base folder suffix. #ifdef QT_DEBUG -# define QV2RAY_CONFIG_DIR_SUFFIX "_debug/" + #define QV2RAY_CONFIG_DIR_SUFFIX "_debug/" #else -# define QV2RAY_CONFIG_DIR_SUFFIX "/" + #define QV2RAY_CONFIG_DIR_SUFFIX "/" #endif // Get Configured Config Dir Path @@ -68,17 +68,17 @@ using namespace Qv2ray::base::objects::transfer; #define QV2RAY_GENERATED_DIR (QV2RAY_CONFIG_DIR + "generated/") #define QV2RAY_GENERATED_FILE_PATH (QV2RAY_GENERATED_DIR + "config.gen.json") -#if ! defined (QV2RAY_DEFAULT_VCORE_PATH) && ! defined (QV2RAY_DEFAULT_VASSETS_PATH) -# define QV2RAY_DEFAULT_VASSETS_PATH (QV2RAY_CONFIG_DIR + "vcore/") -# ifdef Q_OS_WIN -# define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe") -# else -# define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray") -# endif -#elif defined (QV2RAY_DEFAULT_VCORE_PATH) && defined (QV2RAY_DEFAULT_VASSETS_PATH) +#if !defined(QV2RAY_DEFAULT_VCORE_PATH) && !defined(QV2RAY_DEFAULT_VASSETS_PATH) + #define QV2RAY_DEFAULT_VASSETS_PATH (QV2RAY_CONFIG_DIR + "vcore/") + #ifdef Q_OS_WIN + #define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe") + #else + #define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray") + #endif +#elif defined(QV2RAY_DEFAULT_VCORE_PATH) && defined(QV2RAY_DEFAULT_VASSETS_PATH) // ---- Using user-specified VCore and VAssets path #else -# error Both QV2RAY_DEFAULT_VCORE_PATH and QV2RAY_DEFAULT_VASSETS_PATH need to be presented when using manually specify the paths. + #error Both QV2RAY_DEFAULT_VCORE_PATH and QV2RAY_DEFAULT_VASSETS_PATH need to be presented when using manually specify the paths. #endif #ifdef Q_OS_WIN @@ -86,8 +86,8 @@ using namespace Qv2ray::base::objects::transfer; //# define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe") //# define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl.exe") #else -# define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray") -# define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl") + #define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray") + #define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl") #endif #define QV2RAY_VCORE_LOG_DIRNAME "logs/" @@ -95,15 +95,15 @@ using namespace Qv2ray::base::objects::transfer; #define QV2RAY_VCORE_ERROR_LOG_FILENAME "error.log" // GUI TOOLS -#define RED(obj) \ - auto _temp = obj->palette(); \ - _temp.setColor(QPalette::Text, Qt::red); \ +#define RED(obj) \ + auto _temp = obj->palette(); \ + _temp.setColor(QPalette::Text, Qt::red); \ obj->setPalette(_temp); -#define BLACK(obj) \ - obj->setPalette(QWidget::palette()); +#define BLACK(obj) obj->setPalette(QWidget::palette()); -#define QV2RAY_UI_RESOURCES_ROOT ((GlobalConfig.uiConfig.useDarkTheme) ? QStringLiteral(":/assets/icons/ui_dark/") : QStringLiteral(":/assets/icons/ui_light/")) +#define QV2RAY_UI_RESOURCES_ROOT \ + ((GlobalConfig.uiConfig.useDarkTheme) ? QStringLiteral(":/assets/icons/ui_dark/") : QStringLiteral(":/assets/icons/ui_light/")) #define QICON_R(file) QIcon(QV2RAY_UI_RESOURCES_ROOT + file) #define QSTRN(num) QString::number(num) @@ -117,7 +117,8 @@ using namespace Qv2ray::base::objects::transfer; #define QV2RAY_USE_FPROXY_KEY "_QV2RAY_USE_GLOBAL_FORWARD_PROXY_" -#define JSON_ROOT_TRY_REMOVE(obj) if (root.contains(obj)) { root.remove(obj); } +#define JSON_ROOT_TRY_REMOVE(obj) \ + if (root.contains(obj)) { root.remove(obj); } namespace Qv2ray { @@ -129,4 +130,4 @@ namespace Qv2ray isExiting = true; QApplication::quit(); } -} +} // namespace Qv2ray diff --git a/src/base/Qv2rayFeatures.hpp b/src/base/Qv2rayFeatures.hpp index ba731ebb..9de9ecf7 100644 --- a/src/base/Qv2rayFeatures.hpp +++ b/src/base/Qv2rayFeatures.hpp @@ -3,7 +3,7 @@ // // Always use libgRPC++ on windows platform. #ifndef WITH_LIB_GRPCPP -# ifdef _WIN32 -# define WITH_LIB_GRPCPP -# endif + #ifdef _WIN32 + #define WITH_LIB_GRPCPP + #endif #endif diff --git a/src/base/Qv2rayLog.cpp b/src/base/Qv2rayLog.cpp index 925e3120..560c7e57 100644 --- a/src/base/Qv2rayLog.cpp +++ b/src/base/Qv2rayLog.cpp @@ -1,5 +1,7 @@ #include "Qv2rayLog.hpp" + #include "base/GlobalInstances.hpp" + #include namespace Qv2ray::base @@ -15,18 +17,22 @@ namespace Qv2ray::base auto logString = "[" + module + "]: " + log; auto funcPrepend = QString::fromStdString(func + ":" + to_string(line) + " "); - if (isDebugBuild) { - // Debug build version, we only print info for DEBUG logs and print ALL info when debugLog presents, - if (type == QV2RAY_LOG_DEBUG || StartupOption.debugLog) { - logString = logString.prepend(funcPrepend); - } - } else { + if (isDebugBuild) + { + // Debug build version, we only print info for DEBUG logs and print + // ALL info when debugLog presents, + if (type == QV2RAY_LOG_DEBUG || StartupOption.debugLog) { logString = logString.prepend(funcPrepend); } + } + else + { // We only process DEBUG log in Release mode - if (type == QV2RAY_LOG_DEBUG) { - if (StartupOption.debugLog) { - logString = logString.prepend(funcPrepend); - } else { - // Discard debug log in non-debug Qv2ray version with no-debugLog mode. + if (type == QV2RAY_LOG_DEBUG) + { + if (StartupOption.debugLog) { logString = logString.prepend(funcPrepend); } + else + { + // Discard debug log in non-debug Qv2ray version with + // no-debugLog mode. return; } } @@ -50,4 +56,4 @@ namespace Qv2ray::base __purgerBuffer->clear(); return result; } -} +} // namespace Qv2ray::base diff --git a/src/base/Qv2rayLog.hpp b/src/base/Qv2rayLog.hpp index a06c20e5..2043403a 100644 --- a/src/base/Qv2rayLog.hpp +++ b/src/base/Qv2rayLog.hpp @@ -17,17 +17,17 @@ namespace Qv2ray::base { void __QV2RAY_LOG_FUNC__(int type, const std::string &func, int line, const QString &module, const QString &log); const QString readLastLog(); -} +} // namespace Qv2ray::base #define NEWLINE "\r\n" #define QV2RAY_LOG_NORMAL 0 -#define QV2RAY_LOG_DEBUG 1 +#define QV2RAY_LOG_DEBUG 1 #ifndef Q_OS_WIN -#define Qv2ray_PRETTY_FUNCTION __PRETTY_FUNCTION__ + #define Qv2ray_PRETTY_FUNCTION __PRETTY_FUNCTION__ #else -#define Qv2ray_PRETTY_FUNCTION __FUNCSIG__ + #define Qv2ray_PRETTY_FUNCTION __FUNCSIG__ #endif #define __LOG_IMPL(LEVEL, MODULE, MSG) __QV2RAY_LOG_FUNC__(LEVEL, Qv2ray_PRETTY_FUNCTION, __LINE__, MODULE, MSG); @@ -36,23 +36,23 @@ namespace Qv2ray::base #define DEBUG(MODULE, MSG) __LOG_IMPL(QV2RAY_LOG_DEBUG, (MODULE), (MSG)); // Log modules used by Qv2ray -const inline QString MODULE_INIT = "INIT" ; -const inline QString MODULE_MESSAGING = "BASE-MESSAGING" ; -const inline QString MODULE_UI = "CORE-UI" ; -const inline QString MODULE_GRAPH = "CORE-UI-GRAPH" ; -const inline QString MODULE_SETTINGS = "CORE-SETTINGS" ; -const inline QString MODULE_VCORE = "CORE-VCORE" ; +const inline QString MODULE_INIT = "INIT"; +const inline QString MODULE_MESSAGING = "BASE-MESSAGING"; +const inline QString MODULE_UI = "CORE-UI"; +const inline QString MODULE_GRAPH = "CORE-UI-GRAPH"; +const inline QString MODULE_SETTINGS = "CORE-SETTINGS"; +const inline QString MODULE_VCORE = "CORE-VCORE"; // -const inline QString MODULE_CONNECTION = "CORE-CONNECTION" ; -const inline QString MODULE_SUBSCRIPTION = "CORE-SUBSCRIPTION" ; -const inline QString MODULE_IMPORT = "CORE-IMPORT" ; -const inline QString MODULE_EXPORT = "CORE-EXPORT" ; +const inline QString MODULE_CONNECTION = "CORE-CONNECTION"; +const inline QString MODULE_SUBSCRIPTION = "CORE-SUBSCRIPTION"; +const inline QString MODULE_IMPORT = "CORE-IMPORT"; +const inline QString MODULE_EXPORT = "CORE-EXPORT"; // -const inline QString MODULE_NETWORK = "COMMON-NETWORK" ; -const inline QString MODULE_FILEIO = "COMMON-FILEIO" ; +const inline QString MODULE_NETWORK = "COMMON-NETWORK"; +const inline QString MODULE_FILEIO = "COMMON-FILEIO"; // -const inline QString MODULE_PROXY = "COMPONENT-PROXY" ; -const inline QString MODULE_UPDATE = "COMPONENT-UPDATE" ; -const inline QString MODULE_PLUGIN = "COMPONENT-PLUGIN" ; +const inline QString MODULE_PROXY = "COMPONENT-PROXY"; +const inline QString MODULE_UPDATE = "COMPONENT-UPDATE"; +const inline QString MODULE_PLUGIN = "COMPONENT-PLUGIN"; // ================================================================ -const inline QString MODULE_CORE_HANDLER = "QV2RAY-CORE"; +const inline QString MODULE_CORE_HANDLER = "QV2RAY-CORE"; diff --git a/src/base/models/CoreObjectModels.hpp b/src/base/models/CoreObjectModels.hpp index c8294b9b..7500273e 100644 --- a/src/base/models/CoreObjectModels.hpp +++ b/src/base/models/CoreObjectModels.hpp @@ -1,37 +1,46 @@ #pragma once -#include +#include "3rdparty/x2struct/x2struct.hpp" + #include #include -#include "3rdparty/x2struct/x2struct.hpp" +#include namespace Qv2ray::base::objects { // // Used in config generation - struct AccountObject { + struct AccountObject + { QString user; QString pass; XTOSTRUCT(O(user, pass)) }; // // - struct ApiObject { + struct ApiObject + { QString tag; QList services; - ApiObject() : tag("api"), services() {} + ApiObject() : tag("api"), services() + { + } XTOSTRUCT(O(tag, services)) }; // // - struct SystemPolicyObject { + struct SystemPolicyObject + { bool statsInboundUplink; bool statsInboundDownlink; - SystemPolicyObject() : statsInboundUplink(), statsInboundDownlink() {} + SystemPolicyObject() : statsInboundUplink(), statsInboundDownlink() + { + } XTOSTRUCT(O(statsInboundUplink, statsInboundDownlink)) }; // // - struct LevelPolicyObject { + struct LevelPolicyObject + { int handshake; int connIdle; int uplinkOnly; @@ -39,20 +48,26 @@ namespace Qv2ray::base::objects bool statsUserUplink; bool statsUserDownlink; int bufferSize; - LevelPolicyObject(): handshake(), connIdle(), uplinkOnly(), downlinkOnly(), statsUserUplink(), statsUserDownlink(), bufferSize() {} + LevelPolicyObject() : handshake(), connIdle(), uplinkOnly(), downlinkOnly(), statsUserUplink(), statsUserDownlink(), bufferSize() + { + } XTOSTRUCT(O(handshake, connIdle, uplinkOnly, downlinkOnly, statsUserUplink, statsUserDownlink, bufferSize)) }; // // - struct PolicyObject { + struct PolicyObject + { QMap level; QList system; - PolicyObject(): level(), system() {} + PolicyObject() : level(), system() + { + } XTOSTRUCT(O(level, system)) }; // // - struct RuleObject { + struct RuleObject + { // Added due to the request of @aliyuchang33 bool QV2RAY_RULE_ENABLED; bool QV2RAY_RULE_USE_BALANCER; @@ -70,65 +85,89 @@ namespace Qv2ray::base::objects QString attrs; QString outboundTag; QString balancerTag; - RuleObject() : QV2RAY_RULE_ENABLED(true), QV2RAY_RULE_USE_BALANCER(false), QV2RAY_RULE_TAG("new rule"), type("field"), domain(), ip(), port("1-65535"), network(""), source(), user(), inboundTag(), protocol(), attrs(), outboundTag(""), balancerTag("") {} - XTOSTRUCT(O(QV2RAY_RULE_ENABLED, QV2RAY_RULE_USE_BALANCER, QV2RAY_RULE_TAG, type, domain, ip, port, network, source, user, inboundTag, protocol, attrs, outboundTag, balancerTag)) + RuleObject() + : QV2RAY_RULE_ENABLED(true), QV2RAY_RULE_USE_BALANCER(false), QV2RAY_RULE_TAG("new rule"), type("field"), domain(), ip(), + port("1-65535"), network(""), source(), user(), inboundTag(), protocol(), attrs(), outboundTag(""), balancerTag("") + { + } + XTOSTRUCT(O(QV2RAY_RULE_ENABLED, QV2RAY_RULE_USE_BALANCER, QV2RAY_RULE_TAG, type, domain, ip, port, network, source, user, inboundTag, + protocol, attrs, outboundTag, balancerTag)) }; // // - struct BalancerObject { - QString tag ; + struct BalancerObject + { + QString tag; QList selector; - BalancerObject() : tag(), selector() {} + BalancerObject() : tag(), selector() + { + } XTOSTRUCT(O(tag, selector)) }; // // namespace transfer { - struct HTTPRequestObject { + struct HTTPRequestObject + { QString version; QString method; QList path; QMap> headers; - HTTPRequestObject(): version("1.1"), method("GET"), path(), headers() {} + HTTPRequestObject() : version("1.1"), method("GET"), path(), headers() + { + } XTOSTRUCT(O(version, method, path, headers)) }; // // - struct HTTPResponseObject { + struct HTTPResponseObject + { QString version; QString status; QString reason; QMap> headers; - HTTPResponseObject(): version("1.1"), status("200"), reason("OK"), headers() {} + HTTPResponseObject() : version("1.1"), status("200"), reason("OK"), headers() + { + } XTOSTRUCT(O(version, status, reason, headers)) }; // // - struct TCPHeader_M_Object { + struct TCPHeader_M_Object + { QString type; HTTPRequestObject request; HTTPResponseObject response; - TCPHeader_M_Object(): type("none"), request(), response() {} + TCPHeader_M_Object() : type("none"), request(), response() + { + } XTOSTRUCT(O(type, request, response)) }; // // - struct HeaderObject { + struct HeaderObject + { QString type; - HeaderObject(): type("none") {} + HeaderObject() : type("none") + { + } XTOSTRUCT(O(type)) }; // // - struct TCPObject { + struct TCPObject + { TCPHeader_M_Object header; - TCPObject(): header() {} + TCPObject() : header() + { + } XTOSTRUCT(O(header)) }; // // - struct KCPObject { + struct KCPObject + { int mtu = 1350; int tti = 20; int uplinkCapacity = 5; @@ -137,84 +176,111 @@ namespace Qv2ray::base::objects int readBufferSize = 1; int writeBufferSize = 1; HeaderObject header; - KCPObject(): header() {} + KCPObject() : header() + { + } XTOSTRUCT(O(mtu, tti, uplinkCapacity, downlinkCapacity, congestion, readBufferSize, writeBufferSize, header)) }; // // - struct WebSocketObject { + struct WebSocketObject + { QString path; QMap headers; - WebSocketObject(): path("/"), headers() {} + WebSocketObject() : path("/"), headers() + { + } XTOSTRUCT(O(path, headers)) }; // // - struct HttpObject { + struct HttpObject + { QList host; QString path; - HttpObject() : host(), path("/") {} + HttpObject() : host(), path("/") + { + } XTOSTRUCT(O(host, path)) }; // // - struct DomainSocketObject { + struct DomainSocketObject + { QString path; - DomainSocketObject(): path("/") {} + DomainSocketObject() : path("/") + { + } XTOSTRUCT(O(path)) }; // // - struct QuicObject { + struct QuicObject + { QString security; QString key; HeaderObject header; - QuicObject(): security(""), key(""), header() {} + QuicObject() : security(""), key(""), header() + { + } XTOSTRUCT(O(security, key, header)) }; // // - struct SockoptObject { + struct SockoptObject + { int mark; bool tcpFastOpen; QString tproxy; - SockoptObject(): mark(0), tcpFastOpen(false), tproxy("off") {} + SockoptObject() : mark(0), tcpFastOpen(false), tproxy("off") + { + } XTOSTRUCT(O(mark, tcpFastOpen, tproxy)) }; // // - struct CertificateObject { + struct CertificateObject + { QString usage; QString certificateFile; QString keyFile; QList certificate; QList key; - CertificateObject(): usage(), certificateFile(), keyFile(), certificate(), key() {} + CertificateObject() : usage(), certificateFile(), keyFile(), certificate(), key() + { + } XTOSTRUCT(O(usage, certificateFile, keyFile, certificate, key)) }; // // - struct TLSObject { + struct TLSObject + { QString serverName; bool allowInsecure; QList alpn; QList certificates; bool disableSystemRoot; - TLSObject(): serverName(), allowInsecure(), certificates(), disableSystemRoot() {} + TLSObject() : serverName(), allowInsecure(), certificates(), disableSystemRoot() + { + } XTOSTRUCT(O(serverName, allowInsecure, alpn, certificates, disableSystemRoot)) }; - } + } // namespace transfer // // - struct SniffingObject { + struct SniffingObject + { bool enabled = false; QList destOverride; - SniffingObject(): enabled(), destOverride() {} + SniffingObject() : enabled(), destOverride() + { + } XTOSTRUCT(O(enabled, destOverride)) }; // // - struct StreamSettingsObject { + struct StreamSettingsObject + { QString network; QString security; transfer::SockoptObject sockopt; @@ -225,15 +291,22 @@ namespace Qv2ray::base::objects transfer::HttpObject httpSettings; transfer::DomainSocketObject dsSettings; transfer::QuicObject quicSettings; - StreamSettingsObject(): network("tcp"), security("none"), sockopt(), tlsSettings(), tcpSettings(), kcpSettings(), wsSettings(), httpSettings(), dsSettings(), quicSettings() {} + StreamSettingsObject() + : network("tcp"), security("none"), sockopt(), tlsSettings(), tcpSettings(), kcpSettings(), wsSettings(), httpSettings(), + dsSettings(), quicSettings() + { + } XTOSTRUCT(O(network, security, sockopt, tcpSettings, tlsSettings, kcpSettings, wsSettings, httpSettings, dsSettings, quicSettings)) }; // // - struct MuxObject { + struct MuxObject + { bool enabled; int concurrency; - MuxObject(): enabled(), concurrency() {} + MuxObject() : enabled(), concurrency() + { + } XTOSTRUCT(O(enabled, concurrency)) }; // @@ -241,21 +314,28 @@ namespace Qv2ray::base::objects namespace protocol { // DNS, OutBound - struct DNSOut { + struct DNSOut + { QString network; QString address; int port; - DNSOut(): network(""), address("0.0.0.0"), port(0) {} + DNSOut() : network(""), address("0.0.0.0"), port(0) + { + } XTOSTRUCT(O(network, address, port)) }; // // MTProto, InBound || OutBound - struct MTProtoIn { - struct UserObject { + struct MTProtoIn + { + struct UserObject + { QString email; int level; QString secret; - UserObject() : email("user@domain.com"), level(0), secret("") {} + UserObject() : email("user@domain.com"), level(0), secret("") + { + } XTOSTRUCT(O(email, level, secret)) }; QList users; @@ -263,42 +343,55 @@ namespace Qv2ray::base::objects }; // // Socks, OutBound - struct SocksServerObject { - struct UserObject { + struct SocksServerObject + { + struct UserObject + { QString user; QString pass; int level; - UserObject(): user("username"), pass("password"), level(0) {} + UserObject() : user("username"), pass("password"), level(0) + { + } XTOSTRUCT(O(user, pass, level)) }; QString address; int port; QList users; - SocksServerObject(): address("0.0.0.0"), port(0), users() {} + SocksServerObject() : address("0.0.0.0"), port(0), users() + { + } XTOSTRUCT(O(address, port, users)) }; // // VMess Server - struct VMessServerObject { - struct UserObject { + struct VMessServerObject + { + struct UserObject + { QString id; int alterId; QString security; int level; - UserObject() : id(""), alterId(64), security("auto"), level(0) {} + UserObject() : id(""), alterId(64), security("auto"), level(0) + { + } XTOSTRUCT(O(id, alterId, security, level)) }; QString address; int port; QList users; - VMessServerObject(): address(""), port(0), users() {} + VMessServerObject() : address(""), port(0), users() + { + } XTOSTRUCT(O(address, port, users)) }; // // ShadowSocks Server - struct ShadowSocksServerObject { + struct ShadowSocksServerObject + { QString email; QString address; QString method; @@ -306,8 +399,11 @@ namespace Qv2ray::base::objects bool ota; int level; int port; - ShadowSocksServerObject(): email("user@domain.com"), address("0.0.0.0"), method("aes-256-cfb"), password(""), ota(false), level(0), port(0) {} + ShadowSocksServerObject() + : email("user@domain.com"), address("0.0.0.0"), method("aes-256-cfb"), password(""), ota(false), level(0), port(0) + { + } XTOSTRUCT(O(email, address, port, method, password, ota, level)) }; - } -} + } // namespace protocol +} // namespace Qv2ray::base::objects diff --git a/src/base/models/QvConfigIdentifier.hpp b/src/base/models/QvConfigIdentifier.hpp index 8f871966..b35fd8f3 100644 --- a/src/base/models/QvConfigIdentifier.hpp +++ b/src/base/models/QvConfigIdentifier.hpp @@ -1,38 +1,50 @@ #pragma once +#include "3rdparty/x2struct/x2struct.hpp" + #include #include -#include "3rdparty/x2struct/x2struct.hpp" namespace Qv2ray::base { using namespace std::chrono; // Common struct for Groups and Subscriptions - struct GroupObject_Config { + struct GroupObject_Config + { QString displayName; QList connections; int64_t importDate; - GroupObject_Config(): displayName(), connections(), importDate() { } + GroupObject_Config() : displayName(), connections(), importDate() + { + } XTOSTRUCT(O(displayName, connections, importDate)) }; - struct SubscriptionObject_Config : GroupObject_Config { + struct SubscriptionObject_Config : GroupObject_Config + { // QString address; int64_t lastUpdated; float updateInterval; - SubscriptionObject_Config(): address(""), lastUpdated(system_clock::to_time_t(system_clock::now())), updateInterval(10) { } + SubscriptionObject_Config() : address(""), lastUpdated(system_clock::to_time_t(system_clock::now())), updateInterval(10) + { + } XTOSTRUCT(O(lastUpdated, updateInterval, address, connections, displayName, importDate)) }; - struct ConnectionObject_Config { + struct ConnectionObject_Config + { QString displayName; int64_t importDate; int64_t lastConnected; int64_t latency; int64_t upLinkData; int64_t downLinkData; - ConnectionObject_Config(): displayName(), importDate(system_clock::to_time_t(system_clock::now())), lastConnected(), latency(0), upLinkData(0), downLinkData(0) { } + ConnectionObject_Config() + : displayName(), importDate(system_clock::to_time_t(system_clock::now())), lastConnected(), latency(0), upLinkData(0), + downLinkData(0) + { + } XTOSTRUCT(O(displayName, importDate, lastConnected, latency, upLinkData, downLinkData)) }; -} +} // namespace Qv2ray::base using namespace Qv2ray::base; diff --git a/src/base/models/QvConfigModel.hpp b/src/base/models/QvConfigModel.hpp index 7ca44201..521fc4f1 100644 --- a/src/base/models/QvConfigModel.hpp +++ b/src/base/models/QvConfigModel.hpp @@ -2,46 +2,59 @@ #include "3rdparty/x2struct/x2struct.hpp" #include "base/models/CoreObjectModels.hpp" #include "base/models/QvConfigIdentifier.hpp" + #include const int QV2RAY_CONFIG_VERSION = 9; namespace Qv2ray::base::config { - struct QvBarLine { + struct QvBarLine + { QString Family; bool Bold, Italic; int ColorA, ColorR, ColorG, ColorB; int ContentType; double Size; QString Message; - QvBarLine(): Family("Consolas"), Bold(true), Italic(false), ColorA(255), ColorR(255), ColorG(255), ColorB(255), - ContentType(0), Size(9), Message("") { } + QvBarLine() + : Family("Consolas"), Bold(true), Italic(false), ColorA(255), ColorR(255), ColorG(255), ColorB(255), ContentType(0), Size(9), + Message("") + { + } XTOSTRUCT(O(Bold, Italic, ColorA, ColorR, ColorG, ColorB, Size, Family, Message, ContentType)) }; - struct QvBarPage { + struct QvBarPage + { int OffsetYpx; QList Lines; - QvBarPage(): OffsetYpx(5) { } + QvBarPage() : OffsetYpx(5) + { + } XTOSTRUCT(O(OffsetYpx, Lines)) }; - struct Qv2rayToolBarConfig { + struct Qv2rayToolBarConfig + { QList Pages; XTOSTRUCT(O(Pages)) }; - struct Qv2rayPACConfig { + struct Qv2rayPACConfig + { bool enablePAC; int port; QString localIP; bool useSocksProxy; - Qv2rayPACConfig(): enablePAC(false), port(8989), useSocksProxy(false) { } + Qv2rayPACConfig() : enablePAC(false), port(8989), useSocksProxy(false) + { + } XTOSTRUCT(O(enablePAC, port, localIP, useSocksProxy)) }; - struct Qv2rayForwardProxyConfig { + struct Qv2rayForwardProxyConfig + { bool enableForwardProxy; QString type; QString serverAddress; @@ -49,12 +62,15 @@ namespace Qv2ray::base::config bool useAuth; QString username; QString password; - Qv2rayForwardProxyConfig(): enableForwardProxy(false), type("http"), serverAddress("127.0.0.1"), port(8008), - useAuth(false), username(), password() { } + Qv2rayForwardProxyConfig() + : enableForwardProxy(false), type("http"), serverAddress("127.0.0.1"), port(8008), useAuth(false), username(), password() + { + } XTOSTRUCT(O(enableForwardProxy, type, serverAddress, port, useAuth, username, password)) }; - struct Qv2rayInboundsConfig { + struct Qv2rayInboundsConfig + { QString listenip; bool setSystemProxy; Qv2rayPACConfig pacConfig; @@ -72,42 +88,56 @@ namespace Qv2ray::base::config bool http_useAuth; objects::AccountObject httpAccount; - Qv2rayInboundsConfig(): - listenip("127.0.0.1"), setSystemProxy(false), pacConfig(), - useSocks(true), socks_port(1088), socks_useAuth(false), socksUDP(true), socksLocalIP("127.0.0.1"), socksAccount(), - useHTTP(true), http_port(8888), http_useAuth(false), httpAccount() {} + Qv2rayInboundsConfig() + : listenip("127.0.0.1"), setSystemProxy(false), pacConfig(), useSocks(true), socks_port(1088), socks_useAuth(false), socksUDP(true), + socksLocalIP("127.0.0.1"), socksAccount(), useHTTP(true), http_port(8888), http_useAuth(false), httpAccount() + { + } - XTOSTRUCT(O(setSystemProxy, pacConfig, listenip, useSocks, useHTTP, socks_port, socks_useAuth, socksAccount, socksUDP, socksLocalIP, http_port, http_useAuth, httpAccount)) + XTOSTRUCT(O(setSystemProxy, pacConfig, listenip, useSocks, useHTTP, socks_port, socks_useAuth, socksAccount, socksUDP, socksLocalIP, + http_port, http_useAuth, httpAccount)) }; - struct Qv2rayUIConfig { + struct Qv2rayUIConfig + { QString theme; QString language; bool useDarkTheme; bool useDarkTrayIcon; int maximumLogLines; - Qv2rayUIConfig() : theme("Fusion"), language("en_US"), useDarkTheme(false), useDarkTrayIcon(true), maximumLogLines(500) { } + Qv2rayUIConfig() : theme("Fusion"), language("en_US"), useDarkTheme(false), useDarkTrayIcon(true), maximumLogLines(500) + { + } XTOSTRUCT(O(theme, language, useDarkTheme, useDarkTrayIcon, maximumLogLines)) }; - struct Qv2rayConnectionConfig { + struct Qv2rayConnectionConfig + { bool bypassCN; bool enableProxy; bool withLocalDNS; QList dnsList; Qv2rayForwardProxyConfig forwardProxyConfig; - Qv2rayConnectionConfig() : bypassCN(true), enableProxy(true), withLocalDNS(false), dnsList(QStringList() << "8.8.4.4" << "1.1.1.1") { } + Qv2rayConnectionConfig() + : bypassCN(true), enableProxy(true), withLocalDNS(false), dnsList(QStringList() << "8.8.4.4" + << "1.1.1.1") + { + } XTOSTRUCT(O(bypassCN, enableProxy, withLocalDNS, dnsList, forwardProxyConfig)) }; - struct Qv2rayAPIConfig { + struct Qv2rayAPIConfig + { bool enableAPI; int statsPort; - Qv2rayAPIConfig(): enableAPI(true), statsPort(15490) { } + Qv2rayAPIConfig() : enableAPI(true), statsPort(15490) + { + } XTOSTRUCT(O(enableAPI, statsPort)) }; - struct Qv2rayConfig { + struct Qv2rayConfig + { int config_version; bool tProxySupport; int logLevel; @@ -129,23 +159,13 @@ namespace Qv2ray::base::config Qv2rayInboundsConfig inboundConfig; Qv2rayConnectionConfig connectionConfig; - Qv2rayConfig(): - config_version(QV2RAY_CONFIG_VERSION), - tProxySupport(false), - logLevel(), - v2CorePath(), - v2AssetsPath(), - ignoredVersion(), - groups(), - subscriptions(), - connections(), - uiConfig(), apiConfig(), toolBarConfig(), inboundConfig(), connectionConfig() { } + Qv2rayConfig() + : config_version(QV2RAY_CONFIG_VERSION), tProxySupport(false), logLevel(), v2CorePath(), v2AssetsPath(), ignoredVersion(), groups(), + subscriptions(), connections(), uiConfig(), apiConfig(), toolBarConfig(), inboundConfig(), connectionConfig() + { + } - XTOSTRUCT(O(config_version, ignoredVersion, - tProxySupport, - logLevel, uiConfig, - v2CorePath, v2AssetsPath, - groups, connections, subscriptions, - autoStartId, inboundConfig, connectionConfig, toolBarConfig, apiConfig)) + XTOSTRUCT(O(config_version, ignoredVersion, tProxySupport, logLevel, uiConfig, v2CorePath, v2AssetsPath, groups, connections, + subscriptions, autoStartId, inboundConfig, connectionConfig, toolBarConfig, apiConfig)) }; -} +} // namespace Qv2ray::base::config diff --git a/src/base/models/QvRuntimeConfig.hpp b/src/base/models/QvRuntimeConfig.hpp index 944dd4a1..8995e7f4 100644 --- a/src/base/models/QvRuntimeConfig.hpp +++ b/src/base/models/QvRuntimeConfig.hpp @@ -5,8 +5,9 @@ namespace Qv2ray::base { - struct Qv2rayRuntimeConfig { + struct Qv2rayRuntimeConfig + { // bool screenShotHideQv2ray = false; }; -} +} // namespace Qv2ray::base diff --git a/src/base/models/QvSafeType.hpp b/src/base/models/QvSafeType.hpp index 0244f8ed..adf17f6d 100644 --- a/src/base/models/QvSafeType.hpp +++ b/src/base/models/QvSafeType.hpp @@ -1,15 +1,22 @@ #pragma once -#include #include #include +#include -#define SAFE_TYPEDEF_EXTRA(Base, name, extra) \ - class name : public Base { \ - public: \ - template \ - explicit name (Args... args) : Base(args...) {} \ - const Base& raw() const { return *this; } \ - extra }; +#define SAFE_TYPEDEF_EXTRA(Base, name, extra) \ + class name : public Base \ + { \ + public: \ + template \ + explicit name(Args... args) : Base(args...) \ + { \ + } \ + const Base &raw() const \ + { \ + return *this; \ + } \ + extra \ + }; #define nothing #define SAFE_TYPEDEF(Base, name) SAFE_TYPEDEF_EXTRA(Base, name, nothing) @@ -31,5 +38,4 @@ namespace Qv2ray::base::safetype SAFE_TYPEDEF(QJsonObject, ROUTERULE) SAFE_TYPEDEF(INOUTLIST, OUTBOUNDS) SAFE_TYPEDEF(INOUTLIST, INBOUNDS) -} - +} // namespace Qv2ray::base::safetype diff --git a/src/base/models/QvStartupConfig.hpp b/src/base/models/QvStartupConfig.hpp index 224a9635..21c61b0e 100644 --- a/src/base/models/QvStartupConfig.hpp +++ b/src/base/models/QvStartupConfig.hpp @@ -4,7 +4,8 @@ namespace Qv2ray { namespace base { - struct QvStartupOptions { + struct QvStartupOptions + { /// No API subsystem bool noAPI; /// Explicitly run as root user. @@ -14,5 +15,5 @@ namespace Qv2ray /// Enable Network toolbar plugin. bool enableToolbarPlguin; }; - } -} + } // namespace base +} // namespace Qv2ray diff --git a/src/common/CommandArgs.cpp b/src/common/CommandArgs.cpp index 54081b41..b394c850 100644 --- a/src/common/CommandArgs.cpp +++ b/src/common/CommandArgs.cpp @@ -1,15 +1,16 @@ #include "CommandArgs.hpp" + #include "base/Qv2rayBase.hpp" namespace Qv2ray::common { - QvCommandArgParser::QvCommandArgParser() : QObject(), - noAPIOption("noAPI", QObject::tr("Disable gRPC API subsystems.")), - runAsRootOption("I-just-wanna-run-with-root", QObject::tr("Explicitly run Qv2ray as root.")), - debugOption("debug", QObject::tr("Enable Debug Output")), - withToolbarOption("withToolbarPlugin", QObject::tr("Enable Qv2ray network toolbar plugin")), - // - helpOption("FAKE"), versionOption("FAKE") + QvCommandArgParser::QvCommandArgParser() + : QObject(), noAPIOption("noAPI", QObject::tr("Disable gRPC API subsystems.")), + runAsRootOption("I-just-wanna-run-with-root", QObject::tr("Explicitly run Qv2ray as root.")), + debugOption("debug", QObject::tr("Enable Debug Output")), + withToolbarOption("withToolbarPlugin", QObject::tr("Enable Qv2ray network toolbar plugin")), + // + helpOption("FAKE"), versionOption("FAKE") { parser.setApplicationDescription(QObject::tr("Qv2ray - A cross-platform Qt frontend for V2ray.")); parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); @@ -24,33 +25,36 @@ namespace Qv2ray::common CommandLineParseResult QvCommandArgParser::ParseCommandLine(QString *errorMessage) { - if (!parser.parse(QCoreApplication::arguments())) { + if (!parser.parse(QCoreApplication::arguments())) + { *errorMessage = parser.errorText(); return CommandLineError; } - if (parser.isSet(versionOption)) - return CommandLineVersionRequested; + if (parser.isSet(versionOption)) return CommandLineVersionRequested; - if (parser.isSet(helpOption)) - return CommandLineHelpRequested; + if (parser.isSet(helpOption)) return CommandLineHelpRequested; - if (parser.isSet(noAPIOption)) { + if (parser.isSet(noAPIOption)) + { DEBUG(MODULE_INIT, "noAPIOption is set.") StartupOption.noAPI = true; } - if (parser.isSet(runAsRootOption)) { + if (parser.isSet(runAsRootOption)) + { DEBUG(MODULE_INIT, "runAsRootOption is set.") StartupOption.forceRunAsRootUser = true; } - if (parser.isSet(debugOption)) { + if (parser.isSet(debugOption)) + { DEBUG(MODULE_INIT, "debugOption is set.") StartupOption.debugLog = true; } - if (parser.isSet(withToolbarOption)) { + if (parser.isSet(withToolbarOption)) + { DEBUG(MODULE_INIT, "withToolbarOption is set.") StartupOption.enableToolbarPlguin = true; } @@ -58,4 +62,4 @@ namespace Qv2ray::common return CommandLineOk; } -} +} // namespace Qv2ray::common diff --git a/src/common/CommandArgs.hpp b/src/common/CommandArgs.hpp index 72092b52..d77444e7 100644 --- a/src/common/CommandArgs.hpp +++ b/src/common/CommandArgs.hpp @@ -4,7 +4,8 @@ namespace Qv2ray::common { - enum CommandLineParseResult { + enum CommandLineParseResult + { CommandLineOk, CommandLineError, CommandLineVersionRequested, @@ -12,24 +13,24 @@ namespace Qv2ray::common }; class QvCommandArgParser : public QObject { - Q_OBJECT - public: - QvCommandArgParser(); - CommandLineParseResult ParseCommandLine(QString *errorMessage); - const QCommandLineParser *Parser() - { - return &parser; - } + Q_OBJECT + public: + QvCommandArgParser(); + CommandLineParseResult ParseCommandLine(QString *errorMessage); + const QCommandLineParser *Parser() + { + return &parser; + } - private: - QCommandLineParser parser; - QCommandLineOption noAPIOption; - QCommandLineOption runAsRootOption; - QCommandLineOption debugOption; - QCommandLineOption withToolbarOption; - QCommandLineOption helpOption; - QCommandLineOption versionOption; + private: + QCommandLineParser parser; + QCommandLineOption noAPIOption; + QCommandLineOption runAsRootOption; + QCommandLineOption debugOption; + QCommandLineOption withToolbarOption; + QCommandLineOption helpOption; + QCommandLineOption versionOption; }; -} +} // namespace Qv2ray::common using namespace Qv2ray::common; diff --git a/src/common/HTTPRequestHelper.cpp b/src/common/HTTPRequestHelper.cpp index dbf2856d..eead1a0e 100644 --- a/src/common/HTTPRequestHelper.cpp +++ b/src/common/HTTPRequestHelper.cpp @@ -1,7 +1,9 @@ #include "HTTPRequestHelper.hpp" + +#include "base/Qv2rayBase.hpp" + #include #include -#include "base/Qv2rayBase.hpp" namespace Qv2ray::common { @@ -18,7 +20,8 @@ namespace Qv2ray::common { QUrl qUrl = QUrl(url); - if (!qUrl.isValid()) { + if (!qUrl.isValid()) + { LOG(MODULE_NETWORK, "Provided URL is invalid: " + url) return false; } @@ -37,11 +40,14 @@ namespace Qv2ray::common { this->setUrl(url); - if (useProxy) { + if (useProxy) + { auto proxy = QNetworkProxyFactory::systemProxyForQuery(); accessManager.setProxy(proxy.first()); LOG(MODULE_NETWORK, "Sync get is using system proxy settings") - } else { + } + else + { accessManager.setProxy(QNetworkProxy(QNetworkProxy::ProxyType::NoProxy)); } @@ -62,28 +68,34 @@ namespace Qv2ray::common void QvHttpRequestHelper::get(const QString &url) { this->setUrl(url); - // request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); + // request.setRawHeader("Content-Type", + // "application/x-www-form-urlencoded"); reply = accessManager.get(request); connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished_p); connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead); } - //void QvHttpRequestHelper::post(const QString &url, const QByteArray &data) + // void QvHttpRequestHelper::post(const QString &url, const QByteArray + // &data) //{ // this->setUrl(url); // request.setRawHeader("Content-Type", "application/json"); // reply = accessManager.post(request, data); - // connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished); - // connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead); + // connect(reply, &QNetworkReply::finished, this, + // &QvHttpRequestHelper::onRequestFinished); connect(reply, + // &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead); //} - // void QvHttpRequestHelper::put(const QString &url, const QByteArray &data) + // void QvHttpRequestHelper::put(const QString &url, const QByteArray + // &data) // { // this->setUrl(url); // request.setRawHeader("Content-Type", "application/json"); // reply = accessManager.put(request, data); - // connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished); - // connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead); + // connect(reply, &QNetworkReply::finished, this, + // &QvHttpRequestHelper::onRequestFinished); connect(reply, + // &QNetworkReply::readyRead, this, + // &QvHttpRequestHelper::onReadyRead); // } // void QvHttpRequestHelper::del(const QString &url) @@ -91,26 +103,31 @@ namespace Qv2ray::common // this->setUrl(url); // request.setRawHeader("Content-Type", "application/json"); // reply = accessManager.deleteResource(request); - // connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished); - // connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead); + // connect(reply, &QNetworkReply::finished, this, + // &QvHttpRequestHelper::onRequestFinished); connect(reply, + // &QNetworkReply::readyRead, this, + // &QvHttpRequestHelper::onReadyRead); // } - // void QvHttpRequestHelper::login(const QString &url, const QByteArray &data) + // void QvHttpRequestHelper::login(const QString &url, const QByteArray + // &data) // { // this->setUrl(url); - // request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); - // reply = accessManager.post(request, data); - // connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished); - // connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead); + // request.setRawHeader("Content-Type", + // "application/x-www-form-urlencoded"); reply = + // accessManager.post(request, data); connect(reply, + // &QNetworkReply::finished, this, + // &QvHttpRequestHelper::onRequestFinished); connect(reply, + // &QNetworkReply::readyRead, this, + // &QvHttpRequestHelper::onReadyRead); // } void QvHttpRequestHelper::onRequestFinished_p() { - if (reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute).toBool()) { - DEBUG(MODULE_NETWORK, "HTTP/2 was used.") - } + if (reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute).toBool()) { DEBUG(MODULE_NETWORK, "HTTP/2 was used.") } - if (reply->error() != QNetworkReply::NoError) { + if (reply->error() != QNetworkReply::NoError) + { QString error = QMetaEnum::fromType().key(reply->error()); LOG(MODULE_NETWORK, "Network request error string: " + error) QByteArray empty; @@ -125,4 +142,4 @@ namespace Qv2ray::common DEBUG(MODULE_NETWORK, "A request is now ready read") this->data += reply->readAll(); } -} +} // namespace Qv2ray::common diff --git a/src/common/HTTPRequestHelper.hpp b/src/common/HTTPRequestHelper.hpp index 73c08d3b..00b1c611 100644 --- a/src/common/HTTPRequestHelper.hpp +++ b/src/common/HTTPRequestHelper.hpp @@ -18,45 +18,46 @@ #pragma once -#include -#include -#include #include +#include +#include +#include namespace Qv2ray::common { class QvHttpRequestHelper : public QObject { - Q_OBJECT - public: - explicit QvHttpRequestHelper(); - ~QvHttpRequestHelper(); - bool setUrl(const QString &url); - void setHeader(const QByteArray &key, const QByteArray &value); - // get - QByteArray syncget(const QString &url, bool useProxy); - void get(const QString &url); - //// insert - //void post(const QString &url, const QByteArray &data); - //// update - //void put(const QString &url, const QByteArray &data); - //// delete - //void del(const QString &url); - //void login(const QString &url, const QByteArray &data); - signals: - void httpRequestFinished(QByteArray &data); + Q_OBJECT + public: + explicit QvHttpRequestHelper(); + ~QvHttpRequestHelper(); + bool setUrl(const QString &url); + void setHeader(const QByteArray &key, const QByteArray &value); + // get + QByteArray syncget(const QString &url, bool useProxy); + void get(const QString &url); + //// insert + // void post(const QString &url, const QByteArray &data); + //// update + // void put(const QString &url, const QByteArray &data); + //// delete + // void del(const QString &url); + // void login(const QString &url, const QByteArray &data); + signals: + void httpRequestFinished(QByteArray &data); - public slots: - void onRequestFinished_p(); - private slots: - void onReadyRead(); - private: - QByteArray data; - QUrl url; - QNetworkReply *reply; - QNetworkRequest request; - QNetworkAccessManager accessManager; + public slots: + void onRequestFinished_p(); + private slots: + void onReadyRead(); + + private: + QByteArray data; + QUrl url; + QNetworkReply *reply; + QNetworkRequest request; + QNetworkAccessManager accessManager; }; -} +} // namespace Qv2ray::common using namespace Qv2ray::common; diff --git a/src/common/LogHighlighter.cpp b/src/common/LogHighlighter.cpp index e4ba39ec..46c6f42f 100644 --- a/src/common/LogHighlighter.cpp +++ b/src/common/LogHighlighter.cpp @@ -1,30 +1,32 @@ #include "LogHighlighter.hpp" + #include "common/QvHelpers.hpp" #define TO_EOL "(([\\s\\S]*)|([\\d\\D]*)|([\\w\\W]*))$" namespace Qv2ray::common { - SyntaxHighlighter::SyntaxHighlighter(bool darkMode, QTextDocument *parent) - : QSyntaxHighlighter(parent) + SyntaxHighlighter::SyntaxHighlighter(bool darkMode, QTextDocument *parent) : QSyntaxHighlighter(parent) { HighlightingRule rule; keywordFormat.setForeground(darkMode ? Qt::darkMagenta : Qt::magenta); keywordFormat.setFontWeight(QFont::Bold); - const QString keywordPatterns[] = { - "tcp", "udp" - }; + const QString keywordPatterns[] = { "tcp", "udp" }; - for (const QString &pattern : keywordPatterns) { + for (const QString &pattern : keywordPatterns) + { rule.pattern = QRegularExpression(pattern); rule.format = keywordFormat; highlightingRules.append(rule); } - if (darkMode) { + if (darkMode) + { ipHostFormat.setForeground(Qt::yellow); warningFormat.setForeground(QColor(230, 180, 0)); - } else { + } + else + { ipHostFormat.setForeground(Qt::black); ipHostFormat.setFontWeight(QFont::Bold); warningFormat.setForeground(Qt::white); @@ -49,7 +51,7 @@ namespace Qv2ray::common rule.format = debugFormat; highlightingRules.append(rule); // - infoFormat.setForeground(darkMode ? Qt::lightGray : Qt::darkCyan); + infoFormat.setForeground(darkMode ? Qt::lightGray : Qt::darkCyan); rule.pattern = QRegularExpression("\\[[Ii]nfo\\]" TO_EOL); rule.format = infoFormat; highlightingRules.append(rule); @@ -119,10 +121,12 @@ namespace Qv2ray::common void SyntaxHighlighter::highlightBlock(const QString &text) { - for (const HighlightingRule &rule : qAsConst(highlightingRules)) { + for (const HighlightingRule &rule : qAsConst(highlightingRules)) + { QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); - while (matchIterator.hasNext()) { + while (matchIterator.hasNext()) + { QRegularExpressionMatch match = matchIterator.next(); setFormat(match.capturedStart(), match.capturedLength(), rule.format); } @@ -130,4 +134,4 @@ namespace Qv2ray::common setCurrentBlockState(0); } -} +} // namespace Qv2ray::common diff --git a/src/common/LogHighlighter.hpp b/src/common/LogHighlighter.hpp index ba8c6edf..7a4284e0 100644 --- a/src/common/LogHighlighter.hpp +++ b/src/common/LogHighlighter.hpp @@ -49,45 +49,46 @@ ****************************************************************************/ #pragma once +#include #include #include -#include #include namespace Qv2ray::common { class SyntaxHighlighter : public QSyntaxHighlighter { - Q_OBJECT + Q_OBJECT - public: - explicit SyntaxHighlighter(bool darkMode, QTextDocument *parent = nullptr); + public: + explicit SyntaxHighlighter(bool darkMode, QTextDocument *parent = nullptr); - protected: - void highlightBlock(const QString &text) override; + protected: + void highlightBlock(const QString &text) override; - private: - struct HighlightingRule { - QRegularExpression pattern; - QTextCharFormat format; - }; - QVector highlightingRules; + private: + struct HighlightingRule + { + QRegularExpression pattern; + QTextCharFormat format; + }; + QVector highlightingRules; - QTextCharFormat keywordFormat; - QTextCharFormat dateFormat; - QTextCharFormat acceptedFormat; - QTextCharFormat rejectedFormat; - QTextCharFormat failedFormat; - QTextCharFormat warningFormat; - QTextCharFormat infoFormat; - QTextCharFormat debugFormat; - QTextCharFormat timeFormat; - QTextCharFormat ipHostFormat; - QTextCharFormat v2rayComponentFormat; - // - QTextCharFormat qvAppLogFormat; - QTextCharFormat qvAppDebugLogFormat; + QTextCharFormat keywordFormat; + QTextCharFormat dateFormat; + QTextCharFormat acceptedFormat; + QTextCharFormat rejectedFormat; + QTextCharFormat failedFormat; + QTextCharFormat warningFormat; + QTextCharFormat infoFormat; + QTextCharFormat debugFormat; + QTextCharFormat timeFormat; + QTextCharFormat ipHostFormat; + QTextCharFormat v2rayComponentFormat; + // + QTextCharFormat qvAppLogFormat; + QTextCharFormat qvAppDebugLogFormat; }; -} +} // namespace Qv2ray::common using namespace Qv2ray::common; diff --git a/src/common/QJsonModel.cpp b/src/common/QJsonModel.cpp index 479723a5..7dafbe60 100644 --- a/src/common/QJsonModel.cpp +++ b/src/common/QJsonModel.cpp @@ -10,8 +10,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,10 +23,10 @@ */ #include "QJsonModel.hpp" -#include -#include -#include +#include +#include +#include QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent) { @@ -60,8 +60,7 @@ int QJsonTreeItem::childCount() const int QJsonTreeItem::row() const { - if (mParent) - return mParent->mChilds.indexOf(const_cast(this)); + if (mParent) return mParent->mChilds.indexOf(const_cast(this)); return 0; } @@ -101,27 +100,34 @@ QJsonTreeItem *QJsonTreeItem::load(const QJsonValue &value, QJsonTreeItem *paren QJsonTreeItem *rootItem = new QJsonTreeItem(parent); rootItem->setKey("root"); - if (value.isObject()) { - //Get all QJsonValue childs - for (QString key : value.toObject().keys()) { + if (value.isObject()) + { + // Get all QJsonValue childs + for (QString key : value.toObject().keys()) + { QJsonValue v = value.toObject().value(key); QJsonTreeItem *child = load(v, rootItem); child->setKey(key); child->setType(v.type()); rootItem->appendChild(child); } - } else if (value.isArray()) { - //Get all QJsonValue childs + } + else if (value.isArray()) + { + // Get all QJsonValue childs int index = 0; - for (QJsonValue v : value.toArray()) { + for (QJsonValue v : value.toArray()) + { QJsonTreeItem *child = load(v, rootItem); child->setKey(QString::number(index)); child->setType(v.type()); rootItem->appendChild(child); ++index; } - } else { + } + else + { rootItem->setValue(value.toVariant().toString()); rootItem->setType(value.type()); } @@ -131,35 +137,27 @@ QJsonTreeItem *QJsonTreeItem::load(const QJsonValue &value, QJsonTreeItem *paren //========================================================================= -QJsonModel::QJsonModel(QObject *parent) - : QAbstractItemModel(parent) - , mRootItem{new QJsonTreeItem} +QJsonModel::QJsonModel(QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem } { mHeaders.append("key"); mHeaders.append("value"); } -QJsonModel::QJsonModel(const QString &fileName, QObject *parent) - : QAbstractItemModel(parent) - , mRootItem{new QJsonTreeItem} +QJsonModel::QJsonModel(const QString &fileName, QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem } { mHeaders.append("key"); mHeaders.append("value"); load(fileName); } -QJsonModel::QJsonModel(QIODevice *device, QObject *parent) - : QAbstractItemModel(parent) - , mRootItem{new QJsonTreeItem} +QJsonModel::QJsonModel(QIODevice *device, QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem } { mHeaders.append("key"); mHeaders.append("value"); load(device); } -QJsonModel::QJsonModel(const QByteArray &json, QObject *parent) - : QAbstractItemModel(parent) - , mRootItem{new QJsonTreeItem} +QJsonModel::QJsonModel(const QByteArray &json, QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem } { mHeaders.append("key"); mHeaders.append("value"); @@ -176,10 +174,13 @@ bool QJsonModel::load(const QString &fileName) QFile file(fileName); bool success = false; - if (file.open(QIODevice::ReadOnly)) { + if (file.open(QIODevice::ReadOnly)) + { success = load(&file); file.close(); - } else success = false; + } + else + success = false; return success; } @@ -193,14 +194,18 @@ bool QJsonModel::loadJson(const QByteArray &json) { auto const &jdoc = QJsonDocument::fromJson(json); - if (!jdoc.isNull()) { + if (!jdoc.isNull()) + { beginResetModel(); delete mRootItem; - if (jdoc.isArray()) { + if (jdoc.isArray()) + { mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.array())); mRootItem->setType(QJsonValue::Array); - } else { + } + else + { mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.object())); mRootItem->setType(QJsonValue::Object); } @@ -213,24 +218,21 @@ bool QJsonModel::loadJson(const QByteArray &json) return false; } - QVariant QJsonModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) return QVariant(); QJsonTreeItem *item = static_cast(index.internalPointer()); - if (role == Qt::DisplayRole) { - if (index.column() == 0) - return QString("%1").arg(item->key()); + if (role == Qt::DisplayRole) + { + if (index.column() == 0) return QString("%1").arg(item->key()); - if (index.column() == 1) - return QString("%1").arg(item->value()); - } else if (Qt::EditRole == role) { - if (index.column() == 1) { - return QString("%1").arg(item->value()); - } + if (index.column() == 1) return QString("%1").arg(item->value()); + } + else if (Qt::EditRole == role) + { + if (index.column() == 1) { return QString("%1").arg(item->value()); } } return QVariant(); @@ -240,11 +242,13 @@ bool QJsonModel::setData(const QModelIndex &index, const QVariant &value, int ro { int col = index.column(); - if (Qt::EditRole == role) { - if (col == 1) { + if (Qt::EditRole == role) + { + if (col == 1) + { QJsonTreeItem *item = static_cast(index.internalPointer()); item->setValue(value.toString()); - emit dataChanged(index, index, {Qt::EditRole}); + emit dataChanged(index, index, { Qt::EditRole }); return true; } } @@ -252,49 +256,40 @@ bool QJsonModel::setData(const QModelIndex &index, const QVariant &value, int ro return false; } - - QVariant QJsonModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role != Qt::DisplayRole) - return QVariant(); + if (role != Qt::DisplayRole) return QVariant(); - if (orientation == Qt::Horizontal) { - return mHeaders.value(section); - } else + if (orientation == Qt::Horizontal) { return mHeaders.value(section); } + else return QVariant(); } QModelIndex QJsonModel::index(int row, int column, const QModelIndex &parent) const { - if (!hasIndex(row, column, parent)) - return QModelIndex(); + if (!hasIndex(row, column, parent)) return QModelIndex(); QJsonTreeItem *parentItem; - if (!parent.isValid()) - parentItem = mRootItem; + if (!parent.isValid()) parentItem = mRootItem; else parentItem = static_cast(parent.internalPointer()); QJsonTreeItem *childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); + if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } QModelIndex QJsonModel::parent(const QModelIndex &index) const { - if (!index.isValid()) - return QModelIndex(); + if (!index.isValid()) return QModelIndex(); QJsonTreeItem *childItem = static_cast(index.internalPointer()); QJsonTreeItem *parentItem = childItem->parent(); - if (parentItem == mRootItem) - return QModelIndex(); + if (parentItem == mRootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } @@ -303,11 +298,9 @@ int QJsonModel::rowCount(const QModelIndex &parent) const { QJsonTreeItem *parentItem; - if (parent.column() > 0) - return 0; + if (parent.column() > 0) return 0; - if (!parent.isValid()) - parentItem = mRootItem; + if (!parent.isValid()) parentItem = mRootItem; else parentItem = static_cast(parent.internalPointer()); @@ -322,14 +315,14 @@ int QJsonModel::columnCount(const QModelIndex &parent) const Qt::ItemFlags QJsonModel::flags(const QModelIndex &index) const { - int col = index.column(); + int col = index.column(); auto item = static_cast(index.internalPointer()); auto isArray = QJsonValue::Array == item->type(); auto isObject = QJsonValue::Object == item->type(); - if ((col == 1) && !(isArray || isObject)) { - return Qt::ItemIsEditable | QAbstractItemModel::flags(index); - } else { + if ((col == 1) && !(isArray || isObject)) { return Qt::ItemIsEditable | QAbstractItemModel::flags(index); } + else + { return QAbstractItemModel::flags(index); } } @@ -339,40 +332,47 @@ QJsonDocument QJsonModel::json() const auto v = genJson(mRootItem); QJsonDocument doc; - if (v.isObject()) { - doc = QJsonDocument(v.toObject()); - } else { + if (v.isObject()) { doc = QJsonDocument(v.toObject()); } + else + { doc = QJsonDocument(v.toArray()); } return doc; } -QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const +QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const { - auto type = item->type(); - int nchild = item->childCount(); + auto type = item->type(); + int nchild = item->childCount(); - if (QJsonValue::Object == type) { + if (QJsonValue::Object == type) + { QJsonObject jo; - for (int i = 0; i < nchild; ++i) { + for (int i = 0; i < nchild; ++i) + { auto ch = item->child(i); auto key = ch->key(); jo.insert(key, genJson(ch)); } - return jo; - } else if (QJsonValue::Array == type) { + return jo; + } + else if (QJsonValue::Array == type) + { QJsonArray arr; - for (int i = 0; i < nchild; ++i) { + for (int i = 0; i < nchild; ++i) + { auto ch = item->child(i); arr.append(genJson(ch)); } return arr; - } else { + } + else + { QJsonValue va(item->value()); return va; } diff --git a/src/common/QJsonModel.hpp b/src/common/QJsonModel.hpp index c88679ed..69bddec8 100644 --- a/src/common/QJsonModel.hpp +++ b/src/common/QJsonModel.hpp @@ -1,101 +1,94 @@ /* -* The MIT License (MIT) -* -* Copyright (c) 2011 SCHUTZ Sacha -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all -* copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -*/ + * The MIT License (MIT) + * + * Copyright (c) 2011 SCHUTZ Sacha + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ #pragma once #include -#include -#include -#include -#include #include +#include +#include +#include +#include class QJsonModel; class QJsonItem; class QJsonTreeItem { - public: - QJsonTreeItem(QJsonTreeItem *parent = nullptr); - ~QJsonTreeItem(); - void appendChild(QJsonTreeItem *item); - QJsonTreeItem *child(int row); - QJsonTreeItem *parent(); - int childCount() const; - int row() const; - void setKey(const QString &key); - void setValue(const QString &value); - void setType(const QJsonValue::Type &type); - QString key() const; - QString value() const; - QJsonValue::Type type() const; - - - static QJsonTreeItem *load(const QJsonValue &value, QJsonTreeItem *parent = 0); - - protected: - - - private: - QString mKey; - QString mValue; - QJsonValue::Type mType; - QList mChilds; - QJsonTreeItem *mParent; + public: + QJsonTreeItem(QJsonTreeItem *parent = nullptr); + ~QJsonTreeItem(); + void appendChild(QJsonTreeItem *item); + QJsonTreeItem *child(int row); + QJsonTreeItem *parent(); + int childCount() const; + int row() const; + void setKey(const QString &key); + void setValue(const QString &value); + void setType(const QJsonValue::Type &type); + QString key() const; + QString value() const; + QJsonValue::Type type() const; + static QJsonTreeItem *load(const QJsonValue &value, QJsonTreeItem *parent = 0); + protected: + private: + QString mKey; + QString mValue; + QJsonValue::Type mType; + QList mChilds; + QJsonTreeItem *mParent; }; //--------------------------------------------------- class QJsonModel : public QAbstractItemModel { - Q_OBJECT - public: - explicit QJsonModel(QObject *parent = nullptr); - QJsonModel(const QString &fileName, QObject *parent = nullptr); - QJsonModel(QIODevice *device, QObject *parent = nullptr); - QJsonModel(const QByteArray &json, QObject *parent = nullptr); - ~QJsonModel(); - bool load(const QString &fileName); - bool load(QIODevice *device); - bool loadJson(const QByteArray &json); - QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; - QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; - QJsonDocument json() const; - - private: - QJsonValue genJson(QJsonTreeItem *) const; - - QJsonTreeItem *mRootItem; - QStringList mHeaders; + Q_OBJECT + public: + explicit QJsonModel(QObject *parent = nullptr); + QJsonModel(const QString &fileName, QObject *parent = nullptr); + QJsonModel(QIODevice *device, QObject *parent = nullptr); + QJsonModel(const QByteArray &json, QObject *parent = nullptr); + ~QJsonModel(); + bool load(const QString &fileName); + bool load(QIODevice *device); + bool loadJson(const QByteArray &json); + QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; + QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + QJsonDocument json() const; + private: + QJsonValue genJson(QJsonTreeItem *) const; + QJsonTreeItem *mRootItem; + QStringList mHeaders; }; diff --git a/src/common/QvHelpers.cpp b/src/common/QvHelpers.cpp index 7df5bd45..33455bbd 100644 --- a/src/common/QvHelpers.cpp +++ b/src/common/QvHelpers.cpp @@ -1,4 +1,5 @@ #include "common/QvHelpers.hpp" + #include namespace Qv2ray::common @@ -8,7 +9,8 @@ namespace Qv2ray::common const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); QString randomString; - for (int i = 0; i < len; ++i) { + for (int i = 0; i < len; ++i) + { uint rand = QRandomGenerator::system()->generate(); uint max = static_cast(possibleCharacters.length()); QChar nextChar = possibleCharacters[rand % max]; @@ -73,9 +75,9 @@ namespace Qv2ray::common QJsonDocument doc = QJsonDocument::fromJson(source.toUtf8(), &error); Q_UNUSED(doc) - if (error.error == QJsonParseError::NoError) { - return ""; - } else { + if (error.error == QJsonParseError::NoError) { return ""; } + else + { LOG(MODULE_UI, "WARNING: Json parse returns: " + error.errorString()) return error.errorString(); } @@ -108,16 +110,16 @@ namespace Qv2ray::common { list list; - for (auto line : _string.split(QRegExp("[\r\n]"), QString::SkipEmptyParts)) { - list.push_back(line.toStdString()); - } + for (auto line : _string.split(QRegExp("[\r\n]"), QString::SkipEmptyParts)) { list.push_back(line.toStdString()); } return list; } QStringList GetFileList(QDir dir) { - return dir.entryList(QStringList() << "*" << "*.*", QDir::Hidden | QDir::Files); + return dir.entryList(QStringList() << "*" + << "*.*", + QDir::Hidden | QDir::Files); } bool FileExistsIn(QDir dir, QString fileName) @@ -147,8 +149,7 @@ namespace Qv2ray::common int i; double dblByte = bytes; - for (i = 0; i < 5 && bytes >= 1024; i++, bytes /= 1024) - dblByte = bytes / 1024.0; + for (i = 0; i < 5 && bytes >= 1024; i++, bytes /= 1024) dblByte = bytes / 1024.0; sprintf(str, "%.2f", dblByte); return QString(str) + " " + QString(sizes[i]); @@ -163,9 +164,8 @@ namespace Qv2ray::common QString RemoveInvalidFileName(const QString &fileName) { std::string _name = fileName.toStdString(); - std::replace_if(_name.begin(), _name.end(), [](char c) { - return std::string::npos != string(R"("/\?%&^*;:|><)").find(c); - }, '_'); + std::replace_if( + _name.begin(), _name.end(), [](char c) { return std::string::npos != string(R"("/\?%&^*;:|><)").find(c); }, '_'); return QString::fromStdString(_name); } @@ -174,20 +174,25 @@ namespace Qv2ray::common { int i = 1; - if (!QDir(baseDir).exists()) { + if (!QDir(baseDir).exists()) + { QDir(baseDir).mkpath(baseDir); LOG(MODULE_FILEIO, "Making path: " + baseDir) } - while (true) { - if (!QFile(baseDir + "/" + fileName + "_" + QSTRN(i) + extension).exists()) { + while (true) + { + if (!QFile(baseDir + "/" + fileName + "_" + QSTRN(i) + extension).exists()) + { *fileName = *fileName + "_" + QSTRN(i); return; - } else { + } + else + { DEBUG(MODULE_FILEIO, "File with name: " + *fileName + "_" + QSTRN(i) + extension + " already exists") } i++; } } -} +} // namespace Qv2ray::common diff --git a/src/common/QvHelpers.hpp b/src/common/QvHelpers.hpp index 6d8d818b..cca199d8 100644 --- a/src/common/QvHelpers.hpp +++ b/src/common/QvHelpers.hpp @@ -1,10 +1,13 @@ #pragma once #include "base/Qv2rayBase.hpp" + #include -#define REGEX_IPV6_ADDR R"(\[\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*\])" -#define REGEX_IPV4_ADDR R"((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]))" +#define REGEX_IPV6_ADDR \ + R"(\[\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*\])" +#define REGEX_IPV4_ADDR \ + R"((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]))" #define REGEX_PORT_NUMBER R"(([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])*)" namespace Qv2ray::common @@ -19,7 +22,8 @@ namespace Qv2ray::common // void QvMessageBoxWarn(QWidget *parent, QString title, QString text); void QvMessageBoxInfo(QWidget *parent, QString title, QString text); - QMessageBox::StandardButton QvMessageBoxAsk(QWidget *parent, QString title, QString text, QMessageBox::StandardButton extraButtons = QMessageBox::NoButton); + QMessageBox::StandardButton QvMessageBoxAsk(QWidget *parent, QString title, QString text, + QMessageBox::StandardButton extraButtons = QMessageBox::NoButton); // QString StringFromFile(const QString &filePath); QString StringFromFile(QFile *source); @@ -40,16 +44,16 @@ namespace Qv2ray::common inline QString GenerateUuid() { return GenerateRandomString().toLower(); - //return QUuid::createUuid().toString(QUuid::WithoutBraces); + // return QUuid::createUuid().toString(QUuid::WithoutBraces); } // - template + template QString StructToJsonString(const TYPE t) { return QString::fromStdString(x2struct::X::tojson(t, "", 4, ' ')); } // - template + template TYPE StructFromJsonString(const QString &str) { TYPE v; @@ -68,9 +72,7 @@ namespace Qv2ray::common { QString t = str; t.truncate(limit); - return (limit == -1 || str.length() < limit) - ? str - : (t + suffix); + return (limit == -1 || str.length() < limit) ? str : (t + suffix); } namespace validation @@ -92,7 +94,7 @@ namespace Qv2ray::common { return IsIPv4Address(addr) || IsIPv6Address(addr); } - } + } // namespace validation inline QString timeToString(const time_t &t) { @@ -102,6 +104,6 @@ namespace Qv2ray::common strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", _tm); return QString(MY_TIME); } -} +} // namespace Qv2ray::common using namespace Qv2ray::common; diff --git a/src/common/QvTranslator.hpp b/src/common/QvTranslator.hpp index 23002b28..d632d55b 100644 --- a/src/common/QvTranslator.hpp +++ b/src/common/QvTranslator.hpp @@ -7,15 +7,15 @@ namespace Qv2ray::common { class QvTranslator { - public: - QvTranslator(const QString &lang) - { - QTranslator *translator = new QTranslator(); - translator->load(lang + ".qm", ":/translations/"); - this->pTranslator.reset(translator); - } + public: + QvTranslator(const QString &lang) + { + QTranslator *translator = new QTranslator(); + translator->load(lang + ".qm", ":/translations/"); + this->pTranslator.reset(translator); + } - public: - std::unique_ptr pTranslator; + public: + std::unique_ptr pTranslator; }; } // namespace Qv2ray::common diff --git a/src/components/autolaunch/QvAutoLaunch.cpp b/src/components/autolaunch/QvAutoLaunch.cpp index e441f7b1..475ce0c4 100644 --- a/src/components/autolaunch/QvAutoLaunch.cpp +++ b/src/components/autolaunch/QvAutoLaunch.cpp @@ -1,13 +1,14 @@ #include "QvAutoLaunch.hpp" -#include + #include #include +#include #include #include // macOS headers (possibly OBJ-c) #if defined(Q_OS_MAC) -#include -#include + #include + #include #endif namespace Qv2ray::components::autolaunch { @@ -34,8 +35,10 @@ namespace Qv2ray::components::autolaunch } #elif defined Q_OS_MAC - // From https://github.com/nextcloud/desktop/blob/master/src/common/utility_mac.cpp - // this is quite some duplicate code with setLaunchOnStartup, at some point we should fix this FIXME. + // From + // https://github.com/nextcloud/desktop/blob/master/src/common/utility_mac.cpp + // this is quite some duplicate code with setLaunchOnStartup, at some + // point we should fix this FIXME. bool returnValue = false; QString filePath = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).absolutePath(); CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8); @@ -49,16 +52,16 @@ namespace Qv2ray::components::autolaunch CFArrayRef itemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue); CFStringRef appUrlRefString = CFURLGetString(urlRef); // no need for release - for (int i = 0; i < CFArrayGetCount(itemsArray); i++) { - LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(itemsArray, i); + for (int i = 0; i < CFArrayGetCount(itemsArray); i++) + { + LSSharedFileListItemRef item = (LSSharedFileListItemRef) CFArrayGetValueAtIndex(itemsArray, i); CFURLRef itemUrlRef = NULL; - if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef) { + if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef) + { CFStringRef itemUrlString = CFURLGetString(itemUrlRef); - if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo) { - returnValue = true; - } + if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo) { returnValue = true; } CFRelease(itemUrlRef); } @@ -86,16 +89,20 @@ namespace Qv2ray::components::autolaunch QString appName = QApplication::applicationName(); QSettings reg("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); - if (enable) { + if (enable) + { QString strAppPath = QDir::toNativeSeparators(QCoreApplication::applicationFilePath()); reg.setValue(appName, strAppPath); - } else { + } + else + { reg.remove(appName); } } #elif defined Q_OS_MAC - // From https://github.com/nextcloud/desktop/blob/master/src/common/utility_mac.cpp + // From + // https://github.com/nextcloud/desktop/blob/master/src/common/utility_mac.cpp QString filePath = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).absolutePath(); CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8); CFURLRef urlRef = CFURLCreateWithFileSystemPath(0, folderCFStr, kCFURLPOSIXPathStyle, true); @@ -103,30 +110,31 @@ namespace Qv2ray::components::autolaunch if (loginItems && enable) { - //Insert an item to the list. - LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, - kLSSharedFileListItemLast, 0, 0, - urlRef, 0, 0); + // Insert an item to the list. + LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemLast, 0, 0, urlRef, 0, 0); - if (item) - CFRelease(item); + if (item) CFRelease(item); CFRelease(loginItems); - } else if (loginItems && !enable) + } + else if (loginItems && !enable) { // We need to iterate over the items and check which one is "ours". UInt32 seedValue; CFArrayRef itemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue); CFStringRef appUrlRefString = CFURLGetString(urlRef); - for (int i = 0; i < CFArrayGetCount(itemsArray); i++) { - LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(itemsArray, i); + for (int i = 0; i < CFArrayGetCount(itemsArray); i++) + { + LSSharedFileListItemRef item = (LSSharedFileListItemRef) CFArrayGetValueAtIndex(itemsArray, i); CFURLRef itemUrlRef = NULL; - if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef) { + if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef) + { CFStringRef itemUrlString = CFURLGetString(itemUrlRef); - if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo) { + if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo) + { LSSharedFileListItemRemove(loginItems, item); // remove it! } @@ -143,22 +151,27 @@ namespace Qv2ray::components::autolaunch } #elif defined Q_OS_LINUX - // From https://github.com/nextcloud/desktop/blob/master/src/common/utility_unix.cpp + // From + // https://github.com/nextcloud/desktop/blob/master/src/common/utility_unix.cpp QString appName = QApplication::applicationName(); QString userAutoStartPath = getUserAutostartDir_private(); QString desktopFileLocation = userAutoStartPath + appName + QLatin1String(".desktop"); if (enable) { - if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath)) { - // qCWarning(lcUtility) << "Could not create autostart folder" << userAutoStartPath; + if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath)) + { + // qCWarning(lcUtility) << "Could not create autostart folder" + // << userAutoStartPath; return; } QFile iniFile(desktopFileLocation); - if (!iniFile.open(QIODevice::WriteOnly)) { - // qCWarning(lcUtility) << "Could not write auto start entry" << desktopFileLocation; + if (!iniFile.open(QIODevice::WriteOnly)) + { + // qCWarning(lcUtility) << "Could not write auto start entry" << + // desktopFileLocation; return; } @@ -174,13 +187,15 @@ namespace Qv2ray::components::autolaunch << QLatin1String("Type=") << "Application" << endl << QLatin1String("StartupNotify=") << "false" << endl << QLatin1String("X-GNOME-Autostart-enabled=") << "true" << endl; - } else + } + else { - if (!QFile::remove(desktopFileLocation)) { - // qCWarning(lcUtility) << "Could not remove autostart desktop file"; + if (!QFile::remove(desktopFileLocation)) + { + // qCWarning(lcUtility) << "Could not remove autostart desktop + // file"; } } } #endif -} - +} // namespace Qv2ray::components::autolaunch diff --git a/src/components/autolaunch/QvAutoLaunch.hpp b/src/components/autolaunch/QvAutoLaunch.hpp index 1c9e6443..7311e01c 100644 --- a/src/components/autolaunch/QvAutoLaunch.hpp +++ b/src/components/autolaunch/QvAutoLaunch.hpp @@ -4,7 +4,7 @@ namespace Qv2ray::components::autolaunch { bool GetLaunchAtLoginStatus(); void SetLaunchAtLoginStatus(bool enable); -} +} // namespace Qv2ray::components::autolaunch using namespace Qv2ray::components; using namespace Qv2ray::components::autolaunch; diff --git a/src/components/geosite/QvGeositeReader.cpp b/src/components/geosite/QvGeositeReader.cpp index 83f78c50..6a6f2f2e 100644 --- a/src/components/geosite/QvGeositeReader.cpp +++ b/src/components/geosite/QvGeositeReader.cpp @@ -1,4 +1,5 @@ #include "QvGeositeReader.hpp" + #include "libs/gen/v2ray_geosite.pb.h" namespace Qv2ray::components::geosite @@ -13,7 +14,8 @@ namespace Qv2ray::components::geosite QFile f(filepath); bool opened = f.open(QFile::OpenModeFlag::ReadOnly); - if (!opened) { + if (!opened) + { LOG(MODULE_FILEIO, "File cannot be opened: " + filepath) return list; } @@ -24,7 +26,8 @@ namespace Qv2ray::components::geosite GeoSiteList sites; sites.ParseFromArray(content.data(), content.size()); - for (auto e : sites.entry()) { + for (auto e : sites.entry()) + { // We want to use lower string. list << QString::fromStdString(e.country_code()).toLower(); } @@ -34,4 +37,4 @@ namespace Qv2ray::components::geosite google::protobuf::ShutdownProtobufLibrary(); return list; } -} +} // namespace Qv2ray::components::geosite diff --git a/src/components/icmping/win/ICMPPinger.cpp b/src/components/icmping/win/ICMPPinger.cpp index 39d9272f..ccff38bb 100644 --- a/src/components/icmping/win/ICMPPinger.cpp +++ b/src/components/icmping/win/ICMPPinger.cpp @@ -1,41 +1,38 @@ #include "ICMPPinger.hpp" -ICMPPinger::ICMPPinger(UINT64 timeout = DEFAULT_TIMEOUT) { +ICMPPinger::ICMPPinger(UINT64 timeout = DEFAULT_TIMEOUT) +{ // create icmp handle - if ((this->hIcmpFile = IcmpCreateFile()) == INVALID_HANDLE_VALUE) { - throw "IcmpCreateFile failed"; - } + if ((this->hIcmpFile = IcmpCreateFile()) == INVALID_HANDLE_VALUE) { throw "IcmpCreateFile failed"; } // remember the timeout this->timeout = timeout; } -ICMPPinger::~ICMPPinger() { +ICMPPinger::~ICMPPinger() +{ // release the handle on destruction IcmpCloseHandle(this->hIcmpFile); } -std::pair, std::optional> ICMPPinger::ping(const std::string& ipAddr) { +std::pair, std::optional> ICMPPinger::ping(const std::string &ipAddr) +{ // convert network address const auto addr = inet_addr(ipAddr.c_str()); - if (addr == INADDR_NONE) { - return std::pair(std::nullopt, "invalid ip address: " + ipAddr); - } + if (addr == INADDR_NONE) { return std::pair(std::nullopt, "invalid ip address: " + ipAddr); } // request buffer const static char bufRequest[] = "echo test"; // response buffer const auto responseSize = sizeof(ICMP_ECHO_REPLY) + sizeof(bufRequest); - const std::unique_ptr bufRecv(new(char[responseSize])); + const std::unique_ptr bufRecv(new (char[responseSize])); // send echo - auto ret = IcmpSendEcho(this->hIcmpFile, addr, (LPVOID)bufRequest, sizeof(bufRequest), NULL, bufRecv.get(), responseSize, this->timeout); - + auto ret = IcmpSendEcho(this->hIcmpFile, addr, (LPVOID) bufRequest, sizeof(bufRequest), NULL, bufRecv.get(), responseSize, this->timeout); + // ret == 0: failed - if (ret == 0) { - return std::pair(std::nullopt, "IcmpSendEcho returned error"); - } + if (ret == 0) { return std::pair(std::nullopt, "IcmpSendEcho returned error"); } // read round-trip time PICMP_ECHO_REPLY pReply = (PICMP_ECHO_REPLY) bufRecv.get(); diff --git a/src/components/icmping/win/ICMPPinger.hpp b/src/components/icmping/win/ICMPPinger.hpp index f6382049..f0bfa39e 100644 --- a/src/components/icmping/win/ICMPPinger.hpp +++ b/src/components/icmping/win/ICMPPinger.hpp @@ -6,27 +6,26 @@ * License: WTFPL */ -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include -#include -#include +class ICMPPinger +{ + public: + ICMPPinger(UINT64 timeout = DEFAULT_TIMEOUT); + ~ICMPPinger(); + public: + static const UINT64 DEFAULT_TIMEOUT = 10000U; -class ICMPPinger { - public: - ICMPPinger(UINT64 timeout = DEFAULT_TIMEOUT); - ~ICMPPinger(); + public: + std::pair, std::optional> ping(const std::string &ipAddr); - public: - static const UINT64 DEFAULT_TIMEOUT = 10000U; - - public: - std::pair, std::optional> ping(const std::string& ipAddr); - - private: - HANDLE hIcmpFile; - UINT64 timeout = DEFAULT_TIMEOUT; + private: + HANDLE hIcmpFile; + UINT64 timeout = DEFAULT_TIMEOUT; }; diff --git a/src/components/pac/QvGFWPACConverter.cpp b/src/components/pac/QvGFWPACConverter.cpp index efb1bf61..49fd1a02 100644 --- a/src/components/pac/QvGFWPACConverter.cpp +++ b/src/components/pac/QvGFWPACConverter.cpp @@ -21,29 +21,23 @@ namespace Qv2ray::components::pac bool passRule1 = originLine.find("|") != string::npos; // Proxy Lines bool passRule2 = originLine.find(".") != string::npos; // Link-Contained Lines - if (originLine[endPosition] == '\n') { - endPosition -= 1; - } + if (originLine[endPosition] == '\n') { endPosition -= 1; } - if (originLine.find("http://") != string::npos) { - startPosition += 8; - } else if (originLine.find("https://") != string::npos) { + if (originLine.find("http://") != string::npos) { startPosition += 8; } + else if (originLine.find("https://") != string::npos) + { startPosition += 9; } // Skip unrelated lines - if (skipRule1 || skipRule2 || skipRule3 || skipRule4) { - return ""; - } else if (passRule2) { - if (passRule1) { - startPosition += originLine.find_last_of("|") + 1; - } + if (skipRule1 || skipRule2 || skipRule3 || skipRule4) { return ""; } + else if (passRule2) + { + if (passRule1) { startPosition += originLine.find_last_of("|") + 1; } if (originLine[startPosition] == '\n') startPosition += 1; - for (size_t i = startPosition; i < endPosition; ++i) { - returnBuffer += originLine[i]; - } + for (size_t i = startPosition; i < endPosition; ++i) { returnBuffer += originLine[i]; } } return returnBuffer; @@ -52,19 +46,19 @@ namespace Qv2ray::components::pac QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString) { auto rawFileContent = Base64Decode(rawContent).toStdString(); - string readBuffer = ""; //cleanup + string readBuffer = ""; // cleanup string writeBuffer; string domainListCache = ""; - for (size_t i = 0; i < rawFileContent.size(); ++i) { + for (size_t i = 0; i < rawFileContent.size(); ++i) + { readBuffer += rawFileContent[i]; - if (rawFileContent[i + 1] == '\n') { + if (rawFileContent[i + 1] == '\n') + { writeBuffer = getRawDomain(readBuffer); - if (writeBuffer != "") { - domainListCache += writeBuffer + "\n"; - } + if (writeBuffer != "") { domainListCache += writeBuffer + "\n"; } readBuffer = ""; i += 1; @@ -72,19 +66,22 @@ namespace Qv2ray::components::pac } size_t rotatorTwo = 0; - string readDomainBuffer = ""; + string readDomainBuffer = ""; bool isFirstLine = true; string outputContent = ""; - //Header + // Header outputContent += "var domains = {\n"; - //Read and process output content line by line - while (rotatorTwo < domainListCache.size()) { - while (true) { - //Get Domain + // Read and process output content line by line + while (rotatorTwo < domainListCache.size()) + { + while (true) + { + // Get Domain readDomainBuffer += domainListCache[rotatorTwo]; - if (domainListCache[rotatorTwo + 1] == '\n') { + if (domainListCache[rotatorTwo + 1] == '\n') + { rotatorTwo += 2; break; } @@ -92,9 +89,10 @@ namespace Qv2ray::components::pac rotatorTwo++; } - //Format + // Format if (!isFirstLine) outputContent += ",\n"; - else isFirstLine = false; + else + isFirstLine = false; outputContent += "\t\""; outputContent += readDomainBuffer; @@ -102,32 +100,18 @@ namespace Qv2ray::components::pac readDomainBuffer = ""; } - //End Message - outputContent += - NEWLINE "};" - NEWLINE "" - NEWLINE " var proxy = \"" + customProxyString.toStdString() + ";\";" + - NEWLINE " var direct = 'DIRECT;';" - NEWLINE " function FindProxyForURL(url, host) {" - NEWLINE " var suffix;" - NEWLINE " var pos = host.lastIndexOf('.');" - NEWLINE " pos = host.lastIndexOf('.', pos - 1);" - NEWLINE " //" - NEWLINE " while (1) {" - NEWLINE " if (domains[host] != undefined) {" - NEWLINE " return proxy;" - NEWLINE " }" - NEWLINE " else if (pos <= 0) {" - NEWLINE " return domains['.' + host] != undefined ? proxy : direct;" - NEWLINE " }" - NEWLINE " suffix = host.substring(pos);" - NEWLINE " if (domains[suffix] != undefined) {" - NEWLINE " return proxy;" - NEWLINE " }" - NEWLINE " pos = host.lastIndexOf('.', pos - 1);" - NEWLINE " }" - NEWLINE " }"; + // End Message + outputContent += NEWLINE "};" NEWLINE "" NEWLINE " var proxy = \"" + customProxyString.toStdString() + ";\";" + + NEWLINE " var direct = 'DIRECT;';" NEWLINE " function FindProxyForURL(url, host) {" NEWLINE + " var suffix;" NEWLINE " var pos = host.lastIndexOf('.');" NEWLINE + " pos = host.lastIndexOf('.', pos - 1);" NEWLINE " //" NEWLINE " while (1) {" NEWLINE + " if (domains[host] != undefined) {" NEWLINE " return proxy;" NEWLINE + " }" NEWLINE " else if (pos <= 0) {" NEWLINE + " return domains['.' + host] != undefined ? proxy : direct;" NEWLINE " }" NEWLINE + " suffix = host.substring(pos);" NEWLINE " if (domains[suffix] != undefined) {" NEWLINE + " return proxy;" NEWLINE " }" NEWLINE + " pos = host.lastIndexOf('.', pos - 1);" NEWLINE " }" NEWLINE " }"; // return QString::fromStdString(outputContent); } -} +} // namespace Qv2ray::components::pac diff --git a/src/components/pac/QvPACHandler.cpp b/src/components/pac/QvPACHandler.cpp index 033f1a32..456159b1 100644 --- a/src/components/pac/QvPACHandler.cpp +++ b/src/components/pac/QvPACHandler.cpp @@ -1,8 +1,9 @@ #include "QvPACHandler.hpp" + +#include "common/QvHelpers.hpp" +#include "core/CoreUtils.hpp" #include "qhttprequest.h" #include "qhttpresponse.h" -#include "core/CoreUtils.hpp" -#include "common/QvHelpers.hpp" namespace Qv2ray::components::pac { @@ -13,9 +14,7 @@ namespace Qv2ray::components::pac } PACServer::~PACServer() { - if (isStarted) { - pacServer.close(); - } + if (isStarted) { pacServer.close(); } } void PACServer::SetProxyString(const QString &proxyString) { @@ -36,10 +35,13 @@ namespace Qv2ray::components::pac // auto result = pacServer.listen(QHostAddress(address), static_cast(port)); - if (result) { + if (result) + { isStarted = true; DEBUG(MODULE_PROXY, "Started PAC handler") - } else { + } + else + { LOG(MODULE_PROXY, "Failed to listen on port " + QSTRN(port) + ", possible permission denied.") QvMessageBoxWarn(nullptr, tr("PAC Handler"), tr("Failed to listen PAC request on this port, please verify the permissions")); } @@ -47,7 +49,8 @@ namespace Qv2ray::components::pac void PACServer::StopServer() { - if (isStarted) { + if (isStarted) + { pacServer.close(); DEBUG(MODULE_PROXY, "PAC Handler stopped.") isStarted = false; @@ -58,22 +61,28 @@ namespace Qv2ray::components::pac { rsp->setHeader("Server", "Qv2ray/" QV2RAY_VERSION_STRING " PAC_Handler"); - if (req->method() == QHttpRequest::HTTP_GET) { + if (req->method() == QHttpRequest::HTTP_GET) + { // - if (req->path() == "/pac") { + if (req->path() == "/pac") + { DEBUG(MODULE_PROXY, "Serving PAC file request.") // rsp->setHeader("Content-Type", "application/javascript; charset=utf-8"); rsp->writeHead(QHttpResponse::StatusCode::STATUS_OK); rsp->end(pacContent.toUtf8()); DEBUG(MODULE_PROXY, "Serving a pac file...") - } else { + } + else + { rsp->writeHead(QHttpResponse::StatusCode::STATUS_NOT_FOUND); rsp->end("NOT FOUND"); } - } else { + } + else + { rsp->writeHead(QHttpResponse::StatusCode::STATUS_METHOD_NOT_ALLOWED); rsp->end("PAC ONLY SUPPORT GET"); } } -} +} // namespace Qv2ray::components::pac diff --git a/src/components/pac/QvPACHandler.hpp b/src/components/pac/QvPACHandler.hpp index 323da610..e739ae30 100644 --- a/src/components/pac/QvPACHandler.hpp +++ b/src/components/pac/QvPACHandler.hpp @@ -1,5 +1,6 @@ #pragma once #include "qhttpserver.h" + #include #include @@ -8,26 +9,26 @@ namespace Qv2ray::components::pac QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString); class PACServer : public QObject { - Q_OBJECT - public: - explicit PACServer(); - ~PACServer(); - void SetProxyString(const QString &proxyString); - void StartListen(); - void StopServer(); + Q_OBJECT + public: + explicit PACServer(); + ~PACServer(); + void SetProxyString(const QString &proxyString); + void StartListen(); + void StopServer(); - QString gfwFilePath; + QString gfwFilePath; - public slots: - void onNewRequest(QHttpRequest *request, QHttpResponse *response); + public slots: + void onNewRequest(QHttpRequest *request, QHttpResponse *response); - private: - bool isStarted; - QHttpServer pacServer; - QString pacContent; - QString proxyString; + private: + bool isStarted; + QHttpServer pacServer; + QString pacContent; + QString proxyString; }; -} +} // namespace Qv2ray::components::pac using namespace Qv2ray::components; using namespace Qv2ray::components::pac; diff --git a/src/components/plugins/toolbar/QvToolbar.cpp b/src/components/plugins/toolbar/QvToolbar.cpp index 0ecdb877..7b8d7685 100644 --- a/src/components/plugins/toolbar/QvToolbar.cpp +++ b/src/components/plugins/toolbar/QvToolbar.cpp @@ -1,7 +1,8 @@ #include -#include "ui/w_MainWindow.hpp" #include "components/plugins/toolbar/QvToolbar.hpp" + #include "common/QvHelpers.hpp" +#include "ui/w_MainWindow.hpp" namespace Qv2ray::components::plugins { @@ -31,118 +32,137 @@ namespace Qv2ray::components::plugins QString GetAnswerToRequest(const QString &pchRequest) { auto instance = MainWindow::mwInstance; - //if (instance == nullptr || instance->vinstance == nullptr) { + // if (instance == nullptr || instance->vinstance == nullptr) { // LOG(PLUGIN, "MainWindow != nullptr Assertion failed!") // return "{}"; //} // - //auto vinstance = instance->vinstance; + // auto vinstance = instance->vinstance; // auto req = pchRequest.trimmed(); QString reply = "{}"; - if (req == "START") { - emit instance->Connect(); - } else if (req == "STOP") { + if (req == "START") { emit instance->Connect(); } + else if (req == "STOP") + { emit instance->DisConnect(); - } else if (req == "RESTART") { + } + else if (req == "RESTART") + { emit instance->ReConnect(); } auto BarConfig = GlobalConfig.toolBarConfig; - for (auto i = 0; i < BarConfig.Pages.size(); i++) { - for (auto j = 0; j < BarConfig.Pages[i].Lines.size(); j++) { + for (auto i = 0; i < BarConfig.Pages.size(); i++) + { + for (auto j = 0; j < BarConfig.Pages[i].Lines.size(); j++) + { #define CL BarConfig.Pages[i].Lines[j] - switch (CL.ContentType) { - case 0: { + switch (CL.ContentType) + { + case 0: + { // Custom Text // We do nothing... break; } - case 101: { + case 101: + { // Current Time CL.Message = QTime().currentTime().toString("hh:mm:ss"); break; } - case 102: { + case 102: + { // Current Date CL.Message = QDate().currentDate().toString("yyyy-MM-dd"); break; } - case 103: { + case 103: + { // Current Qv2ray Version CL.Message = QV2RAY_VERSION_STRING; break; } - //case 104: { - // // Current Connection Name - // CL.Message = instance->GetCurrentConnectedConfigName(); - // break; - //} - // - //case 105: { - // // Current Connection Status - // CL.Message = instance->vinstance->KernelStarted - // ? QObject::tr("Connected") - // : QObject::tr("Disconnected"); - // break; - //} - // - //case 201: { - // // Total upload speed; - // CL.Message = FormatBytes(vinstance->getAllSpeedUp()) + "/s"; - // break; - //} - // - //case 202: { - // // Total download speed; - // CL.Message = FormatBytes(vinstance->getAllSpeedDown()) + "/s"; - // break; - //} - // - //case 203: { - // // Upload speed for tag - // CL.Message = FormatBytes(vinstance->getTagSpeedUp(CL.Message)) + "/s"; - // break; - //} - // - //case 204: { - // // Download speed for tag - // CL.Message = FormatBytes(vinstance->getTagSpeedDown(CL.Message)) + "/s"; - // break; - //} - // - //case 301: { - // // Total Upload - // CL.Message = FormatBytes(vinstance->getAllDataUp()); - // break; - //} - // - //case 302: { - // // Total download - // CL.Message = FormatBytes(vinstance->getAllDataDown()); - // break; - //} - // - //case 303: { - // // Upload for tag - // CL.Message = FormatBytes(vinstance->getTagDataUp(CL.Message)); - // break; - //} - // - //case 304: { - // // Download for tag - // CL.Message = FormatBytes(vinstance->getTagDataDown(CL.Message)); - // break; - //} + // case 104: { + // // Current Connection Name + // CL.Message = + // instance->GetCurrentConnectedConfigName(); + // break; + //} + // + // case 105: { + // // Current Connection Status + // CL.Message = + // instance->vinstance->KernelStarted + // ? QObject::tr("Connected") + // : QObject::tr("Disconnected"); + // break; + //} + // + // case 201: { + // // Total upload speed; + // CL.Message = + // FormatBytes(vinstance->getAllSpeedUp()) + + // "/s"; break; + //} + // + // case 202: { + // // Total download speed; + // CL.Message = + // FormatBytes(vinstance->getAllSpeedDown()) + + // "/s"; break; + //} + // + // case 203: { + // // Upload speed for tag + // CL.Message = + // FormatBytes(vinstance->getTagSpeedUp(CL.Message)) + // + "/s"; break; + //} + // + // case 204: { + // // Download speed for tag + // CL.Message = + // FormatBytes(vinstance->getTagSpeedDown(CL.Message)) + // + "/s"; break; + //} + // + // case 301: { + // // Total Upload + // CL.Message = + // FormatBytes(vinstance->getAllDataUp()); break; + //} + // + // case 302: { + // // Total download + // CL.Message = + // FormatBytes(vinstance->getAllDataDown()); + // break; + //} + // + // case 303: { + // // Upload for tag + // CL.Message = + // FormatBytes(vinstance->getTagDataUp(CL.Message)); + // break; + //} + // + // case 304: { + // // Download for tag + // CL.Message = + // FormatBytes(vinstance->getTagDataDown(CL.Message)); + // break; + //} - default: { + default: + { CL.Message = "Not Supported?"; break; } @@ -153,5 +173,5 @@ namespace Qv2ray::components::plugins reply = StructToJsonString(BarConfig); return reply; } - } -} + } // namespace Toolbar +} // namespace Qv2ray::components::plugins diff --git a/src/components/plugins/toolbar/QvToolbar.hpp b/src/components/plugins/toolbar/QvToolbar.hpp index 84e45967..6dd2b563 100644 --- a/src/components/plugins/toolbar/QvToolbar.hpp +++ b/src/components/plugins/toolbar/QvToolbar.hpp @@ -9,25 +9,23 @@ namespace Qv2ray::components::plugins namespace Toolbar { /// NO NOT CHANGE THE ORDER - static const QMap NetSpeedPluginMessages { - { 0, QObject::tr("Custom Text")}, - // Current Status - { 101, QObject::tr("Current Time") }, - { 102, QObject::tr("Current Date") }, - { 103, QObject::tr("Current Qv2ray Version") }, - { 104, QObject::tr("Current Connection Name") }, - { 105, QObject::tr("Current Connection Status") }, - // Speeds - { 201, QObject::tr("Total Upload Speed") }, - { 202, QObject::tr("Total Download Speed") }, - { 203, QObject::tr("Upload Speed for Specific Tag") }, - { 204, QObject::tr("Download Speed for Specific Tag") }, - // Datas - { 301, QObject::tr("Total Uploaded Data") }, - { 302, QObject::tr("Total Downloaded Data") }, - { 303, QObject::tr("Uploaded Data for Specific Tag") }, - { 304, QObject::tr("Downloaded Data for Specific Tag") } - }; + static const QMap NetSpeedPluginMessages{ { 0, QObject::tr("Custom Text") }, + // Current Status + { 101, QObject::tr("Current Time") }, + { 102, QObject::tr("Current Date") }, + { 103, QObject::tr("Current Qv2ray Version") }, + { 104, QObject::tr("Current Connection Name") }, + { 105, QObject::tr("Current Connection Status") }, + // Speeds + { 201, QObject::tr("Total Upload Speed") }, + { 202, QObject::tr("Total Download Speed") }, + { 203, QObject::tr("Upload Speed for Specific Tag") }, + { 204, QObject::tr("Download Speed for Specific Tag") }, + // Datas + { 301, QObject::tr("Total Uploaded Data") }, + { 302, QObject::tr("Total Downloaded Data") }, + { 303, QObject::tr("Uploaded Data for Specific Tag") }, + { 304, QObject::tr("Downloaded Data for Specific Tag") } }; void StartProcessingPlugins(); void StopProcessingPlugins(); #ifdef Q_OS_WIN @@ -35,7 +33,7 @@ namespace Qv2ray::components::plugins { void StartNamedPipeThread(); void KillNamedPipeThread(); - } + } // namespace _win #endif #ifdef Q_OS_LINUX namespace _linux @@ -45,13 +43,12 @@ namespace Qv2ray::components::plugins void StartMessageQThread(); void StopMessageQThread(); - } + } // namespace _linux #endif QString GetAnswerToRequest(const QString &pchRequest); - } -} + } // namespace Toolbar +} // namespace Qv2ray::components::plugins using namespace Qv2ray::components; using namespace Qv2ray::components::plugins::Toolbar; - diff --git a/src/components/plugins/toolbar/QvToolbar_linux.cpp b/src/components/plugins/toolbar/QvToolbar_linux.cpp index 5ff3ec30..de82ec56 100644 --- a/src/components/plugins/toolbar/QvToolbar_linux.cpp +++ b/src/components/plugins/toolbar/QvToolbar_linux.cpp @@ -1,9 +1,10 @@ #include #ifdef Q_OS_LINUX -#include "components/plugins/toolbar/QvToolbar.hpp" -#include "common/QvHelpers.hpp" -#include -#include + #include "common/QvHelpers.hpp" + #include "components/plugins/toolbar/QvToolbar.hpp" + + #include + #include namespace Qv2ray::components::plugins::Toolbar { namespace _linux @@ -16,35 +17,43 @@ namespace Qv2ray::components::plugins::Toolbar { QLocalSocket *socket = server->nextPendingConnection(); - if (!socket->waitForConnected() || !socket->waitForReadyRead()) - return; + if (!socket->waitForConnected() || !socket->waitForReadyRead()) return; - try { - while (!isExiting && socket->isOpen() && socket->isValid() && socket->waitForReadyRead()) { + try + { + while (!isExiting && socket->isOpen() && socket->isValid() && socket->waitForReadyRead()) + { // CANNOT PROPERLY READ... // Temp-ly fixed (but why and how?) auto in = QString(socket->readAll()); - if (!isExiting && !in.isEmpty()) { + if (!isExiting && !in.isEmpty()) + { auto out = GetAnswerToRequest(in); // socket->write(out.toUtf8()); socket->flush(); - } else { + } + else + { QThread::msleep(200); } } - } catch (...) { + } + catch (...) + { LOG(MODULE_PLUGIN, "Closing a broken socket.") } } void DataMessageQThread() { server = new QLocalServer(); - // BUG Sometimes failed to listen due to improper close of last session. + // BUG Sometimes failed to listen due to improper close of last + // session. bool listening = server->listen(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_LINUX); - while (!isExiting && !listening) { + while (!isExiting && !listening) + { QThread::msleep(500); listening = server->listen(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_LINUX); } @@ -53,7 +62,8 @@ namespace Qv2ray::components::plugins::Toolbar server->setSocketOptions(QLocalServer::WorldAccessOption); QObject::connect(server, &QLocalServer::newConnection, &qobject_proxy); - while (!isExiting) { + while (!isExiting) + { bool result = server->waitForNewConnection(5000, &timeOut); DEBUG(MODULE_PLUGIN, "Plugin thread listening failed: " + server->errorString()) DEBUG(MODULE_PLUGIN, "waitForNewConnection: " + QString(result ? "true" : "false") + ", " + QString(timeOut ? "true" : "false")) @@ -72,13 +82,14 @@ namespace Qv2ray::components::plugins::Toolbar { isExiting = true; - if (linuxWorkerThread->isRunning()) { + if (linuxWorkerThread->isRunning()) + { LOG(MODULE_PLUGIN, "Waiting for linuxWorkerThread to stop.") linuxWorkerThread->wait(); } delete _linux::linuxWorkerThread; } - } -} + } // namespace _linux +} // namespace Qv2ray::components::plugins::Toolbar #endif diff --git a/src/components/plugins/toolbar/QvToolbar_win.cpp b/src/components/plugins/toolbar/QvToolbar_win.cpp index 4662e77a..f7553fb7 100644 --- a/src/components/plugins/toolbar/QvToolbar_win.cpp +++ b/src/components/plugins/toolbar/QvToolbar_win.cpp @@ -1,8 +1,9 @@ #include #ifdef Q_OS_WIN -#include "components/plugins/toolbar/QvToolbar.hpp" -#include "common/QvHelpers.hpp" -#include + #include "common/QvHelpers.hpp" + #include "components/plugins/toolbar/QvToolbar.hpp" + + #include namespace Qv2ray::components::plugins::Toolbar { namespace _win @@ -25,40 +26,53 @@ namespace Qv2ray::components::plugins::Toolbar { auto hThread = CreateThread(nullptr, 0, NamedPipeMasterThread, nullptr, 0, nullptr); - if (hThread == nullptr) { + if (hThread == nullptr) + { LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" + QSTRN(GetLastError())) return; - } else CloseHandle(hThread); + } + else + CloseHandle(hThread); } DWORD WINAPI NamedPipeMasterThread(LPVOID lpvParam) { Q_UNUSED(lpvParam) - BOOL fConnected = FALSE; - DWORD dwThreadId = 0; + BOOL fConnected = FALSE; + DWORD dwThreadId = 0; HANDLE hPipe = INVALID_HANDLE_VALUE; auto lpszPipename = QString(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_WIN).toStdWString(); - while (!isExiting) { - //printf("Pipe Server: Main thread awaiting client connection on %s\n", lpszPipename.c_str()); - hPipe = CreateNamedPipe(lpszPipename.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 0, nullptr); + while (!isExiting) + { + // printf("Pipe Server: Main thread awaiting client connection + // on %s\n", lpszPipename.c_str()); + hPipe = CreateNamedPipe(lpszPipename.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 0, nullptr); - if (hPipe == INVALID_HANDLE_VALUE) { + if (hPipe == INVALID_HANDLE_VALUE) + { LOG(MODULE_PLUGIN, "CreateNamedPipe failed, GLE=" + QSTRN(GetLastError())) return static_cast(-1); } fConnected = ConnectNamedPipe(hPipe, nullptr) ? true : (GetLastError() == ERROR_PIPE_CONNECTED); - if (fConnected) { + if (fConnected) + { LOG(MODULE_PLUGIN, "Client connected, creating a processing thread") ThreadHandle = CreateThread(nullptr, 0, InstanceThread, hPipe, 0, &dwThreadId); - if (ThreadHandle == nullptr) { + if (ThreadHandle == nullptr) + { LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" + QSTRN(GetLastError())) return static_cast(-1); - } else CloseHandle(ThreadHandle); - } else CloseHandle(hPipe); + } + else + CloseHandle(ThreadHandle); + } + else + CloseHandle(hPipe); } return 0; @@ -71,13 +85,16 @@ namespace Qv2ray::components::plugins::Toolbar HANDLE hPipe = static_cast(lpvParam); TCHAR pchRequest[BUFSIZE] = { 0 }; - while (!isExiting) { + while (!isExiting) + { fSuccess = ReadFile(hPipe, pchRequest, BUFSIZE * sizeof(TCHAR), &cbBytesRead, nullptr); - if (!fSuccess || cbBytesRead == 0) { - if (GetLastError() == ERROR_BROKEN_PIPE) { - LOG(MODULE_PLUGIN, "InstanceThread: client disconnected, GLE=" + QSTRN(GetLastError())) - } else { + if (!fSuccess || cbBytesRead == 0) + { + if (GetLastError() == ERROR_BROKEN_PIPE) + { LOG(MODULE_PLUGIN, "InstanceThread: client disconnected, GLE=" + QSTRN(GetLastError())) } + else + { LOG(MODULE_PLUGIN, "InstanceThread ReadFile failed, GLE=" + QSTRN(GetLastError())) } @@ -87,17 +104,20 @@ namespace Qv2ray::components::plugins::Toolbar auto req = QString::fromStdWString(pchRequest); QString replyQString = "{}"; - if (!isExiting) { + if (!isExiting) + { replyQString = GetAnswerToRequest(req); // // REPLY as std::string std::string pchReply = replyQString.toUtf8().constData(); cbReplyBytes = static_cast(pchReply.length() + 1) * sizeof(CHAR); - //cbReplyBytes = static_cast(replyQString.length() + 1) * sizeof(TCHAR); + // cbReplyBytes = static_cast(replyQString.length() + + // 1) * sizeof(TCHAR); // fSuccess = WriteFile(hPipe, pchReply.c_str(), cbReplyBytes, &cbWritten, nullptr); - if (!fSuccess || cbReplyBytes != cbWritten) { + if (!fSuccess || cbReplyBytes != cbWritten) + { LOG(MODULE_PLUGIN, "InstanceThread WriteFile failed, GLE=" + QSTRN(GetLastError())) break; } @@ -109,6 +129,6 @@ namespace Qv2ray::components::plugins::Toolbar CloseHandle(hPipe); return 1; } - } -} + } // namespace _win +} // namespace Qv2ray::components::plugins::Toolbar #endif diff --git a/src/components/proxy/QvProxyConfigurator.cpp b/src/components/proxy/QvProxyConfigurator.cpp index 9c12000f..84b85c3a 100644 --- a/src/components/proxy/QvProxyConfigurator.cpp +++ b/src/components/proxy/QvProxyConfigurator.cpp @@ -1,8 +1,10 @@ #include "QvProxyConfigurator.hpp" + #include "common/QvHelpers.hpp" #ifdef Q_OS_WIN -#include "wininet.h" -#include + #include "wininet.h" + + #include #endif namespace Qv2ray::components::proxy @@ -23,11 +25,10 @@ namespace Qv2ray::components::proxy QStringList result; // Start from 1 since first line is unneeded. - for (auto i = 1; i < lines.count(); i++) { + for (auto i = 1; i < lines.count(); i++) + { // * means disabled. - if (!lines[i].contains("*")) { - result << (lines[i].contains(" ") ? "\"" + lines[i] + "\"" : lines[i]); - } + if (!lines[i].contains("*")) { result << (lines[i].contains(" ") ? "\"" + lines[i] + "\"" : lines[i]); } } LOG(MODULE_PROXY, "Found " + QSTRN(result.size()) + " network services: " + result.join(";")) @@ -35,8 +36,9 @@ namespace Qv2ray::components::proxy } #endif #ifdef Q_OS_WIN -#define NO_CONST(expr) const_cast(expr) - //static auto DEFAULT_CONNECTION_NAME = NO_CONST(L"DefaultConnectionSettings"); + #define NO_CONST(expr) const_cast(expr) + // static auto DEFAULT_CONNECTION_NAME = + // NO_CONST(L"DefaultConnectionSettings"); /// /// INTERNAL FUNCTION bool __QueryProxyOptions() @@ -52,81 +54,64 @@ namespace Qv2ray::components::proxy Option[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER; // List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); - List.pszConnection = nullptr;// NO_CONST(DEFAULT_CONNECTION_NAME); + List.pszConnection = nullptr; // NO_CONST(DEFAULT_CONNECTION_NAME); List.dwOptionCount = 5; List.dwOptionError = 0; List.pOptions = Option; - if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) { - LOG(MODULE_PROXY, "InternetQueryOption failed, GLE=" + QSTRN(GetLastError())) - } + if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) + { LOG(MODULE_PROXY, "InternetQueryOption failed, GLE=" + QSTRN(GetLastError())) } LOG(MODULE_PROXY, "System default proxy info:") - if (Option[0].Value.pszValue != nullptr) { - LOG(MODULE_PROXY, QString::fromWCharArray(Option[0].Value.pszValue)) - } + if (Option[0].Value.pszValue != nullptr) { LOG(MODULE_PROXY, QString::fromWCharArray(Option[0].Value.pszValue)) } - if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL) { - LOG(MODULE_PROXY, "PROXY_TYPE_AUTO_PROXY_URL") - } + if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL) + { LOG(MODULE_PROXY, "PROXY_TYPE_AUTO_PROXY_URL") } - if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT) { - LOG(MODULE_PROXY, "PROXY_TYPE_AUTO_DETECT") - } + if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT) { LOG(MODULE_PROXY, "PROXY_TYPE_AUTO_DETECT") } - if ((Option[2].Value.dwValue & PROXY_TYPE_DIRECT) == PROXY_TYPE_DIRECT) { - LOG(MODULE_PROXY, "PROXY_TYPE_DIRECT") - } + if ((Option[2].Value.dwValue & PROXY_TYPE_DIRECT) == PROXY_TYPE_DIRECT) { LOG(MODULE_PROXY, "PROXY_TYPE_DIRECT") } - if ((Option[2].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY) { - LOG(MODULE_PROXY, "PROXY_TYPE_PROXY") - } + if ((Option[2].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY) { LOG(MODULE_PROXY, "PROXY_TYPE_PROXY") } - if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) { - LOG(MODULE_PROXY, "InternetQueryOption failed,GLE=" + QSTRN(GetLastError())) - } + if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) + { LOG(MODULE_PROXY, "InternetQueryOption failed,GLE=" + QSTRN(GetLastError())) } - if (Option[4].Value.pszValue != nullptr) { - LOG(MODULE_PROXY, QString::fromStdWString(Option[4].Value.pszValue)) - } + if (Option[4].Value.pszValue != nullptr) { LOG(MODULE_PROXY, QString::fromStdWString(Option[4].Value.pszValue)) } INTERNET_VERSION_INFO Version; nSize = sizeof(INTERNET_VERSION_INFO); InternetQueryOption(nullptr, INTERNET_OPTION_VERSION, &Version, &nSize); - if (Option[0].Value.pszValue != nullptr) { - GlobalFree(Option[0].Value.pszValue); - } + if (Option[0].Value.pszValue != nullptr) { GlobalFree(Option[0].Value.pszValue); } - if (Option[3].Value.pszValue != nullptr) { - GlobalFree(Option[3].Value.pszValue); - } + if (Option[3].Value.pszValue != nullptr) { GlobalFree(Option[3].Value.pszValue); } - if (Option[4].Value.pszValue != nullptr) { - GlobalFree(Option[4].Value.pszValue); - } + if (Option[4].Value.pszValue != nullptr) { GlobalFree(Option[4].Value.pszValue); } return false; } bool __SetProxyOptions(LPWSTR proxy_full_addr, bool isPAC) { INTERNET_PER_CONN_OPTION_LIST list; - BOOL bReturn; - DWORD dwBufSize = sizeof(list); + BOOL bReturn; + DWORD dwBufSize = sizeof(list); // Fill the list structure. list.dwSize = sizeof(list); // NULL == LAN, otherwise connectoid name. list.pszConnection = nullptr; - if (isPAC) { + if (isPAC) + { LOG(MODULE_PROXY, "Setting system proxy for PAC") // list.dwOptionCount = 2; list.pOptions = new INTERNET_PER_CONN_OPTION[2]; // Ensure that the memory was allocated. - if (nullptr == list.pOptions) { + if (nullptr == list.pOptions) + { // Return FALSE if the memory wasn't allocated. return FALSE; } @@ -137,15 +122,15 @@ namespace Qv2ray::components::proxy // Set proxy name. list.pOptions[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL; list.pOptions[1].Value.pszValue = proxy_full_addr; - } else { + } + else + { LOG(MODULE_PROXY, "Setting system proxy for Global Proxy") // list.dwOptionCount = 3; list.pOptions = new INTERNET_PER_CONN_OPTION[3]; - if (nullptr == list.pOptions) { - return false; - } + if (nullptr == list.pOptions) { return false; } // Set flags. list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; @@ -161,7 +146,7 @@ namespace Qv2ray::components::proxy // Set the options on the connection. bReturn = InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize); - delete [] list.pOptions; + delete[] list.pOptions; InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0); InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0); return bReturn; @@ -173,29 +158,26 @@ namespace Qv2ray::components::proxy bool hasHTTP = (httpPort != 0); bool hasSOCKS = (socksPort != 0); - if (!(hasHTTP || hasSOCKS || usePAC)) { + if (!(hasHTTP || hasSOCKS || usePAC)) + { LOG(MODULE_PROXY, "Nothing?") return; } - if (usePAC) { - LOG(MODULE_PROXY, "Qv2ray will set system proxy to use PAC file") - } else { - if (hasHTTP) { - LOG(MODULE_PROXY, "Qv2ray will set system proxy to use HTTP") - } + if (usePAC) { LOG(MODULE_PROXY, "Qv2ray will set system proxy to use PAC file") } + else + { + if (hasHTTP) { LOG(MODULE_PROXY, "Qv2ray will set system proxy to use HTTP") } - if (hasSOCKS) { - LOG(MODULE_PROXY, "Qv2ray will set system proxy to use SOCKS") - } + if (hasSOCKS) { LOG(MODULE_PROXY, "Qv2ray will set system proxy to use SOCKS") } } #ifdef Q_OS_WIN QString __a; - if (usePAC) { - __a = address; - } else { + if (usePAC) { __a = address; } + else + { __a = (hasHTTP ? "http://" : "socks5://") + address + ":" + QSTRN(httpPort); } @@ -205,9 +187,7 @@ namespace Qv2ray::components::proxy // __QueryProxyOptions(); - if (!__SetProxyOptions(proxyStrW, usePAC)) { - LOG(MODULE_PROXY, "Failed to set proxy.") - } + if (!__SetProxyOptions(proxyStrW, usePAC)) { LOG(MODULE_PROXY, "Failed to set proxy.") } __QueryProxyOptions(); #elif defined(Q_OS_LINUX) @@ -215,18 +195,21 @@ namespace Qv2ray::components::proxy auto proxyMode = usePAC ? "auto" : "manual"; actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg(proxyMode); - if (usePAC) { - actions << QString("gsettings set org.gnome.system.proxy autoconfig-url '%1'").arg(address); - } else { - if (hasHTTP) { + if (usePAC) { actions << QString("gsettings set org.gnome.system.proxy autoconfig-url '%1'").arg(address); } + else + { + if (hasHTTP) + { actions << QString("gsettings set org.gnome.system.proxy.http host '%1'").arg(address); actions << QString("gsettings set org.gnome.system.proxy.http port %1").arg(httpPort); // actions << QString("gsettings set org.gnome.system.proxy.https host '%1'").arg(address); - actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort);; + actions << QString("gsettings set org.gnome.system.proxy.https port %1").arg(httpPort); + ; } - if (hasSOCKS) { + if (hasSOCKS) + { actions << QString("gsettings set org.gnome.system.proxy.socks host '%1'").arg(address); actions << QString("gsettings set org.gnome.system.proxy.socks port %1").arg(socksPort); } @@ -234,12 +217,13 @@ namespace Qv2ray::components::proxy // note: do not use std::all_of / any_of / none_of, // because those are short-circuit and cannot guarantee atomicity. - auto result = std::count_if(actions.cbegin(), actions.cend(), [](const QString & action) { - DEBUG(MODULE_PROXY, action) - return QProcess::execute(action) == QProcess::NormalExit; - }) == actions.size(); + auto result = std::count_if(actions.cbegin(), actions.cend(), [](const QString &action) { + DEBUG(MODULE_PROXY, action) + return QProcess::execute(action) == QProcess::NormalExit; + }) == actions.size(); - if (!result) { + if (!result) + { LOG(MODULE_PROXY, "Something wrong happens when setting system proxy -> Gnome ONLY.") LOG(MODULE_PROXY, "If you are using KDE Plasma and receiving this message, just simply ignore this.") } @@ -247,21 +231,27 @@ namespace Qv2ray::components::proxy Q_UNUSED(result); #else - for (auto service : macOSgetNetworkServices()) { + for (auto service : macOSgetNetworkServices()) + { LOG(MODULE_PROXY, "Setting proxy for interface: " + service) - if (usePAC) { + if (usePAC) + { QProcess::execute("/usr/sbin/networksetup -setautoproxystate " + service + " on"); QProcess::execute("/usr/sbin/networksetup -setautoproxyurl " + service + " " + address); - } else { - if (hasHTTP) { + } + else + { + if (hasHTTP) + { QProcess::execute("/usr/sbin/networksetup -setwebproxystate " + service + " on"); QProcess::execute("/usr/sbin/networksetup -setsecurewebproxystate " + service + " on"); QProcess::execute("/usr/sbin/networksetup -setwebproxy " + service + " " + address + " " + QSTRN(httpPort)); QProcess::execute("/usr/sbin/networksetup -setsecurewebproxy " + service + " " + address + " " + QSTRN(httpPort)); } - if (hasSOCKS) { + if (hasSOCKS) + { QProcess::execute("/usr/sbin/networksetup -setsocksfirewallproxystate " + service + " on"); QProcess::execute("/usr/sbin/networksetup -setsocksfirewallproxy " + service + " " + address + " " + QSTRN(socksPort)); } @@ -287,7 +277,8 @@ namespace Qv2ray::components::proxy list.pOptions = new INTERNET_PER_CONN_OPTION[list.dwOptionCount]; // Make sure the memory was allocated. - if (nullptr == list.pOptions) { + if (nullptr == list.pOptions) + { // Return FALSE if the memory wasn't allocated. LOG(MODULE_PROXY, "Failed to allocat memory in DisableConnectionProxy()") } @@ -298,14 +289,15 @@ namespace Qv2ray::components::proxy // // Set the options on the connection. bReturn = InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize); - delete [] list.pOptions; + delete[] list.pOptions; InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0); InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0); #elif defined(Q_OS_LINUX) QProcess::execute("gsettings set org.gnome.system.proxy mode 'none'"); #else - for (auto service : macOSgetNetworkServices()) { + for (auto service : macOSgetNetworkServices()) + { LOG(MODULE_PROXY, "Clearing proxy for interface: " + service) QProcess::execute("/usr/sbin/networksetup -setautoproxystate " + service + " off"); QProcess::execute("/usr/sbin/networksetup -setwebproxystate " + service + " off"); @@ -315,4 +307,4 @@ namespace Qv2ray::components::proxy #endif } -} +} // namespace Qv2ray::components::proxy diff --git a/src/components/proxy/QvProxyConfigurator.hpp b/src/components/proxy/QvProxyConfigurator.hpp index 3eb9c91a..f8e071d8 100644 --- a/src/components/proxy/QvProxyConfigurator.hpp +++ b/src/components/proxy/QvProxyConfigurator.hpp @@ -1,12 +1,12 @@ #pragma once -#include #include +#include // namespace Qv2ray::components::proxy { void ClearSystemProxy(); void SetSystemProxy(const QString &address, int http_port, int socks_port, bool usePAC); -} +} // namespace Qv2ray::components::proxy using namespace Qv2ray::components; using namespace Qv2ray::components::proxy; diff --git a/src/components/speedchart/speedplotview.cpp b/src/components/speedchart/speedplotview.cpp index 9dae7d5f..848d4b32 100644 --- a/src/components/speedchart/speedplotview.cpp +++ b/src/components/speedchart/speedplotview.cpp @@ -14,39 +14,40 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * In addition, as a special exception, the copyright holders give permission to * link this program with the OpenSSL project's "OpenSSL" library (or with * modified versions of it that use the same license as the "OpenSSL" library), * and distribute the linked executables. You must obey the GNU General Public - * License in all respects for all of the code used other than "OpenSSL". If you - * modify file(s), you may extend this exception to your version of the file(s), - * but you are not obligated to do so. If you do not wish to do so, delete this - * exception statement from your version. + * License in all respects for all of the code used other than "OpenSSL". If + * you modify file(s), you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. */ #include "speedplotview.hpp" +#include #include #include #include #include -#include - #define VIEWABLE 120 // use binary prefix standards from IEC 60027-2 // see http://en.wikipedia.org/wiki/Kilobyte -enum class SizeUnit { - Byte, // 1024^0, - KibiByte, // 1024^1, - MebiByte, // 1024^2, - GibiByte, // 1024^3, - TebiByte, // 1024^4, - PebiByte, // 1024^5, - ExbiByte // 1024^6, +enum class SizeUnit +{ + Byte, // 1024^0, + KibiByte, // 1024^1, + MebiByte, // 1024^2, + GibiByte, // 1024^3, + TebiByte, // 1024^4, + PebiByte, // 1024^5, + ExbiByte // 1024^6, // int64 is used for sizes and thus the next units can not be handled // ZebiByte, // 1024^7, // YobiByte, // 1024^8 @@ -54,27 +55,25 @@ enum class SizeUnit { namespace { - const struct { + const struct + { const char *source; const char *comment; - } units[] = { - QT_TRANSLATE_NOOP3("misc", "B", "bytes"), - QT_TRANSLATE_NOOP3("misc", "KiB", "kibibytes (1024 bytes)"), - QT_TRANSLATE_NOOP3("misc", "MiB", "mebibytes (1024 kibibytes)"), - QT_TRANSLATE_NOOP3("misc", "GiB", "gibibytes (1024 mibibytes)"), - QT_TRANSLATE_NOOP3("misc", "TiB", "tebibytes (1024 gibibytes)"), - QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"), - QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)") - }; -} + } units[] = { QT_TRANSLATE_NOOP3("misc", "B", "bytes"), + QT_TRANSLATE_NOOP3("misc", "KiB", "kibibytes (1024 bytes)"), + QT_TRANSLATE_NOOP3("misc", "MiB", "mebibytes (1024 kibibytes)"), + QT_TRANSLATE_NOOP3("misc", "GiB", "gibibytes (1024 mibibytes)"), + QT_TRANSLATE_NOOP3("misc", "TiB", "tebibytes (1024 gibibytes)"), + QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"), + QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)") }; +} // namespace QString unitString(const SizeUnit unit, const bool isSpeed) { const auto &unitString = units[static_cast(unit)]; QString ret = QCoreApplication::translate("misc", unitString.source, unitString.comment); - if (isSpeed) - ret += QCoreApplication::translate("misc", "/s", "per second"); + if (isSpeed) ret += QCoreApplication::translate("misc", "/s", "per second"); return ret; } @@ -82,36 +81,34 @@ QString unitString(const SizeUnit unit, const bool isSpeed) int friendlyUnitPrecision(const SizeUnit unit) { // friendlyUnit's number of digits after the decimal point - switch (unit) { - case SizeUnit::Byte: - return 0; + switch (unit) + { + case SizeUnit::Byte: return 0; case SizeUnit::KibiByte: - case SizeUnit::MebiByte: - return 1; + case SizeUnit::MebiByte: return 1; - case SizeUnit::GibiByte: - return 2; + case SizeUnit::GibiByte: return 2; - default: - return 3; + default: return 3; } } qlonglong sizeInBytes(qreal size, const SizeUnit unit) { - for (int i = 0; i < static_cast(unit); ++i) - size *= 1024; + for (int i = 0; i < static_cast(unit); ++i) size *= 1024; return size; } namespace { - // table of supposed nice steps for grid marks to get nice looking quarters of scale - const double roundingTable[] = {1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8}; + // table of supposed nice steps for grid marks to get nice looking quarters + // of scale + const double roundingTable[] = { 1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8 }; - struct SplittedValue { + struct SplittedValue + { double arg; SizeUnit unit; qint64 sizeInBytes() const @@ -122,56 +119,53 @@ namespace SplittedValue getRoundedYScale(double value) { - if (value == 0.0) return {0, SizeUnit::Byte}; + if (value == 0.0) return { 0, SizeUnit::Byte }; - if (value <= 12.0) return {12, SizeUnit::Byte}; + if (value <= 12.0) return { 12, SizeUnit::Byte }; SizeUnit calculatedUnit = SizeUnit::Byte; - while (value > 1024) { + while (value > 1024) + { value /= 1024; calculatedUnit = static_cast(static_cast(calculatedUnit) + 1); } - if (value > 100.0) { + if (value > 100.0) + { int roundedValue = static_cast(value / 40) * 40; - while (roundedValue < value) - roundedValue += 40; + while (roundedValue < value) roundedValue += 40; - return {static_cast(roundedValue), calculatedUnit}; + return { static_cast(roundedValue), calculatedUnit }; } - if (value > 10.0) { + if (value > 10.0) + { int roundedValue = static_cast(value / 4) * 4; - while (roundedValue < value) - roundedValue += 4; + while (roundedValue < value) roundedValue += 4; - return {static_cast(roundedValue), calculatedUnit}; + return { static_cast(roundedValue), calculatedUnit }; } - for (const auto &roundedValue : roundingTable) { - if (value <= roundedValue) - return {roundedValue, calculatedUnit}; + for (const auto &roundedValue : roundingTable) + { + if (value <= roundedValue) return { roundedValue, calculatedUnit }; } - return {10.0, calculatedUnit}; + return { 10.0, calculatedUnit }; } QString formatLabel(const double argValue, const SizeUnit unit) { // check is there need for digits after decimal separator const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0; - return QLocale::system().toString(argValue, 'f', precision) - + QString::fromUtf8(" ") - + unitString(unit, true); + return QLocale::system().toString(argValue, 'f', precision) + QString::fromUtf8(" ") + unitString(unit, true); } -} +} // namespace -SpeedPlotView::SpeedPlotView(QWidget *parent) - : QGraphicsView(parent) - , m_currentData(&m_datahalfMin) +SpeedPlotView::SpeedPlotView(QWidget *parent) : QGraphicsView(parent), m_currentData(&m_datahalfMin) { QPen greenPen; greenPen.setWidthF(1.5); @@ -193,9 +187,7 @@ void SpeedPlotView::pushPoint(const SpeedPlotView::PointData &point) { m_datahalfMin.push_back(point); - while (m_datahalfMin.length() > VIEWABLE) { - m_datahalfMin.removeFirst(); - } + while (m_datahalfMin.length() > VIEWABLE) { m_datahalfMin.removeFirst(); } } void SpeedPlotView::replot() @@ -213,11 +205,12 @@ quint64 SpeedPlotView::maxYValue() auto &queue = getCurrentData(); quint64 maxYValue = 0; - for (int id = UP; id < NB_GRAPHS; ++id) { + for (int id = UP; id < NB_GRAPHS; ++id) + { // 30 is half min - for (int i = queue.size() - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j) { - if (queue[i].y[id] > maxYValue) - maxYValue = queue[i].y[id]; + for (int i = queue.size() - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j) + { + if (queue[i].y[id] > maxYValue) maxYValue = queue[i].y[id]; } } @@ -244,12 +237,12 @@ void SpeedPlotView::paintEvent(QPaintEvent *) int yAxisWidth = 0; for (const QString &label : speedLabels) - if (fontMetrics.horizontalAdvance(label) > yAxisWidth) - yAxisWidth = fontMetrics.horizontalAdvance(label); + if (fontMetrics.horizontalAdvance(label) > yAxisWidth) yAxisWidth = fontMetrics.horizontalAdvance(label); int i = 0; - for (const QString &label : speedLabels) { + for (const QString &label : speedLabels) + { QRectF labelRect(rect.topLeft() + QPointF(-yAxisWidth, (i++) * 0.25 * rect.height() - fontMetrics.height()), QSizeF(2 * yAxisWidth, fontMetrics.height())); painter.drawText(labelRect, label, Qt::AlignRight | Qt::AlignTop); @@ -269,7 +262,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *) painter.drawLine(fullRect.left(), rect.bottom(), rect.right(), rect.bottom()); const int TIME_AXIS_DIVISIONS = 6; - for (int i = 0; i < TIME_AXIS_DIVISIONS; ++i) { + for (int i = 0; i < TIME_AXIS_DIVISIONS; ++i) + { const int x = rect.left() + (i * rect.width()) / TIME_AXIS_DIVISIONS; painter.drawLine(x, fullRect.top(), x, fullRect.bottom()); } @@ -282,10 +276,12 @@ void SpeedPlotView::paintEvent(QPaintEvent *) const double xTickSize = static_cast(rect.width()) / VIEWABLE; auto &queue = getCurrentData(); - for (int id = UP; id < NB_GRAPHS; ++id) { + for (int id = UP; id < NB_GRAPHS; ++id) + { QVector points; - for (int i = static_cast(queue.size()) - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j) { + for (int i = static_cast(queue.size()) - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j) + { int newX = rect.right() - j * xTickSize; int newY = rect.bottom() - queue[i].y[id] * yMultiplier; points.push_back(QPoint(newX, newY)); @@ -300,27 +296,28 @@ void SpeedPlotView::paintEvent(QPaintEvent *) double legendHeight = 0; int legendWidth = 0; - for (const auto &property : m_properties) { - if (fontMetrics.horizontalAdvance(property.name) > legendWidth) - legendWidth = fontMetrics.horizontalAdvance(property.name); + for (const auto &property : m_properties) + { + if (fontMetrics.horizontalAdvance(property.name) > legendWidth) legendWidth = fontMetrics.horizontalAdvance(property.name); legendHeight += 1.5 * fontMetrics.height(); } QRectF legendBackgroundRect(QPoint(legendTopLeft.x() - 4, legendTopLeft.y() - 4), QSizeF(legendWidth + 8, legendHeight + 8)); QColor legendBackgroundColor = QWidget::palette().color(QWidget::backgroundRole()); - legendBackgroundColor.setAlpha(128); // 50% transparent + legendBackgroundColor.setAlpha(128); // 50% transparent painter.fillRect(legendBackgroundRect, legendBackgroundColor); i = 0; - for (const auto &property : m_properties) { + for (const auto &property : m_properties) + { int nameSize = fontMetrics.horizontalAdvance(property.name); double indent = 1.5 * (i++) * fontMetrics.height(); painter.setPen(property.pen); painter.drawLine(legendTopLeft + QPointF(0, indent + fontMetrics.height()), legendTopLeft + QPointF(nameSize, indent + fontMetrics.height())); - painter.drawText(QRectF(legendTopLeft + QPointF(0, indent), QSizeF(2 * nameSize, fontMetrics.height())), - property.name, QTextOption(Qt::AlignVCenter)); + painter.drawText(QRectF(legendTopLeft + QPointF(0, indent), QSizeF(2 * nameSize, fontMetrics.height())), property.name, + QTextOption(Qt::AlignVCenter)); } } @@ -328,8 +325,6 @@ SpeedPlotView::GraphProperties::GraphProperties() { } -SpeedPlotView::GraphProperties::GraphProperties(const QString &name, const QPen &pen) - : name(name) - , pen(pen) +SpeedPlotView::GraphProperties::GraphProperties(const QString &name, const QPen &pen) : name(name), pen(pen) { } diff --git a/src/components/speedchart/speedplotview.hpp b/src/components/speedchart/speedplotview.hpp index a796b212..d1910bed 100644 --- a/src/components/speedchart/speedplotview.hpp +++ b/src/components/speedchart/speedplotview.hpp @@ -36,43 +36,46 @@ class QPen; class SpeedPlotView : public QGraphicsView { - Q_OBJECT + Q_OBJECT - public: - enum GraphID { - UP = 0, - DOWN, - NB_GRAPHS - }; + public: + enum GraphID + { + UP = 0, + DOWN, + NB_GRAPHS + }; - struct PointData { - qint64 x; - quint64 y[NB_GRAPHS]; - }; + struct PointData + { + qint64 x; + quint64 y[NB_GRAPHS]; + }; - explicit SpeedPlotView(QWidget *parent = nullptr); - void pushPoint(const PointData &point); - void Clear(); - void replot(); + explicit SpeedPlotView(QWidget *parent = nullptr); + void pushPoint(const PointData &point); + void Clear(); + void replot(); - protected: - void paintEvent(QPaintEvent *event) override; + protected: + void paintEvent(QPaintEvent *event) override; - private: - struct GraphProperties { - GraphProperties(); - GraphProperties(const QString &name, const QPen &pen); + private: + struct GraphProperties + { + GraphProperties(); + GraphProperties(const QString &name, const QPen &pen); - QString name; - QPen pen; - }; + QString name; + QPen pen; + }; - quint64 maxYValue(); - QList &getCurrentData(); - QList m_datahalfMin; - QList *m_currentData; + quint64 maxYValue(); + QList &getCurrentData(); + QList m_datahalfMin; + QList *m_currentData; - QMap m_properties; + QMap m_properties; }; #endif // SPEEDPLOTVIEW_H diff --git a/src/components/speedchart/speedwidget.cpp b/src/components/speedchart/speedwidget.cpp index 4e548bd2..13c119cf 100644 --- a/src/components/speedchart/speedwidget.cpp +++ b/src/components/speedchart/speedwidget.cpp @@ -14,20 +14,23 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * In addition, as a special exception, the copyright holders give permission to * link this program with the OpenSSL project's "OpenSSL" library (or with * modified versions of it that use the same license as the "OpenSSL" library), * and distribute the linked executables. You must obey the GNU General Public - * License in all respects for all of the code used other than "OpenSSL". If you - * modify file(s), you may extend this exception to your version of the file(s), - * but you are not obligated to do so. If you do not wish to do so, delete this - * exception statement from your version. + * License in all respects for all of the code used other than "OpenSSL". If + * you modify file(s), you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. */ #include "speedwidget.hpp" +#include "speedplotview.hpp" + #include #include #include @@ -35,10 +38,7 @@ #include #include -#include "speedplotview.hpp" - -SpeedWidget::SpeedWidget(QWidget *parent) - : QWidget(parent) +SpeedWidget::SpeedWidget(QWidget *parent) : QWidget(parent) { m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); @@ -52,7 +52,9 @@ SpeedWidget::SpeedWidget(QWidget *parent) m_plot->show(); } -SpeedWidget::~SpeedWidget() {} +SpeedWidget::~SpeedWidget() +{ +} void SpeedWidget::AddPointData(long up, long down) { diff --git a/src/components/speedchart/speedwidget.hpp b/src/components/speedchart/speedwidget.hpp index e6462332..cd3e1ece 100644 --- a/src/components/speedchart/speedwidget.hpp +++ b/src/components/speedchart/speedwidget.hpp @@ -41,17 +41,18 @@ class SpeedPlotView; class SpeedWidget : public QWidget { - Q_OBJECT + Q_OBJECT - public: - explicit SpeedWidget(QWidget *parent); - ~SpeedWidget(); - void AddPointData(long up, long down); - void Clear(); - private: - QVBoxLayout *m_layout; - QHBoxLayout *m_hlayout; - SpeedPlotView *m_plot; + public: + explicit SpeedWidget(QWidget *parent); + ~SpeedWidget(); + void AddPointData(long up, long down); + void Clear(); + + private: + QVBoxLayout *m_layout; + QHBoxLayout *m_hlayout; + SpeedPlotView *m_plot; }; #endif // SPEEDWIDGET_H diff --git a/src/core/CoreSafeTypes.hpp b/src/core/CoreSafeTypes.hpp index 824d1ca9..145624cd 100644 --- a/src/core/CoreSafeTypes.hpp +++ b/src/core/CoreSafeTypes.hpp @@ -1,38 +1,43 @@ #pragma once -#include -#include -#include - #include "base/models/QvConfigIdentifier.hpp" +#include +#include +#include + namespace Qv2ray::core { - template + template class IDType { - public: - explicit IDType(const QString &id): m_id(id) {} - friend bool operator==(const IDType &lhs, const IDType &rhs) - { - return lhs.m_id == rhs.m_id; - } - friend bool operator!=(const IDType &lhs, const IDType &rhs) - { - return lhs.toString() != rhs.toString(); - } - const QString &toString() const - { - return m_id; - } - uint qHash(uint seed) const - { - return ::qHash(m_id, seed); - } - private: - QString m_id; - }; + public: + explicit IDType() : m_id("null") + { + } + explicit IDType(const QString &id) : m_id(id) + { + } + friend bool operator==(const IDType &lhs, const IDType &rhs) + { + return lhs.m_id == rhs.m_id; + } + friend bool operator!=(const IDType &lhs, const IDType &rhs) + { + return lhs.toString() != rhs.toString(); + } + const QString &toString() const + { + return m_id; + } + uint qHash(uint seed) const + { + return ::qHash(m_id, seed); + } + private: + QString m_id; + }; // Define several safetypes to prevent misuse of QString. class __QvGroup; @@ -48,9 +53,7 @@ namespace Qv2ray::core { QList list; - for (auto str : strings) { - list << IDType(str); - } + for (auto str : strings) { list << IDType(str); } return list; } @@ -60,21 +63,23 @@ namespace Qv2ray::core { QList list; - for (auto id : ids) { - list << id.toString(); - } + for (auto id : ids) { list << id.toString(); } return list; } - template uint qHash(const IDType &key, uint seed = 0) + template + uint qHash(const IDType &key, uint seed = 0) { return key.qHash(seed); } // /// Metadata object representing a connection. - struct ConnectionMetaObject : ConnectionObject_Config { + struct ConnectionMetaObject : ConnectionObject_Config + { GroupId groupId = NullGroupId; - ConnectionMetaObject(): ConnectionObject_Config() { } + ConnectionMetaObject() : ConnectionObject_Config() + { + } // Suger for down casting. ConnectionMetaObject(const ConnectionObject_Config &base) : ConnectionMetaObject() { @@ -88,13 +93,16 @@ namespace Qv2ray::core }; /// Metadata object representing a group. - struct GroupMetaObject: SubscriptionObject_Config { + struct GroupMetaObject : SubscriptionObject_Config + { // Implicit base of two types, since group object is actually the group base object. bool isSubscription; QList connections; // Suger for down casting. - GroupMetaObject(): connections() {} - GroupMetaObject(const GroupObject_Config &base): GroupMetaObject() + GroupMetaObject() : connections() + { + } + GroupMetaObject(const GroupObject_Config &base) : GroupMetaObject() { this->isSubscription = false; this->displayName = base.displayName; @@ -102,7 +110,7 @@ namespace Qv2ray::core this->connections = StringsToIdList(base.connections); } // Suger for down casting. - GroupMetaObject(const SubscriptionObject_Config &base): GroupMetaObject((GroupObject_Config)base) + GroupMetaObject(const SubscriptionObject_Config &base) : GroupMetaObject((GroupObject_Config) base) { this->address = base.address; this->lastUpdated = base.lastUpdated; @@ -110,6 +118,6 @@ namespace Qv2ray::core this->isSubscription = true; } }; -} +} // namespace Qv2ray::core using namespace Qv2ray::core; diff --git a/src/core/CoreUtils.cpp b/src/core/CoreUtils.cpp index ba9cd913..72c0c98f 100644 --- a/src/core/CoreUtils.cpp +++ b/src/core/CoreUtils.cpp @@ -24,26 +24,33 @@ namespace Qv2ray::core *port = 0; *protocol = out["protocol"].toString(QObject::tr("N/A")).toLower(); - if (*protocol == "vmess") { - auto Server = StructFromJsonString(JsonToString(out["settings"].toObject()["vnext"].toArray().first().toObject())); + if (*protocol == "vmess") + { + auto Server = + StructFromJsonString(JsonToString(out["settings"].toObject()["vnext"].toArray().first().toObject())); *host = Server.address; *port = Server.port; return true; - } else if (*protocol == "shadowsocks") { + } + else if (*protocol == "shadowsocks") + { auto x = JsonToString(out["settings"].toObject()["servers"].toArray().first().toObject()); auto Server = StructFromJsonString(x); *host = Server.address; *port = Server.port; return true; - } else if (*protocol == "socks") { + } + else if (*protocol == "socks") + { auto x = JsonToString(out["settings"].toObject()["servers"].toArray().first().toObject()); auto Server = StructFromJsonString(x); *host = Server.address; *port = Server.port; return true; - } else { + } + else + { return false; } } -} - +} // namespace Qv2ray::core diff --git a/src/core/CoreUtils.hpp b/src/core/CoreUtils.hpp index 06e59652..4a93d64d 100644 --- a/src/core/CoreUtils.hpp +++ b/src/core/CoreUtils.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include #include +#include namespace Qv2ray::core { @@ -26,6 +26,6 @@ namespace Qv2ray::core bool GetOutboundData(const OUTBOUND &out, QString *host, int *port, QString *protocol); bool IsComplexConfig(const CONFIGROOT &root); -} +} // namespace Qv2ray::core using namespace Qv2ray::core; diff --git a/src/core/config/ConfigBackend.cpp b/src/core/config/ConfigBackend.cpp index b3406fd0..6ea686b5 100644 --- a/src/core/config/ConfigBackend.cpp +++ b/src/core/config/ConfigBackend.cpp @@ -1,4 +1,5 @@ #include "ConfigBackend.hpp" + #include "common/QvHelpers.hpp" namespace Qv2ray::core::config @@ -14,10 +15,8 @@ namespace Qv2ray::core::config { Qv2rayConfigPath = path; - if (!path.endsWith("/")) { - Qv2rayConfigPath += "/"; - } + if (!path.endsWith("/")) { Qv2rayConfigPath += "/"; } } -} +} // namespace Qv2ray::core::config using namespace Qv2ray::core::config; diff --git a/src/core/config/ConfigBackend.hpp b/src/core/config/ConfigBackend.hpp index 35966a29..6ea855b8 100644 --- a/src/core/config/ConfigBackend.hpp +++ b/src/core/config/ConfigBackend.hpp @@ -4,7 +4,7 @@ namespace Qv2ray::core::config { void SaveGlobalConfig(const Qv2rayConfig &conf); void SetConfigDirPath(const QString &path); -} +} // namespace Qv2ray::core::config using namespace Qv2ray::core; using namespace Qv2ray::core::config; diff --git a/src/core/config/ConfigUpgrade.cpp b/src/core/config/ConfigUpgrade.cpp index 4b07e8cc..54a02117 100644 --- a/src/core/config/ConfigUpgrade.cpp +++ b/src/core/config/ConfigUpgrade.cpp @@ -13,11 +13,14 @@ namespace Qv2ray // Private member QJsonObject UpgradeConfig_Inc(int fromVersion, QJsonObject root) { - switch (fromVersion) { + switch (fromVersion) + { // -------------------------------------------------------------------------------------- // Below is for Qv2ray version 2 - case 4: { - // We changed the "proxyCN" to "bypassCN" as it's easier to understand.... + case 4: + { + // We changed the "proxyCN" to "bypassCN" as it's easier to + // understand.... auto v2_oldProxyCN = root["proxyCN"].toBool(); // // From 3 to 4, we changed 'runAsRoot' to 'tProxySupport' @@ -38,7 +41,7 @@ namespace Qv2ray root.remove("inBoundSettings"); UPGRADELOG("Renamed inBoundSettings to inboundConfig.") // - //connectionConfig + // connectionConfig QJsonObject o; o["dnsList"] = root["dnsList"]; o["withLocalDNS"] = root["withLocalDNS"]; @@ -66,13 +69,15 @@ namespace Qv2ray } // Qv2ray version 2, RC 2 - case 5: { + case 5: + { // Added subscription auto update auto subs = root["subscribes"].toObject(); root.remove("subscribes"); QJsonObject newSubscriptions; - for (auto item = subs.begin(); item != subs.end(); item++) { + for (auto item = subs.begin(); item != subs.end(); item++) + { auto key = item.key(); SubscriptionObject_Config _conf; _conf.address = item.value().toString(); @@ -88,7 +93,8 @@ namespace Qv2ray } // Qv2ray version 2, RC 4 - case 6: { + case 6: + { // Moved API Stats port from connectionConfig to apiConfig QJsonObject apiConfig; apiConfig["enableAPI"] = true; @@ -97,7 +103,8 @@ namespace Qv2ray break; } - case 7: { + case 7: + { auto lang = root["uiConfig"].toObject()["language"].toString().replace("-", "_"); auto uiConfig = root["uiConfig"].toObject(); uiConfig["language"] = lang; @@ -106,23 +113,24 @@ namespace Qv2ray break; } - // From version 8 to 9, we introduced a lot of new connection metainfo(s) - case 8: { + // From version 8 to 9, we introduced a lot of new connection + // metainfo(s) + case 8: + { // Generate a default group QJsonObject defaultGroup; QStringList defaultGroupConnectionId; defaultGroup["displayName"] = QObject::tr("Default Group"); QString defaultGroupId = "000000000000"; - if (!QDir(QV2RAY_CONNECTIONS_DIR + defaultGroupId).exists()) { - QDir().mkpath(QV2RAY_CONNECTIONS_DIR + defaultGroupId); - } + if (!QDir(QV2RAY_CONNECTIONS_DIR + defaultGroupId).exists()) { QDir().mkpath(QV2RAY_CONNECTIONS_DIR + defaultGroupId); } QString autoStartId; UPGRADELOG("Upgrading connections...") QJsonObject rootConnections; - for (auto config : root["configs"].toArray()) { + for (auto config : root["configs"].toArray()) + { UPGRADELOG("Migrating: " + config.toString()) // // MOVE FILES. @@ -133,17 +141,19 @@ namespace Qv2ray DEBUG(MODULE_SETTINGS, "Generated new UUID: " + newUuid); // Check Autostart Id - if (root["autoStartConfig"].toObject()["subscriptionName"].toString().isEmpty()) { - if (root["autoStartConfig"].toObject()["connectionName"].toString() == config.toString()) { - autoStartId = newUuid; - } + if (root["autoStartConfig"].toObject()["subscriptionName"].toString().isEmpty()) + { + if (root["autoStartConfig"].toObject()["connectionName"].toString() == config.toString()) { autoStartId = newUuid; } } - if (configFile.exists()) { + if (configFile.exists()) + { auto newPath = QV2RAY_CONNECTIONS_DIR + defaultGroupId + "/" + newUuid + QV2RAY_CONFIG_FILE_EXTENSION; configFile.rename(newPath); UPGRADELOG("Moved: " + filePath + " to " + newPath); - } else { + } + else + { UPGRADELOG("WARNING! This file is not found, possible loss of data!") continue; } @@ -159,7 +169,8 @@ namespace Qv2ray QJsonObject rootSubscriptions = root.take("subscriptions").toObject(); QJsonObject newSubscriptions; - for (auto i = 0; i < rootSubscriptions.count(); i++) { + for (auto i = 0; i < rootSubscriptions.count(); i++) + { auto key = rootSubscriptions.keys()[i]; auto value = rootSubscriptions.value(key); // @@ -176,15 +187,14 @@ namespace Qv2ray auto newDirPath = QV2RAY_SUBSCRIPTION_DIR + subsUuid; QDir newDir(newDirPath); - if (!newDir.exists()) { - newDir.mkpath(newDirPath); - } + if (!newDir.exists()) { newDir.mkpath(newDirPath); } // With extensions auto fileList = GetFileList(baseDirPath); // Copy every file within a subscription. - for (auto fileName : fileList) { + for (auto fileName : fileList) + { auto subsConnectionId = GenerateUuid(); auto baseFilePath = baseDirPath + "/" + fileName; auto newFilePath = newDirPath + "/" + subsConnectionId + QV2RAY_CONFIG_FILE_EXTENSION; @@ -199,10 +209,10 @@ namespace Qv2ray // // Check Autostart Id - if (root["autoStartConfig"].toObject()["subscriptionName"].toString() == key) { - if (root["autoStartConfig"].toObject()["connectionName"].toString() == subsConnection["displayName"].toString()) { - autoStartId = subsConnectionId; - } + if (root["autoStartConfig"].toObject()["subscriptionName"].toString() == key) + { + if (root["autoStartConfig"].toObject()["connectionName"].toString() == subsConnection["displayName"].toString()) + { autoStartId = subsConnectionId; } } } @@ -222,12 +232,15 @@ namespace Qv2ray break; } - default: { - // Due to technical issue, we cannot maintain all of those upgrade processes anymore. - // Check https://github.com/Qv2ray/Qv2ray/issues/353#issuecomment-586117507 for more information + default: + { + // Due to technical issue, we cannot maintain all of those + // upgrade processes anymore. Check + // https://github.com/Qv2ray/Qv2ray/issues/353#issuecomment-586117507 + // for more information QvMessageBoxWarn(nullptr, QObject::tr("Configuration Upgrade Failed"), QObject::tr("Unsupported config version number: ") + QSTRN(fromVersion) + NEWLINE + NEWLINE + - QObject::tr("Please upgrade firstly up to Qv2ray v2.0/v2.1 and try again.")); + QObject::tr("Please upgrade firstly up to Qv2ray v2.0/v2.1 and try again.")); throw new runtime_error("The configuration version of your old Qv2ray installation is out-of-date and that" " version is not supported anymore, please try to update to an intermediate version of Qv2ray first."); } @@ -242,10 +255,8 @@ namespace Qv2ray { LOG(MODULE_SETTINGS, "Migrating config from version " + QSTRN(fromVersion) + " to " + QSTRN(toVersion)) - for (int i = fromVersion; i < toVersion; i++) { - root = UpgradeConfig_Inc(i, root); - } + for (int i = fromVersion; i < toVersion; i++) { root = UpgradeConfig_Inc(i, root); } return root; } -} +} // namespace Qv2ray diff --git a/src/core/connection/ConnectionIO.cpp b/src/core/connection/ConnectionIO.cpp index d153d653..4c4b528a 100644 --- a/src/core/connection/ConnectionIO.cpp +++ b/src/core/connection/ConnectionIO.cpp @@ -1,4 +1,5 @@ #include "ConnectionIO.hpp" + #include "common/QvHelpers.hpp" namespace Qv2ray::core::connection @@ -8,16 +9,19 @@ namespace Qv2ray::core::connection //// //// Save Connection to a place, with checking if there's existing file. //// If so, append "_N" to the name. - //bool SaveConnectionConfig(CONFIGROOT obj, QString *alias, bool canOverrideExisting) + // bool SaveConnectionConfig(CONFIGROOT obj, QString *alias, bool + // canOverrideExisting) //{ // auto str = JsonToString(obj); - // auto fullPath = QV2RAY_CONFIG_DIR + *alias + QV2RAY_CONFIG_FILE_EXTENSION; + // auto fullPath = QV2RAY_CONFIG_DIR + *alias + + // QV2RAY_CONFIG_FILE_EXTENSION; // // // If there's already a file AND we CANNOT override existing file. // if (QFile::exists(fullPath) && !canOverrideExisting) { // // Alias is a pointer to a QString. - // DeducePossibleFileName(QV2RAY_CONFIG_DIR, alias, QV2RAY_CONFIG_FILE_EXTENSION); - // fullPath = QV2RAY_CONFIG_DIR + *alias + QV2RAY_CONFIG_FILE_EXTENSION; + // DeducePossibleFileName(QV2RAY_CONFIG_DIR, alias, + // QV2RAY_CONFIG_FILE_EXTENSION); fullPath = QV2RAY_CONFIG_DIR + + // *alias + QV2RAY_CONFIG_FILE_EXTENSION; // } // // LOG(MODULE_SETTINGS, "Saving a config named: " + *alias) @@ -25,7 +29,8 @@ namespace Qv2ray::core::connection // return StringToFile(&str, &config); //} // - //bool SaveSubscriptionConfig(CONFIGROOT obj, const QString &subscription, QString *name) + // bool SaveSubscriptionConfig(CONFIGROOT obj, const QString + // &subscription, QString *name) //{ // auto str = JsonToString(obj); // auto fName = *name; @@ -34,27 +39,31 @@ namespace Qv2ray::core::connection // fName = RemoveInvalidFileName(fName); // } // - // QFile config(QV2RAY_SUBSCRIPTION_DIR + subscription + "/" + fName + QV2RAY_CONFIG_FILE_EXTENSION); + // QFile config(QV2RAY_SUBSCRIPTION_DIR + subscription + "/" + fName + // + QV2RAY_CONFIG_FILE_EXTENSION); // // // If there's already a file. THIS IS EXTREMELY RARE // if (config.exists()) { - // LOG(MODULE_FILEIO, "Trying to overrwrite an existing subscription config file. THIS IS RARE") + // LOG(MODULE_FILEIO, "Trying to overrwrite an existing + // subscription config file. THIS IS RARE") // } // // LOG(MODULE_SETTINGS, "Saving a subscription named: " + fName) // bool result = StringToFile(&str, &config); // // if (!result) { - // LOG(MODULE_FILEIO, "Failed to save a connection config from subscription: " + subscription + ", name: " + fName) + // LOG(MODULE_FILEIO, "Failed to save a connection config from + // subscription: " + subscription + ", name: " + fName) // } // // *name = fName; // return result; //} // - //bool RemoveConnection(const QString &alias) + // bool RemoveConnection(const QString &alias) //{ - // QFile config(QV2RAY_CONFIG_DIR + alias + QV2RAY_CONFIG_FILE_EXTENSION); + // QFile config(QV2RAY_CONFIG_DIR + alias + + // QV2RAY_CONFIG_FILE_EXTENSION); // // if (!config.exists()) { // LOG(MODULE_FILEIO, "Trying to remove a non-existing file?") @@ -64,9 +73,11 @@ namespace Qv2ray::core::connection // } //} // - //bool RemoveSubscriptionConnection(const QString &subsName, const QString &name) + // bool RemoveSubscriptionConnection(const QString &subsName, const + // QString &name) //{ - // QFile config(QV2RAY_SUBSCRIPTION_DIR + subsName + "/" + name + QV2RAY_CONFIG_FILE_EXTENSION); + // QFile config(QV2RAY_SUBSCRIPTION_DIR + subsName + "/" + name + + // QV2RAY_CONFIG_FILE_EXTENSION); // // if (!config.exists()) { // LOG(MODULE_FILEIO, "Trying to remove a non-existing file?") @@ -76,25 +87,32 @@ namespace Qv2ray::core::connection // } //} // - //bool RenameConnection(const QString &originalName, const QString &newName) + // bool RenameConnection(const QString &originalName, const QString + // &newName) //{ - // LOG(MODULE_CONNECTION, "[RENAME] --> ORIGINAL: " + originalName + ", NEW: " + newName) - // return QFile::rename(QV2RAY_CONFIG_DIR + originalName + QV2RAY_CONFIG_FILE_EXTENSION, QV2RAY_CONFIG_DIR + newName + QV2RAY_CONFIG_FILE_EXTENSION); + // LOG(MODULE_CONNECTION, "[RENAME] --> ORIGINAL: " + originalName + + // ", NEW: " + newName) return QFile::rename(QV2RAY_CONFIG_DIR + + // originalName + QV2RAY_CONFIG_FILE_EXTENSION, QV2RAY_CONFIG_DIR + + // newName + QV2RAY_CONFIG_FILE_EXTENSION); //} // - //bool RenameSubscription(const QString &originalName, const QString &newName) + // bool RenameSubscription(const QString &originalName, const QString + // &newName) //{ - // LOG(MODULE_SUBSCRIPTION, "[RENAME] --> ORIGINAL: " + originalName + ", NEW: " + newName) - // return QDir().rename(QV2RAY_SUBSCRIPTION_DIR + originalName, QV2RAY_SUBSCRIPTION_DIR + newName); + // LOG(MODULE_SUBSCRIPTION, "[RENAME] --> ORIGINAL: " + originalName + // + ", NEW: " + newName) return + // QDir().rename(QV2RAY_SUBSCRIPTION_DIR + originalName, + // QV2RAY_SUBSCRIPTION_DIR + newName); //} // - //CONFIGROOT ConvertConfigFromFile(QString sourceFilePath, bool importComplex) + // CONFIGROOT ConvertConfigFromFile(QString sourceFilePath, bool + // importComplex) //{ // QFile source(sourceFilePath); // // if (!source.exists()) { - // LOG(MODULE_FILEIO, "Trying to import from an non-existing file.") - // return CONFIGROOT(); + // LOG(MODULE_FILEIO, "Trying to import from an non-existing + // file.") return CONFIGROOT(); // } // // auto root = CONFIGROOT(JsonFromString(StringFromFile(&source))); @@ -111,4 +129,4 @@ namespace Qv2ray::core::connection // return root; //} } -} +} // namespace Qv2ray::core::connection diff --git a/src/core/connection/ConnectionIO.hpp b/src/core/connection/ConnectionIO.hpp index 010f45fd..c6114159 100644 --- a/src/core/connection/ConnectionIO.hpp +++ b/src/core/connection/ConnectionIO.hpp @@ -7,8 +7,8 @@ namespace Qv2ray::core::connection { // File Protocol CONFIGROOT ConvertConfigFromFile(QString sourceFilePath, bool importComplex); - } -} + } // namespace ConnectionIO +} // namespace Qv2ray::core::connection using namespace Qv2ray::core::connection; using namespace Qv2ray::core::connection::ConnectionIO; diff --git a/src/core/connection/Generation.cpp b/src/core/connection/Generation.cpp index 28dc3c52..b4864c2c 100644 --- a/src/core/connection/Generation.cpp +++ b/src/core/connection/Generation.cpp @@ -1,12 +1,14 @@ #include "Generation.hpp" -#include "core/CoreUtils.hpp" + #include "common/QvHelpers.hpp" +#include "core/CoreUtils.hpp" namespace Qv2ray::core::connection { namespace Generation { - // -------------------------- BEGIN CONFIG GENERATIONS ---------------------------------------------------------------------------- + // -------------------------- BEGIN CONFIG GENERATIONS + // ---------------------------------------------------------------------------- ROUTING GenerateRoutes(bool enableProxy, bool proxyCN) { ROUTING root; @@ -15,8 +17,10 @@ namespace Qv2ray::core::connection // For Rules list ROUTERULELIST rulesList; - if (!enableProxy) { - // This is added to disable all proxies, as a alternative influence of #64 + if (!enableProxy) + { + // This is added to disable all proxies, as a alternative + // influence of #64 rulesList.append(GenerateSingleRouteRule(QStringList() << "regexp:.*", true, OUTBOUND_TAG_DIRECT)); } @@ -28,7 +32,8 @@ namespace Qv2ray::core::connection rulesList.append(GenerateSingleRouteRule(QStringList() << "geosite:cn", true, proxyCN ? OUTBOUND_TAG_DIRECT : OUTBOUND_TAG_PROXY)); // // As a bug fix of #64, this default rule has been disabled. - //rulesList.append(GenerateSingleRouteRule(QStringList({"regexp:.*"}), true, globalProxy ? OUTBOUND_TAG_PROXY : OUTBOUND_TAG_DIRECT)); + // rulesList.append(GenerateSingleRouteRule(QStringList({"regexp:.*"}), + // true, globalProxy ? OUTBOUND_TAG_PROXY : OUTBOUND_TAG_DIRECT)); root.insert("rules", rulesList); RROOT } @@ -56,20 +61,24 @@ namespace Qv2ray::core::connection RROOT } - OUTBOUNDSETTING GenerateShadowSocksOUT(QList servers) + OUTBOUNDSETTING + GenerateShadowSocksOUT(QList servers) { OUTBOUNDSETTING root; QJsonArray x; - foreach (auto server, servers) { - x.append(GenerateShadowSocksServerOUT(server.email, server.address, server.port, server.method, server.password, server.ota, server.level)); + foreach (auto server, servers) + { + x.append(GenerateShadowSocksServerOUT(server.email, server.address, server.port, server.method, server.password, server.ota, + server.level)); } root.insert("servers", x); RROOT } - OUTBOUNDSETTING GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level) + OUTBOUNDSETTING GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, + int level) { OUTBOUNDSETTING root; JADD(email, address, port, method, password, level, ota) @@ -81,7 +90,8 @@ namespace Qv2ray::core::connection QJsonObject root; QJsonArray servers(QJsonArray::fromStringList(dnsServers)); - if (withLocalhost) { + if (withLocalhost) + { // https://github.com/lhy0403/Qv2ray/issues/64 // The fix patch didn't touch this line below. // @@ -93,7 +103,7 @@ namespace Qv2ray::core::connection RROOT } - INBOUNDSETTING GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel) + INBOUNDSETTING GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel) { INBOUNDSETTING root; JADD(address, port, network, timeout, followRedirect, userLevel) @@ -105,17 +115,14 @@ namespace Qv2ray::core::connection INBOUNDSETTING root; QJsonArray accounts; - foreach (auto account, _accounts) { - if (account.user.isEmpty() && account.pass.isEmpty()) { - continue; - } + foreach (auto account, _accounts) + { + if (account.user.isEmpty() && account.pass.isEmpty()) { continue; } accounts.append(GetRootObject(account)); } - if (!accounts.isEmpty()) { - JADD(accounts) - } + if (!accounts.isEmpty()) { JADD(accounts) } JADD(timeout, allowTransparent, userLevel) RROOT @@ -130,7 +137,8 @@ namespace Qv2ray::core::connection oneServer["address"] = address; oneServer["port"] = port; - if (useAuth) { + if (useAuth) + { QJsonArray users; QJsonObject oneUser; oneUser["user"] = username; @@ -150,35 +158,34 @@ namespace Qv2ray::core::connection INBOUNDSETTING root; QJsonArray accounts; - foreach (auto acc, _accounts) { - if (acc.user.isEmpty() && acc.pass.isEmpty()) { - continue; - } + foreach (auto acc, _accounts) + { + if (acc.user.isEmpty() && acc.pass.isEmpty()) { continue; } accounts.append(GetRootObject(acc)); } - if (!accounts.isEmpty()) { - JADD(accounts) - } + if (!accounts.isEmpty()) { JADD(accounts) } - if (udp) { - JADD(auth, udp, ip, userLevel) - } else { + if (udp) { JADD(auth, udp, ip, userLevel) } + else + { JADD(auth, userLevel) } RROOT } - OUTBOUND GenerateOutboundEntry(QString protocol, OUTBOUNDSETTING settings, QJsonObject streamSettings, QJsonObject mux, QString sendThrough, QString tag) + OUTBOUND GenerateOutboundEntry(QString protocol, OUTBOUNDSETTING settings, QJsonObject streamSettings, QJsonObject mux, + QString sendThrough, QString tag) { OUTBOUND root; JADD(sendThrough, protocol, settings, tag, streamSettings, mux) RROOT } - INBOUND GenerateInboundEntry(QString listen, int port, QString protocol, INBOUNDSETTING settings, QString tag, QJsonObject sniffing, QJsonObject allocate) + INBOUND GenerateInboundEntry(QString listen, int port, QString protocol, INBOUNDSETTING settings, QString tag, QJsonObject sniffing, + QJsonObject allocate) { INBOUND root; LOG(MODULE_CONNECTION, "allocation is not used here.") @@ -192,20 +199,18 @@ namespace Qv2ray::core::connection QJsonObject root; QJsonArray services; - if (withHandler) - services << "HandlerService"; + if (withHandler) services << "HandlerService"; - if (withLogger) - services << "LoggerService"; + if (withLogger) services << "LoggerService"; - if (withStats) - services << "StatsService"; + if (withStats) services << "StatsService"; JADD(services, tag) RROOT } - // -------------------------- END CONFIG GENERATIONS ------------------------------------------------------------------------------ + // -------------------------- END CONFIG GENERATIONS + // ------------------------------------------------------------------------------ // BEGIN RUNTIME CONFIG GENERATION CONFIGROOT GenerateRuntimeConfig(CONFIGROOT root) @@ -213,8 +218,10 @@ namespace Qv2ray::core::connection bool isComplex = IsComplexConfig(root); QJsonObject logObject; // - //logObject.insert("access", QV2RAY_CONFIG_PATH + QV2RAY_VCORE_LOG_DIRNAME + QV2RAY_VCORE_ACCESS_LOG_FILENAME); - //logObject.insert("error", QV2RAY_CONFIG_PATH + QV2RAY_VCORE_LOG_DIRNAME + QV2RAY_VCORE_ERROR_LOG_FILENAME); + // logObject.insert("access", QV2RAY_CONFIG_PATH + + // QV2RAY_VCORE_LOG_DIRNAME + QV2RAY_VCORE_ACCESS_LOG_FILENAME); + // logObject.insert("error", QV2RAY_CONFIG_PATH + + // QV2RAY_VCORE_LOG_DIRNAME + QV2RAY_VCORE_ERROR_LOG_FILENAME); // logObject.insert("loglevel", vLogLevels[GlobalConfig.logLevel]); root.insert("log", logObject); @@ -225,20 +232,24 @@ namespace Qv2ray::core::connection // // - // If inbounds list is empty we append our global configured inbounds to the config. - if (!root.contains("inbounds") || root["inbounds"].toArray().empty()) { + // If inbounds list is empty we append our global configured + // inbounds to the config. + if (!root.contains("inbounds") || root["inbounds"].toArray().empty()) + { INBOUNDS inboundsList; // HTTP Inbound - if (GlobalConfig.inboundConfig.useHTTP) { + if (GlobalConfig.inboundConfig.useHTTP) + { INBOUND httpInBoundObject; httpInBoundObject.insert("listen", GlobalConfig.inboundConfig.listenip); httpInBoundObject.insert("port", GlobalConfig.inboundConfig.http_port); httpInBoundObject.insert("protocol", "http"); httpInBoundObject.insert("tag", "http_IN"); - if (GlobalConfig.inboundConfig.http_useAuth) { - auto httpInSettings = GenerateHTTPIN(QList() << GlobalConfig.inboundConfig.httpAccount); + if (GlobalConfig.inboundConfig.http_useAuth) + { + auto httpInSettings = GenerateHTTPIN(QList() << GlobalConfig.inboundConfig.httpAccount); httpInBoundObject.insert("settings", httpInSettings); } @@ -246,7 +257,8 @@ namespace Qv2ray::core::connection } // SOCKS Inbound - if (GlobalConfig.inboundConfig.useSocks) { + if (GlobalConfig.inboundConfig.useSocks) + { INBOUND socksInBoundObject; socksInBoundObject.insert("listen", GlobalConfig.inboundConfig.listenip); socksInBoundObject.insert("port", GlobalConfig.inboundConfig.socks_port); @@ -254,8 +266,7 @@ namespace Qv2ray::core::connection socksInBoundObject.insert("tag", "socks_IN"); auto socksInSettings = GenerateSocksIN(GlobalConfig.inboundConfig.socks_useAuth ? "password" : "noauth", QList() << GlobalConfig.inboundConfig.socksAccount, - GlobalConfig.inboundConfig.socksUDP, - GlobalConfig.inboundConfig.socksLocalIP); + GlobalConfig.inboundConfig.socksUDP, GlobalConfig.inboundConfig.socksLocalIP); socksInBoundObject.insert("settings", socksInSettings); inboundsList.append(socksInBoundObject); } @@ -264,14 +275,16 @@ namespace Qv2ray::core::connection DEBUG(MODULE_CONNECTION, "Added global config inbounds to the config") } - // Process every inbounds to make sure a tag is configured, fixed API 0 speed - // issue when no tag is configured. + // Process every inbounds to make sure a tag is configured, fixed + // API 0 speed issue when no tag is configured. INBOUNDS newTaggedInbounds = INBOUNDS(root["inbounds"].toArray()); - for (auto i = 0; i < newTaggedInbounds.count(); i++) { + for (auto i = 0; i < newTaggedInbounds.count(); i++) + { auto _inboundItem = newTaggedInbounds[i].toObject(); - if (!_inboundItem.contains("tag") || _inboundItem["tag"].toString().isEmpty()) { + if (!_inboundItem.contains("tag") || _inboundItem["tag"].toString().isEmpty()) + { LOG(MODULE_SETTINGS, "Adding a tag to an inbound.") _inboundItem["tag"] = GenerateRandomString(8); newTaggedInbounds[i] = _inboundItem; @@ -281,52 +294,66 @@ namespace Qv2ray::core::connection root["inbounds"] = newTaggedInbounds; // // - // Note: The part below always makes the whole functionality in trouble...... - // BE EXTREME CAREFUL when changing these code below... - // See: https://github.com/lhy0403/Qv2ray/issues/129 - // routeCountLabel in Mainwindow makes here failed to ENOUGH-ly check the routing tables + // Note: The part below always makes the whole functionality in + // trouble...... BE EXTREME CAREFUL when changing these code + // below... See: https://github.com/lhy0403/Qv2ray/issues/129 + // routeCountLabel in Mainwindow makes here failed to ENOUGH-ly + // check the routing tables - if (isComplex) { + if (isComplex) + { // For some config files that has routing entries already. // We DO NOT add extra routings. // // HOWEVER, we need to verify the QV2RAY_RULE_ENABLED entry. - // And what's more, process (by removing unused items) from a rule object. + // And what's more, process (by removing unused items) from a + // rule object. ROUTING routing = ROUTING(root["routing"].toObject()); ROUTERULELIST rules; LOG(MODULE_CONNECTION, "Processing an existing routing table.") - for (auto _rule : routing["rules"].toArray()) { + for (auto _rule : routing["rules"].toArray()) + { auto _b = _rule.toObject(); - if (_b.contains("QV2RAY_RULE_USE_BALANCER")) { - if (_b["QV2RAY_RULE_USE_BALANCER"].toBool()) { + if (_b.contains("QV2RAY_RULE_USE_BALANCER")) + { + if (_b["QV2RAY_RULE_USE_BALANCER"].toBool()) + { // We use balancer _b.remove("outboundTag"); - } else { + } + else + { // We only use the normal outbound _b.remove("balancerTag"); } - } else { + } + else + { LOG(MODULE_SETTINGS, "We found a rule without QV2RAY_RULE_USE_BALANCER, so don't process it.") } // If this entry has been disabled. - if (_b.contains("QV2RAY_RULE_ENABLED") && _b["QV2RAY_RULE_ENABLED"].toBool() == true) { - rules.append(_b); - } else { + if (_b.contains("QV2RAY_RULE_ENABLED") && _b["QV2RAY_RULE_ENABLED"].toBool() == true) { rules.append(_b); } + else + { LOG(MODULE_SETTINGS, "Discarded a rule as it's been set DISABLED") } } routing["rules"] = rules; root["routing"] = routing; - } else { + } + else + { // LOG(MODULE_CONNECTION, "Inserting default values to simple config") - if (root["outbounds"].toArray().count() != 1) { - // There are no ROUTING but 2 or more outbounds.... This is rare, but possible. + if (root["outbounds"].toArray().count() != 1) + { + // There are no ROUTING but 2 or more outbounds.... This is + // rare, but possible. LOG(MODULE_CONNECTION, "WARN: This message usually indicates the config file has logic errors:") LOG(MODULE_CONNECTION, "WARN: --> The config file has NO routing section, however more than 1 outbounds are detected.") } @@ -337,11 +364,13 @@ namespace Qv2ray::core::connection // Process forward proxy #define fpConf GlobalConfig.connectionConfig.forwardProxyConfig - if (fpConf.enableForwardProxy) { + if (fpConf.enableForwardProxy) + { auto outboundArray = root["outbounds"].toArray(); auto firstOutbound = outboundArray.first().toObject(); - if (firstOutbound[QV2RAY_USE_FPROXY_KEY].toBool(false)) { + if (firstOutbound[QV2RAY_USE_FPROXY_KEY].toBool(false)) + { LOG(MODULE_CONNECTION, "Applying forward proxy to current connection.") auto proxy = PROXYSETTING(); proxy["tag"] = OUTBOUND_TAG_FORWARD_PROXY; @@ -349,13 +378,20 @@ namespace Qv2ray::core::connection // FP Outbound. OUTBOUNDSETTING fpOutbound; - if (fpConf.type.toLower() == "http" || fpConf.type.toLower() == "socks") { - fpOutbound = GenerateHTTPSOCKSOut(fpConf.serverAddress, fpConf.port, fpConf.useAuth, fpConf.username, fpConf.password); - outboundArray.push_back(GenerateOutboundEntry(fpConf.type.toLower(), fpOutbound, QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_FORWARD_PROXY)); - } else { + if (fpConf.type.toLower() == "http" || fpConf.type.toLower() == "socks") + { + fpOutbound = + GenerateHTTPSOCKSOut(fpConf.serverAddress, fpConf.port, fpConf.useAuth, fpConf.username, fpConf.password); + outboundArray.push_back(GenerateOutboundEntry(fpConf.type.toLower(), fpOutbound, QJsonObject(), QJsonObject(), + "0.0.0.0", OUTBOUND_TAG_FORWARD_PROXY)); + } + else + { LOG(MODULE_CONNECTION, "WARNING: Unsupported outbound type: " + fpConf.type) } - } else { + } + else + { // Remove proxySettings from firstOutbound firstOutbound.remove("proxySettings"); } @@ -366,7 +402,8 @@ namespace Qv2ray::core::connection #undef fpConf OUTBOUNDS outbounds = OUTBOUNDS(root["outbounds"].toArray()); - outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_DIRECT)); + outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", + OUTBOUND_TAG_DIRECT)); root["outbounds"] = outbounds; } @@ -407,7 +444,8 @@ namespace Qv2ray::core::connection INBOUNDS inbounds = INBOUNDS(root["inbounds"].toArray()); INBOUNDSETTING fakeDocodemoDoor; fakeDocodemoDoor["address"] = "127.0.0.1"; - QJsonObject apiInboundsRoot = GenerateInboundEntry("127.0.0.1", GlobalConfig.apiConfig.statsPort, "dokodemo-door", fakeDocodemoDoor, API_TAG_INBOUND); + QJsonObject apiInboundsRoot = + GenerateInboundEntry("127.0.0.1", GlobalConfig.apiConfig.statsPort, "dokodemo-door", fakeDocodemoDoor, API_TAG_INBOUND); inbounds.push_front(apiInboundsRoot); root["inbounds"] = inbounds; // @@ -417,5 +455,5 @@ namespace Qv2ray::core::connection } return root; } - } -} + } // namespace Generation +} // namespace Qv2ray::core::connection diff --git a/src/core/connection/Generation.hpp b/src/core/connection/Generation.hpp index 0392180f..3fc7ebb8 100644 --- a/src/core/connection/Generation.hpp +++ b/src/core/connection/Generation.hpp @@ -5,7 +5,7 @@ namespace Qv2ray::core::connection namespace Generation { // Important config generation algorithms. - const QStringList vLogLevels = {"none", "debug", "info", "warning", "error"}; + const QStringList vLogLevels = { "none", "debug", "info", "warning", "error" }; ROUTING GenerateRoutes(bool enableProxy, bool cnProxy); ROUTERULE GenerateSingleRouteRule(QStringList list, bool isDomain, QString outboundTag, QString type = "field"); QJsonObject GenerateDNS(bool withLocalhost, QStringList dnsServers); @@ -15,20 +15,24 @@ namespace Qv2ray::core::connection OUTBOUNDSETTING GenerateFreedomOUT(QString domainStrategy, QString redirect, int userLevel); OUTBOUNDSETTING GenerateBlackHoleOUT(bool useHTTP); OUTBOUNDSETTING GenerateShadowSocksOUT(QList servers); - OUTBOUNDSETTING GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level); + OUTBOUNDSETTING GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, + int level); OUTBOUNDSETTING GenerateHTTPSOCKSOut(QString address, int port, bool useAuth, QString username, QString password); // // Inbounds Protocols - INBOUNDSETTING GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel); + INBOUNDSETTING GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel); INBOUNDSETTING GenerateHTTPIN(QList accounts, int timeout = 300, bool allowTransparent = true, int userLevel = 0); - INBOUNDSETTING GenerateSocksIN(QString auth, QList _accounts, bool udp = false, QString ip = "127.0.0.1", int userLevel = 0); + INBOUNDSETTING GenerateSocksIN(QString auth, QList _accounts, bool udp = false, QString ip = "127.0.0.1", + int userLevel = 0); // // Generate FINAL Configs CONFIGROOT GenerateRuntimeConfig(CONFIGROOT root); - OUTBOUND GenerateOutboundEntry(QString protocol, OUTBOUNDSETTING settings, QJsonObject streamSettings, QJsonObject mux = QJsonObject(), QString sendThrough = "0.0.0.0", QString tag = OUTBOUND_TAG_PROXY); - INBOUND GenerateInboundEntry(QString listen, int port, QString protocol, INBOUNDSETTING settings, QString tag, QJsonObject sniffing = QJsonObject(), QJsonObject allocate = QJsonObject()); - } -} + OUTBOUND GenerateOutboundEntry(QString protocol, OUTBOUNDSETTING settings, QJsonObject streamSettings, QJsonObject mux = QJsonObject(), + QString sendThrough = "0.0.0.0", QString tag = OUTBOUND_TAG_PROXY); + INBOUND GenerateInboundEntry(QString listen, int port, QString protocol, INBOUNDSETTING settings, QString tag, + QJsonObject sniffing = QJsonObject(), QJsonObject allocate = QJsonObject()); + } // namespace Generation +} // namespace Qv2ray::core::connection using namespace Qv2ray::core; using namespace Qv2ray::core::connection; diff --git a/src/core/connection/SSDConverter.hpp b/src/core/connection/SSDConverter.hpp index 40d948e0..9175957e 100644 --- a/src/core/connection/SSDConverter.hpp +++ b/src/core/connection/SSDConverter.hpp @@ -33,57 +33,68 @@ namespace Qv2ray::core::handlers * - log list * in case of error, no objects will be returned. */ - std::pair >>>, QStringList> - decodeSSD(const QString &uri, const QString &pattern = DEFAULT_NAME_PATTERN); - } -} + std::pair>>>, QStringList> decodeSSD( + const QString &uri, const QString &pattern = DEFAULT_NAME_PATTERN); + } // namespace ssd +} // namespace Qv2ray::core::handlers -#define MUST_EXIST(fieldName) \ - if (obj[(fieldName)].isUndefined()) {\ - logList << QObject::tr("invalid ssd link: json: field %1 must exist").arg(fieldName);\ - return std::make_pair(std::nullopt, logList);\ +#define MUST_EXIST(fieldName) \ + if (obj[(fieldName)].isUndefined()) \ + { \ + logList << QObject::tr("invalid ssd link: json: field %1 must exist").arg(fieldName); \ + return std::make_pair(std::nullopt, logList); \ } -#define MUST_PORT(fieldName) MUST_EXIST(fieldName);\ - if (int value = obj[(fieldName)].toInt(-1); value < 0 || value > 65535) { \ - logList << QObject::tr("invalid ssd link: json: field %1 must be valid port number");\ - return std::make_pair(std::nullopt, logList);\ +#define MUST_PORT(fieldName) \ + MUST_EXIST(fieldName); \ + if (int value = obj[(fieldName)].toInt(-1); value < 0 || value > 65535) \ + { \ + logList << QObject::tr("invalid ssd link: json: field %1 must be valid port number"); \ + return std::make_pair(std::nullopt, logList); \ } -#define MUST_STRING(fieldName) MUST_EXIST(fieldName);\ - if (!obj[(fieldName)].isString()) {\ - logList << QObject::tr("invalid ssd link: json: field %1 must be of type 'string'").arg(fieldName);\ - return std::make_pair(std::nullopt, logList);\ +#define MUST_STRING(fieldName) \ + MUST_EXIST(fieldName); \ + if (!obj[(fieldName)].isString()) \ + { \ + logList << QObject::tr("invalid ssd link: json: field %1 must be of type 'string'").arg(fieldName); \ + return std::make_pair(std::nullopt, logList); \ } -#define MUST_ARRAY(fieldName) MUST_EXIST(fieldName);\ - if (!obj[(fieldName)].isArray()) {\ - logList << QObject::tr("invalid ssd link: json: field %1 must be an array").arg(fieldName);\ - return std::make_pair(std::nullopt, logList);\ +#define MUST_ARRAY(fieldName) \ + MUST_EXIST(fieldName); \ + if (!obj[(fieldName)].isArray()) \ + { \ + logList << QObject::tr("invalid ssd link: json: field %1 must be an array").arg(fieldName); \ + return std::make_pair(std::nullopt, logList); \ } -#define SERVER_SHOULD_BE_OBJECT(server) \ - if (!server.isObject()) {\ - logList << QObject::tr("skipping invalid ssd server: server must be an object");\ - continue;\ +#define SERVER_SHOULD_BE_OBJECT(server) \ + if (!server.isObject()) \ + { \ + logList << QObject::tr("skipping invalid ssd server: server must be an object"); \ + continue; \ } -#define SHOULD_EXIST(fieldName) \ - if (serverObject[(fieldName)].isUndefined()) { \ - logList << QObject::tr("skipping invalid ssd server: missing required field %1").arg(fieldName);\ - continue;\ +#define SHOULD_EXIST(fieldName) \ + if (serverObject[(fieldName)].isUndefined()) \ + { \ + logList << QObject::tr("skipping invalid ssd server: missing required field %1").arg(fieldName); \ + continue; \ } -#define SHOULD_STRING(fieldName) SHOULD_EXIST(fieldName); \ - if (!serverObject[(fieldName)].isString()) { \ - logList << QObject::tr("skipping invalid ssd server: field %1 should be of type 'string'").arg(fieldName);\ - continue; \ +#define SHOULD_STRING(fieldName) \ + SHOULD_EXIST(fieldName); \ + if (!serverObject[(fieldName)].isString()) \ + { \ + logList << QObject::tr("skipping invalid ssd server: field %1 should be of type 'string'").arg(fieldName); \ + continue; \ } - -std::pair >>>, QStringList> -Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &pattern) +std::pair>>>, QStringList> Qv2ray::core::handlers::ssd:: + decodeSSD(const QString &uri, const QString &pattern) { // The list for the parsing log. QStringList logList; // ssd links should begin with "ssd://" - if (!uri.startsWith("ssd://")) { + if (!uri.startsWith("ssd://")) + { logList << QObject::tr("invalid ssd link: should begin with ssd://"); return std::make_pair(std::nullopt, logList); } @@ -92,7 +103,8 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter const auto ssdURIBody = QStringRef(&uri, 5, uri.length() - 6); const auto decodedJSON = QByteArray::fromBase64(ssdURIBody.toUtf8()); - if (decodedJSON.length() == 0) { + if (decodedJSON.length() == 0) + { logList << QObject::tr("invalid ssd link: base64 parse failed"); return std::make_pair(std::nullopt, logList); } @@ -101,13 +113,15 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter QJsonParseError err; QJsonDocument document = QJsonDocument::fromJson(decodedJSON, &err); - if (document.isNull()) { + if (document.isNull()) + { logList << QObject::tr("invalid ssd link: json parse failed: ") % err.errorString(); return std::make_pair(std::nullopt, logList); } // json should be an object - if (!document.isObject()) { + if (!document.isObject()) + { logList << QObject::tr("invalid ssd link: found non-object json, aborting"); return std::make_pair(std::nullopt, logList); } @@ -127,7 +141,8 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter // check: rc4-md5 is not supported by v2ray-core // TODO: more checks, including all algorithms - if (encryption == "rc4-md5") { + if (encryption == "rc4-md5") + { logList << QObject::tr("invalid ssd link: rc4-md5 encryption is not supported by v2ray-core"); return std::make_pair(std::nullopt, logList); } @@ -142,7 +157,8 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter // // iterate through the servers - for (QJsonValueRef server : obj["servers"].toArray()) { + for (QJsonValueRef server : obj["servers"].toArray()) + { SERVER_SHOULD_BE_OBJECT(server); QJsonObject serverObject = server.toObject(); ShadowSocksServerObject ssObject; @@ -158,11 +174,13 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter // port selection: // normal: use global settings // overriding: use current config - if (serverObject["port"].isUndefined()) { - ssObject.port = port; - } else if (auto currPort = serverObject["port"].toInt(-1); port >= 0 && port <= 65535) { + if (serverObject["port"].isUndefined()) { ssObject.port = port; } + else if (auto currPort = serverObject["port"].toInt(-1); port >= 0 && port <= 65535) + { ssObject.port = currPort; - } else { + } + else + { logList << QObject::tr("warning: invalid port encountered. using fallback value."); ssObject.port = port; } @@ -172,11 +190,13 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter // entitled: using given name QString nodeName; - if (serverObject["remarks"].isUndefined()) { - nodeName = QString("%1:%2").arg(ssObject.address).arg(ssObject.port); - } else if (serverObject["remarks"].isString()) { + if (serverObject["remarks"].isUndefined()) { nodeName = QString("%1:%2").arg(ssObject.address).arg(ssObject.port); } + else if (serverObject["remarks"].isString()) + { nodeName = serverObject["remarks"].toString(); - } else { + } + else + { logList << QObject::tr("warning: invalid name encountered. using fallback value."); nodeName = QString("%1:%2").arg(ssObject.address).arg(ssObject.port); } @@ -186,9 +206,9 @@ Qv2ray::core::handlers::ssd::decodeSSD(const QString &uri, const QString &patter // specified: use given value double ratio = 1.0; - if (auto currRatio = serverObject["ratio"].toDouble(-1.0); currRatio != -1.0) { - ratio = currRatio; - } else if (!serverObject["ratio"].isUndefined()) { + if (auto currRatio = serverObject["ratio"].toDouble(-1.0); currRatio != -1.0) { ratio = currRatio; } + else if (!serverObject["ratio"].isUndefined()) + { logList << QObject::tr("warning: invalid ratio encountered. using fallback value."); } diff --git a/src/core/connection/Serialization.cpp b/src/core/connection/Serialization.cpp index ab47b53e..25bb2433 100644 --- a/src/core/connection/Serialization.cpp +++ b/src/core/connection/Serialization.cpp @@ -1,4 +1,5 @@ #include "Serialization.hpp" + #include "Generation.hpp" #include "common/QvHelpers.hpp" #include "core/CoreUtils.hpp" @@ -12,11 +13,13 @@ namespace Qv2ray::core::connection { CONFIGROOT config; - if (link.startsWith("vmess://")) { - config = ConvertConfigFromVMessString(link, alias, errMessage); - } else if (link.startsWith("ss://")) { + if (link.startsWith("vmess://")) { config = ConvertConfigFromVMessString(link, alias, errMessage); } + else if (link.startsWith("ss://")) + { config = ConvertConfigFromSSString(link, alias, errMessage); - } else { + } + else + { *errMessage = QObject::tr("Unsupported share link format."); } @@ -31,21 +34,29 @@ namespace Qv2ray::core::connection auto type = outbound["protocol"].toString(); QString sharelink = ""; - if (type == "vmess") { - auto vmessServer = StructFromJsonString(JsonToString(outbound["settings"].toObject()["vnext"].toArray().first().toObject())); + if (type == "vmess") + { + auto vmessServer = + StructFromJsonString(JsonToString(outbound["settings"].toObject()["vnext"].toArray().first().toObject())); auto transport = StructFromJsonString(JsonToString(outbound["streamSettings"].toObject())); sharelink = ConvertConfigToVMessString(transport, vmessServer, alias); - } else if (type == "shadowsocks") { - auto ssServer = StructFromJsonString(JsonToString(outbound["settings"].toObject()["servers"].toArray().first().toObject())); + } + else if (type == "shadowsocks") + { + auto ssServer = StructFromJsonString( + JsonToString(outbound["settings"].toObject()["servers"].toArray().first().toObject())); sharelink = ConvertConfigToSSString(ssServer, alias, isSip002); - } else { + } + else + { LOG(MODULE_CONNECTION, "Unsupported outbound type: " + type) } return sharelink; } - // From https://github.com/2dust/v2rayN/wiki/%E5%88%86%E4%BA%AB%E9%93%BE%E6%8E%A5%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E(ver-2) + // From + // https://github.com/2dust/v2rayN/wiki/%E5%88%86%E4%BA%AB%E9%93%BE%E6%8E%A5%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E(ver-2) QString ConvertConfigToVMessString(const StreamSettingsObject &transfer, const VMessServerObject &serverConfig, const QString &alias) { QJsonObject vmessUriRoot; @@ -59,15 +70,19 @@ namespace Qv2ray::core::connection vmessUriRoot["net"] = transfer.network; vmessUriRoot["tls"] = transfer.security; - if (transfer.network == "tcp") { - vmessUriRoot["type"] = transfer.tcpSettings.header.type; - } else if (transfer.network == "kcp") { + if (transfer.network == "tcp") { vmessUriRoot["type"] = transfer.tcpSettings.header.type; } + else if (transfer.network == "kcp") + { vmessUriRoot["type"] = transfer.kcpSettings.header.type; - } else if (transfer.network == "quic") { + } + else if (transfer.network == "quic") + { vmessUriRoot["type"] = transfer.quicSettings.header.type; vmessUriRoot["host"] = transfer.quicSettings.security; vmessUriRoot["path"] = transfer.quicSettings.key; - } else if (transfer.network == "ws") { + } + else if (transfer.network == "ws") + { auto x = transfer.wsSettings.headers; auto host = x.contains("host"); auto CapHost = x.contains("Host"); @@ -75,7 +90,9 @@ namespace Qv2ray::core::connection // vmessUriRoot["host"] = realHost; vmessUriRoot["path"] = transfer.wsSettings.path; - } else if (transfer.network == "h2" || transfer.network == "http") { + } + else if (transfer.network == "h2" || transfer.network == "http") + { vmessUriRoot["host"] = transfer.httpSettings.host.join(","); vmessUriRoot["path"] = transfer.httpSettings.path; } @@ -89,8 +106,8 @@ namespace Qv2ray::core::connection { // String may start with: vmess:// and ss:// // We only process vmess:// here - // Some subscription providers may use plain vmess:// saperated by lines - // But others may use base64 of above. + // Some subscription providers may use plain vmess:// saperated by + // lines But others may use base64 of above. auto result = QString::fromUtf8(arr).trimmed(); return result.startsWith("vmess://") ? result : Base64Decode(result); } @@ -100,8 +117,9 @@ namespace Qv2ray::core::connection ShadowSocksServerObject server; QString d_name; - //auto ssUri = _ssUri.toStdString(); - if (ssUri.length() < 5) { + // auto ssUri = _ssUri.toStdString(); + if (ssUri.length() < 5) + { LOG(MODULE_CONNECTION, "ss:// string too short") *errMessage = QObject::tr("SS URI is too short"); } @@ -110,53 +128,51 @@ namespace Qv2ray::core::connection auto hashPos = uri.lastIndexOf("#"); DEBUG(MODULE_CONNECTION, "Hash sign position: " + QSTRN(hashPos)) - if (hashPos >= 0) { + if (hashPos >= 0) + { // Get the name/remark d_name = uri.mid(uri.lastIndexOf("#") + 1); uri.truncate(hashPos); } // No plugins for Qv2ray so disable those lnes.i - //size_t pluginPos = uri.find_first_of('/'); + // size_t pluginPos = uri.find_first_of('/'); // - //if (pluginPos != std::string::npos) { + // if (pluginPos != std::string::npos) { // // TODO: support plugins. For now, just ignore them // uri.erase(pluginPos); //} auto atPos = uri.indexOf('@'); DEBUG(MODULE_CONNECTION, "At sign position: " + QSTRN(atPos)) - if (atPos < 0) { + if (atPos < 0) + { // Old URI scheme QString decoded = QByteArray::fromBase64(uri.toUtf8(), QByteArray::Base64Option::OmitTrailingEquals); auto colonPos = decoded.indexOf(':'); DEBUG(MODULE_CONNECTION, "Colon position: " + QSTRN(colonPos)) - if (colonPos < 0) { - *errMessage = QObject::tr("Can't find the colon separator between method and password"); - } + if (colonPos < 0) { *errMessage = QObject::tr("Can't find the colon separator between method and password"); } server.method = decoded.left(colonPos); decoded.remove(0, colonPos + 1); atPos = decoded.lastIndexOf('@'); DEBUG(MODULE_CONNECTION, "At sign position: " + QSTRN(atPos)) - if (atPos < 0) { - *errMessage = QObject::tr("Can't find the at separator between password and hostname"); - } + if (atPos < 0) { *errMessage = QObject::tr("Can't find the at separator between password and hostname"); } server.password = decoded.mid(0, atPos); decoded.remove(0, atPos + 1); colonPos = decoded.lastIndexOf(':'); DEBUG(MODULE_CONNECTION, "Colon position: " + QSTRN(colonPos)) - if (colonPos < 0) { - *errMessage = QObject::tr("Can't find the colon separator between hostname and port"); - } + if (colonPos < 0) { *errMessage = QObject::tr("Can't find the colon separator between hostname and port"); } server.address = decoded.mid(0, colonPos); server.port = decoded.mid(colonPos + 1).toInt(); - } else { + } + else + { // SIP002 URI scheme auto x = QUrl::fromUserInput(uri); server.address = x.host(); @@ -166,9 +182,7 @@ namespace Qv2ray::core::connection // DEBUG(MODULE_CONNECTION, "Userinfo splitter position: " + QSTRN(userInfoSp)) - if (userInfoSp < 0) { - *errMessage = QObject::tr("Can't find the colon separator between method and password"); - } + if (userInfoSp < 0) { *errMessage = QObject::tr("Can't find the colon separator between method and password"); } QString method = userInfo.mid(0, userInfoSp); server.method = method; @@ -178,7 +192,8 @@ namespace Qv2ray::core::connection d_name = QUrl::fromPercentEncoding(d_name.toUtf8()); CONFIGROOT root; OUTBOUNDS outbounds; - outbounds.append(GenerateOutboundEntry("shadowsocks", GenerateShadowSocksOUT(QList() << server), QJsonObject())); + outbounds.append( + GenerateOutboundEntry("shadowsocks", GenerateShadowSocksOUT(QList() << server), QJsonObject())); JADD(outbounds) *alias = alias->isEmpty() ? d_name : *alias + "_" + d_name; LOG(MODULE_CONNECTION, "Deduced alias: " + *alias) @@ -189,12 +204,15 @@ namespace Qv2ray::core::connection { auto myAlias = QUrl::toPercentEncoding(alias); - if (isSip002) { + if (isSip002) + { LOG(MODULE_CONNECTION, "Converting an ss-server config to Sip002 ss:// format") QString plainUserInfo = server.method + ":" + server.password; QString userinfo(plainUserInfo.toUtf8().toBase64(QByteArray::Base64Option::Base64UrlEncoding).data()); return "ss://" + userinfo + "@" + server.address + ":" + QSTRN(server.port) + "#" + myAlias; - } else { + } + else + { LOG(MODULE_CONNECTION, "Converting an ss-server config to old ss:// string format") QString ssUri = server.method + ":" + server.password + "@" + server.address + ":" + QSTRN(server.port); return "ss://" + ssUri.toUtf8().toBase64(QByteArray::Base64Option::OmitTrailingEquals) + "#" + myAlias; @@ -209,7 +227,8 @@ namespace Qv2ray::core::connection LOG(MODULE_SETTINGS, "Trying to convert from a vmess string.") QString vmess = vmessStr; - if (vmess.trimmed() != vmess) { + if (vmess.trimmed() != vmess) + { LOG(MODULE_SETTINGS, "VMess string has some prefix/postfix spaces, trimming.") vmess = vmessStr.trimmed(); } @@ -217,16 +236,19 @@ namespace Qv2ray::core::connection // Reset errMessage *errMessage = ""; - if (!vmess.toLower().startsWith("vmess://")) { + if (!vmess.toLower().startsWith("vmess://")) + { *errMessage = QObject::tr("VMess string should start with 'vmess://'"); return default; } - try { + try + { QStringRef vmessJsonB64(&vmess, 8, vmess.length() - 8); auto b64Str = vmessJsonB64.toString(); - if (b64Str.isEmpty()) { + if (b64Str.isEmpty()) + { *errMessage = QObject::tr("VMess string should be a valid base64 string"); return default; } @@ -234,14 +256,16 @@ namespace Qv2ray::core::connection auto vmessString = Base64Decode(b64Str); auto jsonErr = VerifyJsonString(vmessString); - if (!jsonErr.isEmpty()) { + if (!jsonErr.isEmpty()) + { *errMessage = jsonErr; return default; } auto vmessConf = JsonFromString(vmessString); - if (vmessConf.isEmpty()) { + if (vmessConf.isEmpty()) + { *errMessage = QObject::tr("JSON should not be empty"); return default; } @@ -249,21 +273,23 @@ namespace Qv2ray::core::connection bool flag = true; // C is a quick hack... #define C(k) vmessConf.contains(k) - // id, aid, port and add are mandatory fields of a vmess:// link. + // id, aid, port and add are mandatory fields of a vmess:// + // link. flag = flag && C("id") && C("aid") && C("port") && C("add"); // Stream Settings auto net = C("net") ? vmessConf["net"].toString() : "tcp"; - if (net == "http" || net == "ws") - flag = flag && C("host") && C("path"); + if (net == "http" || net == "ws") flag = flag && C("host") && C("path"); else if (net == "domainsocket") flag = flag && C("path"); else if (net == "quic") flag = flag && C("host") && C("type") && C("path"); #undef C - //return flag ? 0 : 1; - } catch (exception *e) { + // return flag ? 0 : 1; + } + catch (exception *e) + { *errMessage = e->what(); LOG(MODULE_IMPORT, "Failed to decode vmess string: " + *errMessage) delete e; @@ -279,44 +305,62 @@ namespace Qv2ray::core::connection int port, aid; // // key = key in JSON and the variable name. - // values = Candidate variable list, if not match, the first one is used as default. - // [[val.size() <= 1]] is used when only the default value exists. - // - It can be empty, if so, if the key is not in the JSON, or the value is empty, it'll report an error. - // - Else if it contains one thing. if the key is not in the JSON, or the value is empty, it'll use that one. - // - Else if it contains many things, when the key IS in the JSON but not in those THINGS, it'll use the first one in the THINGS + // values = Candidate variable list, if not match, the first one is + // used as default. + // [[val.size() <= 1]] is used when only the default value + // exists. + // - It can be empty, if so, if the key is not in + // the JSON, or the value is empty, it'll report an error. + // - Else if it contains one thing. if the key is not in + // the JSON, or the value is empty, it'll use that one. + // - Else if it contains many things, when the key IS in + // the JSON but not in those THINGS, it'll use the first + // one in the THINGS // - Else, it'll use the value found from the JSON object. // #define empty_arg -#define __vmess_checker__func(key, values) \ - {\ - auto val = QStringList() values;\ - if (vmessConf.contains(#key) && !vmessConf[#key].toVariant().toString().trimmed().isEmpty() \ - && (val.size() <= 1 || val.contains(vmessConf[#key].toVariant().toString()))) {\ - key = vmessConf[#key].toVariant().toString();\ - DEBUG(MODULE_IMPORT, "Found key \"" #key "\" within the vmess object.")\ - } else if (!val.isEmpty()) {\ - key = val.first(); \ - DEBUG(MODULE_IMPORT, "Using key \"" #key "\" from the first candidate list: " + key)\ - } else{\ - *errMessage = QObject::tr(#key " does not exist."); \ - LOG(MODULE_IMPORT, "Cannot process \"" #key "\" since it's not included in the json object." ) \ - LOG(MODULE_IMPORT, " --> values: " + val.join(";")) \ - LOG(MODULE_IMPORT, " --> PS: " + ps) \ - }\ +#define __vmess_checker__func(key, values) \ + { \ + auto val = QStringList() values; \ + if (vmessConf.contains(#key) && !vmessConf[#key].toVariant().toString().trimmed().isEmpty() && \ + (val.size() <= 1 || val.contains(vmessConf[#key].toVariant().toString()))) \ + { \ + key = vmessConf[#key].toVariant().toString(); \ + DEBUG(MODULE_IMPORT, "Found key \"" #key "\" within the vmess object.") \ + } \ + else if (!val.isEmpty()) \ + { \ + key = val.first(); \ + DEBUG(MODULE_IMPORT, "Using key \"" #key "\" from the first candidate list: " + key) \ + } \ + else \ + { \ + *errMessage = QObject::tr(#key " does not exist."); \ + LOG(MODULE_IMPORT, "Cannot process \"" #key "\" since it's not included in the json object.") \ + LOG(MODULE_IMPORT, " --> values: " + val.join(";")) \ + LOG(MODULE_IMPORT, " --> PS: " + ps) \ + } \ } - // Strict check of VMess protocol, to check if the specified value is in the correct range. + // Strict check of VMess protocol, to check if the specified value + // is in the correct range. // // Get Alias (AKA ps) from address and port. __vmess_checker__func(ps, << vmessConf["add"].toVariant().toString() + ":" + vmessConf["port"].toVariant().toString()); - __vmess_checker__func(add, empty_arg) - __vmess_checker__func(id, empty_arg) - __vmess_checker__func(net, << "tcp" << "http" << "h2" << "ws" << "kcp" << "domainsocket" << "quic") - __vmess_checker__func(type, << "none" << "http" << "srtp" << "utp" << "wechat-video") - __vmess_checker__func(path, << "") - __vmess_checker__func(host, << "") - __vmess_checker__func(tls, << "") - // - port = vmessConf["port"].toVariant().toInt(); + __vmess_checker__func(add, empty_arg) __vmess_checker__func(id, empty_arg) __vmess_checker__func(net, << "tcp" + << "http" + << "h2" + << "ws" + << "kcp" + << "domainsocket" + << "quic") + __vmess_checker__func(type, << "none" + << "http" + << "srtp" + << "utp" + << "wechat-video") __vmess_checker__func(path, << "") __vmess_checker__func(host, << "") + __vmess_checker__func(tls, << "") + // + port = vmessConf["port"].toVariant().toInt(); aid = vmessConf["aid"].toVariant().toInt(); // Apply the settings. // @@ -340,23 +384,29 @@ namespace Qv2ray::core::connection // Stream Settings StreamSettingsObject streaming; - if (net == "tcp") { - streaming.tcpSettings.header.type = type; - } else if (net == "http" || net == "h2") { + if (net == "tcp") { streaming.tcpSettings.header.type = type; } + else if (net == "http" || net == "h2") + { // Fill hosts for HTTP - for (auto _host : host.split(',')) { - streaming.httpSettings.host.push_back(_host.trimmed()); - } + for (auto _host : host.split(',')) { streaming.httpSettings.host.push_back(_host.trimmed()); } streaming.httpSettings.path = path; - } else if (net == "ws") { + } + else if (net == "ws") + { streaming.wsSettings.headers["Host"] = host; streaming.wsSettings.path = path; - } else if (net == "kcp") { + } + else if (net == "kcp") + { streaming.kcpSettings.header.type = type; - } else if (net == "domainsocket") { + } + else if (net == "domainsocket") + { streaming.dsSettings.path = path; - } else if (net == "quic") { + } + else if (net == "quic") + { streaming.quicSettings.security = host; streaming.quicSettings.header.type = type; streaming.quicSettings.key = path; @@ -364,7 +414,8 @@ namespace Qv2ray::core::connection // FIXME: makeshift patch for #290. // to be rewritten after refactoring. - if (tls == "tls" && host != "" && (net == "tcp" || net == "ws")) { + if (tls == "tls" && host != "" && (net == "tcp" || net == "ws")) + { streaming.tlsSettings.serverName = host; streaming.tlsSettings.allowInsecure = false; } @@ -378,10 +429,11 @@ namespace Qv2ray::core::connection auto outbound = GenerateOutboundEntry("vmess", vConf, GetRootObject(streaming), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_PROXY); // root["outbounds"] = QJsonArray() << outbound; - // If previous alias is empty, just the PS is needed, else, append a "_" + // If previous alias is empty, just the PS is needed, else, append a + // "_" *alias = alias->trimmed().isEmpty() ? ps : *alias + "_" + ps; #undef default return root; } - } -} + } // namespace Serialization +} // namespace Qv2ray::core::connection diff --git a/src/core/connection/Serialization.hpp b/src/core/connection/Serialization.hpp index fffb574d..99a03c24 100644 --- a/src/core/connection/Serialization.hpp +++ b/src/core/connection/Serialization.hpp @@ -5,7 +5,7 @@ namespace Qv2ray::core::connection { namespace Serialization { - //int VerifyVMessProtocolString(QString vmess); + // int VerifyVMessProtocolString(QString vmess); QString DecodeSubscriptionString(QByteArray arr); // General @@ -19,8 +19,8 @@ namespace Qv2ray::core::connection // SS URI Protocol CONFIGROOT ConvertConfigFromSSString(const QString &ss, QString *alias, QString *errMessage); QString ConvertConfigToSSString(const ShadowSocksServerObject &server, const QString &alias, bool isSip002); - } -} + } // namespace Serialization +} // namespace Qv2ray::core::connection using namespace Qv2ray::core; using namespace Qv2ray::core::connection; diff --git a/src/core/handler/ConnectionHandler.cpp b/src/core/handler/ConnectionHandler.cpp index a4a4608b..16eb6aa1 100644 --- a/src/core/handler/ConnectionHandler.cpp +++ b/src/core/handler/ConnectionHandler.cpp @@ -1,6 +1,8 @@ #include "ConnectionHandler.hpp" + #include "common/QvHelpers.hpp" #include "core/config/ConfigBackend.hpp" +#include "core/connection/Serialization.hpp" namespace Qv2ray::core::handlers { @@ -10,26 +12,23 @@ namespace Qv2ray::core::handlers DEBUG(MODULE_CORE_HANDLER, "ConnectionHandler Constructor.") // Do we need to check how many of them are loaded? - for (auto i = 0; i < GlobalConfig.connections.count(); i++) { - connections[ConnectionId(GlobalConfig.connections.keys()[i])] = GlobalConfig.connections.values()[i]; - } + for (auto i = 0; i < GlobalConfig.connections.count(); i++) + { connections[ConnectionId(GlobalConfig.connections.keys()[i])] = GlobalConfig.connections.values()[i]; } - for (auto key : GlobalConfig.subscriptions.keys()) { + for (auto key : GlobalConfig.subscriptions.keys()) + { auto val = GlobalConfig.subscriptions[key]; groups[GroupId(key)] = val; - for (auto conn : val.connections) { - connections[ConnectionId(conn)].groupId = GroupId(key); - } + for (auto conn : val.connections) { connections[ConnectionId(conn)].groupId = GroupId(key); } } - for (auto key : GlobalConfig.groups.keys()) { + for (auto key : GlobalConfig.groups.keys()) + { auto val = GlobalConfig.groups[key]; groups[GroupId(key)] = val; - for (auto conn : val.connections) { - connections[ConnectionId(conn)].groupId = GroupId(key); - } + for (auto conn : val.connections) { connections[ConnectionId(conn)].groupId = GroupId(key); } } vCoreInstance = new V2rayKernelInstance(); @@ -47,7 +46,7 @@ namespace Qv2ray::core::handlers pingConnectionTimerId = startTimer(60 * 1000); } - void QvConnectionHandler::CHSaveConnectionData_p() + void QvConnectionHandler::CHSaveConfigData_p() { // Copy auto newGlobalConfig = GlobalConfig; @@ -55,18 +54,21 @@ namespace Qv2ray::core::handlers newGlobalConfig.groups.clear(); newGlobalConfig.subscriptions.clear(); - for (auto i = 0; i < connections.count(); i++) { - newGlobalConfig.connections[connections.keys()[i].toString()] = connections.values()[i]; - } + for (auto i = 0; i < connections.count(); i++) + { newGlobalConfig.connections[connections.keys()[i].toString()] = connections.values()[i]; } - for (auto i = 0; i < groups.count(); i++) { + for (auto i = 0; i < groups.count(); i++) + { QStringList connections = IdListToStrings(groups.values()[i].connections); - if (groups.values()[i].isSubscription) { + if (groups.values()[i].isSubscription) + { SubscriptionObject_Config o = groups.values()[i]; o.connections = connections; newGlobalConfig.subscriptions[groups.keys()[i].toString()] = o; - } else { + } + else + { GroupObject_Config o = groups.values()[i]; o.connections = connections; newGlobalConfig.groups[groups.keys()[i].toString()] = o; @@ -78,29 +80,25 @@ namespace Qv2ray::core::handlers void QvConnectionHandler::timerEvent(QTimerEvent *event) { - if (event->timerId() == saveTimerId) { - CHSaveConnectionData_p(); - } else if (event->timerId() == pingAllTimerId) { + if (event->timerId() == saveTimerId) { CHSaveConfigData_p(); } + else if (event->timerId() == pingAllTimerId) + { StartLatencyTest(); - } else if (event->timerId() == pingConnectionTimerId) { - if (currentConnectionId != NullConnectionId) { - StartLatencyTest(currentConnectionId); - } + } + else if (event->timerId() == pingConnectionTimerId) + { + if (currentConnectionId != NullConnectionId) { StartLatencyTest(currentConnectionId); } } } void QvConnectionHandler::StartLatencyTest() { - for (auto connection : connections.keys()) { - StartLatencyTest(connection); - } + for (auto connection : connections.keys()) { StartLatencyTest(connection); } } void QvConnectionHandler::StartLatencyTest(const GroupId &id) { - for (auto connection : groups[id].connections) { - StartLatencyTest(connection); - } + for (auto connection : groups[id].connections) { StartLatencyTest(connection); } } void QvConnectionHandler::StartLatencyTest(const ConnectionId &id) @@ -123,10 +121,9 @@ namespace Qv2ray::core::handlers { QList subsList; - for (auto group : groups.keys()) { - if (groups[group].isSubscription) { - subsList.push_back(group); - } + for (auto group : groups.keys()) + { + if (groups[group].isSubscription) { subsList.push_back(group); } } return subsList; @@ -149,10 +146,9 @@ namespace Qv2ray::core::handlers const ConnectionId QvConnectionHandler::GetConnectionIdByDisplayName(const QString &displayName) const { - for (auto conn : connections.keys()) { - if (connections[conn].displayName == displayName) { - return conn; - } + for (auto conn : connections.keys()) + { + if (connections[conn].displayName == displayName) { return conn; } } return NullConnectionId; @@ -160,10 +156,9 @@ namespace Qv2ray::core::handlers const GroupId QvConnectionHandler::GetGroupIdByDisplayName(const QString &displayName) const { - for (auto group : groups.keys()) { - if (groups[group].displayName == displayName) { - return group; - } + for (auto group : groups.keys()) + { + if (groups[group].displayName == displayName) { return group; } } return NullGroupId; @@ -171,48 +166,57 @@ namespace Qv2ray::core::handlers const GroupId QvConnectionHandler::GetConnectionGroupId(const ConnectionId &id) const { - if (!connections.contains(id)) { - LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString()); - } + if (!connections.contains(id)) { LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString()); } return connections[id].groupId; } double QvConnectionHandler::GetConnectionLatency(const ConnectionId &id) const { - if (!connections.contains(id)) { - LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString()); - } + if (!connections.contains(id)) { LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString()); } return connections[id].latency; } const optional QvConnectionHandler::DeleteConnection(const ConnectionId &id) { - // TODO - Q_UNUSED(id) - return ""; + // + auto groupId = connections[id].groupId; + QFile connectionFile((groups[groupId].isSubscription ? QV2RAY_SUBSCRIPTION_DIR : QV2RAY_CONNECTIONS_DIR) + groupId.toString() + "/" + + id.toString() + QV2RAY_CONFIG_FILE_EXTENSION); + // + bool exists = connectionFile.exists(); + if (exists) + { + bool removed = connectionFile.remove(); + if (removed) + { + connections.remove(id); + groups[groupId].connections.removeAll(id); + return {}; + } + else + return "Failed to remove file"; + } + else + return tr("File does not exist."); } const optional QvConnectionHandler::StartConnection(const ConnectionId &identifier) { - if (!connections.contains(identifier)) { - return tr("No connection selected!") + NEWLINE + tr("Please select a config from the list."); - } + if (!connections.contains(identifier)) { return tr("No connection selected!") + NEWLINE + tr("Please select a config from the list."); } - if (currentConnectionId != NullConnectionId) { - StopConnection(); - } + if (currentConnectionId != NullConnectionId) { StopConnection(); } CONFIGROOT root = GetConnectionRoot(connections[identifier].groupId, identifier); return CHStartConnection_p(identifier, root); } - void QvConnectionHandler::StopConnection() //const ConnectionId &id + void QvConnectionHandler::StopConnection() // const ConnectionId &id { // Currently just simply stop it. //_UNUSED(id) - //if (currentConnectionId == id) { + // if (currentConnectionId == id) { //} CHStopConnection_p(); } @@ -226,9 +230,7 @@ namespace Qv2ray::core::handlers { QString result; - if (!connections.contains(id)) { - result = tr("N/A"); - } + if (!connections.contains(id)) { result = tr("N/A"); } CONFIGROOT root = GetConnectionRoot(connections[id].groupId, id); QStringList protocols; @@ -236,12 +238,12 @@ namespace Qv2ray::core::handlers auto outbound = root["outbounds"].toArray().first().toObject(); result.append(outbound["protocol"].toString()); - if (outbound.contains("streamSettings")) { - result.append(" + " + outbound["streamSettings"].toObject()["network"].toString()); + if (outbound.contains("streamSettings")) + { + result.append(" / " + outbound["streamSettings"].toObject()["network"].toString()); - if (outbound["streamSettings"].toObject().contains("tls")) { - result.append(outbound["streamSettings"].toObject()["tls"].toBool() ? " + tls" : ""); - } + if (outbound["streamSettings"].toObject().contains("tls")) + { result.append(outbound["streamSettings"].toObject()["tls"].toBool() ? " / tls" : ""); } } return result; @@ -249,23 +251,23 @@ namespace Qv2ray::core::handlers const tuple QvConnectionHandler::GetConnectionUsageAmount(const ConnectionId &id) const { - if (!connections.contains(id)) { - return make_tuple(0, 0); - } + if (!connections.contains(id)) { return make_tuple(0, 0); } return make_tuple(connections[id].upLinkData, connections[id].downLinkData); } - //const GroupMetaObject QvConnectionHandler::GetGroup(const GroupId &id) const + // const GroupMetaObject QvConnectionHandler::GetGroup(const GroupId &id) + // const //{ // return groups[id]; //} QvConnectionHandler::~QvConnectionHandler() { - CHSaveConnectionData_p(); + CHSaveConfigData_p(); - if (vCoreInstance->KernelStarted) { + if (vCoreInstance->KernelStarted) + { vCoreInstance->StopConnection(); LOG(MODULE_CORE_HANDLER, "Stopped connection from destructor.") } @@ -285,36 +287,49 @@ namespace Qv2ray::core::handlers return CONFIGROOT(JsonFromString(StringFromFile(path))); } - const tuple QvConnectionHandler::GetConnectionInfo(const ConnectionId &id) const + const tuple QvConnectionHandler::GetConnectionData(const ConnectionId &id) const { + // TODO, what if is complex? auto root = GetConnectionRoot(id); - bool validOutboundFound = false; - QString host; - int port; - for (auto item : root["outbounds"].toArray()) { - OUTBOUND outBoundRoot = OUTBOUND(item.toObject()); - QString outboundType = ""; - validOutboundFound = GetOutboundData(outBoundRoot, &host, &port, &outboundType); - - if (validOutboundFound) { - return make_tuple(host, port); - } else { - LOG(MODULE_CORE_HANDLER, "Unknown outbound entry: " + outboundType + ", cannot deduce host and port.") - } - } - - return make_tuple(QObject::tr("N/A"), 0); + bool isSucceed = false; + auto result = CHGetOutboundData_p(root, &isSucceed); + return result; } + const tuple QvConnectionHandler::CHGetOutboundData_p(const CONFIGROOT &root, bool *ok) const + { + *ok = false; + for (auto item : root["outbounds"].toArray()) + { + OUTBOUND outBoundRoot = OUTBOUND(item.toObject()); + QString host; + int port; + QString outboundType = ""; + + if (GetOutboundData(outBoundRoot, &host, &port, &outboundType)) + { + *ok = true; + return make_tuple(outboundType, host, port); + } + else + { + LOG(MODULE_CORE_HANDLER, "Unknown outbound type: " + outboundType + ", cannot deduce host and port.") + } + } + return make_tuple(tr("N/A"), tr("N/A"), 0); + } void QvConnectionHandler::OnLatencyDataArrived(const QvTCPingResultObject &result) { - if (connections.contains(result.connectionId)) { + if (connections.contains(result.connectionId)) + { connections[result.connectionId].latency = result.avg; emit OnLatencyTestFinished(result.connectionId, result.avg); - } else { + } + else + { LOG(MODULE_CORE_HANDLER, "Received a latecy result with non-exist connection id.") } } @@ -322,8 +337,8 @@ namespace Qv2ray::core::handlers bool QvConnectionHandler::UpdateConnection(const ConnectionId &id, const CONFIGROOT &root) { auto groupId = connections[id].groupId; - auto path = (groups[groupId].isSubscription ? QV2RAY_SUBSCRIPTION_DIR : QV2RAY_CONNECTIONS_DIR) - + groupId.toString() + "/" + id.toString() + QV2RAY_CONFIG_FILE_EXTENSION; + auto path = (groups[groupId].isSubscription ? QV2RAY_SUBSCRIPTION_DIR : QV2RAY_CONNECTIONS_DIR) + groupId.toString() + "/" + + id.toString() + QV2RAY_CONFIG_FILE_EXTENSION; auto content = JsonToString(root); emit OnConnectionChanged(id); return StringToFile(content, path); @@ -333,10 +348,101 @@ namespace Qv2ray::core::handlers { tuple result; - if (!groups[id].isSubscription) { - return result; - } + if (!groups[id].isSubscription) { return result; } return make_tuple(groups[id].address, groups[id].lastUpdated, groups[id].updateInterval); } -} + + bool QvConnectionHandler::UpdateSubscription(const GroupId &id, bool useSystemProxy) + { + if (isHttpRequestInProgress) { return false; } + isHttpRequestInProgress = true; + auto data = httpHelper->syncget(groups[id].address, useSystemProxy); + isHttpRequestInProgress = false; + return CHUpdateSubscription_p(id, data); + } + + bool QvConnectionHandler::CHUpdateSubscription_p(const GroupId &id, const QByteArray &subscriptionData) + { + if (!groups.contains(id)) { return false; } + bool isAutoConnectionContainedWithin = groups[id].connections.contains(ConnectionId(GlobalConfig.autoStartId)); + Q_UNUSED(isAutoConnectionContainedWithin) + // + // Anyway, we try our best to preserve the connection id. + QMap nameMap; + QMap, ConnectionId> typeMap; + for (auto conn : groups[id].connections) + { + nameMap[GetDisplayName(conn)] = conn; + auto [protocol, host, port] = GetConnectionData(conn); + if (port != 0) { typeMap[make_tuple(protocol, host, port)] = conn; } + } + // + /// List that is holding connection IDs to be updated. + auto connectionsOrig = groups[id].connections; + auto str = DecodeSubscriptionString(subscriptionData); + if (str.isEmpty()) return false; + // + auto subsList = SplitLines(str); + QDir(QV2RAY_SUBSCRIPTION_DIR + id.toString()).removeRecursively(); + QDir().mkpath(QV2RAY_SUBSCRIPTION_DIR + id.toString()); + + bool hasErrorOccured = false; + for (auto vmess : subsList) + { + QString errMessage; + QString _alias; + auto config = ConvertConfigFromString(vmess.trimmed(), &_alias, &errMessage); + + if (!errMessage.isEmpty()) + { + LOG(MODULE_SUBSCRIPTION, "Processing a subscription with following error: " + errMessage) + hasErrorOccured = true; + continue; + } + bool canGetOutboundData = false; + auto outboundData = CHGetOutboundData_p(config, &canGetOutboundData); + // + // Begin guessing new ConnectionId + if (nameMap.contains(_alias)) + { + // Just go and save the connection... + LOG(MODULE_CORE_HANDLER, "Guessed id from name: " + _alias + ", connectionId: " + nameMap[_alias].toString()) + UpdateConnection(nameMap[_alias], config); + // Remove Connection Id from the list. + connectionsOrig.removeAll(nameMap[_alias]); + } + else if (canGetOutboundData && typeMap.contains(outboundData)) + { + LOG(MODULE_CORE_HANDLER, "Guessed id from protocol/host/port pair for connectionId: " + typeMap[outboundData].toString()) + UpdateConnection(typeMap[outboundData], config); + // Update displayName + connections[typeMap[outboundData]].displayName = _alias; + // Remove Connection Id from the list. + connectionsOrig.removeAll(typeMap[outboundData]); + } + else + { + // New connection id is required since nothing matched found... + ConnectionId newId(GenerateUuid()); + connections[newId].groupId = id; + connections[newId].importDate = system_clock::to_time_t(system_clock::now()); + connections[newId].displayName = _alias; + LOG(MODULE_CORE_HANDLER, "Generated new connectionId.") + UpdateConnection(newId, config); + } + // End guessing connectionId + } + + // Check if anything left behind (not being updated or changed significantly) + LOG(MODULE_CORE_HANDLER, "Removed old connections not have been matched.") + for (auto conn : connectionsOrig) + { + LOG(MODULE_CORE_HANDLER, "Removing: " + conn.toString()) + DeleteConnection(conn); + } + + return hasErrorOccured; + } + +} // namespace Qv2ray::core::handlers diff --git a/src/core/handler/ConnectionHandler.hpp b/src/core/handler/ConnectionHandler.hpp index 263ed509..030c03e8 100644 --- a/src/core/handler/ConnectionHandler.hpp +++ b/src/core/handler/ConnectionHandler.hpp @@ -1,134 +1,136 @@ #pragma once #include "base/Qv2rayBase.hpp" +#include "common/HTTPRequestHelper.hpp" +#include "core/CoreSafeTypes.hpp" +#include "core/CoreUtils.hpp" +#include "core/connection/ConnectionIO.hpp" #include "core/kernel/KernelInteractions.hpp" #include "core/tcping/QvTCPing.hpp" -#include "core/CoreSafeTypes.hpp" -#include "core/connection/ConnectionIO.hpp" -#include "core/CoreUtils.hpp" -#include "common/HTTPRequestHelper.hpp" namespace Qv2ray::core::handlers { class QvConnectionHandler : public QObject { - Q_OBJECT - public: - explicit QvConnectionHandler(); - ~QvConnectionHandler(); - // - const QList Connections() const; - // - const QList AllGroups() const; - const QList Subscriptions() const; - const QList Connections(const GroupId &groupId) const; - // - // Generic Get Options - const QString GetDisplayName(const GroupId &id, int limit = -1) const; - const QString GetDisplayName(const ConnectionId &id, int limit = -1) const; - const GroupId GetGroupIdByDisplayName(const QString &displayName) const; - const ConnectionId GetConnectionIdByDisplayName(const QString &displayName) const; - // - // Connectivity Operationss - bool IsConnected(const ConnectionId &id) const; - const optional StartConnection(const ConnectionId &identifier); - void StopConnection(); //const ConnectionId &id - // - // Connection Operations. - const GroupId GetConnectionGroupId(const ConnectionId &id) const; - double GetConnectionLatency(const ConnectionId &id) const; - const ConnectionId &CreateConnection(const QString &displayName, const GroupId &groupId, const CONFIGROOT &root); - const optional DeleteConnection(const ConnectionId &id); - bool UpdateConnection(const ConnectionId &id, const CONFIGROOT &root); - const optional RenameConnection(const ConnectionId &id, const QString &newName); - const ConnectionId DuplicateConnection(const ConnectionId &id); - const optional MoveConnectionGroup(const ConnectionId &id, const GroupId &newGroupId); - // - const CONFIGROOT GetConnectionRoot(const ConnectionId &id) const; - const CONFIGROOT GetConnectionRoot(const GroupId &group, const ConnectionId &id) const; - // - // Get Conncetion Property - const QString GetConnectionProtocolString(const ConnectionId &id) const; - const tuple GetConnectionInfo(const ConnectionId &connectionId) const; - const tuple GetConnectionUsageAmount(const ConnectionId &id) const; - // - // Misc Connection Operations - void StartLatencyTest(); - void StartLatencyTest(const GroupId &id); - void StartLatencyTest(const ConnectionId &id); - // - // Group Operations - const optional DeleteGroup(const GroupId &id); - const optional DuplicateGroup(const GroupId &id); - const GroupId &CreateGroup(const QString displayName, bool isSubscription); - const optional RenameGroup(const GroupId &id, const QString &newName); - // - // Subscriptions - const optional UpdateSubscription(const GroupId &id, bool useSystemProxy); - const optional UpdateSubscriptionASync(const GroupId &id, bool useSystemProxy); - const tuple GetSubscriptionData(const GroupId &id); + Q_OBJECT + public: + explicit QvConnectionHandler(); + ~QvConnectionHandler(); + // + const QList Connections() const; + // + const QList AllGroups() const; + const QList Subscriptions() const; + const QList Connections(const GroupId &groupId) const; + // + // Generic Get Options + const QString GetDisplayName(const GroupId &id, int limit = -1) const; + const QString GetDisplayName(const ConnectionId &id, int limit = -1) const; + const GroupId GetGroupIdByDisplayName(const QString &displayName) const; + const ConnectionId GetConnectionIdByDisplayName(const QString &displayName) const; + // + // Connectivity Operationss + bool IsConnected(const ConnectionId &id) const; + const optional StartConnection(const ConnectionId &identifier); + void StopConnection(); // const ConnectionId &id + // + // Connection Operations. + const GroupId GetConnectionGroupId(const ConnectionId &id) const; + double GetConnectionLatency(const ConnectionId &id) const; + const ConnectionId &CreateConnection(const QString &displayName, const GroupId &groupId, const CONFIGROOT &root); + const optional DeleteConnection(const ConnectionId &id); + bool UpdateConnection(const ConnectionId &id, const CONFIGROOT &root); + const optional RenameConnection(const ConnectionId &id, const QString &newName); + const ConnectionId DuplicateConnection(const ConnectionId &id); + const optional MoveConnectionGroup(const ConnectionId &id, const GroupId &newGroupId); + // + const CONFIGROOT GetConnectionRoot(const ConnectionId &id) const; + const CONFIGROOT GetConnectionRoot(const GroupId &group, const ConnectionId &id) const; + // + // Get Conncetion Property + const QString GetConnectionProtocolString(const ConnectionId &id) const; + const tuple GetConnectionData(const ConnectionId &connectionId) const; + const tuple GetConnectionUsageAmount(const ConnectionId &id) const; + // + // Misc Connection Operations + void StartLatencyTest(); + void StartLatencyTest(const GroupId &id); + void StartLatencyTest(const ConnectionId &id); + // + // Group Operations + const optional DeleteGroup(const GroupId &id); + const optional DuplicateGroup(const GroupId &id); + const GroupId &CreateGroup(const QString displayName, bool isSubscription); + const optional RenameGroup(const GroupId &id, const QString &newName); + // + // Subscriptions + bool UpdateSubscription(const GroupId &id, bool useSystemProxy); + bool UpdateSubscriptionASync(const GroupId &id, bool useSystemProxy); + const tuple GetSubscriptionData(const GroupId &id); - signals: - void OnCrashed(); - void OnConnected(const ConnectionId &id); - void OnDisConnected(const ConnectionId &id); - void OnVCoreLogAvailable(const ConnectionId &id, const QString &log); - void OnStatsAvailable(const ConnectionId &id, - const quint64 uploadSpeed, const quint64 downloadSpeed, - const quint64 totalUpload, const quint64 totalDownload); - // - void OnConnectionCreated(const ConnectionId &id, const QString &displayName); - void OnConnectionRenamed(const ConnectionId &id, const QString &originalName, const QString &newName); - void OnConnectionChanged(const ConnectionId &id); - void OnConnectionGroupChanged(const ConnectionId &id, const QString &originalGroup, const QString &newGroup); - // - void OnLatencyTestStarted(const ConnectionId &id); - void OnLatencyTestFinished(const ConnectionId &id, const uint average); - // - void OnGroupCreated(const GroupId &id, const QString &displayName); - void OnGroupRenamed(const GroupId &id, const QString &oldName, const QString &newName); - void OnGroupDeleted(const GroupId &id, const QString &displayName); - // - //void OnSubscriptionCreated(const GroupId &id, const QString &displayName, const QString &address); - //void OnSubscriptionDeleted(const GroupId &id, const QString &oldName, const QString &newName); - void OnSubscriptionUpdateFinished(const GroupId &id); + signals: + void OnCrashed(); + void OnConnected(const ConnectionId &id); + void OnDisConnected(const ConnectionId &id); + void OnVCoreLogAvailable(const ConnectionId &id, const QString &log); + void OnStatsAvailable(const ConnectionId &id, const quint64 uploadSpeed, const quint64 downloadSpeed, const quint64 totalUpload, + const quint64 totalDownload); + // + void OnConnectionCreated(const ConnectionId &id, const QString &displayName); + void OnConnectionRenamed(const ConnectionId &id, const QString &originalName, const QString &newName); + void OnConnectionChanged(const ConnectionId &id); + void OnConnectionGroupChanged(const ConnectionId &id, const QString &originalGroup, const QString &newGroup); + // + void OnLatencyTestStarted(const ConnectionId &id); + void OnLatencyTestFinished(const ConnectionId &id, const uint average); + // + void OnGroupCreated(const GroupId &id, const QString &displayName); + void OnGroupRenamed(const GroupId &id, const QString &oldName, const QString &newName); + void OnGroupDeleted(const GroupId &id, const QString &displayName); + // + // void OnSubscriptionCreated(const GroupId &id, const QString &displayName, const QString &address); + // void OnSubscriptionDeleted(const GroupId &id, const QString &oldName, const QString &newName); + void OnSubscriptionUpdateFinished(const GroupId &id); - private slots: - void OnStatsDataArrived(const ConnectionId &id, const quint64 uploadSpeed, const quint64 downloadSpeed); - void OnVCoreCrashed(const ConnectionId &id); - void OnLatencyDataArrived(const QvTCPingResultObject &data); + private slots: + void OnStatsDataArrived(const ConnectionId &id, const quint64 uploadSpeed, const quint64 downloadSpeed); + void OnVCoreCrashed(const ConnectionId &id); + void OnLatencyDataArrived(const QvTCPingResultObject &data); - protected: - void timerEvent(QTimerEvent *event) override; + protected: + void timerEvent(QTimerEvent *event) override; - private: - void CHSaveConnectionData_p(); - // - optional CHStartConnection_p(const ConnectionId &id, const CONFIGROOT &root); - void CHStopConnection_p(); - bool CHSaveConnectionConfig_p(CONFIGROOT obj, const ConnectionId &id, bool override); + private: + void CHSaveConfigData_p(); + // + optional CHStartConnection_p(const ConnectionId &id, const CONFIGROOT &root); + void CHStopConnection_p(); + bool CHUpdateSubscription_p(const GroupId &id, const QByteArray &subscriptionData); + // bool CHSaveConnectionConfig_p(CONFIGROOT obj, const ConnectionId &id, bool override); + const tuple CHGetOutboundData_p(const CONFIGROOT &obj, bool *succeed) const; - private: - int saveTimerId; - int pingAllTimerId; - int pingConnectionTimerId; - QHash groups; - QHash connections; - //QHash connectionRootCache; + private: + int saveTimerId; + int pingAllTimerId; + int pingConnectionTimerId; + QHash groups; + QHash connections; + // QHash connectionRootCache; - private: - QvHttpRequestHelper *httpHelper; - QvTCPingHelper *tcpingHelper; - // We only support one cuncurrent connection currently. + private: + QvHttpRequestHelper *httpHelper; + bool isHttpRequestInProgress = false; + QvTCPingHelper *tcpingHelper; + // We only support one cuncurrent connection currently. #ifdef QV2RAY_MULTIPlE_ONNECTION - QHash kernelInstances; + QHash kernelInstances; #else - ConnectionId currentConnectionId = NullConnectionId; - V2rayKernelInstance *vCoreInstance = nullptr; + ConnectionId currentConnectionId = NullConnectionId; + V2rayKernelInstance *vCoreInstance = nullptr; #endif }; inline ::Qv2ray::core::handlers::QvConnectionHandler *ConnectionManager = nullptr; -} +} // namespace Qv2ray::core::handlers using namespace Qv2ray::core::handlers; diff --git a/src/core/handler/V2rayInstanceHandler.cpp b/src/core/handler/V2rayInstanceHandler.cpp index 183ecfb7..500f15cf 100644 --- a/src/core/handler/V2rayInstanceHandler.cpp +++ b/src/core/handler/V2rayInstanceHandler.cpp @@ -8,7 +8,8 @@ optional QvConnectionHandler::CHStartConnection_p(const ConnectionId &i auto fullConfig = GenerateRuntimeConfig(root); auto result = vCoreInstance->StartConnection(id, fullConfig); - if (!result.has_value()) { + if (!result.has_value()) + { currentConnectionId = id; emit OnConnected(currentConnectionId); } @@ -18,13 +19,16 @@ optional QvConnectionHandler::CHStartConnection_p(const ConnectionId &i void QvConnectionHandler::CHStopConnection_p() { - if (vCoreInstance->KernelStarted) { + if (vCoreInstance->KernelStarted) + { vCoreInstance->StopConnection(); // Copy ConnectionId id = currentConnectionId; currentConnectionId = NullConnectionId; emit OnDisConnected(id); - } else { + } + else + { LOG(MODULE_CORE_HANDLER, "VCore is not started, not disconnecting") } } diff --git a/src/core/kernel/APIBackend.cpp b/src/core/kernel/APIBackend.cpp index bd40f437..99d12cf6 100644 --- a/src/core/kernel/APIBackend.cpp +++ b/src/core/kernel/APIBackend.cpp @@ -6,7 +6,7 @@ using grpc::Channel; using grpc::ClientContext; using grpc::Status; #else -#include "libs/libqvb/build/libqvb.h" + #include "libs/libqvb/build/libqvb.h" #endif namespace Qv2ray::core::kernel @@ -22,9 +22,7 @@ namespace Qv2ray::core::kernel DEBUG(MODULE_VCORE, "API Worker initialised.") connect(this, SIGNAL(error(QString)), this, SLOT(errorString(QString))); connect(thread, SIGNAL(started()), this, SLOT(process())); - connect(thread, &QThread::finished, []() { - LOG(MODULE_VCORE, "API thread stopped") - }); + connect(thread, &QThread::finished, []() { LOG(MODULE_VCORE, "API thread stopped") }); started = true; thread->start(); DEBUG(MODULE_VCORE, "API Worker started.") @@ -52,21 +50,22 @@ namespace Qv2ray::core::kernel thread->wait(); // Although thread shouldnot be null, we'll add this check to be safe. - if (thread) { - delete thread; - } + if (thread) { delete thread; } } // API Core Operations // Start processing data. void APIWorker::process() { - while (started) { + while (started) + { QThread::msleep(1000); bool dialed = false; - while (running) { - if (!dialed) { + while (running) + { + if (!dialed) + { auto channelAddress = "127.0.0.1:" + QString::number(GlobalConfig.apiConfig.statsPort); #ifdef WITH_LIB_GRPCPP Channel = grpc::CreateChannel(channelAddress.toStdString(), grpc::InsecureChannelCredentials()); @@ -85,36 +84,44 @@ namespace Qv2ray::core::kernel qint64 value_up = 0; qint64 value_down = 0; - for (auto tag : inboundTags) { + for (auto tag : inboundTags) + { value_up += CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>uplink"); value_down += CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>downlink"); } - if (value_up < 0 || value_down < 0) { + if (value_up < 0 || value_down < 0) + { dialed = false; break; } - if (running) { + if (running) + { apiFailedCounter = 0; emit OnDataReady(value_up, value_down); } #else - for (auto tag : inboundTags) { + for (auto tag : inboundTags) + { auto valup = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>uplink"); auto valdown = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>downlink"); - if (valup < 0 || valdown < 0) { + if (valup < 0 || valdown < 0) + { dialed = false; break; } - if (running) { + if (running) + { apiFailedCounter = 0; emit OnDataReady(tag, valup, valdown); - } else { + } + else + { // If the connection has stopped, just quit. break; } @@ -123,19 +130,22 @@ namespace Qv2ray::core::kernel #endif QThread::msleep(1000); } // end while running - } // end while started + } // end while started thread->exit(); } qint64 APIWorker::CallStatsAPIByName(const QString &name) { - if (apiFailedCounter == QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) { + if (apiFailedCounter == QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) + { LOG(MODULE_VCORE, "API call failure threshold reached, cancelling further API aclls.") emit error("Failed to get statistics data, please check if V2ray is running properly"); apiFailedCounter++; return 0; - } else if (apiFailedCounter > QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) { + } + else if (apiFailedCounter > QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) + { return 0; } @@ -147,7 +157,8 @@ namespace Qv2ray::core::kernel ClientContext context; Status status = Stub->GetStats(&context, request, &response); - if (!status.ok()) { + if (!status.ok()) + { LOG(MODULE_VCORE, "API call returns: " + QSTRN(status.error_code()) + " (" + QString::fromStdString(status.error_message()) + ")") apiFailedCounter++; } @@ -157,7 +168,8 @@ namespace Qv2ray::core::kernel qint64 data = GetStats(const_cast(name.toStdString().c_str()), 1000); #endif - if (data < 0) { + if (data < 0) + { LOG(MODULE_VCORE, "API call returns: " + QSTRN(data)) apiFailedCounter++; return 0; @@ -165,4 +177,4 @@ namespace Qv2ray::core::kernel return data; } -} +} // namespace Qv2ray::core::kernel diff --git a/src/core/kernel/APIBackend.hpp b/src/core/kernel/APIBackend.hpp index a6147fc6..03e35c9d 100644 --- a/src/core/kernel/APIBackend.hpp +++ b/src/core/kernel/APIBackend.hpp @@ -1,9 +1,10 @@ #pragma once #include "base/Qv2rayBase.hpp" #ifdef WITH_LIB_GRPCPP -#include -#include "libs/gen/v2ray_api.pb.h" -#include "libs/gen/v2ray_api.grpc.pb.h" + #include "libs/gen/v2ray_api.grpc.pb.h" + #include "libs/gen/v2ray_api.pb.h" + + #include #endif // Check 10 times before telling user that API has failed. @@ -13,34 +14,34 @@ namespace Qv2ray::core::kernel { class APIWorker : public QObject { - Q_OBJECT + Q_OBJECT - public: - APIWorker(); - ~APIWorker(); - void StartAPI(const QStringList &tags); - void StopAPI(); + public: + APIWorker(); + ~APIWorker(); + void StartAPI(const QStringList &tags); + void StopAPI(); - public slots: - void process(); + public slots: + void process(); - signals: - void OnDataReady(const quint64 _totalUp, const quint64 _totalDown); - void error(const QString &err); + signals: + void OnDataReady(const quint64 _totalUp, const quint64 _totalDown); + void error(const QString &err); - private: - qint64 CallStatsAPIByName(const QString &name); - QStringList inboundTags; - QThread *thread; - // - bool started = false; - bool running = false; - uint apiFailedCounter = 0; + private: + qint64 CallStatsAPIByName(const QString &name); + QStringList inboundTags; + QThread *thread; + // + bool started = false; + bool running = false; + uint apiFailedCounter = 0; #ifdef WITH_LIB_GRPCPP - std::shared_ptr<::grpc::Channel> Channel; - std::unique_ptr<::v2ray::core::app::stats::command::StatsService::Stub> Stub; + std::shared_ptr<::grpc::Channel> Channel; + std::unique_ptr<::v2ray::core::app::stats::command::StatsService::Stub> Stub; #endif }; -} +} // namespace Qv2ray::core::kernel using namespace Qv2ray::core::kernel; diff --git a/src/core/kernel/KernelInteractions.cpp b/src/core/kernel/KernelInteractions.cpp index ee08ce02..3fd0ed72 100644 --- a/src/core/kernel/KernelInteractions.cpp +++ b/src/core/kernel/KernelInteractions.cpp @@ -1,10 +1,12 @@ +#include "KernelInteractions.hpp" + +#include "APIBackend.hpp" +#include "common/QvHelpers.hpp" +#include "core/connection/ConnectionIO.hpp" + +#include #include #include -#include -#include "common/QvHelpers.hpp" -#include "KernelInteractions.hpp" -#include "core/connection/ConnectionIO.hpp" -#include "APIBackend.hpp" namespace Qv2ray::core::kernel { @@ -12,14 +14,17 @@ namespace Qv2ray::core::kernel { QFile coreFile(vCorePath); - if (!coreFile.exists()) { + if (!coreFile.exists()) + { DEBUG(MODULE_VCORE, "V2ray core file cannot be found.") *message = tr("V2ray core executable not found."); return false; } - // Use open() here to prevent `executing` a folder, which may have the same name as the V2ray core. - if (!coreFile.open(QFile::ReadOnly)) { + // Use open() here to prevent `executing` a folder, which may have the + // same name as the V2ray core. + if (!coreFile.open(QFile::ReadOnly)) + { DEBUG(MODULE_VCORE, "V2ray core file cannot be opened, possibly be a folder?") *message = tr("V2ray core file cannot be opened, please ensure there's a file instead of a folder."); return false; @@ -33,28 +38,32 @@ namespace Qv2ray::core::kernel bool hasGeoIP = FileExistsIn(QDir(vAssetsPath), "geoip.dat"); bool hasGeoSite = FileExistsIn(QDir(vAssetsPath), "geosite.dat"); - if (!hasGeoIP && !hasGeoSite) { + if (!hasGeoIP && !hasGeoSite) + { DEBUG(MODULE_VCORE, "V2ray assets path contains none of those two files.") *message = tr("V2ray assets path is not valid."); return false; } - if (!hasGeoIP) { + if (!hasGeoIP) + { DEBUG(MODULE_VCORE, "No geoip.dat in assets path, aborting.") - *message = tr("No geoip.dat in assets path."); + *message = tr("No geoip.dat in assets path."); return false; } - if (!hasGeoSite) { + if (!hasGeoSite) + { DEBUG(MODULE_VCORE, "No geosite.dat in assets path, aborting.") - *message = tr("No geosite.dat in assets path."); + *message = tr("No geosite.dat in assets path."); return false; } // Check if V2ray core returns a version number correctly. QProcess proc; #ifdef Q_OS_WIN32 - // nativeArguments are required for Windows platform, without a reason... + // nativeArguments are required for Windows platform, without a + // reason... proc.setProcessChannelMode(QProcess::MergedChannels); proc.setProgram(vCorePath); proc.setNativeArguments("--version"); @@ -66,7 +75,8 @@ namespace Qv2ray::core::kernel proc.waitForFinished(); auto exitCode = proc.exitCode(); - if (exitCode != 0) { + if (exitCode != 0) + { DEBUG(MODULE_VCORE, "VCore failed with an exit code: " + QSTRN(exitCode)) *message = tr("V2ray core failed with an exit code: ") + QSTRN(exitCode); return false; @@ -75,7 +85,8 @@ namespace Qv2ray::core::kernel QString output = proc.readAllStandardOutput(); LOG(MODULE_VCORE, "V2ray output: " + SplitLines(output).join(";")) - if (SplitLines(output).isEmpty()) { + if (SplitLines(output).isEmpty()) + { *message = tr("V2ray core returns empty string."); return false; } @@ -84,12 +95,12 @@ namespace Qv2ray::core::kernel return true; } - bool V2rayKernelInstance::ValidateConfig(const QString &path) { QString v2rayCheckResult; - if (ValidateKernel(GlobalConfig.v2CorePath, GlobalConfig.v2AssetsPath, &v2rayCheckResult)) { + if (ValidateKernel(GlobalConfig.v2CorePath, GlobalConfig.v2AssetsPath, &v2rayCheckResult)) + { DEBUG(MODULE_VCORE, "V2ray version: " + v2rayCheckResult) // Append assets location env. QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); @@ -98,21 +109,28 @@ namespace Qv2ray::core::kernel QProcess process; process.setProcessEnvironment(env); DEBUG(MODULE_VCORE, "Starting V2ray core with test options") - process.start(GlobalConfig.v2CorePath, QStringList() << "-test" << "-config" << path, QIODevice::ReadWrite | QIODevice::Text); + process.start(GlobalConfig.v2CorePath, + QStringList() << "-test" + << "-config" << path, + QIODevice::ReadWrite | QIODevice::Text); process.waitForFinished(); - if (process.exitCode() != 0) { + if (process.exitCode() != 0) + { QString output = QString(process.readAllStandardOutput()); QvMessageBoxWarn(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17)); return false; - } else { + } + else + { DEBUG(MODULE_VCORE, "Config file check passed.") return true; } - } else { + } + else + { QvMessageBoxWarn(nullptr, tr("Cannot start V2ray"), - tr("V2ray core settings is incorrect.") + NEWLINE + NEWLINE + - tr("The error is: ") + NEWLINE + v2rayCheckResult); + tr("V2ray core settings is incorrect.") + NEWLINE + NEWLINE + tr("The error is: ") + NEWLINE + v2rayCheckResult); return false; } } @@ -120,14 +138,14 @@ namespace Qv2ray::core::kernel V2rayKernelInstance::V2rayKernelInstance() { vProcess = new QProcess(); - connect(vProcess, &QProcess::readyReadStandardOutput, this, [&]() { - emit OnProcessOutputReadyRead(id, vProcess->readAllStandardOutput().trimmed()); - }); + connect(vProcess, &QProcess::readyReadStandardOutput, this, + [&]() { emit OnProcessOutputReadyRead(id, vProcess->readAllStandardOutput().trimmed()); }); connect(vProcess, &QProcess::stateChanged, [&](QProcess::ProcessState state) { DEBUG(MODULE_VCORE, "V2ray kernel process status changed: " + QVariant::fromValue(state).toString()) // If V2ray crashed AFTER we start it. - if (KernelStarted && state == QProcess::NotRunning) { + if (KernelStarted && state == QProcess::NotRunning) + { LOG(MODULE_VCORE, "V2ray kernel crashed.") StopConnection(); emit OnProcessErrored(id); @@ -140,7 +158,8 @@ namespace Qv2ray::core::kernel optional V2rayKernelInstance::StartConnection(const ConnectionId &id, const CONFIGROOT &root) { - if (KernelStarted) { + if (KernelStarted) + { LOG(MODULE_VCORE, "Status is invalid, expect STOPPED when calling StartConnection") return tr("Invalid V2ray Instance Status."); } @@ -151,7 +170,8 @@ namespace Qv2ray::core::kernel // auto filePath = QV2RAY_GENERATED_FILE_PATH; - if (ValidateConfig(filePath)) { + if (ValidateConfig(filePath)) + { QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("V2RAY_LOCATION_ASSET", GlobalConfig.v2AssetsPath); vProcess->setProcessEnvironment(env); @@ -163,10 +183,12 @@ namespace Qv2ray::core::kernel this->id = id; QStringList inboundTags; - for (auto item : root["inbounds"].toArray()) { + for (auto item : root["inbounds"].toArray()) + { auto tag = item.toObject()["tag"].toString(""); - if (tag.isEmpty() || tag == API_TAG_INBOUND) { + if (tag.isEmpty() || tag == API_TAG_INBOUND) + { // Ignore API tag and empty tags. continue; } @@ -178,20 +200,26 @@ namespace Qv2ray::core::kernel apiEnabled = false; // - if (StartupOption.noAPI) { - LOG(MODULE_VCORE, "API has been disabled by the command line argument \"-noAPI\"") - } else if (!GlobalConfig.apiConfig.enableAPI) { + if (StartupOption.noAPI) { LOG(MODULE_VCORE, "API has been disabled by the command line argument \"-noAPI\"") } + else if (!GlobalConfig.apiConfig.enableAPI) + { LOG(MODULE_VCORE, "API has been disabled by the global config option") - } else if (inboundTags.isEmpty()) { + } + else if (inboundTags.isEmpty()) + { LOG(MODULE_VCORE, "API is disabled since no inbound tags configured. This is probably caused by a bad complex config.") - } else { + } + else + { apiWorker->StartAPI(inboundTags); apiEnabled = true; DEBUG(MODULE_VCORE, "Qv2ray API started") } - return { }; - } else { + return {}; + } + else + { KernelStarted = false; return tr("V2ray kernel failed to start."); } @@ -199,12 +227,14 @@ namespace Qv2ray::core::kernel void V2rayKernelInstance::StopConnection() { - if (apiEnabled) { + if (apiEnabled) + { apiWorker->StopAPI(); apiEnabled = false; } - // Set this to false BEFORE close the Process, since we need this flag to capture the real kernel CRASH + // Set this to false BEFORE close the Process, since we need this flag + // to capture the real kernel CRASH KernelStarted = false; vProcess->close(); // Block until V2ray core exits @@ -214,9 +244,7 @@ namespace Qv2ray::core::kernel V2rayKernelInstance::~V2rayKernelInstance() { - if (KernelStarted) { - StopConnection(); - } + if (KernelStarted) { StopConnection(); } delete apiWorker; delete vProcess; @@ -226,4 +254,4 @@ namespace Qv2ray::core::kernel { emit OnNewStatsDataArrived(id, _totalUp, _totalDown); } -} +} // namespace Qv2ray::core::kernel diff --git a/src/core/kernel/KernelInteractions.hpp b/src/core/kernel/KernelInteractions.hpp index dc291a61..13f8187d 100644 --- a/src/core/kernel/KernelInteractions.hpp +++ b/src/core/kernel/KernelInteractions.hpp @@ -1,46 +1,47 @@ #pragma once -#include #include "base/Qv2rayBase.hpp" #include "core/CoreSafeTypes.hpp" +#include + namespace Qv2ray::core::kernel { class APIWorker; class V2rayKernelInstance : public QObject { - Q_OBJECT - public: - explicit V2rayKernelInstance(); - ~V2rayKernelInstance() override; - // - // Speed - qulonglong getTagSpeedUp(const QString &tag); - qulonglong getTagSpeedDown(const QString &tag); - qulonglong getAllSpeedUp(); - qulonglong getAllSpeedDown(); - // - optional StartConnection(const ConnectionId &id, const CONFIGROOT &root); - void StopConnection(); - bool KernelStarted = false; - // - static bool ValidateConfig(const QString &path); - static bool ValidateKernel(const QString &vCorePath, const QString &vAssetsPath, QString *message); + Q_OBJECT + public: + explicit V2rayKernelInstance(); + ~V2rayKernelInstance() override; + // + // Speed + qulonglong getTagSpeedUp(const QString &tag); + qulonglong getTagSpeedDown(const QString &tag); + qulonglong getAllSpeedUp(); + qulonglong getAllSpeedDown(); + // + optional StartConnection(const ConnectionId &id, const CONFIGROOT &root); + void StopConnection(); + bool KernelStarted = false; + // + static bool ValidateConfig(const QString &path); + static bool ValidateKernel(const QString &vCorePath, const QString &vAssetsPath, QString *message); - signals: - void OnProcessErrored(const ConnectionId &id); - void OnProcessOutputReadyRead(const ConnectionId &id, const QString &output); - void OnNewStatsDataArrived(const ConnectionId &id, const quint64 _totalUp, const quint64 _totalDown); + signals: + void OnProcessErrored(const ConnectionId &id); + void OnProcessOutputReadyRead(const ConnectionId &id, const QString &output); + void OnNewStatsDataArrived(const ConnectionId &id, const quint64 _totalUp, const quint64 _totalDown); - public slots: - void onAPIDataReady(const quint64 _totalUp, const quint64 _totalDown); + public slots: + void onAPIDataReady(const quint64 _totalUp, const quint64 _totalDown); - private: - APIWorker *apiWorker; - QProcess *vProcess; - bool apiEnabled; - // - ConnectionId id = NullConnectionId; + private: + APIWorker *apiWorker; + QProcess *vProcess; + bool apiEnabled; + // + ConnectionId id = NullConnectionId; }; -} +} // namespace Qv2ray::core::kernel using namespace Qv2ray::core::kernel; diff --git a/src/core/tcping/QvTCPing.cpp b/src/core/tcping/QvTCPing.cpp index d6cc9642..60c885a9 100644 --- a/src/core/tcping/QvTCPing.cpp +++ b/src/core/tcping/QvTCPing.cpp @@ -1,15 +1,15 @@ #ifdef _WIN32 -#include -#include + #include + #include #else -#include -#include -#include -#include + #include + #include + #include + #include #endif +#include "QtConcurrent/QtConcurrent" #include "QvTCPing.hpp" #include "core/handler/ConnectionHandler.hpp" -#include "QtConcurrent/QtConcurrent" namespace Qv2ray::core::tcping { @@ -23,7 +23,8 @@ namespace Qv2ray::core::tcping void QvTCPingHelper::StopAllLatenceTest() { - while (!pingWorkingThreads.isEmpty()) { + while (!pingWorkingThreads.isEmpty()) + { auto worker = pingWorkingThreads.dequeue(); worker->future().cancel(); worker->cancel(); @@ -35,13 +36,11 @@ namespace Qv2ray::core::tcping watcher->setFuture(QtConcurrent::run(&QvTCPingHelper::TestLatency_p, id, count)); pingWorkingThreads.enqueue(watcher); // - connect(watcher, &QFutureWatcher::finished, this, [ = ]() { + connect(watcher, &QFutureWatcher::finished, this, [=]() { auto result = watcher->result(); this->pingWorkingThreads.removeOne(watcher); - if (!result.errorMessage.isEmpty()) { - LOG(MODULE_NETWORK, "Ping --> " + result.errorMessage) - } + if (!result.errorMessage.isEmpty()) { LOG(MODULE_NETWORK, "Ping --> " + result.errorMessage) } emit this->OnLatencyTestCompleted(result); }); @@ -54,12 +53,14 @@ namespace Qv2ray::core::tcping if (isExiting) return data; - auto [host, port] = ConnectionManager->GetConnectionInfo(id); + auto [protocol, host, port] = ConnectionManager->GetConnectionData(id); + Q_UNUSED(protocol) double successCount = 0, errorCount = 0; addrinfo *resolved; int errcode; - if ((errcode = resolveHost(host.toStdString(), port, &resolved)) != 0) { + if ((errcode = resolveHost(host.toStdString(), port, &resolved)) != 0) + { #ifdef _WIN32 data.errorMessage = QString::fromStdWString(gai_strerror(errcode)); #else @@ -71,26 +72,35 @@ namespace Qv2ray::core::tcping bool noAddress = false; int currentCount = 0; - while (currentCount < count) { + while (currentCount < count) + { if (isExiting) return QvTCPingResultObject(); system_clock::time_point start; system_clock::time_point end; - if ((errcode = testLatency(resolved, &start, &end)) != 0) { - if (errcode != -EADDRNOTAVAIL) { - //LOG(MODULE_NETWORK, "Error connecting to host: " + data.hostName + ":" + QSTRN(data.port) + " " + strerror(-errcode)) + if ((errcode = testLatency(resolved, &start, &end)) != 0) + { + if (errcode != -EADDRNOTAVAIL) + { + // LOG(MODULE_NETWORK, "Error connecting to host: " + + // data.hostName + ":" + QSTRN(data.port) + " " + + // strerror(-errcode)) errorCount++; - } else { - if (noAddress) { - LOG(MODULE_NETWORK, ".") - } else { + } + else + { + if (noAddress) { LOG(MODULE_NETWORK, ".") } + else + { LOG(MODULE_NETWORK, "error connecting to host: " + QSTRN(-errcode) + " " + strerror(-errcode)) } noAddress = true; } - } else { + } + else + { noAddress = false; successCount++; auto milliseconds = std::chrono::duration_cast(end - start); @@ -99,7 +109,8 @@ namespace Qv2ray::core::tcping data.worst = min(data.worst, ms); data.best = max(data.best, ms); - if (ms > 1000) { + if (ms > 1000) + { LOG(MODULE_NETWORK, "Stop the test on the first long connect()") break; /* Stop the test on the first long connect() */ } @@ -146,20 +157,19 @@ namespace Qv2ray::core::tcping int rv = 0; /* try to connect for each of the entries: */ - while (addr != nullptr) { + while (addr != nullptr) + { if (isExiting) return 0; /* create socket */ fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (!fd) { - goto next_addr0; - } + if (!fd) { goto next_addr0; } #ifdef _WIN32 // Windows needs special conversion. - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on)) < 0) #else if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) #endif @@ -172,7 +182,8 @@ namespace Qv2ray::core::tcping /* connect to peer */ // Qt has its own connect() function in QObject.... // So we add "::" here - if (::connect(fd, addr->ai_addr, addr->ai_addrlen) == 0) { + if (::connect(fd, addr->ai_addr, addr->ai_addrlen) == 0) + { *end = system_clock::now(); #ifdef _WIN32 closesocket(fd); @@ -182,17 +193,17 @@ namespace Qv2ray::core::tcping return 0; } -next_addr1: + next_addr1: #ifdef _WIN32 closesocket(fd); #else close(fd); #endif -next_addr0: + next_addr0: addr = addr->ai_next; } rv = rv ? rv : -errno; return rv; } -} +} // namespace Qv2ray::core::tcping diff --git a/src/core/tcping/QvTCPing.hpp b/src/core/tcping/QvTCPing.hpp index 3e69ea20..1153ba61 100644 --- a/src/core/tcping/QvTCPing.hpp +++ b/src/core/tcping/QvTCPing.hpp @@ -4,7 +4,8 @@ namespace Qv2ray::core::tcping { - struct QvTCPingResultObject { + struct QvTCPingResultObject + { ConnectionId connectionId = NullConnectionId; QString errorMessage; int total, succeed, failed; @@ -13,19 +14,20 @@ namespace Qv2ray::core::tcping class QvTCPingHelper : public QObject { - Q_OBJECT + Q_OBJECT - public: - explicit QvTCPingHelper(const int defaultCount = 5, QObject *parent = nullptr); - void TestLatency(const ConnectionId &connectionId); - void StopAllLatenceTest(); - signals: - void OnLatencyTestCompleted(const QvTCPingResultObject &data); - private: - static QvTCPingResultObject TestLatency_p(const ConnectionId &id, const int count); - int count; - QQueue*> pingWorkingThreads; + public: + explicit QvTCPingHelper(const int defaultCount = 5, QObject *parent = nullptr); + void TestLatency(const ConnectionId &connectionId); + void StopAllLatenceTest(); + signals: + void OnLatencyTestCompleted(const QvTCPingResultObject &data); + + private: + static QvTCPingResultObject TestLatency_p(const ConnectionId &id, const int count); + int count; + QQueue *> pingWorkingThreads; }; -} +} // namespace Qv2ray::core::tcping using namespace Qv2ray::core::tcping; diff --git a/src/main.cpp b/src/main.cpp index 90547e69..9d4c2a11 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,37 +1,36 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ui/w_MainWindow.hpp" - +#include "common/CommandArgs.hpp" +#include "common/QvHelpers.hpp" +#include "common/QvTranslator.hpp" #include "core/config/ConfigBackend.hpp" #include "core/handler/ConnectionHandler.hpp" -#include "common/QvHelpers.hpp" -#include "common/CommandArgs.hpp" -#include "common/QvTranslator.hpp" +#include "ui/w_MainWindow.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef Q_OS_UNIX -// For unix root user check -#include "unistd.h" + // For unix root user check + #include "unistd.h" #endif void signalHandler(int signum) { cout << "Interrupt signal (" << signum << ") received." << endl; - //if (MainWindow::mwInstance && MainWindow::mwInstance->vinstance) { + // if (MainWindow::mwInstance && MainWindow::mwInstance->vinstance) { // cout << "Trying to stop connection..." << endl; // MainWindow::mwInstance->vinstance->StopConnection(); //} qApp->exit(-99); } - bool verifyConfigAvaliability(QString path, bool checkExistingConfig) { // Does not exist. @@ -41,17 +40,21 @@ bool verifyConfigAvaliability(QString path, bool checkExistingConfig) QFile testFile(path + ".qv2ray_file_write_test_file" + QSTRN(QTime::currentTime().msecsSinceStartOfDay())); bool opened = testFile.open(QFile::OpenModeFlag::ReadWrite); - if (!opened) { + if (!opened) + { LOG(MODULE_SETTINGS, "Directory at: " + path + " cannot be used as a valid config file path.") LOG(MODULE_INIT, "---> Cannot create a new file or openwrite a file.") return false; - } else { + } + else + { testFile.write("Qv2ray test file, feel free to remove."); testFile.flush(); testFile.close(); bool removed = testFile.remove(); - if (!removed) { + if (!removed) + { // This is rare, as we can create a file but failed to remove it. LOG(MODULE_SETTINGS, "Directory at: " + path + " cannot be used as a valid config file path.") LOG(MODULE_INIT, "---> Cannot remove a file.") @@ -59,7 +62,8 @@ bool verifyConfigAvaliability(QString path, bool checkExistingConfig) } } - if (checkExistingConfig) { + if (checkExistingConfig) + { // Check if an existing config is found. QFile configFile(path + "Qv2ray.conf"); @@ -68,37 +72,52 @@ bool verifyConfigAvaliability(QString path, bool checkExistingConfig) bool opened2 = configFile.open(QIODevice::ReadWrite); - try { - if (opened2) { + try + { + if (opened2) + { // Verify if the config can be loaded. // Failed to parse if we changed the file structure... // Original: - // -- auto conf = StructFromJsonString(configFile.readAll()); + // -- auto conf = + // StructFromJsonString(configFile.readAll()); // - // Verify JSON file format. (only) because this file version may not be upgraded and may contain unsupported structure. + // Verify JSON file format. (only) because this file version may + // not be upgraded and may contain unsupported structure. auto err = VerifyJsonString(StringFromFile(&configFile)); - if (!err.isEmpty()) { + if (!err.isEmpty()) + { LOG(MODULE_INIT, "Json parse returns: " + err) return false; - } else { + } + else + { // If the file format is valid. auto conf = JsonFromString(StringFromFile(&configFile)); - LOG(MODULE_SETTINGS, "Path: " + path + " contains a config file, in version " + conf["config_version"].toVariant().toString()) + LOG(MODULE_SETTINGS, + "Path: " + path + " contains a config file, in version " + conf["config_version"].toVariant().toString()) configFile.close(); return true; } - } else { - LOG(MODULE_SETTINGS, "File: " + configFile.fileName() + " cannot be opened!") + } + else + { + LOG(MODULE_SETTINGS, "File: " + configFile.fileName() + " cannot be opened!") return false; } - } catch (...) { + } + catch (...) + { LOG(MODULE_SETTINGS, "Exception raised when checking config: " + configFile.fileName()) - //LOG(INIT, e->what()) - QvMessageBoxWarn(nullptr, QObject::tr("Warning"), QObject::tr("Qv2ray cannot load the config file from here:") + NEWLINE + configFile.fileName()); + // LOG(INIT, e->what()) + QvMessageBoxWarn(nullptr, QObject::tr("Warning"), + QObject::tr("Qv2ray cannot load the config file from here:") + NEWLINE + configFile.fileName()); return false; } - } else return true; + } + else + return true; } bool initialiseQv2ray() @@ -109,12 +128,14 @@ bool initialiseQv2ray() const QString homeQv2ray = QDir::homePath() + "/.qv2ray" QV2RAY_CONFIG_DIR_SUFFIX; // // - // Some built-in search paths for Qv2ray to find configs. (load the first one if possible). + // Some built-in search paths for Qv2ray to find configs. (load the first + // one if possible). // QStringList configFilePaths; configFilePaths << currentPathConfig; #ifdef WITH_FLATHUB_CONFIG_PATH - // AppConfigLocation uses 'Q'v2ray instead of `q`v2ray. Keep here as backward compatibility. + // AppConfigLocation uses 'Q'v2ray instead of `q`v2ray. Keep here as + // backward compatibility. configFilePaths << QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + QV2RAY_CONFIG_DIR_SUFFIX; #endif configFilePaths << configQv2ray; @@ -123,31 +144,40 @@ bool initialiseQv2ray() QString configPath = ""; bool hasExistingConfig = false; - for (auto path : configFilePaths) { - // Verify the config path, check if the config file exists and in the correct JSON format. - // True means we check for config existance as well. --|HERE | + for (auto path : configFilePaths) + { + // Verify the config path, check if the config file exists and in the + // correct JSON format. True means we check for config existance as + // well. --|HERE | bool isValidConfigPath = verifyConfigAvaliability(path, true); // If we already found a valid config file. just simply load it... if (hasExistingConfig) break; - if (isValidConfigPath) { + if (isValidConfigPath) + { DEBUG(MODULE_INIT, "Path: " + path + " is valid.") configPath = path; hasExistingConfig = true; - } else { + } + else + { LOG(MODULE_INIT, "Path: " + path + " does not contain a valid config file.") } } // If there's no existing config. - if (hasExistingConfig) { + if (hasExistingConfig) + { // Use the config path found by the checks above SetConfigDirPath(configPath); LOG(MODULE_INIT, "Using " + QV2RAY_CONFIG_DIR + " as the config path.") - } else { + } + else + { // - // Create new config at these dirs, these are default values for each platform. + // Create new config at these dirs, these are default values for each + // platform. #ifdef Q_OS_WIN configPath = currentPathConfig; #else @@ -156,23 +186,26 @@ bool initialiseQv2ray() bool mkpathResult = QDir().mkpath(configPath); // Check if the dirs are write-able - if (mkpathResult && verifyConfigAvaliability(configPath, false)) { - // Found a valid config dir, with write permission, but assume no config is located in it. + if (mkpathResult && verifyConfigAvaliability(configPath, false)) + { + // Found a valid config dir, with write permission, but assume no + // config is located in it. LOG(MODULE_INIT, "Set " + configPath + " as the config path.") SetConfigDirPath(configPath); - if (QFile::exists(QV2RAY_CONFIG_FILE)) { + if (QFile::exists(QV2RAY_CONFIG_FILE)) + { // As we already tried to load config from every possible dir. - // This condition branch (!hasExistingConfig check) holds the fact that - // current config dir, should NOT contain any valid file (at least in the same name) - // It usually means that QV2RAY_CONFIG_FILE here is corrupted, in JSON format. - // Otherwise Qv2ray would have loaded this config already instead of notifying to - // create a new config in this folder. + // This condition branch (!hasExistingConfig check) holds the + // fact that current config dir, should NOT contain any valid + // file (at least in the same name) It usually means that + // QV2RAY_CONFIG_FILE here is corrupted, in JSON format. + // Otherwise Qv2ray would have loaded this config already + // instead of notifying to create a new config in this folder. LOG(MODULE_INIT, "This should not occur: Qv2ray config exists but failed to load.") QvMessageBoxWarn(nullptr, QObject::tr("Failed to initialise Qv2ray"), QObject::tr("Failed to determine the location of config file.") + NEWLINE + - QObject::tr("Qv2ray will now exit.") + NEWLINE + - QObject::tr("Please report if you think it's a bug.")); + QObject::tr("Qv2ray will now exit.") + NEWLINE + QObject::tr("Please report if you think it's a bug.")); return false; } @@ -184,7 +217,9 @@ bool initialiseQv2ray() // Save initial config. SaveGlobalConfig(conf); LOG(MODULE_INIT, "Created initial config file.") - } else { + } + else + { // None of the path above can be used as a dir for storing config. // Even the last folder failed to pass the check. LOG(MODULE_INIT, "FATAL") @@ -192,14 +227,14 @@ bool initialiseQv2ray() QString searchPath = configFilePaths.join(NEWLINE); QvMessageBoxWarn(nullptr, QObject::tr("Cannot Start Qv2ray"), QObject::tr("Cannot find a place to store config files.") + NEWLINE + - QObject::tr("Qv2ray has searched these paths below:") + - NEWLINE + NEWLINE + searchPath + NEWLINE + - QObject::tr("Qv2ray will now exit.")); + QObject::tr("Qv2ray has searched these paths below:") + NEWLINE + NEWLINE + searchPath + NEWLINE + + QObject::tr("Qv2ray will now exit.")); return false; } } - if (!QDir(QV2RAY_GENERATED_DIR).exists()) { + if (!QDir(QV2RAY_GENERATED_DIR).exists()) + { // The dir used to generate final config file, for V2ray interaction. QDir().mkdir(QV2RAY_GENERATED_DIR); LOG(MODULE_INIT, "Created config generation dir at: " + QV2RAY_GENERATED_DIR) @@ -208,7 +243,6 @@ bool initialiseQv2ray() return true; } - int main(int argc, char *argv[]) { #ifndef Q_OS_WIN @@ -228,9 +262,9 @@ int main(int argc, char *argv[]) QvCommandArgParser parser; QString errorMessage; - switch (parser.ParseCommandLine(&errorMessage)) { - case CommandLineOk: - break; + switch (parser.ParseCommandLine(&errorMessage)) + { + case CommandLineOk: break; case CommandLineError: cout << errorMessage.toStdString() << endl; @@ -243,16 +277,16 @@ int main(int argc, char *argv[]) LOG("QV2RAY_BUILD_EXTRA_INFO", QV2RAY_BUILD_EXTRA_INFO) return 0; - case CommandLineHelpRequested: - cout << parser.Parser()->helpText().toStdString() << endl; - return 0; + case CommandLineHelpRequested: cout << parser.Parser()->helpText().toStdString() << endl; return 0; } } #ifdef Q_OS_UNIX // Unix OS root user check. - // Do not use getuid() here since it's installed as owned by the root, someone may accidently setuid to it. - if (!StartupOption.forceRunAsRootUser && geteuid() == 0) { + // Do not use getuid() here since it's installed as owned by the root, + // someone may accidently setuid to it. + if (!StartupOption.forceRunAsRootUser && geteuid() == 0) + { LOG("ERROR", QObject::tr("You cannot run Qv2ray as root, please use --I-just-wanna-run-with-root if you REALLY want to do so.")) LOG("ERROR", QObject::tr(" --> USE IT AT YOUR OWN RISK!")) return 1; @@ -263,9 +297,11 @@ int main(int argc, char *argv[]) // finished: command line parsing LOG("QV2RAY_BUILD_INFO", QV2RAY_BUILD_INFO) LOG("QV2RAY_BUILD_EXTRA_INFO", QV2RAY_BUILD_EXTRA_INFO) - LOG(MODULE_INIT, "Qv2ray " QV2RAY_VERSION_STRING " running on " + QSysInfo::prettyProductName() + " " + QSysInfo::currentCpuArchitecture() + NEWLINE) + LOG(MODULE_INIT, + "Qv2ray " QV2RAY_VERSION_STRING " running on " + QSysInfo::prettyProductName() + " " + QSysInfo::currentCpuArchitecture() + NEWLINE) // - // This line must be called before any other ones, since we are using these values to identify instances. + // This line must be called before any other ones, since we are using these + // values to identify instances. SingleApplication::setApplicationName("Qv2ray"); SingleApplication::setApplicationVersion(QV2RAY_VERSION_STRING); SingleApplication::setApplicationDisplayName("Qv2ray"); @@ -275,7 +311,8 @@ int main(int argc, char *argv[]) // ----------------------------> For debug build... SingleApplication::setApplicationName("Qv2ray - DEBUG"); #endif - SingleApplication _qApp(argc, argv, false, SingleApplication::Mode::User | SingleApplication::Mode::ExcludeAppPath | SingleApplication::Mode::ExcludeAppVersion); + SingleApplication _qApp( + argc, argv, false, SingleApplication::Mode::User | SingleApplication::Mode::ExcludeAppPath | SingleApplication::Mode::ExcludeAppVersion); _qApp.setQuitOnLastWindowClosed(false); // Early initialisation // @@ -288,14 +325,11 @@ int main(int argc, char *argv[]) bool _result_ = _qApp.installTranslator(Qv2rayTranslator.get()); LOG(MODULE_UI, "Installing a tranlator from OS: " + _lang + " -- " + (_result_ ? "OK" : "Failed")) // - LOG("LICENCE", NEWLINE "This program comes with ABSOLUTELY NO WARRANTY." NEWLINE - "This is free software, and you are welcome to redistribute it" NEWLINE - "under certain conditions." NEWLINE NEWLINE - "Copyright (c) 2019-2020 Qv2ray Development Group." NEWLINE - NEWLINE NEWLINE + LOG("LICENCE", NEWLINE + "This program comes with ABSOLUTELY NO WARRANTY." NEWLINE "This is free software, and you are welcome to redistribute it" NEWLINE + "under certain conditions." NEWLINE NEWLINE "Copyright (c) 2019-2020 Qv2ray Development Group." NEWLINE NEWLINE NEWLINE "Libraries that have been used in Qv2ray are listed below (Sorted by date added):" NEWLINE - "Copyright (c) 2020 dridk (@dridk): X2Struct (Apache)" NEWLINE - "Copyright (c) 2011 SCHUTZ Sacha (@dridk): QJsonModel (MIT)" NEWLINE + "Copyright (c) 2020 dridk (@dridk): X2Struct (Apache)" NEWLINE "Copyright (c) 2011 SCHUTZ Sacha (@dridk): QJsonModel (MIT)" NEWLINE "Copyright (c) 2020 Nikolaos Ftylitakis (@ftylitak): QZXing (Apache2)" NEWLINE "Copyright (c) 2016 Singein (@Singein): ScreenShot (MIT)" NEWLINE "Copyright (c) 2016 Nikhil Marathe (@nikhilm): QHttpServer (MIT)" NEWLINE @@ -304,48 +338,50 @@ int main(int argc, char *argv[]) "Copyright (c) 2019 TheWanderingCoel (@TheWanderingCoel): ShadowClash (launchatlogin) (GPLv3)" NEWLINE "Copyright (c) 2020 Ram Pani (@DuckSoft): QvRPCBridge (WTFPL)" NEWLINE "Copyright (c) 2019 ShadowSocks (@shadowsocks): libQtShadowsocks (LGPLv3)" NEWLINE - "Copyright (c) 2015-2020 qBittorrent (Anton Lashkov) (@qBittorrent): speedplotview (GPLv2)" NEWLINE - NEWLINE) + "Copyright (c) 2015-2020 qBittorrent (Anton Lashkov) (@qBittorrent): speedplotview (GPLv2)" NEWLINE NEWLINE) // - LOG(MODULE_INIT, "Qv2ray Start Time: " + QSTRN(QTime::currentTime().msecsSinceStartOfDay())) + LOG(MODULE_INIT, "Qv2ray Start Time: " + QSTRN(QTime::currentTime().msecsSinceStartOfDay())) // #ifdef QT_DEBUG - cout << "WARNING: ============================== This is a debug build, many features are not stable enough. ==============================" << endl; + cout << "WARNING: ============================== This is a debug build, many features are not stable enough. ==============================" + << endl; #endif // // Load the language translation list. auto langs = GetFileList(QDir(":/translations")); - if (langs.empty()) { + if (langs.empty()) + { LOG(MODULE_INIT, "FAILED to find any translations. THIS IS A BUILD ERROR.") - QvMessageBoxWarn(nullptr, QObject::tr("Cannot load languages"), QObject::tr("Qv2ray will continue running, but you cannot change the UI language.")); - } else { - for (auto lang : langs) { - LOG(MODULE_INIT, "Found Translator: " + lang) - } + QvMessageBoxWarn(nullptr, QObject::tr("Cannot load languages"), + QObject::tr("Qv2ray will continue running, but you cannot change the UI language.")); + } + else + { + for (auto lang : langs) { LOG(MODULE_INIT, "Found Translator: " + lang) } } // Qv2ray Initialize, find possible config paths and verify them. - if (!initialiseQv2ray()) { - return -1; - } + if (!initialiseQv2ray()) { return -1; } // Load the config for upgrade, but do not parse it to the struct. auto conf = JsonFromString(StringFromFile(QV2RAY_CONFIG_FILE)); auto confVersion = conf["config_version"].toVariant().toString().toInt(); - if (confVersion > QV2RAY_CONFIG_VERSION) { + if (confVersion > QV2RAY_CONFIG_VERSION) + { // Config version is larger than the current version... // This is rare but it may happen.... QvMessageBoxWarn(nullptr, QObject::tr("Qv2ray Cannot Continue"), QObject::tr("You are running a lower version of Qv2ray compared to the current config file.") + NEWLINE + - QObject::tr("Please check if there's an issue explaining about it.") + NEWLINE + - QObject::tr("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE + - QObject::tr("Qv2ray will now exit.")); + QObject::tr("Please check if there's an issue explaining about it.") + NEWLINE + + QObject::tr("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE + + QObject::tr("Qv2ray will now exit.")); return -2; } - if (confVersion < QV2RAY_CONFIG_VERSION) { + if (confVersion < QV2RAY_CONFIG_VERSION) + { // That is, config file needs to be upgraded. conf = Qv2ray::UpgradeConfig(confVersion, QV2RAY_CONFIG_VERSION, conf); } @@ -356,7 +392,8 @@ int main(int argc, char *argv[]) qApp->removeTranslator(Qv2rayTranslator.get()); LOG(MODULE_INIT, "Removed system translations") - if (confObject.uiConfig.language.isEmpty()) { + if (confObject.uiConfig.language.isEmpty()) + { // Prevent empty. LOG(MODULE_UI, "Setting default UI language to en-US") confObject.uiConfig.language = "en-US"; @@ -364,15 +401,15 @@ int main(int argc, char *argv[]) Qv2rayTranslator = std::move(QvTranslator(confObject.uiConfig.language).pTranslator); - if (qApp->installTranslator(Qv2rayTranslator.get())) { - LOG(MODULE_INIT, "Successfully installed a translator for " + confObject.uiConfig.language) - } else { + if (qApp->installTranslator(Qv2rayTranslator.get())) + { LOG(MODULE_INIT, "Successfully installed a translator for " + confObject.uiConfig.language) } + else + { // Do not translate these..... // If a translator fails to load, pop up a message. - QvMessageBoxWarn( - nullptr, "Translation Failed", - "Cannot load translation for " + confObject.uiConfig.language + ", English is now used." + NEWLINE + NEWLINE + - "Please go to Preferences Window to change language or open an Issue"); + QvMessageBoxWarn(nullptr, "Translation Failed", + "Cannot load translation for " + confObject.uiConfig.language + ", English is now used." + NEWLINE + NEWLINE + + "Please go to Preferences Window to change language or open an Issue"); } // Let's save the config. @@ -383,16 +420,16 @@ int main(int argc, char *argv[]) auto osslCurVersion = QSslSocket::sslLibraryVersionString(); LOG(MODULE_NETWORK, "Current OpenSSL version: " + osslCurVersion) - if (!QSslSocket::supportsSsl()) { + if (!QSslSocket::supportsSsl()) + { LOG(MODULE_NETWORK, "Required OpenSSL version: " + osslReqVersion) LOG(MODULE_NETWORK, "OpenSSL library MISSING, Quitting.") QvMessageBoxWarn(nullptr, QObject::tr("Dependency Missing"), QObject::tr("Cannot find openssl libs") + NEWLINE + - QObject::tr("This could be caused by a missing of `openssl` package in your system.") + NEWLINE + - QObject::tr("If you are using an AppImage from Github Action, please report a bug.") + NEWLINE + NEWLINE + - QObject::tr("Technical Details") + NEWLINE + - "OSsl.Rq.V=" + osslReqVersion + NEWLINE + - "OSsl.Cr.V=" + osslCurVersion); + QObject::tr("This could be caused by a missing of `openssl` package in your system.") + NEWLINE + + QObject::tr("If you are using an AppImage from Github Action, please report a bug.") + NEWLINE + NEWLINE + + QObject::tr("Technical Details") + NEWLINE + "OSsl.Rq.V=" + osslReqVersion + NEWLINE + + "OSsl.Cr.V=" + osslCurVersion); return -3; } @@ -406,7 +443,8 @@ int main(int argc, char *argv[]) #ifdef QV2RAY_USE_BUILTIN_DARKTHEME LOG(MODULE_UI, "Using built-in theme.") - if (confObject.uiConfig.useDarkTheme) { + if (confObject.uiConfig.useDarkTheme) + { LOG(MODULE_UI, " --> Using built-in dark theme.") // From https://forum.qt.io/topic/101391/windows-10-dark-theme/4 _qApp.setStyle("Fusion"); @@ -441,7 +479,8 @@ int main(int argc, char *argv[]) QStringList themes = QStyleFactory::keys(); //_qApp.setDesktopFileName("qv2ray.desktop"); - if (themes.contains(confObject.uiConfig.theme)) { + if (themes.contains(confObject.uiConfig.theme)) + { _qApp.setStyle(confObject.uiConfig.theme); LOG(MODULE_INIT + " " + MODULE_UI, "Setting Qv2ray UI themes: " + confObject.uiConfig.theme) } @@ -449,7 +488,8 @@ int main(int argc, char *argv[]) #endif #ifndef QT_DEBUG - try { + try + { #endif //_qApp.setAttribute(Qt::AA_DontUseNativeMenuBar); // Initialise Connection Handler @@ -465,23 +505,19 @@ int main(int argc, char *argv[]) // Handler for session logout, shutdown, etc. // Will not block. QGuiApplication::setFallbackSessionManagementEnabled(false); - QObject::connect(&_qApp, &QGuiApplication::commitDataRequest, []() { - LOG(MODULE_INIT, "Quit triggered by session manager.") - }); + QObject::connect(&_qApp, &QGuiApplication::commitDataRequest, []() { LOG(MODULE_INIT, "Quit triggered by session manager.") }); #ifndef Q_OS_WIN - signal(SIGUSR1, [](int) { - emit MainWindow::mwInstance->Connect(); - }); - signal(SIGUSR2, [](int) { - emit MainWindow::mwInstance->DisConnect(); - }); + signal(SIGUSR1, [](int) { emit MainWindow::mwInstance->Connect(); }); + signal(SIGUSR2, [](int) { emit MainWindow::mwInstance->DisConnect(); }); #endif auto rcode = _qApp.exec(); delete ConnectionManager; LOG(MODULE_INIT, "Quitting normally") return rcode; #ifndef QT_DEBUG - } catch (...) { + } + catch (...) + { QvMessageBoxWarn(nullptr, "ERROR", "There's something wrong happened and Qv2ray will quit now."); LOG(MODULE_INIT, "EXCEPTION THROWN: " __FILE__) return -99; diff --git a/src/ui/editors/w_InboundEditor.cpp b/src/ui/editors/w_InboundEditor.cpp index 5c3d1218..2d95cfb8 100644 --- a/src/ui/editors/w_InboundEditor.cpp +++ b/src/ui/editors/w_InboundEditor.cpp @@ -1,36 +1,45 @@ #include "w_InboundEditor.hpp" -#include "core/CoreUtils.hpp" #include "common/QvHelpers.hpp" +#include "core/CoreUtils.hpp" #include "core/connection/ConnectionIO.hpp" static bool isLoading = false; -#define CHECKLOADING if(isLoading) return; +#define CHECKLOADING \ + if (isLoading) return; -InboundEditor::InboundEditor(INBOUND root, QWidget *parent) : - QDialog(parent), - original(root) +InboundEditor::InboundEditor(INBOUND root, QWidget *parent) : QDialog(parent), original(root) { QvMessageBusConnect(InboundEditor); setupUi(this); this->root = root; auto inboundType = root["protocol"].toString(); allocate = root["allocate"].toObject(); - sniffing = root["sniffing"].toObject(); + sniffing = root["sniffing"].toObject(); - if (inboundType == "http") { - httpSettings = root["settings"].toObject(); - } else if (inboundType == "socks") { + if (inboundType == "http") { httpSettings = root["settings"].toObject(); } + else if (inboundType == "socks") + { socksSettings = root["settings"].toObject(); - } else if (inboundType == "dokodemo-door") { + } + else if (inboundType == "dokodemo-door") + { dokoSettings = root["settings"].toObject(); - } else if (inboundType == "mtproto") { + } + else if (inboundType == "mtproto") + { mtSettings = root["settings"].toObject(); - } else { - if (!root["protocol"].toString().isEmpty()) { + } + else + { + if (!root["protocol"].toString().isEmpty()) + { LOG(MODULE_UI, "Unsupported inbound type: " + inboundType) - QvMessageBoxWarn(this, tr("Inbound type not supported"), tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" + - tr("Inbound: ") + inboundType); - } else { + QvMessageBoxWarn(this, tr("Inbound type not supported"), + tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" + + tr("Inbound: ") + inboundType); + } + else + { LOG(MODULE_UI, "Creating new inbound config") root["protocol"] = inboundType = "http"; } @@ -41,10 +50,9 @@ InboundEditor::InboundEditor(INBOUND root, QWidget *parent) : QvMessageBusSlotImpl(InboundEditor) { - switch (msg) { - MBShowDefaultImpl\ - MBHideDefaultImpl\ - MBRetranslateDefaultImpl\ + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -59,27 +67,28 @@ INBOUND InboundEditor::GenerateNewRoot() INBOUND _newRoot = root; auto inboundType = root["protocol"].toString(); - if (inboundType.isNull() || inboundType.isEmpty()) { - inboundType = "http"; - } + if (inboundType.isNull() || inboundType.isEmpty()) { inboundType = "http"; } - if (inboundType == "http") { + if (inboundType == "http") + { // Remove useless, misleading 'accounts' array. - if (httpAccountListBox->count() == 0) { - httpSettings.remove("accounts"); - } + if (httpAccountListBox->count() == 0) { httpSettings.remove("accounts"); } _newRoot["settings"] = httpSettings; - } else if (inboundType == "socks") { + } + else if (inboundType == "socks") + { // See above - if (socksAccountListBox->count() == 0) { - socksSettings.remove("accounts"); - } + if (socksAccountListBox->count() == 0) { socksSettings.remove("accounts"); } _newRoot["settings"] = socksSettings; - } else if (inboundType == "dokodemo-door") { + } + else if (inboundType == "dokodemo-door") + { _newRoot["settings"] = dokoSettings; - } else if (inboundType == "mtproto") { + } + else if (inboundType == "mtproto") + { _newRoot["settings"] = mtSettings; } @@ -102,7 +111,8 @@ void InboundEditor::LoadUIData() // destOverrideList->setEnabled(sniffing["enabled"].toBool()); - for (auto item : sniffing["destOverride"].toArray()) { + for (auto item : sniffing["destOverride"].toArray()) + { if (item.toString().toLower() == "http") destOverrideList->item(0)->setCheckState(Qt::Checked); if (item.toString().toLower() == "tls") destOverrideList->item(1)->setCheckState(Qt::Checked); @@ -118,9 +128,8 @@ void InboundEditor::LoadUIData() httpUserLevelSB->setValue(httpSettings["userLevel"].toInt()); httpAccountListBox->clear(); - for (auto user : httpSettings["accounts"].toArray()) { - httpAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString()); - } + for (auto user : httpSettings["accounts"].toArray()) + { httpAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString()); } // SOCKS socksAuthCombo->setCurrentText(socksSettings["auth"].toString()); @@ -128,9 +137,8 @@ void InboundEditor::LoadUIData() socksUDPIPAddrTxt->setText(socksSettings["ip"].toString()); socksUserLevelSB->setValue(socksSettings["userLevel"].toInt()); - for (auto user : socksSettings["accounts"].toArray()) { - socksAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString()); - } + for (auto user : socksSettings["accounts"].toArray()) + { socksAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString()); } // Dokodemo-Door dokoFollowRedirectCB->setChecked(dokoSettings["followRedirect"].toBool()); @@ -190,15 +198,18 @@ void InboundEditor::on_httpRemoveUserBtn_clicked() { CHECKLOADING - if (httpAccountListBox->currentRow() != -1) { + if (httpAccountListBox->currentRow() != -1) + { auto item = httpAccountListBox->currentItem(); auto list = httpSettings["accounts"].toArray(); - for (int i = 0 ; i < list.count(); i++) { + for (int i = 0; i < list.count(); i++) + { auto user = list[i].toObject(); auto entry = user["user"].toString() + ":" + user["pass"].toString(); - if (entry == item->text().trimmed()) { + if (entry == item->text().trimmed()) + { list.removeAt(i); httpSettings["accounts"] = list; LOG(MODULE_UI, "Removed http inbound user " + entry) @@ -206,8 +217,11 @@ void InboundEditor::on_httpRemoveUserBtn_clicked() } } - //QvMessageBox(this, tr("Removing a user"), tr("No user has been removed. Why?")); - } else { + // QvMessageBox(this, tr("Removing a user"), tr("No user has been + // removed. Why?")); + } + else + { QvMessageBoxWarn(this, tr("Removing a user"), tr("You haven't selected a user yet.")); } } @@ -220,10 +234,12 @@ void InboundEditor::on_httpAddUserBtn_clicked() // auto list = httpSettings["accounts"].toArray(); - for (int i = 0 ; i < list.count(); i++) { + for (int i = 0; i < list.count(); i++) + { auto _user = list[i].toObject(); - if (_user["user"].toString() == user) { + if (_user["user"].toString() == user) + { QvMessageBoxWarn(this, tr("Add a user"), tr("This user exists already.")); return; } @@ -243,15 +259,18 @@ void InboundEditor::on_socksRemoveUserBtn_clicked() { CHECKLOADING - if (socksAccountListBox->currentRow() != -1) { + if (socksAccountListBox->currentRow() != -1) + { auto item = socksAccountListBox->currentItem(); auto list = socksSettings["accounts"].toArray(); - for (int i = 0 ; i < list.count(); i++) { + for (int i = 0; i < list.count(); i++) + { auto user = list[i].toObject(); auto entry = user["user"].toString() + ":" + user["pass"].toString(); - if (entry == item->text().trimmed()) { + if (entry == item->text().trimmed()) + { list.removeAt(i); socksSettings["accounts"] = list; LOG(MODULE_UI, "Removed http inbound user " + entry) @@ -259,7 +278,9 @@ void InboundEditor::on_socksRemoveUserBtn_clicked() return; } } - } else { + } + else + { QvMessageBoxWarn(this, tr("Removing a user"), tr("You haven't selected a user yet.")); } } @@ -272,10 +293,12 @@ void InboundEditor::on_socksAddUserBtn_clicked() // auto list = socksSettings["accounts"].toArray(); - for (int i = 0 ; i < list.count(); i++) { + for (int i = 0; i < list.count(); i++) + { auto _user = list[i].toObject(); - if (_user["user"].toString() == user) { + if (_user["user"].toString() == user) + { QvMessageBoxWarn(this, tr("Add a user"), tr("This user exists already.")); return; } @@ -322,12 +345,11 @@ void InboundEditor::on_destOverrideList_itemChanged(QListWidgetItem *item) Q_UNUSED(item) QJsonArray list; - for (int i = 0; i < destOverrideList->count(); i++) { + for (int i = 0; i < destOverrideList->count(); i++) + { auto _item = destOverrideList->item(i); - if (_item->checkState() == Qt::Checked) { - list.append(_item->text().toLower()); - } + if (_item->checkState() == Qt::Checked) { list.append(_item->text().toLower()); } } sniffing["destOverride"] = list; @@ -360,7 +382,7 @@ void InboundEditor::on_dokoIPAddrTxt_textEdited(const QString &arg1) void InboundEditor::on_dokoPortSB_valueChanged(int arg1) { CHECKLOADING - dokoSettings["port"] = arg1; + dokoSettings["port"] = arg1; } void InboundEditor::on_dokoTCPCB_stateChanged(int arg1) @@ -461,5 +483,5 @@ void InboundEditor::on_inboundPortTxt_textEdited(const QString &arg1) void InboundEditor::on_socksAuthCombo_currentIndexChanged(const QString &arg1) { CHECKLOADING - socksSettings["auth"] = arg1.toLower(); + socksSettings["auth"] = arg1.toLower(); } diff --git a/src/ui/editors/w_InboundEditor.hpp b/src/ui/editors/w_InboundEditor.hpp index a5d81c8a..be23aed7 100644 --- a/src/ui/editors/w_InboundEditor.hpp +++ b/src/ui/editors/w_InboundEditor.hpp @@ -1,97 +1,100 @@ #pragma once +#include "base/Qv2rayBase.hpp" +#include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_InboundEditor.h" + #include #include #include -#include "ui_w_InboundEditor.h" -#include "base/Qv2rayBase.hpp" -#include "ui/messaging/QvMessageBus.hpp" -class InboundEditor : public QDialog, private Ui::InboundEditor +class InboundEditor + : public QDialog + , private Ui::InboundEditor { - Q_OBJECT + Q_OBJECT - public: - explicit InboundEditor(INBOUND root, QWidget *parent = nullptr); - ~InboundEditor(); - INBOUND OpenEditor(); - public slots: - QvMessageBusSlotDecl + public: + explicit InboundEditor(INBOUND root, QWidget *parent = nullptr); + ~InboundEditor(); + INBOUND OpenEditor(); + public slots: + QvMessageBusSlotDecl; - private slots: - void on_inboundProtocolCombo_currentIndexChanged(const QString &arg1); + private slots: + void on_inboundProtocolCombo_currentIndexChanged(const QString &arg1); - void on_inboundProtocolCombo_currentIndexChanged(int index); + void on_inboundProtocolCombo_currentIndexChanged(int index); - void on_inboundTagTxt_textEdited(const QString &arg1); + void on_inboundTagTxt_textEdited(const QString &arg1); - void on_httpTimeoutSpinBox_valueChanged(int arg1); + void on_httpTimeoutSpinBox_valueChanged(int arg1); - void on_httpTransparentCB_stateChanged(int arg1); + void on_httpTransparentCB_stateChanged(int arg1); - void on_httpUserLevelSB_valueChanged(int arg1); + void on_httpUserLevelSB_valueChanged(int arg1); - void on_httpRemoveUserBtn_clicked(); + void on_httpRemoveUserBtn_clicked(); - void on_httpAddUserBtn_clicked(); + void on_httpAddUserBtn_clicked(); - void on_strategyCombo_currentIndexChanged(const QString &arg1); + void on_strategyCombo_currentIndexChanged(const QString &arg1); - void on_refreshNumberBox_valueChanged(int arg1); + void on_refreshNumberBox_valueChanged(int arg1); - void on_concurrencyNumberBox_valueChanged(int arg1); + void on_concurrencyNumberBox_valueChanged(int arg1); - void on_enableSniffingCB_stateChanged(int arg1); + void on_enableSniffingCB_stateChanged(int arg1); - void on_destOverrideList_itemChanged(QListWidgetItem *item); + void on_destOverrideList_itemChanged(QListWidgetItem *item); - void on_socksUDPCB_stateChanged(int arg1); + void on_socksUDPCB_stateChanged(int arg1); - void on_socksUDPIPAddrTxt_textEdited(const QString &arg1); + void on_socksUDPIPAddrTxt_textEdited(const QString &arg1); - void on_socksUserLevelSB_valueChanged(int arg1); + void on_socksUserLevelSB_valueChanged(int arg1); - void on_socksRemoveUserBtn_clicked(); + void on_socksRemoveUserBtn_clicked(); - void on_socksAddUserBtn_clicked(); + void on_socksAddUserBtn_clicked(); - void on_dokoIPAddrTxt_textEdited(const QString &arg1); + void on_dokoIPAddrTxt_textEdited(const QString &arg1); - void on_dokoPortSB_valueChanged(int arg1); + void on_dokoPortSB_valueChanged(int arg1); - void on_dokoTCPCB_stateChanged(int arg1); + void on_dokoTCPCB_stateChanged(int arg1); - void on_dokoUDPCB_stateChanged(int arg1); + void on_dokoUDPCB_stateChanged(int arg1); - void on_dokoTimeoutSB_valueChanged(int arg1); + void on_dokoTimeoutSB_valueChanged(int arg1); - void on_dokoFollowRedirectCB_stateChanged(int arg1); + void on_dokoFollowRedirectCB_stateChanged(int arg1); - void on_dokoUserLevelSB_valueChanged(int arg1); + void on_dokoUserLevelSB_valueChanged(int arg1); - void on_mtEMailTxt_textEdited(const QString &arg1); + void on_mtEMailTxt_textEdited(const QString &arg1); - void on_mtSecretTxt_textEdited(const QString &arg1); + void on_mtSecretTxt_textEdited(const QString &arg1); - void on_mtUserLevelSB_valueChanged(int arg1); + void on_mtUserLevelSB_valueChanged(int arg1); - void on_inboundHostTxt_textEdited(const QString &arg1); + void on_inboundHostTxt_textEdited(const QString &arg1); - void on_inboundPortTxt_textEdited(const QString &arg1); + void on_inboundPortTxt_textEdited(const QString &arg1); - void on_socksAuthCombo_currentIndexChanged(const QString &arg1); + void on_socksAuthCombo_currentIndexChanged(const QString &arg1); - private: - INBOUND GenerateNewRoot(); - void LoadUIData(); - INBOUND original; - INBOUND root; - // - QJsonObject httpSettings; - QJsonObject socksSettings; - QJsonObject mtSettings; - QJsonObject dokoSettings; - // - QJsonObject sniffing; - QJsonObject allocate; + private: + INBOUND GenerateNewRoot(); + void LoadUIData(); + INBOUND original; + INBOUND root; + // + QJsonObject httpSettings; + QJsonObject socksSettings; + QJsonObject mtSettings; + QJsonObject dokoSettings; + // + QJsonObject sniffing; + QJsonObject allocate; }; diff --git a/src/ui/editors/w_JsonEditor.cpp b/src/ui/editors/w_JsonEditor.cpp index fa7c3b65..cf5c414d 100644 --- a/src/ui/editors/w_JsonEditor.cpp +++ b/src/ui/editors/w_JsonEditor.cpp @@ -2,20 +2,22 @@ #include "common/QvHelpers.hpp" -JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) : - QDialog(parent) +JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) : QDialog(parent) { QvMessageBusConnect(JsonEditor); setupUi(this); original = rootObject; final = rootObject; - QString jsonString = JsonToString(rootObject); + QString jsonString = JsonToString(rootObject); - if (VerifyJsonString(jsonString).isEmpty()) { + if (VerifyJsonString(jsonString).isEmpty()) + { LOG(MODULE_UI, "Begin loading Json Model") jsonTree->setModel(&model); model.loadJson(QJsonDocument(rootObject).toJson()); - } else { + } + else + { QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"), tr("Original Json may contain syntax errors. Json tree is disabled.")); } @@ -26,10 +28,9 @@ JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) : QvMessageBusSlotImpl(JsonEditor) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -38,7 +39,8 @@ QJsonObject JsonEditor::OpenEditor() int resultCode = this->exec(); auto string = jsonEditor->toPlainText(); - while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) { + while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) + { QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"), tr("You must correct these errors before continue.")); resultCode = this->exec(); string = jsonEditor->toPlainText(); @@ -57,13 +59,16 @@ void JsonEditor::on_jsonEditor_textChanged() auto VerifyResult = VerifyJsonString(string); jsonValidateStatus->setText(VerifyResult); - if (VerifyResult.isEmpty()) { + if (VerifyResult.isEmpty()) + { BLACK(jsonEditor) final = JsonFromString(string); model.loadJson(QJsonDocument(final).toJson()); jsonTree->expandAll(); jsonTree->resizeColumnToContents(0); - } else { + } + else + { RED(jsonEditor) } } @@ -74,10 +79,13 @@ void JsonEditor::on_formatJsonBtn_clicked() auto VerifyResult = VerifyJsonString(string); jsonValidateStatus->setText(VerifyResult); - if (VerifyResult.isEmpty()) { + if (VerifyResult.isEmpty()) + { BLACK(jsonEditor) jsonEditor->setPlainText(JsonToString(JsonFromString(string))); - } else { + } + else + { RED(jsonEditor) QvMessageBoxWarn(this, tr("Syntax Errors"), tr("Please fix the JSON errors before continue")); } diff --git a/src/ui/editors/w_JsonEditor.hpp b/src/ui/editors/w_JsonEditor.hpp index b4d98f2b..afdf0b5f 100644 --- a/src/ui/editors/w_JsonEditor.hpp +++ b/src/ui/editors/w_JsonEditor.hpp @@ -1,30 +1,33 @@ #pragma once +#include "base/Qv2rayBase.hpp" +#include "common/QJsonModel.hpp" +#include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_JsonEditor.h" + #include #include -#include "common/QJsonModel.hpp" -#include "base/Qv2rayBase.hpp" -#include "ui_w_JsonEditor.h" -#include "ui/messaging/QvMessageBus.hpp" -class JsonEditor : public QDialog, private Ui::JsonEditor +class JsonEditor + : public QDialog + , private Ui::JsonEditor { - Q_OBJECT + Q_OBJECT - public: - explicit JsonEditor(QJsonObject rootObject, QWidget *parent = nullptr); - ~JsonEditor(); - QJsonObject OpenEditor(); - public slots: - QvMessageBusSlotDecl + public: + explicit JsonEditor(QJsonObject rootObject, QWidget *parent = nullptr); + ~JsonEditor(); + QJsonObject OpenEditor(); + public slots: + QvMessageBusSlotDecl; - private slots: - void on_jsonEditor_textChanged(); + private slots: + void on_jsonEditor_textChanged(); - void on_formatJsonBtn_clicked(); + void on_formatJsonBtn_clicked(); - private: - QJsonModel model; - QJsonObject original; - QJsonObject final; + private: + QJsonModel model; + QJsonObject original; + QJsonObject final; }; diff --git a/src/ui/editors/w_OutboundEditor.cpp b/src/ui/editors/w_OutboundEditor.cpp index da262dc5..14bacfa7 100644 --- a/src/ui/editors/w_OutboundEditor.cpp +++ b/src/ui/editors/w_OutboundEditor.cpp @@ -1,20 +1,16 @@ #include +#include "w_OutboundEditor.hpp" + +#include "core/connection/Generation.hpp" +#include "ui/editors/w_JsonEditor.hpp" +#include "ui/editors/w_RoutesEditor.hpp" +#include "ui/w_MainWindow.hpp" + #include #include #include -#include "w_OutboundEditor.hpp" -#include "ui/w_MainWindow.hpp" -#include "ui/editors/w_JsonEditor.hpp" -#include "ui/editors/w_RoutesEditor.hpp" -#include "core/connection/Generation.hpp" - -OutboundEditor::OutboundEditor(QWidget *parent) - : QDialog(parent), - Tag(""), - Mux(), - vmess(), - shadowsocks() +OutboundEditor::OutboundEditor(QWidget *parent) : QDialog(parent), Tag(""), Mux(), vmess(), shadowsocks() { QvMessageBusConnect(OutboundEditor); setupUi(this); @@ -40,10 +36,9 @@ OutboundEditor::OutboundEditor(QWidget *parent) QvMessageBusSlotImpl(OutboundEditor) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -57,20 +52,28 @@ OutboundEditor::OutboundEditor(OUTBOUND outboundEntry, QWidget *parent) : Outbou useFProxy = outboundEntry[QV2RAY_USE_FPROXY_KEY].toBool(false); ssWidget->SetStreamObject(StructFromJsonString(JsonToString(outboundEntry["streamSettings"].toObject()))); - if (OutboundType == "vmess") { - vmess = StructFromJsonString(JsonToString(outboundEntry["settings"].toObject()["vnext"].toArray().first().toObject())); + if (OutboundType == "vmess") + { + vmess = + StructFromJsonString(JsonToString(outboundEntry["settings"].toObject()["vnext"].toArray().first().toObject())); shadowsocks.port = vmess.port; shadowsocks.address = vmess.address; socks.address = vmess.address; socks.port = vmess.port; - } else if (OutboundType == "shadowsocks") { - shadowsocks = StructFromJsonString(JsonToString(outboundEntry["settings"].toObject()["servers"].toArray().first().toObject())); + } + else if (OutboundType == "shadowsocks") + { + shadowsocks = StructFromJsonString( + JsonToString(outboundEntry["settings"].toObject()["servers"].toArray().first().toObject())); vmess.address = shadowsocks.address; vmess.port = shadowsocks.port; socks.address = shadowsocks.address; socks.port = shadowsocks.port; - } else if (OutboundType == "socks") { - socks = StructFromJsonString(JsonToString(outboundEntry["settings"].toObject()["servers"].toArray().first().toObject())); + } + else if (OutboundType == "socks") + { + socks = + StructFromJsonString(JsonToString(outboundEntry["settings"].toObject()["servers"].toArray().first().toObject())); vmess.address = socks.address; vmess.port = socks.port; shadowsocks.address = socks.address; @@ -81,7 +84,6 @@ OutboundEditor::OutboundEditor(OUTBOUND outboundEntry, QWidget *parent) : Outbou Result = GenerateConnectionJson(); } - OutboundEditor::~OutboundEditor() { } @@ -106,18 +108,23 @@ OUTBOUND OutboundEditor::GenerateConnectionJson() OUTBOUNDSETTING settings; auto streaming = GetRootObject(ssWidget->GetStreamSettings()); - if (OutboundType == "vmess") { + if (OutboundType == "vmess") + { // VMess is only a ServerObject, and we need an array { "vnext": [] } QJsonArray vnext; vnext.append(GetRootObject(vmess)); settings.insert("vnext", vnext); - } else if (OutboundType == "shadowsocks") { + } + else if (OutboundType == "shadowsocks") + { streaming = QJsonObject(); LOG(MODULE_CONNECTION, "Shadowsocks outbound does not need StreamSettings.") QJsonArray servers; servers.append(GetRootObject(shadowsocks)); settings["servers"] = servers; - } else if (OutboundType == "socks") { + } + else if (OutboundType == "socks") + { streaming = QJsonObject(); LOG(MODULE_CONNECTION, "Socks outbound does not need StreamSettings.") QJsonArray servers; @@ -132,14 +139,17 @@ OUTBOUND OutboundEditor::GenerateConnectionJson() void OutboundEditor::ReloadGUI() { - if (OutboundType == "vmess") { + if (OutboundType == "vmess") + { outBoundTypeCombo->setCurrentIndex(0); ipLineEdit->setText(vmess.address); portLineEdit->setText(QSTRN(vmess.port)); idLineEdit->setText(vmess.users.front().id); alterLineEdit->setValue(vmess.users.front().alterId); securityCombo->setCurrentText(vmess.users.front().security); - } else if (OutboundType == "shadowsocks") { + } + else if (OutboundType == "shadowsocks") + { outBoundTypeCombo->setCurrentIndex(1); // ShadowSocks Configs ipLineEdit->setText(shadowsocks.address); @@ -149,7 +159,9 @@ void OutboundEditor::ReloadGUI() ss_otaCheckBox->setChecked(shadowsocks.ota); ss_passwordTxt->setText(shadowsocks.password); ss_encryptionMethod->setCurrentText(shadowsocks.method); - } else if (OutboundType == "socks") { + } + else if (OutboundType == "socks") + { outBoundTypeCombo->setCurrentIndex(2); ipLineEdit->setText(socks.address); portLineEdit->setText(QSTRN(socks.port)); @@ -165,7 +177,6 @@ void OutboundEditor::ReloadGUI() muxConcurrencyTxt->setValue(Mux["concurrency"].toInt()); } - void OutboundEditor::on_buttonBox_accepted() { Result = GenerateConnectionJson(); @@ -180,7 +191,8 @@ void OutboundEditor::on_ipLineEdit_textEdited(const QString &arg1) void OutboundEditor::on_portLineEdit_textEdited(const QString &arg1) { - if (arg1 != "") { + if (arg1 != "") + { vmess.port = arg1.toInt(); shadowsocks.port = arg1.toInt(); socks.port = arg1.toInt(); diff --git a/src/ui/editors/w_OutboundEditor.hpp b/src/ui/editors/w_OutboundEditor.hpp index d8fc403c..153076e0 100644 --- a/src/ui/editors/w_OutboundEditor.hpp +++ b/src/ui/editors/w_OutboundEditor.hpp @@ -1,76 +1,79 @@ #pragma once -#include -#include #include "base/Qv2rayBase.hpp" -#include "ui_w_OutboundEditor.h" -#include "ui/widgets/StreamSettingsWidget.hpp" #include "ui/messaging/QvMessageBus.hpp" +#include "ui/widgets/StreamSettingsWidget.hpp" +#include "ui_w_OutboundEditor.h" -class OutboundEditor : public QDialog, private Ui::OutboundEditor +#include +#include + +class OutboundEditor + : public QDialog + , private Ui::OutboundEditor { - Q_OBJECT - public: - explicit OutboundEditor(QWidget *parent = nullptr); - explicit OutboundEditor(OUTBOUND outboundEntry, QWidget *parent = nullptr); - ~OutboundEditor(); - OUTBOUND OpenEditor(); - QString GetFriendlyName(); - public slots: - QvMessageBusSlotDecl - signals: - void s_reload_config(bool need_restart); - private slots: - void on_buttonBox_accepted(); + Q_OBJECT + public: + explicit OutboundEditor(QWidget *parent = nullptr); + explicit OutboundEditor(OUTBOUND outboundEntry, QWidget *parent = nullptr); + ~OutboundEditor(); + OUTBOUND OpenEditor(); + QString GetFriendlyName(); + public slots: + QvMessageBusSlotDecl; + signals: + void s_reload_config(bool need_restart); + private slots: + void on_buttonBox_accepted(); - void on_ipLineEdit_textEdited(const QString &arg1); + void on_ipLineEdit_textEdited(const QString &arg1); - void on_portLineEdit_textEdited(const QString &arg1); + void on_portLineEdit_textEdited(const QString &arg1); - void on_idLineEdit_textEdited(const QString &arg1); + void on_idLineEdit_textEdited(const QString &arg1); - void on_tagTxt_textEdited(const QString &arg1); + void on_tagTxt_textEdited(const QString &arg1); - void on_muxEnabledCB_stateChanged(int arg1); + void on_muxEnabledCB_stateChanged(int arg1); - void on_muxConcurrencyTxt_valueChanged(int arg1); + void on_muxConcurrencyTxt_valueChanged(int arg1); - void on_alterLineEdit_valueChanged(int arg1); + void on_alterLineEdit_valueChanged(int arg1); - void on_useFPCB_stateChanged(int arg1); + void on_useFPCB_stateChanged(int arg1); - void on_outBoundTypeCombo_currentIndexChanged(int index); + void on_outBoundTypeCombo_currentIndexChanged(int index); - void on_ss_emailTxt_textEdited(const QString &arg1); + void on_ss_emailTxt_textEdited(const QString &arg1); - void on_ss_passwordTxt_textEdited(const QString &arg1); + void on_ss_passwordTxt_textEdited(const QString &arg1); - void on_ss_encryptionMethod_currentIndexChanged(const QString &arg1); + void on_ss_encryptionMethod_currentIndexChanged(const QString &arg1); - void on_ss_levelSpin_valueChanged(int arg1); + void on_ss_levelSpin_valueChanged(int arg1); - void on_ss_otaCheckBox_stateChanged(int arg1); + void on_ss_otaCheckBox_stateChanged(int arg1); - void on_socks_UserNameTxt_textEdited(const QString &arg1); + void on_socks_UserNameTxt_textEdited(const QString &arg1); - void on_socks_PasswordTxt_textEdited(const QString &arg1); + void on_socks_PasswordTxt_textEdited(const QString &arg1); - void on_securityCombo_currentIndexChanged(const QString &arg1); + void on_securityCombo_currentIndexChanged(const QString &arg1); - private: - QString Tag; - void ReloadGUI(); - bool useFProxy; - OUTBOUND GenerateConnectionJson(); - OUTBOUND Original; - OUTBOUND Result; - QJsonObject Mux; - // - // Connection Configs - QString OutboundType; - // - VMessServerObject vmess; - ShadowSocksServerObject shadowsocks; - SocksServerObject socks; - // - StreamSettingsWidget *ssWidget; + private: + QString Tag; + void ReloadGUI(); + bool useFProxy; + OUTBOUND GenerateConnectionJson(); + OUTBOUND Original; + OUTBOUND Result; + QJsonObject Mux; + // + // Connection Configs + QString OutboundType; + // + VMessServerObject vmess; + ShadowSocksServerObject shadowsocks; + SocksServerObject socks; + // + StreamSettingsWidget *ssWidget; }; diff --git a/src/ui/editors/w_RoutesEditor.cpp b/src/ui/editors/w_RoutesEditor.cpp index 1722f773..bd24045a 100644 --- a/src/ui/editors/w_RoutesEditor.cpp +++ b/src/ui/editors/w_RoutesEditor.cpp @@ -1,36 +1,40 @@ // WARNING -// Since it's required for *extra.cpp to know the content of those macros defined below. -// We include this CPP file instead of the proper HPP file. Adding #pragma once to prevent duplicate function instances +// Since it's required for *extra.cpp to know the content of those macros +// defined below. We include this CPP file instead of the proper HPP file. +// Adding #pragma once to prevent duplicate function instances #pragma once #include "w_RoutesEditor.hpp" -#include "core/connection/ConnectionIO.hpp" -#include "core/connection/Generation.hpp" -#include "w_OutboundEditor.hpp" -#include "w_JsonEditor.hpp" -#include "w_InboundEditor.hpp" -#include "ui/w_ImportConfig.hpp" -#include "core/CoreUtils.hpp" -#include "ui/models/RuleNodeModel.hpp" -#include "ui/models/InboundNodeModel.hpp" -#include "ui/models/OutboundNodeModel.hpp" - -#include "NodeStyle.hpp" #include "FlowView.hpp" #include "FlowViewStyle.hpp" +#include "NodeStyle.hpp" +#include "core/CoreUtils.hpp" +#include "core/connection/ConnectionIO.hpp" +#include "core/connection/Generation.hpp" +#include "ui/models/InboundNodeModel.hpp" +#include "ui/models/OutboundNodeModel.hpp" +#include "ui/models/RuleNodeModel.hpp" +#include "ui/w_ImportConfig.hpp" +#include "w_InboundEditor.hpp" +#include "w_JsonEditor.hpp" +#include "w_OutboundEditor.hpp" using QtNodes::FlowView; using namespace Qv2ray::ui::nodemodels; static bool isLoading = false; #define CurrentRule this->rules[this->currentRuleTag] -#define LOADINGCHECK if(isLoading) return; -#define GetFirstNodeData(node, nodeModel, dataModel) (static_cast(static_cast((node).nodeDataModel())->outData(0).get())) +#define LOADINGCHECK \ + if (isLoading) return; +#define GetFirstNodeData(node, nodeModel, dataModel) \ + (static_cast(static_cast((node).nodeDataModel())->outData(0).get())) -#define CHECKEMPTYRULES if (this->rules.isEmpty()) { \ - LOG(MODULE_UI, "No rules currently, we add one.") \ - AddNewRule(); \ +#define CHECKEMPTYRULES \ + if (this->rules.isEmpty()) \ + { \ + LOG(MODULE_UI, "No rules currently, we add one.") \ + AddNewRule(); \ } #define GRAPH_GLOBAL_OFFSET_X -80 @@ -41,18 +45,25 @@ static bool isLoading = false; void RouteEditor::SetupNodeWidget() { - if (GlobalConfig.uiConfig.useDarkTheme) { - ConnectionStyle::setConnectionStyle(R"({"ConnectionStyle": {"ConstructionColor": "gray","NormalColor": "black","SelectedColor": "gray", + if (GlobalConfig.uiConfig.useDarkTheme) + { + ConnectionStyle::setConnectionStyle( + R"({"ConnectionStyle": {"ConstructionColor": "gray","NormalColor": "black","SelectedColor": "gray", "SelectedHaloColor": "deepskyblue","HoveredColor": "deepskyblue","LineWidth": 3.0, "ConstructionLineWidth": 2.0,"PointDiameter": 10.0,"UseDataDefinedColors": true}})"); - } else { - QtNodes::NodeStyle::setNodeStyle(R"({"NodeStyle": {"NormalBoundaryColor": "darkgray","SelectedBoundaryColor": "deepskyblue", + } + else + { + QtNodes::NodeStyle::setNodeStyle( + R"({"NodeStyle": {"NormalBoundaryColor": "darkgray","SelectedBoundaryColor": "deepskyblue", "GradientColor0": "mintcream","GradientColor1": "mintcream","GradientColor2": "mintcream", "GradientColor3": "mintcream","ShadowColor": [200, 200, 200],"FontColor": [10, 10, 10], "FontColorFaded": [100, 100, 100],"ConnectionPointColor": "white","PenWidth": 2.0,"HoveredPenWidth": 2.5, "ConnectionPointDiameter": 10.0,"Opacity": 1.0}})"); - QtNodes::FlowViewStyle::setStyle(R"({"FlowViewStyle": {"BackgroundColor": [255, 255, 240],"FineGridColor": [245, 245, 230],"CoarseGridColor": [235, 235, 220]}})"); - ConnectionStyle::setConnectionStyle(R"({"ConnectionStyle": {"ConstructionColor": "gray","NormalColor": "black","SelectedColor": "gray", + QtNodes::FlowViewStyle::setStyle( + R"({"FlowViewStyle": {"BackgroundColor": [255, 255, 240],"FineGridColor": [245, 245, 230],"CoarseGridColor": [235, 235, 220]}})"); + ConnectionStyle::setConnectionStyle( + R"({"ConnectionStyle": {"ConstructionColor": "gray","NormalColor": "black","SelectedColor": "gray", "SelectedHaloColor": "deepskyblue","HoveredColor": "deepskyblue","LineWidth": 3.0,"ConstructionLineWidth": 2.0, "PointDiameter": 10.0,"UseDataDefinedColors": false}})"); } @@ -91,17 +102,20 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QDialog(pare domainStrategyCombo->setCurrentText(domainStrategy); // Show connections in the node graph - for (auto in : root["inbounds"].toArray()) { + for (auto in : root["inbounds"].toArray()) + { INBOUND _in = INBOUND(in.toObject()); AddInbound(_in); } - for (auto out : root["outbounds"].toArray()) { + for (auto out : root["outbounds"].toArray()) + { OUTBOUND _out = OUTBOUND(out.toObject()); AddOutbound(_out); } - for (auto item : root["routing"].toObject()["rules"].toArray()) { + for (auto item : root["routing"].toObject()["rules"].toArray()) + { auto _rule = StructFromJsonString(JsonToString(item.toObject())); AddRule(_rule); } @@ -110,12 +124,12 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QDialog(pare defaultOutboundCombo->setCurrentText(root["outbounds"].toArray().first().toObject()["tag"].toString()); // Find and add balancers. - for (auto _balancer : root["routing"].toObject()["balancers"].toArray()) { + for (auto _balancer : root["routing"].toObject()["balancers"].toArray()) + { auto _balancerObject = _balancer.toObject(); - if (!_balancerObject["tag"].toString().isEmpty()) { - balancers[_balancerObject["tag"].toString()] = _balancerObject["selector"].toVariant().toStringList(); - } + if (!_balancerObject["tag"].toString().isEmpty()) + { balancers[_balancerObject["tag"].toString()] = _balancerObject["selector"].toVariant().toStringList(); } } isLoading = false; @@ -123,10 +137,9 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QDialog(pare QvMessageBusSlotImpl(RouteEditor) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -140,25 +153,31 @@ void RouteEditor::onNodeClicked(Node &n) auto isIn = inboundNodes.values().contains(&n); auto isRule = ruleNodes.values().contains(&n); - if (isRule) { + if (isRule) + { // It's a rule object currentRuleTag = GetFirstNodeData(n, QvRuleNodeDataModel, RuleNodeData)->GetRuleTag(); DEBUG(MODULE_GRAPH, "Selecting rule: " + currentRuleTag) ShowCurrentRuleDetail(); toolBox->setCurrentIndex(1); - } else if (isOut || isIn) { + } + else if (isOut || isIn) + { // It's an inbound or an outbound. QString alias; QString host; int port; QString protocol; - if (isOut) { + if (isOut) + { alias = GetFirstNodeData(n, QvOutboundNodeModel, OutboundNodeData)->GetOutbound(); QJsonObject _root = outbounds[alias].raw(); throw new runtime_error("Not implemented"); GetOutboundData(OUTBOUND(_root), &host, &port, &protocol); - } else { + } + else + { alias = GetFirstNodeData(n, QvInboundNodeModel, InboundNodeData)->GetInbound(); QJsonObject _root = inbounds[alias].raw(); host = _root["listen"].toString(); @@ -170,7 +189,9 @@ void RouteEditor::onNodeClicked(Node &n) protocolLabel->setText(protocol); portLabel->setNum(port); hostLabel->setText(host); - } else { + } + else + { LOG(MODULE_GRAPH, "Selected an unknown node, RARE.") } } @@ -185,7 +206,8 @@ void RouteEditor::onConnectionCreated(QtNodes::Connection const &c) auto const sourceNode = c.getNode(PortType::Out); auto const targetNode = c.getNode(PortType::In); - if (inboundNodes.values().contains(sourceNode) && ruleNodes.values().contains(targetNode)) { + if (inboundNodes.values().contains(sourceNode) && ruleNodes.values().contains(targetNode)) + { // It's a inbound-rule connection onNodeClicked(*sourceNode); onNodeClicked(*targetNode); @@ -194,14 +216,16 @@ void RouteEditor::onConnectionCreated(QtNodes::Connection const &c) // QStringList has an helper to let us remove duplicates, see below. QStringList _inbounds; - for (auto &&[_, conn] : nodeScene->connections()) { + for (auto &&[_, conn] : nodeScene->connections()) + { auto _connection = conn.get(); - if (_connection->getNode(PortType::In) == targetNode && _connection->getNode(PortType::Out) == sourceNode && _connection->id() != c.id()) { - nodeScene->deleteConnection(*_connection); - } + if (_connection->getNode(PortType::In) == targetNode && _connection->getNode(PortType::Out) == sourceNode && + _connection->id() != c.id()) + { nodeScene->deleteConnection(*_connection); } // Append all inbounds - else if (_connection->getNode(PortType::In) == targetNode) { + else if (_connection->getNode(PortType::In) == targetNode) + { _inbounds.append(GetFirstNodeData(*_connection->getNode(PortType::Out), QvInboundNodeModel, InboundNodeData)->GetInbound()); } } @@ -209,7 +233,9 @@ void RouteEditor::onConnectionCreated(QtNodes::Connection const &c) // caused by multi-in connection _inbounds.removeDuplicates(); CurrentRule.inboundTag = _inbounds; - } else if (ruleNodes.values().contains(sourceNode) && outboundNodes.values().contains(targetNode)) { + } + else if (ruleNodes.values().contains(sourceNode) && outboundNodes.values().contains(targetNode)) + { // It's a rule-outbound connection onNodeClicked(*sourceNode); onNodeClicked(*targetNode); @@ -219,7 +245,9 @@ void RouteEditor::onConnectionCreated(QtNodes::Connection const &c) // Update balancer settings. ShowCurrentRuleDetail(); LOG(MODULE_GRAPH, "Updated outbound: " + CurrentRule.outboundTag) - } else { + } + else + { // It's an impossible connection LOG(MODULE_GRAPH, "Unrecognized connection, RARE.") } @@ -235,7 +263,8 @@ void RouteEditor::onConnectionDeleted(QtNodes::Connection const &c) auto const source = c.getNode(PortType::Out); auto const target = c.getNode(PortType::In); - if (inboundNodes.values().contains(source) && ruleNodes.values().contains(target)) { + if (inboundNodes.values().contains(source) && ruleNodes.values().contains(target)) + { // It's a inbound-rule connection onNodeClicked(*source); onNodeClicked(*target); @@ -243,19 +272,21 @@ void RouteEditor::onConnectionDeleted(QtNodes::Connection const &c) auto _inboundTag = GetFirstNodeData(*source, QvInboundNodeModel, InboundNodeData)->GetInbound(); LOG(MODULE_UI, "Removing inbound: " + _inboundTag + " from rule: " + currentRuleTag) CurrentRule.inboundTag.removeAll(_inboundTag); - } else if (ruleNodes.values().contains(source) && outboundNodes.values().contains(target)) { + } + else if (ruleNodes.values().contains(source) && outboundNodes.values().contains(target)) + { // It's a rule-outbound connection onNodeClicked(*source); onNodeClicked(*target); currentRuleTag = GetFirstNodeData(*source, QvRuleNodeDataModel, RuleNodeData)->GetRuleTag(); auto _outboundTag = GetFirstNodeData(*target, QvOutboundNodeModel, OutboundNodeData)->GetOutbound(); - if (!CurrentRule.QV2RAY_RULE_USE_BALANCER && CurrentRule.outboundTag == _outboundTag) { - CurrentRule.outboundTag.clear(); - } + if (!CurrentRule.QV2RAY_RULE_USE_BALANCER && CurrentRule.outboundTag == _outboundTag) { CurrentRule.outboundTag.clear(); } LOG(MODULE_GRAPH, "Removing an outbound: " + _outboundTag) - } else { + } + else + { // It's an impossible connection LOG(MODULE_GRAPH, "Selected an unknown node, RARE.") } @@ -265,30 +296,35 @@ CONFIGROOT RouteEditor::OpenEditor() { auto result = this->exec(); - if (rules.isEmpty()) { - // Prevent empty rule list causing mis-detection of config type to simple. + if (rules.isEmpty()) + { + // Prevent empty rule list causing mis-detection of config type to + // simple. on_addRouteBtn_clicked(); } // If clicking OK - if (result == QDialog::Accepted) { + if (result == QDialog::Accepted) + { QJsonArray rulesArray; QJsonArray _balancers; // Append rules by order - for (auto i = 0; i < ruleListWidget->count(); i++) { + for (auto i = 0; i < ruleListWidget->count(); i++) + { auto _rule = rules[ruleListWidget->item(i)->text()]; auto ruleJsonObject = GetRootObject(_rule); // Process balancer for a rule - if (_rule.QV2RAY_RULE_USE_BALANCER) { + if (_rule.QV2RAY_RULE_USE_BALANCER) + { // Do not use outbound tag. ruleJsonObject.remove("outboundTag"); // Find balancer list - if (!balancers.contains(_rule.balancerTag)) { - LOG(MODULE_UI, "Cannot find a balancer for tag: " + _rule.balancerTag) - } else { + if (!balancers.contains(_rule.balancerTag)) { LOG(MODULE_UI, "Cannot find a balancer for tag: " + _rule.balancerTag) } + else + { auto _balancerList = balancers[_rule.balancerTag]; QJsonObject balancerEntry; balancerEntry["tag"] = _rule.balancerTag; @@ -298,13 +334,9 @@ CONFIGROOT RouteEditor::OpenEditor() } // Remove some empty fields. - if (_rule.port.isEmpty()) { - ruleJsonObject.remove("port"); - } + if (_rule.port.isEmpty()) { ruleJsonObject.remove("port"); } - if (_rule.network.isEmpty()) { - ruleJsonObject.remove("network"); - } + if (_rule.network.isEmpty()) { ruleJsonObject.remove("network"); } rulesArray.append(ruleJsonObject); } @@ -318,22 +350,25 @@ CONFIGROOT RouteEditor::OpenEditor() QJsonArray _outbounds; // Convert our internal data format to QJsonArray - for (auto x : inbounds) { - if (x.isEmpty()) - continue; + for (auto x : inbounds) + { + if (x.isEmpty()) continue; _inbounds.append(x.raw()); } - for (auto x : outbounds) { - if (x.isEmpty()) - continue; + for (auto x : outbounds) + { + if (x.isEmpty()) continue; - if (getTag(x) == defaultOutbound) { + if (getTag(x) == defaultOutbound) + { LOG(MODULE_CONNECTION, "Pushing default outbound to the front.") // Put the default outbound to the first. _outbounds.push_front(x.raw()); - } else { + } + else + { _outbounds.push_back(x.raw()); } } @@ -342,7 +377,9 @@ CONFIGROOT RouteEditor::OpenEditor() root["outbounds"] = _outbounds; root["routing"] = routing; return root; - } else { + } + else + { return original; } } @@ -355,18 +392,22 @@ RouteEditor::~RouteEditor() disconnect(nodeScene, &FlowScene::connectionCreated, this, &RouteEditor::onConnectionCreated); disconnect(nodeScene, &FlowScene::nodeClicked, this, &RouteEditor::onNodeClicked); } -void RouteEditor::on_buttonBox_accepted() {} +void RouteEditor::on_buttonBox_accepted() +{ +} void RouteEditor::ShowCurrentRuleDetail() { LOADINGCHECK - if (currentRuleTag.isEmpty()) { + if (currentRuleTag.isEmpty()) + { LOG(MODULE_UI, "WARNING, trying to access a non-exist rule entry. return.") return; } - if (!rules.contains(currentRuleTag)) { + if (!rules.contains(currentRuleTag)) + { QvMessageBoxWarn(this, tr("Show rule details"), tr("A rule cannot be found: ") + currentRuleTag); LOG(MODULE_UI, "WARNING, trying to access a non-exist rule entry. return.") return; @@ -384,16 +425,15 @@ void RouteEditor::ShowCurrentRuleDetail() balancerSelectionCombo->clear(); // BUG added the wrong items, should be outbound list. - for (auto out : outbounds) { - balancerSelectionCombo->addItem((out)["tag"].toString()); - } + for (auto out : outbounds) { balancerSelectionCombo->addItem((out)["tag"].toString()); } // // Balancers combo and balancer list. enableBalancerCB->setChecked(CurrentRule.QV2RAY_RULE_USE_BALANCER); balancersWidget->setEnabled(CurrentRule.QV2RAY_RULE_USE_BALANCER); - if (!CurrentRule.balancerTag.isEmpty()) { + if (!CurrentRule.balancerTag.isEmpty()) + { balancerList->clear(); balancerList->addItems(balancers[CurrentRule.balancerTag]); } @@ -490,12 +530,15 @@ void RouteEditor::on_balancerAddBtn_clicked() LOADINGCHECK auto balancerTx = balancerSelectionCombo->currentText(); - if (!balancerTx.isEmpty()) { + if (!balancerTx.isEmpty()) + { this->balancers[CurrentRule.balancerTag].append(balancerSelectionCombo->currentText()); balancerList->addItem(balancerTx); balancerSelectionCombo->setEditText(""); statusLabel->setText(tr("OK")); - } else { + } + else + { statusLabel->setText(tr("Balancer is empty, not processing.")); } } @@ -503,9 +546,7 @@ void RouteEditor::on_balancerDelBtn_clicked() { LOADINGCHECK - if (balancerList->currentRow() < 0) { - return; - } + if (balancerList->currentRow() < 0) { return; } balancers[CurrentRule.balancerTag].removeAt(balancerList->currentRow()); balancerList->takeItem(balancerList->currentRow()); @@ -568,7 +609,8 @@ void RouteEditor::on_enableBalancerCB_stateChanged(int arg1) CurrentRule.QV2RAY_RULE_USE_BALANCER = useBalancer; balancersWidget->setEnabled(useBalancer); - if (CurrentRule.balancerTag.isEmpty()) { + if (CurrentRule.balancerTag.isEmpty()) + { LOG(MODULE_UI, "Creating a new balancer tag.") CurrentRule.balancerTag = GenerateRandomString(6); balancers[CurrentRule.balancerTag] = QStringList(); @@ -576,16 +618,18 @@ void RouteEditor::on_enableBalancerCB_stateChanged(int arg1) DEBUG(MODULE_UI, "Balancer: " + CurrentRule.balancerTag) - if (useBalancer) { + if (useBalancer) + { LOG(MODULE_UI, "A rule has been set to use balancer, disconnect it to any outbound.") auto ruleNode = ruleNodes[currentRuleTag]; - for (auto &&[_, conn] : nodeScene->connections()) { - if (conn.get()->getNode(PortType::Out) == ruleNode) { - nodeScene->deleteConnection(*conn); - } + for (auto &&[_, conn] : nodeScene->connections()) + { + if (conn.get()->getNode(PortType::Out) == ruleNode) { nodeScene->deleteConnection(*conn); } } - } else { + } + else + { QvMessageBoxWarn(this, tr("Route Editor"), tr("To make this rule ready to use, you need to connect it to an outbound node.")); } } @@ -597,8 +641,7 @@ void RouteEditor::on_addDefaultBtn_clicked() auto _Inconfig = GlobalConfig.inboundConfig; // auto _in_httpConf = GenerateHTTPIN(QList() << _Inconfig.httpAccount); - auto _in_socksConf = GenerateSocksIN((_Inconfig.socks_useAuth ? "password" : "noauth"), - QList() << _Inconfig.socksAccount, + auto _in_socksConf = GenerateSocksIN((_Inconfig.socks_useAuth ? "password" : "noauth"), QList() << _Inconfig.socksAccount, _Inconfig.socksUDP, _Inconfig.socksLocalIP); // auto _in_HTTP = GenerateInboundEntry(_Inconfig.listenip, _Inconfig.http_port, "http", _in_httpConf, "HTTP_gConf"); @@ -622,9 +665,7 @@ void RouteEditor::on_addInboundBtn_clicked() InboundEditor w(INBOUND(), this); auto _result = w.OpenEditor(); - if (w.result() == QDialog::Accepted) { - AddInbound(_result); - } + if (w.result() == QDialog::Accepted) { AddInbound(_result); } CHECKEMPTYRULES } @@ -635,19 +676,17 @@ void RouteEditor::on_addOutboundBtn_clicked() // True here for not keep the inbounds. auto configs = w.OpenImport(true); - for (auto i = 0; i < configs.count(); i++) { + for (auto i = 0; i < configs.count(); i++) + { auto conf = configs.values()[i]; auto name = configs.key(conf, ""); - if (name.isEmpty()) - continue; + if (name.isEmpty()) continue; // conf is rootObject, needs to unwrap it. auto confList = conf["outbounds"].toArray(); - for (int i = 0; i < confList.count(); i++) { - AddOutbound(OUTBOUND(confList[i].toObject())); - } + for (int i = 0; i < confList.count(); i++) { AddOutbound(OUTBOUND(confList[i].toObject())); } } CHECKEMPTYRULES @@ -661,7 +700,8 @@ void RouteEditor::on_ruleEnableCB_stateChanged(int arg1) } void RouteEditor::on_delBtn_clicked() { - if (nodeScene->selectedNodes().empty()) { + if (nodeScene->selectedNodes().empty()) + { QvMessageBoxWarn(this, tr("Remove Items"), tr("Please select a node from the graph to continue.")); return; } @@ -671,40 +711,46 @@ void RouteEditor::on_delBtn_clicked() auto isOutbound = outboundNodes.values().contains(firstNode); auto isRule = ruleNodes.values().contains(firstNode); - // Get the tag first, and call inbounds/outbounds/rules container variable remove() - // Remove the node last since some events may trigger. - // Then remove the node container. - if (isInbound) { + // Get the tag first, and call inbounds/outbounds/rules container variable + // remove() Remove the node last since some events may trigger. Then remove + // the node container. + if (isInbound) + { currentInboundOutboundTag = GetFirstNodeData(*firstNode, QvInboundNodeModel, InboundNodeData)->GetInbound(); nodeScene->removeNode(*inboundNodes[currentInboundOutboundTag]); inboundNodes.remove(currentInboundOutboundTag); // Remove corresponded inbound tags from the rules. - for (auto k : rules.keys()) { + for (auto k : rules.keys()) + { auto v = rules[k]; v.inboundTag.removeAll(currentInboundOutboundTag); rules[k] = v; } inbounds.remove(currentInboundOutboundTag); - } else if (isOutbound) { + } + else if (isOutbound) + { currentInboundOutboundTag = GetFirstNodeData(*firstNode, QvOutboundNodeModel, OutboundNodeData)->GetOutbound(); outbounds.remove(currentInboundOutboundTag); ResolveDefaultOutboundTag(currentInboundOutboundTag, ""); // Remove corresponded outbound tags from the rules. - for (auto k : rules.keys()) { + for (auto k : rules.keys()) + { auto v = rules[k]; - if (v.outboundTag == currentInboundOutboundTag) - v.outboundTag.clear(); + if (v.outboundTag == currentInboundOutboundTag) v.outboundTag.clear(); rules[k] = v; } nodeScene->removeNode(*outboundNodes[currentInboundOutboundTag]); outboundNodes.remove(currentInboundOutboundTag); - } else if (isRule) { + } + else if (isRule) + { ruleEnableCB->setEnabled(false); ruleTagLineEdit->setEnabled(false); ruleRenameBtn->setEnabled(false); @@ -719,27 +765,30 @@ void RouteEditor::on_delBtn_clicked() // Remove item from the rule order list widget. ruleListWidget->takeItem(ruleListWidget->row(ruleListWidget->findItems(RuleTag, Qt::MatchExactly).first())); CHECKEMPTYRULES - //currentRuleTag = rules.firstKey(); - //ShowCurrentRuleDetail(); - } else { + // currentRuleTag = rules.firstKey(); + // ShowCurrentRuleDetail(); + } + else + { LOG(MODULE_UI, "Unknown node selected.") QvMessageBoxWarn(this, tr("Error"), tr("Qv2ray entered an unknown state.")); } } void RouteEditor::on_editBtn_clicked() { - if (nodeScene->selectedNodes().empty()) { - QvMessageBoxWarn(this, tr("Edit Inbound/Outbound"), tr("Please select a node from the graph to continue.")); - } + if (nodeScene->selectedNodes().empty()) + { QvMessageBoxWarn(this, tr("Edit Inbound/Outbound"), tr("Please select a node from the graph to continue.")); } auto firstNode = nodeScene->selectedNodes().at(0); auto isInbound = inboundNodes.values().contains(firstNode); auto isOutbound = outboundNodes.values().contains(firstNode); - if (isInbound) { + if (isInbound) + { currentInboundOutboundTag = GetFirstNodeData(*firstNode, QvInboundNodeModel, InboundNodeData)->GetInbound(); - if (!inbounds.contains(currentInboundOutboundTag)) { + if (!inbounds.contains(currentInboundOutboundTag)) + { QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); return; } @@ -749,14 +798,18 @@ void RouteEditor::on_editBtn_clicked() auto protocol = _in["protocol"].toString(); int _code; - if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") { - QvMessageBoxWarn(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + - tr("We will launch Json Editor instead.")); + if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") + { + QvMessageBoxWarn(this, tr("Cannot Edit"), + tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + + tr("We will launch Json Editor instead.")); statusLabel->setText(tr("Opening JSON editor")); JsonEditor w(_in, this); _result = INBOUND(w.OpenEditor()); _code = w.result(); - } else { + } + else + { InboundEditor w(_in, this); statusLabel->setText(tr("Opening default inbound editor")); _result = w.OpenEditor(); @@ -765,22 +818,24 @@ void RouteEditor::on_editBtn_clicked() statusLabel->setText(tr("OK")); - if (_code == QDialog::Accepted) { + if (_code == QDialog::Accepted) + { bool isTagChanged = getTag(_in) != getTag(_result); - if (isTagChanged) { - RenameItemTag(RENAME_INBOUND, getTag(_in), getTag(_result)); - } + if (isTagChanged) { RenameItemTag(RENAME_INBOUND, getTag(_in), getTag(_result)); } DEBUG(MODULE_UI, "Removed old tag: " + getTag(_in)) inbounds.remove(getTag(_in)); DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) inbounds[getTag(_result)] = _result; } - } else if (isOutbound) { + } + else if (isOutbound) + { currentInboundOutboundTag = GetFirstNodeData(*firstNode, QvOutboundNodeModel, OutboundNodeData)->GetOutbound(); - if (!outbounds.contains(currentInboundOutboundTag)) { + if (!outbounds.contains(currentInboundOutboundTag)) + { QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); return; } @@ -790,25 +845,30 @@ void RouteEditor::on_editBtn_clicked() auto protocol = _out["protocol"].toString().toLower(); int _code; - if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") { + if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") + { QvMessageBoxWarn(this, tr("Unsupported Outbound Type"), tr("This outbound entry is not supported by the GUI editor.") + NEWLINE + - tr("We will launch Json Editor instead.")); + tr("We will launch Json Editor instead.")); JsonEditor w(_out, this); statusLabel->setText(tr("Opening JSON editor")); _result = OUTBOUND(w.OpenEditor()); _code = w.result(); - } else { + } + else + { OutboundEditor w(_out, this); statusLabel->setText(tr("Opening default outbound editor.")); _result = w.OpenEditor(); _code = w.result(); } - if (_code == QDialog::Accepted) { + if (_code == QDialog::Accepted) + { bool isTagChanged = getTag(_out) != getTag(_result); - if (isTagChanged) { + if (isTagChanged) + { DEBUG(MODULE_UI, "Outbound tag is changed: " + QString(isTagChanged)) RenameItemTag(RENAME_OUTBOUND, getTag(_out), getTag(_result)); DEBUG(MODULE_UI, "Removed old tag: " + getTag(_out)) @@ -819,7 +879,9 @@ void RouteEditor::on_editBtn_clicked() outbounds[getTag(_result)] = _result; statusLabel->setText(tr("OK")); } - } else { + } + else + { LOG(MODULE_UI, "Cannot apply 'edit' operation to non-inbound and non-outbound") } } @@ -840,16 +902,23 @@ void RouteEditor::on_ruleRenameBtn_clicked() { auto newTag = ruleTagLineEdit->text(); - if (newTag.isEmpty()) { + if (newTag.isEmpty()) + { LOG(MODULE_UI, "Tag is empty, this is ILLEGAL!") QvMessageBoxWarn(this, tr("Renaming a tag"), tr("New tag is empty, please try another.")); - } else if (newTag == CurrentRule.QV2RAY_RULE_TAG) { + } + else if (newTag == CurrentRule.QV2RAY_RULE_TAG) + { LOG(MODULE_UI, "No tag changed, returning.") QvMessageBoxInfo(this, tr("Renaming a tag"), tr("New tag is the same as the original one.")); - } else if (rules.contains(newTag)) { + } + else if (rules.contains(newTag)) + { LOG(MODULE_UI, "Tag duplicate detected.") QvMessageBoxWarn(this, tr("Renaming a tag"), tr("Duplicate rule tag detected, please try another.")); - } else { + } + else + { RenameItemTag(RENAME_RULE, CurrentRule.QV2RAY_RULE_TAG, newTag); } } diff --git a/src/ui/editors/w_RoutesEditor.hpp b/src/ui/editors/w_RoutesEditor.hpp index 04c0fbbf..9aa52f4d 100644 --- a/src/ui/editors/w_RoutesEditor.hpp +++ b/src/ui/editors/w_RoutesEditor.hpp @@ -1,131 +1,134 @@ #pragma once -#include +#include "ConnectionStyle.hpp" +#include "FlowScene.hpp" +#include "Node.hpp" +#include "NodeData.hpp" +#include "common/QvHelpers.hpp" + #include #include #include #include -#include "common/QvHelpers.hpp" +#include -#include "Node.hpp" -#include "NodeData.hpp" -#include "ConnectionStyle.hpp" -#include "FlowScene.hpp" - -using QtNodes::Node; -using QtNodes::FlowScene; using QtNodes::ConnectionStyle; +using QtNodes::FlowScene; +using QtNodes::Node; -#include "ui_w_RoutesEditor.h" #include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_RoutesEditor.h" -enum ROUTE_EDIT_MODE { +enum ROUTE_EDIT_MODE +{ RENAME_INBOUND, RENAME_OUTBOUND, RENAME_RULE, }; -class RouteEditor : public QDialog, private Ui::RouteEditor +class RouteEditor + : public QDialog + , private Ui::RouteEditor { - Q_OBJECT + Q_OBJECT - public: - explicit RouteEditor(QJsonObject connection, QWidget *parent = nullptr); - ~RouteEditor(); - CONFIGROOT OpenEditor(); - public slots: - QvMessageBusSlotDecl + public: + explicit RouteEditor(QJsonObject connection, QWidget *parent = nullptr); + ~RouteEditor(); + CONFIGROOT OpenEditor(); + public slots: + QvMessageBusSlotDecl; - private slots: - void on_buttonBox_accepted(); + private slots: + void on_buttonBox_accepted(); - void on_insertDirectBtn_clicked(); + void on_insertDirectBtn_clicked(); - void on_routeProtocolHTTPCB_stateChanged(int arg1); + void on_routeProtocolHTTPCB_stateChanged(int arg1); - void on_routeProtocolTLSCB_stateChanged(int arg1); + void on_routeProtocolTLSCB_stateChanged(int arg1); - void on_routeProtocolBTCB_stateChanged(int arg1); + void on_routeProtocolBTCB_stateChanged(int arg1); - void on_balancerAddBtn_clicked(); + void on_balancerAddBtn_clicked(); - void on_balancerDelBtn_clicked(); + void on_balancerDelBtn_clicked(); - void on_hostList_textChanged(); + void on_hostList_textChanged(); - void on_ipList_textChanged(); + void on_ipList_textChanged(); - void on_routePortTxt_textEdited(const QString &arg1); + void on_routePortTxt_textEdited(const QString &arg1); - void on_routeUserTxt_textEdited(const QString &arg1); + void on_routeUserTxt_textEdited(const QString &arg1); - void on_addRouteBtn_clicked(); + void on_addRouteBtn_clicked(); - void on_netBothRB_clicked(); + void on_netBothRB_clicked(); - void on_netUDPRB_clicked(); + void on_netUDPRB_clicked(); - void on_netTCPRB_clicked(); + void on_netTCPRB_clicked(); - void on_routeUserTxt_textChanged(); + void on_routeUserTxt_textChanged(); - void on_sourceIPList_textChanged(); + void on_sourceIPList_textChanged(); - void on_enableBalancerCB_stateChanged(int arg1); + void on_enableBalancerCB_stateChanged(int arg1); - void on_addDefaultBtn_clicked(); + void on_addDefaultBtn_clicked(); - void on_insertBlackBtn_clicked(); + void on_insertBlackBtn_clicked(); - void on_addInboundBtn_clicked(); + void on_addInboundBtn_clicked(); - void on_addOutboundBtn_clicked(); + void on_addOutboundBtn_clicked(); - void on_ruleEnableCB_stateChanged(int arg1); + void on_ruleEnableCB_stateChanged(int arg1); - void on_delBtn_clicked(); + void on_delBtn_clicked(); - void on_editBtn_clicked(); + void on_editBtn_clicked(); - void on_domainStrategyCombo_currentIndexChanged(const QString &arg1); + void on_domainStrategyCombo_currentIndexChanged(const QString &arg1); - void on_defaultOutboundCombo_currentIndexChanged(const QString &arg1); + void on_defaultOutboundCombo_currentIndexChanged(const QString &arg1); - void on_ruleRenameBtn_clicked(); + void on_ruleRenameBtn_clicked(); - public slots: - void onNodeClicked(QtNodes::Node &n); - void onConnectionCreated(QtNodes::Connection const &c); - void onConnectionDeleted(QtNodes::Connection const &c); + public slots: + void onNodeClicked(QtNodes::Node &n); + void onConnectionCreated(QtNodes::Connection const &c); + void onConnectionDeleted(QtNodes::Connection const &c); - private: - void RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, const QString newTag); - void ShowCurrentRuleDetail(); - // - QString currentRuleTag; - QString currentInboundOutboundTag; - QMap balancers; - QString domainStrategy; - QString defaultOutbound; - // - QMap inbounds; - QMap outbounds; - QMap rules; - // - CONFIGROOT root; - CONFIGROOT original; - // - // ---------------------------- Node Graph Impl -------------------------- - void SetupNodeWidget(); - QMap inboundNodes; - QMap outboundNodes; - QMap ruleNodes; - // - FlowScene *nodeScene; - // ---------------------------- Extra Source File Headers ---------------- - void AddInbound(INBOUND in); - void AddOutbound(OUTBOUND out); - void AddRule(RuleObject rule); - QString AddNewRule(); - void ResolveDefaultOutboundTag(QString original, QString newTag); + private: + void RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, const QString newTag); + void ShowCurrentRuleDetail(); + // + QString currentRuleTag; + QString currentInboundOutboundTag; + QMap balancers; + QString domainStrategy; + QString defaultOutbound; + // + QMap inbounds; + QMap outbounds; + QMap rules; + // + CONFIGROOT root; + CONFIGROOT original; + // + // ---------------------------- Node Graph Impl -------------------------- + void SetupNodeWidget(); + QMap inboundNodes; + QMap outboundNodes; + QMap ruleNodes; + // + FlowScene *nodeScene; + // ---------------------------- Extra Source File Headers ---------------- + void AddInbound(INBOUND in); + void AddOutbound(OUTBOUND out); + void AddRule(RuleObject rule); + QString AddNewRule(); + void ResolveDefaultOutboundTag(QString original, QString newTag); }; diff --git a/src/ui/editors/w_RoutesEditor_extra.cpp b/src/ui/editors/w_RoutesEditor_extra.cpp index 87e8baa6..cd44d994 100644 --- a/src/ui/editors/w_RoutesEditor_extra.cpp +++ b/src/ui/editors/w_RoutesEditor_extra.cpp @@ -1,18 +1,16 @@ // WARNING -// Since it's required for this file to know the content of the macros defined in another CPP file. -// We included an CPP file instead of the proper HPP file. +// Since it's required for this file to know the content of the macros defined +// in another CPP file. We included an CPP file instead of the proper HPP file. #include "w_RoutesEditor.cpp" -// Supplementary source file for Routes editor, basically providing routes-related operations. - +// Supplementary source file for Routes editor, basically providing +// routes-related operations. void RouteEditor::AddInbound(INBOUND in) { QString tag = getTag(in); - if (inbounds.contains(tag)) { - tag = tag + "_" + GenerateRandomString(5); - } + if (inbounds.contains(tag)) { tag = tag + "_" + GenerateRandomString(5); } in["tag"] = tag; auto _nodeData = make_unique(make_shared(tag)); @@ -29,9 +27,7 @@ void RouteEditor::AddOutbound(OUTBOUND out) { QString tag = getTag(out); - if (outbounds.contains(tag)) { - tag = tag + "_" + GenerateRandomString(5); - } + if (outbounds.contains(tag)) { tag = tag + "_" + GenerateRandomString(5); } out["tag"] = tag; auto _nodeData = make_unique(make_shared(tag)); @@ -64,9 +60,7 @@ QString RouteEditor::AddNewRule() void RouteEditor::AddRule(RuleObject rule) { // Prevent duplicate - if (ruleNodes.contains(rule.QV2RAY_RULE_TAG)) { - rule.QV2RAY_RULE_TAG += "-" + GenerateRandomString(5); - } + if (ruleNodes.contains(rule.QV2RAY_RULE_TAG)) { rule.QV2RAY_RULE_TAG += "-" + GenerateRandomString(5); } rules[rule.QV2RAY_RULE_TAG] = rule; auto pos = nodeGraphWidget->pos(); @@ -76,25 +70,34 @@ void RouteEditor::AddRule(RuleObject rule) auto &node = nodeScene->createNode(std::move(_nodeData)); nodeScene->setNodePosition(node, pos); - for (auto inTag : rule.inboundTag) { - if (!inboundNodes.contains(inTag)) { + for (auto inTag : rule.inboundTag) + { + if (!inboundNodes.contains(inTag)) + { LOG(MODULE_UI, "No inbound tag found for rule: " + rule.QV2RAY_RULE_TAG + ", inbound tag: " + inTag) QvMessageBoxWarn(this, tr("No Inbound"), tr("No inbound item found: ") + inTag); rule.inboundTag.removeAll(inTag); - } else { + } + else + { auto inboundNode = inboundNodes[inTag]; nodeScene->createConnection(node, 0, *inboundNode, 0); } } // If not using balancers (use outbound tag) - if (!rule.QV2RAY_RULE_USE_BALANCER) { - if (outboundNodes.contains(rule.outboundTag)) { + if (!rule.QV2RAY_RULE_USE_BALANCER) + { + if (outboundNodes.contains(rule.outboundTag)) + { DEBUG(MODULE_GRAPH, "Found outbound tag: " + rule.outboundTag + ", for rule: " + rule.QV2RAY_RULE_TAG) nodeScene->createConnection(*outboundNodes[rule.outboundTag], 0, node, 0); - } else { + } + else + { LOG(MODULE_GRAPH, "Outbound tag not found: " + rule.outboundTag + ", for: " + rule.QV2RAY_RULE_TAG) - //QvMessageBoxWarn(this, tr("No outbound tag"), tr("Please connect the rule with an outbound.")); + // QvMessageBoxWarn(this, tr("No outbound tag"), tr("Please connect + // the rule with an outbound.")); } } @@ -105,19 +108,20 @@ void RouteEditor::AddRule(RuleObject rule) // Do not use reference here, we need deep void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString newTag) { - switch (mode) { + switch (mode) + { case RENAME_RULE: - if (rules.contains(originalTag) && ruleNodes.contains(originalTag)) { - if (rules.contains(newTag) && rules.contains(newTag)) { + if (rules.contains(originalTag) && ruleNodes.contains(originalTag)) + { + if (rules.contains(newTag) && rules.contains(newTag)) + { QvMessageBoxWarn(this, tr("Rename tags"), tr("The new tag has been used, we appended a postfix.")); newTag += "_" + GenerateRandomString(5); } auto node = static_cast(ruleNodes[originalTag]->nodeDataModel()); - if (node == nullptr) { - LOG(MODULE_GRAPH, "EMPTY NODE WARN") - } + if (node == nullptr) { LOG(MODULE_GRAPH, "EMPTY NODE WARN") } node->setData(newTag); // @@ -125,27 +129,30 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, rules[newTag].QV2RAY_RULE_TAG = newTag; ruleNodes[newTag] = ruleNodes.take(originalTag); // - // No other operation needed, but need to rename the one in the ruleOrder list widget. + // No other operation needed, but need to rename the one in the + // ruleOrder list widget. auto items = ruleListWidget->findItems(originalTag, Qt::MatchExactly); - if (items.isEmpty()) { - LOG(MODULE_UI, "Cannot find a node: " + originalTag) - } else { + if (items.isEmpty()) { LOG(MODULE_UI, "Cannot find a node: " + originalTag) } + else + { items.first()->setText(newTag); } - if (currentRuleTag == originalTag) { - currentRuleTag = newTag; - } - } else { + if (currentRuleTag == originalTag) { currentRuleTag = newTag; } + } + else + { LOG(MODULE_UI, "There's nothing match " + originalTag + " in the containers.") } break; case RENAME_OUTBOUND: - if (outbounds.contains(originalTag) && outboundNodes.contains(originalTag)) { - if (outbounds.contains(newTag) && outboundNodes.contains(newTag)) { + if (outbounds.contains(originalTag) && outboundNodes.contains(originalTag)) + { + if (outbounds.contains(newTag) && outboundNodes.contains(newTag)) + { QvMessageBoxWarn(this, tr("Rename tags"), tr("The new tag has been used, we appended a postfix.")); newTag += "_" + GenerateRandomString(5); } @@ -154,34 +161,39 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, outboundNodes[newTag] = outboundNodes.take(originalTag); auto node = static_cast(outboundNodes[newTag]->nodeDataModel()); - if (node == nullptr) { - LOG(MODULE_GRAPH, "EMPTY NODE WARN") - } + if (node == nullptr) { LOG(MODULE_GRAPH, "EMPTY NODE WARN") } node->setData(newTag); // Change outbound tag in rules accordingly. - for (auto k : rules.keys()) { + for (auto k : rules.keys()) + { auto v = rules[k]; - if (v.outboundTag == originalTag) { + if (v.outboundTag == originalTag) + { v.outboundTag = newTag; - // Put this inside the if block since no need an extra operation if the condition is false. + // Put this inside the if block since no need an extra + // operation if the condition is false. rules[k] = v; } } // Resolve default outbound. ResolveDefaultOutboundTag(originalTag, newTag); - } else { + } + else + { LOG(MODULE_UI, "Failed to rename an outbound --> Item not found.") } break; case RENAME_INBOUND: - if (inbounds.contains(originalTag) && inboundNodes.contains(originalTag)) { - if (inbounds.contains(newTag) && inboundNodes.contains(newTag)) { + if (inbounds.contains(originalTag) && inboundNodes.contains(originalTag)) + { + if (inbounds.contains(newTag) && inboundNodes.contains(newTag)) + { QvMessageBoxWarn(this, tr("Rename tags"), tr("The new tag has been used, we appended a postfix.")); newTag += "_" + GenerateRandomString(5); } @@ -190,26 +202,29 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, inboundNodes[newTag] = inboundNodes.take(originalTag); auto node = static_cast(inboundNodes[newTag]->nodeDataModel()); - if (node == nullptr) { - LOG(MODULE_GRAPH, "EMPTY NODE WARN") - } + if (node == nullptr) { LOG(MODULE_GRAPH, "EMPTY NODE WARN") } node->setData(newTag); // Change inbound tag in rules accordingly. // k -> rule tag // v -> rule object - for (auto k : rules.keys()) { + for (auto k : rules.keys()) + { auto v = rules[k]; - if (v.inboundTag.contains(originalTag)) { + if (v.inboundTag.contains(originalTag)) + { v.inboundTag.append(newTag); v.inboundTag.removeAll(originalTag); - // Put this inside the if block since no need an extra operation if the condition is false. + // Put this inside the if block since no need an extra + // operation if the condition is false. rules[k] = v; } } - } else { + } + else + { LOG(MODULE_UI, "Failed to rename an outbound --> Item not found.") } @@ -219,26 +234,31 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, void RouteEditor::ResolveDefaultOutboundTag(QString original, QString newTag) { - LOG(MODULE_UI, "Resolving default outbound settings: default=" + defaultOutbound + " original=" + original + " new=" + newTag) + LOG(MODULE_UI, "Resolving default outbound settings: default=" + defaultOutbound + " original=" + original + " new=" + newTag) auto isDefaultChanged = original == defaultOutbound; defaultOutboundCombo->clear(); defaultOutboundCombo->addItems(outbounds.keys()); - if (!isDefaultChanged) { + if (!isDefaultChanged) + { LOG(MODULE_UI, "Default outbound is not changed: retaining: " + defaultOutbound) // Just simply restore the default one. defaultOutboundCombo->setCurrentText(defaultOutbound); - } else if (newTag.isEmpty()) { + } + else if (newTag.isEmpty()) + { LOG(MODULE_UI, "Default outbound is removed, using first key from the outbounds as the default one.") // Removed the default one, so set the first one as the default. - if (outbounds.isEmpty()) { - defaultOutbound.clear(); - } else { + if (outbounds.isEmpty()) { defaultOutbound.clear(); } + else + { defaultOutbound = getTag(outbounds.first()); defaultOutboundCombo->addItem(outbounds.firstKey()); } - } else { + } + else + { LOG(MODULE_UI, "Default outbound is renamed, ") defaultOutboundCombo->setCurrentText(newTag); defaultOutbound = newTag; diff --git a/src/ui/messaging/QvMessageBus.cpp b/src/ui/messaging/QvMessageBus.cpp index 122d4314..5b2514a4 100644 --- a/src/ui/messaging/QvMessageBus.cpp +++ b/src/ui/messaging/QvMessageBus.cpp @@ -1,8 +1,9 @@ -#include - #include "QvMessageBus.hpp" + #include "base/Qv2rayBase.hpp" +#include + namespace Qv2ray::ui::messaging { QvMessageBusObject::QvMessageBusObject() @@ -15,4 +16,4 @@ namespace Qv2ray::ui::messaging LOG(MODULE_MESSAGING, "Emitting signal: " + QString(metaEnum.valueToKey(msg))); emit QvSendMessage(msg); } -} +} // namespace Qv2ray::ui::messaging diff --git a/src/ui/messaging/QvMessageBus.hpp b/src/ui/messaging/QvMessageBus.hpp index ca36fd69..4ef11e91 100644 --- a/src/ui/messaging/QvMessageBus.hpp +++ b/src/ui/messaging/QvMessageBus.hpp @@ -6,28 +6,27 @@ #define QvMessageBusSlotSig const QvMBMessage &msg #define QvMessageBusSlotIdentifier on_QvMessageReceived -#define QvMessageBusSlotDecl void QvMessageBusSlotIdentifier(QvMessageBusSlotSig); +#define QvMessageBusSlotDecl void QvMessageBusSlotIdentifier(QvMessageBusSlotSig) #define QvMessageBusSlotImpl(CLASSNAME) void CLASSNAME::QvMessageBusSlotIdentifier(QvMessageBusSlotSig) -#define MBShowDefaultImpl \ - case SHOW_WINDOWS:\ - this->setWindowOpacity(1);\ - break; +#define MBShowDefaultImpl \ + case SHOW_WINDOWS: \ + this->setWindowOpacity(1); \ + break; -#define MBHideDefaultImpl \ - case HIDE_WINDOWS:\ - this->setWindowOpacity(0);\ - break; +#define MBHideDefaultImpl \ + case HIDE_WINDOWS: \ + this->setWindowOpacity(0); \ + break; -#define MBRetranslateDefaultImpl \ - case RETRANSLATE:\ - this->retranslateUi(this);\ - break; +#define MBRetranslateDefaultImpl \ + case RETRANSLATE: this->retranslateUi(this); break; namespace Qv2ray::ui::messaging { Q_NAMESPACE - enum QvMBMessage { + enum QvMBMessage + { /// Show all windows. SHOW_WINDOWS, /// Hide all windows. @@ -43,20 +42,20 @@ namespace Qv2ray::ui::messaging // class QvMessageBusObject : public QObject { - Q_OBJECT - public: - explicit QvMessageBusObject(); + Q_OBJECT + public: + explicit QvMessageBusObject(); - // - void EmitGlobalSignal(const QvMBMessage &msg); - signals: - void QvSendMessage(const QvMBMessage &msg); - //private slots: - // void on_QvMessageReceived(QvMessage msg); + // + void EmitGlobalSignal(const QvMBMessage &msg); + signals: + void QvSendMessage(const QvMBMessage &msg); + // private slots: + // void on_QvMessageReceived(QvMessage msg); }; // Danger, new is used here. Possible memory leak (hope not so much leak) inline QvMessageBusObject messageBus = QvMessageBusObject(); -} +} // namespace Qv2ray::ui::messaging using namespace Qv2ray::ui::messaging; diff --git a/src/ui/models/InboundNodeModel.cpp b/src/ui/models/InboundNodeModel.cpp index c83ba037..caa42543 100644 --- a/src/ui/models/InboundNodeModel.cpp +++ b/src/ui/models/InboundNodeModel.cpp @@ -1,6 +1,6 @@ #include "ui/models/InboundNodeModel.hpp" -QvInboundNodeModel::QvInboundNodeModel(std::shared_ptr data): NodeDataModel() +QvInboundNodeModel::QvInboundNodeModel(std::shared_ptr data) : NodeDataModel() { _in = data; _label = new QLabel(); diff --git a/src/ui/models/InboundNodeModel.hpp b/src/ui/models/InboundNodeModel.hpp index 472bd410..fac642d4 100644 --- a/src/ui/models/InboundNodeModel.hpp +++ b/src/ui/models/InboundNodeModel.hpp @@ -1,68 +1,72 @@ #pragma once -#include #include "ui/models/NodeModelsBase.hpp" +#include + class QvInboundNodeModel : public NodeDataModel { - Q_OBJECT - public: - explicit QvInboundNodeModel(std::shared_ptr data); - ~QvInboundNodeModel() - { - //if (_label) { - // delete _label; - //} - } + Q_OBJECT + public: + explicit QvInboundNodeModel(std::shared_ptr data); + ~QvInboundNodeModel() + { + // if (_label) { + // delete _label; + //} + } - QString caption() const override - { - return "Nothing"; - } + QString caption() const override + { + return "Nothing"; + } - bool captionVisible() const override - { - return false; - } + bool captionVisible() const override + { + return false; + } - unsigned int nPorts(PortType portType) const override - { - return portType == PortType::Out ? 1 : 0; - } + unsigned int nPorts(PortType portType) const override + { + return portType == PortType::Out ? 1 : 0; + } - QString name() const override - { - return "InboundNode"; - } + QString name() const override + { + return "InboundNode"; + } - NodeDataType dataType(PortType portType, PortIndex portIndex) const override - { - Q_UNUSED(portType); - Q_UNUSED(portIndex); - return inboundType; - } + NodeDataType dataType(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return inboundType; + } - std::shared_ptr outData(PortIndex) override - { - return _in; - } + std::shared_ptr outData(PortIndex) override + { + return _in; + } - void setInData(std::shared_ptr, int) override {} - void setData(const QString &data) - { - _in = make_shared(data); - _label->setText(data); - _label->adjustSize(); - } + void setInData(std::shared_ptr, int) override + { + } + void setData(const QString &data) + { + _in = make_shared(data); + _label->setText(data); + _label->adjustSize(); + } - QWidget *embeddedWidget() override - { - return _label; - } - private: - NodeValidationState modelValidationState = NodeValidationState::Warning; - QString modelValidationError = tr("Missing or incorrect inputs"); - // - std::shared_ptr _in; - QLabel *_label; + QWidget *embeddedWidget() override + { + return _label; + } + + private: + NodeValidationState modelValidationState = NodeValidationState::Warning; + QString modelValidationError = tr("Missing or incorrect inputs"); + // + std::shared_ptr _in; + QLabel *_label; }; diff --git a/src/ui/models/NodeModelsBase.hpp b/src/ui/models/NodeModelsBase.hpp index 36d3336b..69b5f204 100644 --- a/src/ui/models/NodeModelsBase.hpp +++ b/src/ui/models/NodeModelsBase.hpp @@ -1,101 +1,99 @@ #pragma once -#include - #include "NodeDataModel.hpp" #include "PortType.hpp" - #include "common/QvHelpers.hpp" -using QtNodes::PortType; -using QtNodes::PortIndex; +#include + using QtNodes::NodeData; -using QtNodes::NodeDataType; using QtNodes::NodeDataModel; -using QtNodes::NodeValidationState; - - using QtNodes::NodeDataType; +using QtNodes::NodeValidationState; +using QtNodes::PortIndex; +using QtNodes::PortType; + using QtNodes::NodeData; +using QtNodes::NodeDataType; const int GRAPH_NODE_LABEL_FONTSIZE_INCREMENT = 3; namespace Qv2ray::ui::nodemodels { - const NodeDataType outboundType = {"outbound", "Outbound Object"}; - const NodeDataType inboundType = {"inbound", "Inbound Object"}; + const NodeDataType outboundType = { "outbound", "Outbound Object" }; + const NodeDataType inboundType = { "inbound", "Inbound Object" }; /// The class can potentially incapsulate any user data /// need to be transferred within the Node Editor graph class InboundNodeData : public NodeData { - public: - InboundNodeData() - { - DEBUG(MODULE_GRAPH, "DANGER: Initialising a data model without value.") - } - InboundNodeData(QString in) : _inboundTag(in) { } + public: + InboundNodeData(){ DEBUG(MODULE_GRAPH, "DANGER: Initialising a data model without value.") } InboundNodeData(QString in) + : _inboundTag(in) + { + } - NodeDataType type() const override - { - return inboundType; - } + NodeDataType type() const override + { + return inboundType; + } - QString GetInbound() - { - return _inboundTag; - } - private: - QString _inboundTag; + QString GetInbound() + { + return _inboundTag; + } + + private: + QString _inboundTag; }; /// The class can potentially incapsulate any user data /// need to be transferred within the Node Editor graph class OutboundNodeData : public NodeData { - public: - OutboundNodeData() : _outboundTag() - { - DEBUG(MODULE_GRAPH, "DANGER: Initialising a data model without value.") - } - OutboundNodeData(QString out) : _outboundTag(out) { } + public: + OutboundNodeData() + : _outboundTag(){ DEBUG(MODULE_GRAPH, "DANGER: Initialising a data model without value.") } OutboundNodeData(QString out) + : _outboundTag(out) + { + } - NodeDataType type() const override - { - return outboundType; - } + NodeDataType type() const override + { + return outboundType; + } - QString GetOutbound() - { - return _outboundTag; - } - private: - QString _outboundTag; + QString GetOutbound() + { + return _outboundTag; + } + + private: + QString _outboundTag; }; /// The class can potentially incapsulate any user data /// need to be transferred within the Node Editor graph class RuleNodeData : public NodeData { - public: - RuleNodeData() : _ruleTag() - { - DEBUG(MODULE_GRAPH, "DANGER: Initialising a data model without value.") - } - RuleNodeData(QString out) : _ruleTag(out) { } + public: + RuleNodeData() + : _ruleTag(){ DEBUG(MODULE_GRAPH, "DANGER: Initialising a data model without value.") } RuleNodeData(QString out) : _ruleTag(out) + { + } - NodeDataType type() const override - { - return outboundType; - } + NodeDataType type() const override + { + return outboundType; + } - QString GetRuleTag() - { - return _ruleTag; - } - private: - QString _ruleTag; + QString GetRuleTag() + { + return _ruleTag; + } + + private: + QString _ruleTag; }; -} - +} // namespace Qv2ray::ui::nodemodels using namespace Qv2ray::ui::nodemodels; diff --git a/src/ui/models/OutboundNodeModel.cpp b/src/ui/models/OutboundNodeModel.cpp index a73d87a7..37f6ee80 100644 --- a/src/ui/models/OutboundNodeModel.cpp +++ b/src/ui/models/OutboundNodeModel.cpp @@ -1,6 +1,6 @@ #include "ui/models/OutboundNodeModel.hpp" -QvOutboundNodeModel::QvOutboundNodeModel(std::shared_ptr data): NodeDataModel() +QvOutboundNodeModel::QvOutboundNodeModel(std::shared_ptr data) : NodeDataModel() { _out = data; _label = new QLabel(); diff --git a/src/ui/models/OutboundNodeModel.hpp b/src/ui/models/OutboundNodeModel.hpp index 1a23a985..d1e9ce2a 100644 --- a/src/ui/models/OutboundNodeModel.hpp +++ b/src/ui/models/OutboundNodeModel.hpp @@ -1,74 +1,80 @@ #pragma once -#include #include "ui/models/NodeModelsBase.hpp" +#include + class QvOutboundNodeModel : public NodeDataModel { - Q_OBJECT - public: - explicit QvOutboundNodeModel(std::shared_ptr data); - ~QvOutboundNodeModel() - { - //if (_label) { - // delete _label; - //} - } + Q_OBJECT + public: + explicit QvOutboundNodeModel(std::shared_ptr data); + ~QvOutboundNodeModel() + { + // if (_label) { + // delete _label; + //} + } - QString caption() const override - { - return "Nothing"; - } + QString caption() const override + { + return "Nothing"; + } - bool captionVisible() const override - { - return false; - } + bool captionVisible() const override + { + return false; + } - unsigned int nPorts(PortType portType) const override - { - return portType == PortType::In ? 1 : 0; - } + unsigned int nPorts(PortType portType) const override + { + return portType == PortType::In ? 1 : 0; + } - QString name() const override - { - return "OutboundNode"; - } + QString name() const override + { + return "OutboundNode"; + } - NodeDataType dataType(PortType portType, PortIndex portIndex) const override - { - Q_UNUSED(portType); - Q_UNUSED(portIndex); - return outboundType; - } + NodeDataType dataType(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return outboundType; + } - std::shared_ptr outData(PortIndex) override - { - return _out; - } + std::shared_ptr outData(PortIndex) override + { + return _out; + } - void setInData(shared_ptr, int) override {} + void setInData(shared_ptr, int) override + { + } - void setInData(vector>, int) override {} - void setData(const QString &data) - { - _out = make_shared(data); - _label->setText(_out->GetOutbound()); - _label->adjustSize(); - } + void setInData(vector>, int) override + { + } + void setData(const QString &data) + { + _out = make_shared(data); + _label->setText(_out->GetOutbound()); + _label->adjustSize(); + } - QWidget *embeddedWidget() override - { - return _label; - } + QWidget *embeddedWidget() override + { + return _label; + } - ConnectionPolicy portInConnectionPolicy(PortIndex) const override - { - return ConnectionPolicy::Many; - } - private: - NodeValidationState modelValidationState = NodeValidationState::Warning; - QString modelValidationError = tr("Missing or incorrect inputs"); - // - std::shared_ptr _out; - QLabel *_label; + ConnectionPolicy portInConnectionPolicy(PortIndex) const override + { + return ConnectionPolicy::Many; + } + + private: + NodeValidationState modelValidationState = NodeValidationState::Warning; + QString modelValidationError = tr("Missing or incorrect inputs"); + // + std::shared_ptr _out; + QLabel *_label; }; diff --git a/src/ui/models/RuleNodeModel.cpp b/src/ui/models/RuleNodeModel.cpp index f62c02ab..8d668ca3 100644 --- a/src/ui/models/RuleNodeModel.cpp +++ b/src/ui/models/RuleNodeModel.cpp @@ -1,6 +1,6 @@ #include "ui/models/RuleNodeModel.hpp" -QvRuleNodeDataModel::QvRuleNodeDataModel(std::shared_ptr data): NodeDataModel() +QvRuleNodeDataModel::QvRuleNodeDataModel(std::shared_ptr data) : NodeDataModel() { _ruleTag = data; _label = new QLabel(); diff --git a/src/ui/models/RuleNodeModel.hpp b/src/ui/models/RuleNodeModel.hpp index bf75fa2b..4f27eb0b 100644 --- a/src/ui/models/RuleNodeModel.hpp +++ b/src/ui/models/RuleNodeModel.hpp @@ -1,98 +1,103 @@ #pragma once -#include #include "ui/models/NodeModelsBase.hpp" +#include + class QvRuleNodeDataModel : public NodeDataModel { - Q_OBJECT - public: - QvRuleNodeDataModel(std::shared_ptr data); - ~QvRuleNodeDataModel() + Q_OBJECT + public: + QvRuleNodeDataModel(std::shared_ptr data); + ~QvRuleNodeDataModel() + { + // if (_label) { + // delete _label; + //} + } + + QString caption() const override + { + return "Nothing"; + } + + bool captionVisible() const override + { + return false; + } + + unsigned int nPorts(PortType portType) const override + { + if (portType == PortType::In) { return 1; } + else if (portType == PortType::Out) { - //if (_label) { - // delete _label; - //} + return 1; + } + else + { + return 0; + } + } + + QString name() const override + { + return "RuleNode"; + } + + NodeDataType dataType(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portIndex) + + switch (portType) + { + case PortType::In: return inboundType; + + case PortType::Out: return outboundType; + + case PortType::None: break; } - QString caption() const override - { - return "Nothing"; - } + return NodeDataType(); + } - bool captionVisible() const override - { - return false; - } + std::shared_ptr outData(PortIndex port) override + { + Q_UNUSED(port) + return _ruleTag; + } - unsigned int nPorts(PortType portType) const override - { - if (portType == PortType::In) { - return 1; - } else if (portType == PortType::Out) { - return 1; - } else { - return 0; - } - } + void setInData(std::shared_ptr, int) override + { + } + void setInData(vector>, int) override + { + } + void setData(const QString &data) + { + _ruleTag = make_shared(data); + _label->setText(_ruleTag->GetRuleTag()); + _label->adjustSize(); + } - QString name() const override - { - return "RuleNode"; - } + QWidget *embeddedWidget() override + { + return _label; + } - NodeDataType dataType(PortType portType, PortIndex portIndex) const override - { - Q_UNUSED(portIndex) + ConnectionPolicy portInConnectionPolicy(PortIndex) const override + { + return ConnectionPolicy::Many; + } - switch (portType) { - case PortType::In: - return inboundType; + ConnectionPolicy portOutConnectionPolicy(PortIndex) const override + { + return ConnectionPolicy::One; + } - case PortType::Out: - return outboundType; - - case PortType::None: - break; - } - - return NodeDataType(); - } - - std::shared_ptr outData(PortIndex port) override - { - Q_UNUSED(port) - return _ruleTag; - } - - void setInData(std::shared_ptr, int) override {} - void setInData(vector>, int) override {} - void setData(const QString &data) - { - _ruleTag = make_shared(data); - _label->setText(_ruleTag->GetRuleTag()); - _label->adjustSize(); - } - - QWidget *embeddedWidget() override - { - return _label; - } - - ConnectionPolicy portInConnectionPolicy(PortIndex) const override - { - return ConnectionPolicy::Many; - } - - ConnectionPolicy portOutConnectionPolicy(PortIndex) const override - { - return ConnectionPolicy::One; - } - - private: - NodeValidationState modelValidationState = NodeValidationState::Warning; - QString modelValidationError = tr("Missing or incorrect inputs"); - // - shared_ptr _ruleTag; - QLabel *_label; + private: + NodeValidationState modelValidationState = NodeValidationState::Warning; + QString modelValidationError = tr("Missing or incorrect inputs"); + // + shared_ptr _ruleTag; + QLabel *_label; }; diff --git a/src/ui/w_ExportConfig.cpp b/src/ui/w_ExportConfig.cpp index 9c91f107..fa659aba 100644 --- a/src/ui/w_ExportConfig.cpp +++ b/src/ui/w_ExportConfig.cpp @@ -1,12 +1,11 @@ #include "w_ExportConfig.hpp" #include "common/QvHelpers.hpp" #include "core/connection/Serialization.hpp" + #include // Private initialiser -ConfigExporter::ConfigExporter(QWidget *parent) : - QDialog(parent), - qzxing(this) +ConfigExporter::ConfigExporter(QWidget *parent) : QDialog(parent), qzxing(this) { setupUi(this); QvMessageBusConnect(ConfigExporter); @@ -14,10 +13,9 @@ ConfigExporter::ConfigExporter(QWidget *parent) : QvMessageBusSlotImpl(ConfigExporter) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -25,7 +23,7 @@ ConfigExporter::~ConfigExporter() { } -//ConfigExporter::ConfigExporter(QWidget *parent) : ConfigExporter(parent) +// ConfigExporter::ConfigExporter(QWidget *parent) : ConfigExporter(parent) //{ // // WIP // // /auto &x = connection; @@ -49,17 +47,13 @@ void ConfigExporter::changeEvent(QEvent *e) { QDialog::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - retranslateUi(this); - break; + switch (e->type()) + { + case QEvent::LanguageChange: retranslateUi(this); break; - case QEvent::Resize: - imageLabel->setPixmap(QPixmap::fromImage(image)); - break; + case QEvent::Resize: imageLabel->setPixmap(QPixmap::fromImage(image)); break; - default: - break; + default: break; } } diff --git a/src/ui/w_ExportConfig.hpp b/src/ui/w_ExportConfig.hpp index 4bbf95a9..ffce983a 100644 --- a/src/ui/w_ExportConfig.hpp +++ b/src/ui/w_ExportConfig.hpp @@ -1,32 +1,36 @@ #pragma once -#include "ui_w_ExportConfig.h" -#include "base/Qv2rayBase.hpp" #include "3rdparty/qzxing/src/QZXing.h" +#include "base/Qv2rayBase.hpp" #include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_ExportConfig.h" -class ConfigExporter : public QDialog, private Ui::ExportConfigWindow +class ConfigExporter + : public QDialog + , private Ui::ExportConfigWindow { - Q_OBJECT + Q_OBJECT - public: - explicit ConfigExporter(QWidget *parent = nullptr); - ~ConfigExporter(); - void OpenExport(); - public slots: - QvMessageBusSlotDecl - protected: - void changeEvent(QEvent *e); - private slots: - void on_closeBtn_clicked(); + public: + explicit ConfigExporter(QWidget *parent = nullptr); + ~ConfigExporter(); + void OpenExport(); + public slots: + QvMessageBusSlotDecl; - void on_saveBtn_clicked(); + protected: + void changeEvent(QEvent *e); + private slots: + void on_closeBtn_clicked(); - void on_copyImageBtn_clicked(); + void on_saveBtn_clicked(); - void on_copyVMessBtn_clicked(); - private: - QZXing qzxing; - QImage image; - QString message; + void on_copyImageBtn_clicked(); + + void on_copyVMessBtn_clicked(); + + private: + QZXing qzxing; + QImage image; + QString message; }; diff --git a/src/ui/w_ImportConfig.cpp b/src/ui/w_ImportConfig.cpp index 622eb657..573ceb3f 100644 --- a/src/ui/w_ImportConfig.cpp +++ b/src/ui/w_ImportConfig.cpp @@ -1,26 +1,25 @@ #include +#include "w_ImportConfig.hpp" + +#include "3rdparty/qzxing/src/QZXing.h" +#include "core/CoreUtils.hpp" +#include "core/connection/ConnectionIO.hpp" +#include "core/connection/Serialization.hpp" +#include "core/kernel/KernelInteractions.hpp" +#include "ui/editors/w_JsonEditor.hpp" +#include "ui/editors/w_OutboundEditor.hpp" +#include "ui/editors/w_RoutesEditor.hpp" +#include "ui/w_SubscriptionManager.hpp" +#include "w_ScreenShot_Core.hpp" + #include #include #include #include #include #include -#include "3rdparty/qzxing/src/QZXing.h" -#include "core/CoreUtils.hpp" -#include "core/kernel/KernelInteractions.hpp" -#include "core/connection/ConnectionIO.hpp" -#include "core/connection/Serialization.hpp" - -#include "w_ScreenShot_Core.hpp" -#include "ui/editors/w_OutboundEditor.hpp" -#include "ui/editors/w_JsonEditor.hpp" -#include "w_ImportConfig.hpp" -#include "ui/w_SubscriptionManager.hpp" -#include "ui/editors/w_RoutesEditor.hpp" - -ImportConfigWindow::ImportConfigWindow(QWidget *parent) - : QDialog(parent) +ImportConfigWindow::ImportConfigWindow(QWidget *parent) : QDialog(parent) { setupUi(this); nameTxt->setText(QDateTime::currentDateTime().toString("MMdd_hhmm")); @@ -30,10 +29,9 @@ ImportConfigWindow::ImportConfigWindow(QWidget *parent) QvMessageBusSlotImpl(ImportConfigWindow) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -43,7 +41,8 @@ ImportConfigWindow::~ImportConfigWindow() QMap ImportConfigWindow::OpenImport(bool partialImport) { - // partial import means only import as an outbound, will set keepImported to false and disable the checkbox + // partial import means only import as an outbound, will set keepImported to + // false and disable the checkbox // keepImportedInboundCheckBox->setChecked(!outboundsOnly); keepImportedInboundCheckBox->setEnabled(!partialImport); routeEditBtn->setEnabled(!partialImport); @@ -61,9 +60,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked() { bool hideQv2ray = hideQv2rayCB->isChecked(); - if (hideQv2ray) { - messageBus.EmitGlobalSignal(QvMBMessage::HIDE_WINDOWS); - } + if (hideQv2ray) { messageBus.EmitGlobalSignal(QvMBMessage::HIDE_WINDOWS); } QApplication::processEvents(); QThread::msleep(static_cast(doubleSpinBox->value() * 1000)); @@ -72,24 +69,29 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked() auto _r = w.result(); // Explicitly delete w to call UNREGISTER_WINDOW - if (hideQv2ray) { + if (hideQv2ray) + { messageBus.EmitGlobalSignal(QvMBMessage::SHOW_WINDOWS); - //ShowAllGlobalWindow(); + // ShowAllGlobalWindow(); } - if (_r == QDialog::Accepted) { + if (_r == QDialog::Accepted) + { QZXing decoder; decoder.setDecoder(QZXing::DecoderFormat_QR_CODE | QZXing::DecoderFormat_EAN_13); auto str = decoder.decodeImage(pix); - //auto str = QZXing().decodeImage(pix); + // auto str = QZXing().decodeImage(pix); - if (str.trimmed().isEmpty()) { + if (str.trimmed().isEmpty()) + { LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + QSTRN(pix.width()) + ", v=" + QSTRN(pix.height())) QvMessageBoxWarn(this, tr("Capture QRCode"), tr("Cannot find a valid QRCode from this region.")); - } else { + } + else + { vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE); - //QvMessageBoxWarn(this, tr("Capture QRCode"), tr("Successfully imported a QR code form the screen.")); - //this->show(); + // QvMessageBoxWarn(this, tr("Capture QRCode"), tr("Successfully + // imported a QR code form the screen.")); this->show(); } } } @@ -97,26 +99,30 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked() void ImportConfigWindow::on_beginImportBtn_clicked() { QString aliasPrefix = nameTxt->text(); - //auto conf = GetGlobalConfig(); + // auto conf = GetGlobalConfig(); - switch (tabWidget->currentIndex()) { - case 0: { + switch (tabWidget->currentIndex()) + { + case 0: + { //// From File... - //bool ImportAsComplex = keepImportedInboundCheckBox->isChecked(); - //QString path = fileLineTxt->text(); + // bool ImportAsComplex = keepImportedInboundCheckBox->isChecked(); + // QString path = fileLineTxt->text(); // - //if (!V2rayKernelInstance::ValidateConfig(path)) { - // QvMessageBoxWarn(this, tr("Import config file"), tr("Failed to check the validity of the config file.")); - // return; + // if (!V2rayKernelInstance::ValidateConfig(path)) { + // QvMessageBoxWarn(this, tr("Import config file"), tr("Failed to + // check the validity of the config file.")); return; //} // - //aliasPrefix += "_" + QFileInfo(path).fileName(); - ////CONFIGROOT config = ConvertConfigFromFile(path, ImportAsComplex); - //connections[aliasPrefix] = config; - //break; + // aliasPrefix += "_" + QFileInfo(path).fileName(); + ////CONFIGROOT config = ConvertConfigFromFile(path, + /// ImportAsComplex); + // connections[aliasPrefix] = config; + // break; } - case 1: { + case 1: + { QStringList linkList = SplitLines(vmessConnectionStringTxt->toPlainText()); // // Clear UI and error lists @@ -126,24 +132,30 @@ void ImportConfigWindow::on_beginImportBtn_clicked() // LOG(MODULE_IMPORT, QSTRN(linkList.count()) + " string found in vmess box.") - while (!linkList.isEmpty()) { + while (!linkList.isEmpty()) + { aliasPrefix = nameTxt->text(); auto link = linkList.takeFirst(); QString errMessage; CONFIGROOT config = ConvertConfigFromString(link, &aliasPrefix, &errMessage); // If the config is empty or we have any err messages. - if (config.isEmpty() || !errMessage.isEmpty()) { + if (config.isEmpty() || !errMessage.isEmpty()) + { // To prevent duplicated values. linkErrors[link] = QSTRN(linkErrors.count() + 1) + ": " + errMessage; continue; - } else { + } + else + { connections[aliasPrefix] = config; } } - if (!linkErrors.isEmpty()) { - for (auto item : linkErrors) { + if (!linkErrors.isEmpty()) + { + for (auto item : linkErrors) + { vmessConnectionStringTxt->appendPlainText(linkErrors.key(item)); errorsList->addItem(item); } @@ -173,10 +185,13 @@ void ImportConfigWindow::on_selectImageBtn_clicked() decoder.setDecoder(QZXing::DecoderFormat_QR_CODE | QZXing::DecoderFormat_EAN_13); auto str = decoder.decodeImage(QImage::fromData(buf)); - if (str.isEmpty()) { + if (str.isEmpty()) + { QvMessageBoxWarn(this, tr("QRCode scanning failed"), tr("Cannot find any QRCode from the image.")); return; - } else { + } + else + { vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE); } } @@ -184,9 +199,7 @@ void ImportConfigWindow::on_errorsList_currentItemChanged(QListWidgetItem *curre { Q_UNUSED(previous) - if (current == nullptr) { - return; - } + if (current == nullptr) { return; } auto currentErrorText = current->text(); auto vmessEntry = linkErrors.key(currentErrorText); @@ -194,9 +207,7 @@ void ImportConfigWindow::on_errorsList_currentItemChanged(QListWidgetItem *curre auto startPos = vmessConnectionStringTxt->toPlainText().indexOf(vmessEntry); auto endPos = startPos + vmessEntry.length(); - if (startPos < 0) { - return; - } + if (startPos < 0) { return; } // Select vmess string that is invalid. QTextCursor c = vmessConnectionStringTxt->textCursor(); @@ -208,36 +219,43 @@ void ImportConfigWindow::on_editFileBtn_clicked() { QFile file(fileLineTxt->text()); - if (!file.exists()) { - QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Provided file not found: ") + fileLineTxt->text()); + if (!file.exists()) + { + QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Provided file not found: ") + fileLineTxt->text()); return; } auto jsonString = StringFromFile(&file); auto jsonCheckingError = VerifyJsonString(jsonString); - if (!jsonCheckingError.isEmpty()) { + if (!jsonCheckingError.isEmpty()) + { LOG(MODULE_FILEIO, "Currupted JSON file detected") - if (QvMessageBoxAsk(this, tr("Edit file as JSON"), tr("The file you selected has json syntax error. Continue editing may make you lose data. Would you like to continue?") + NEWLINE + jsonCheckingError) != QMessageBox::Yes) { - return; - } else { + if (QvMessageBoxAsk( + this, tr("Edit file as JSON"), + tr("The file you selected has json syntax error. Continue editing may make you lose data. Would you like to continue?") + + NEWLINE + jsonCheckingError) != QMessageBox::Yes) + { return; } + else + { LOG(MODULE_FILEIO, "Continue editing curruped json file, data loss is expected.") } } - auto json = JsonFromString(jsonString); + auto json = JsonFromString(jsonString); JsonEditor editor(json, this); json = editor.OpenEditor(); - if (editor.result() == QDialog::Accepted) { + if (editor.result() == QDialog::Accepted) + { auto str = JsonToString(json); bool result = StringToFile(str, file); - if (!result) { - QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Failed to save file, please check if you have proper permissions")); - } - } else { + if (!result) { QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Failed to save file, please check if you have proper permissions")); } + } + else + { LOG(MODULE_FILEIO, "Canceled saving a file.") } } @@ -249,7 +267,8 @@ void ImportConfigWindow::on_connectionEditBtn_clicked() bool isChanged = w.result() == QDialog::Accepted; QString alias = w.GetFriendlyName(); - if (isChanged) { + if (isChanged) + { OUTBOUNDS outboundsList; outboundsList.push_back(outboundEntry); CONFIGROOT root; @@ -257,7 +276,9 @@ void ImportConfigWindow::on_connectionEditBtn_clicked() // connections[alias] = root; accept(); - } else { + } + else + { return; } } @@ -275,7 +296,8 @@ void ImportConfigWindow::on_subscriptionButton_clicked() auto importToComplex = !keepImportedInboundCheckBox->isEnabled(); connections.clear(); - if (importToComplex) { + if (importToComplex) + { auto _result = w.GetSelectedConfig(); connections[_result.first] = _result.second; } @@ -290,10 +312,13 @@ void ImportConfigWindow::on_routeEditBtn_clicked() bool isChanged = w.result() == QDialog::Accepted; QString alias = nameTxt->text(); - if (isChanged) { + if (isChanged) + { connections[alias] = result; accept(); - } else { + } + else + { return; } } diff --git a/src/ui/w_ImportConfig.hpp b/src/ui/w_ImportConfig.hpp index 718e8657..09bbbd0c 100644 --- a/src/ui/w_ImportConfig.hpp +++ b/src/ui/w_ImportConfig.hpp @@ -1,44 +1,47 @@ #pragma once -#include -#include -#include #include "base/Qv2rayBase.hpp" -#include "ui_w_ImportConfig.h" #include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_ImportConfig.h" -class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow +#include +#include +#include + +class ImportConfigWindow + : public QDialog + , private Ui::ImportConfigWindow { - Q_OBJECT + Q_OBJECT - public: - explicit ImportConfigWindow(QWidget *parent = nullptr); - ~ImportConfigWindow(); - QMap OpenImport(bool outboundsOnly = false); - public slots: - QvMessageBusSlotDecl - private slots: + public: + explicit ImportConfigWindow(QWidget *parent = nullptr); + ~ImportConfigWindow(); + QMap OpenImport(bool outboundsOnly = false); + public slots: + QvMessageBusSlotDecl; + private slots: - void on_selectFileBtn_clicked(); + void on_selectFileBtn_clicked(); - void on_qrFromScreenBtn_clicked(); - void on_beginImportBtn_clicked(); - void on_selectImageBtn_clicked(); - void on_errorsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); + void on_qrFromScreenBtn_clicked(); + void on_beginImportBtn_clicked(); + void on_selectImageBtn_clicked(); + void on_errorsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); - void on_editFileBtn_clicked(); + void on_editFileBtn_clicked(); - void on_connectionEditBtn_clicked(); + void on_connectionEditBtn_clicked(); - void on_cancelImportBtn_clicked(); + void on_cancelImportBtn_clicked(); - void on_subscriptionButton_clicked(); + void on_subscriptionButton_clicked(); - void on_routeEditBtn_clicked(); + void on_routeEditBtn_clicked(); - void on_hideQv2rayCB_stateChanged(int arg1); + void on_hideQv2rayCB_stateChanged(int arg1); - private: - QMap connections; - QMap linkErrors; + private: + QMap connections; + QMap linkErrors; }; diff --git a/src/ui/w_MainWindow.cpp b/src/ui/w_MainWindow.cpp index 9dda22e4..39743d16 100644 --- a/src/ui/w_MainWindow.cpp +++ b/src/ui/w_MainWindow.cpp @@ -1,76 +1,86 @@ #pragma once #include "w_MainWindow.hpp" + +#include "ui/editors/w_JsonEditor.hpp" +#include "ui/editors/w_OutboundEditor.hpp" +#include "ui/editors/w_RoutesEditor.hpp" +#include "w_ExportConfig.hpp" #include "w_ImportConfig.hpp" #include "w_PreferencesWindow.hpp" #include "w_SubscriptionManager.hpp" -#include "w_ExportConfig.hpp" -#include "ui/editors/w_OutboundEditor.hpp" -#include "ui/editors/w_RoutesEditor.hpp" -#include "ui/editors/w_JsonEditor.hpp" //#include +#include "components/pac/QvPACHandler.hpp" +#include "components/plugins/toolbar/QvToolbar.hpp" +#include "core/connection/ConnectionIO.hpp" +#include "ui/widgets/ConnectionInfoWidget.hpp" + #include #include +#include #include #include #include #include +#include #include #include -#include #include #include -#include -#include "components/plugins/toolbar/QvToolbar.hpp" -#include "components/pac/QvPACHandler.hpp" - -#include "core/connection/ConnectionIO.hpp" -#include "ui/widgets/ConnectionInfoWidget.hpp" - -// MainWindow.cpp --> Main MainWindow source file, handles mostly UI-related operations. +// MainWindow.cpp --> Main MainWindow source file, handles mostly UI-related +// operations. #define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING // -#define GetItemWidget(item) (qobject_cast(connectionListWidget->itemWidget(item, 0))) +#define GetItemWidget(item) (qobject_cast(connectionListWidget->itemWidget(item, 0))) /* -#define ItemConnectionIdentifier(__item__) (__item__->data(0, Qt::UserRole).value()) +#define ItemConnectionIdentifier(__item__) (__item__->data(0, +Qt::UserRole).value()) -#define CheckConfigType(_item_, TYPE) (connections.contains(ItemConnectionIdentifier(_item_)) && connections[ItemConnectionIdentifier(_item_)].configType == CONNECTION_ ## TYPE) +#define CheckConfigType(_item_, TYPE) +(connections.contains(ItemConnectionIdentifier(_item_)) && +connections[ItemConnectionIdentifier(_item_)].configType == CONNECTION_ ## TYPE) -#define SUBSCRIPTION_CONFIG_MODIFY_ASK(_item_) \ - if (!CheckConfigType(_item_, REGULAR)) { \ - if (QvMessageBoxAsk(this, QObject::tr("Editing a subscription config"), QObject::tr("You are trying to edit a config loaded from subscription.") + \ - NEWLINE + QObject::tr("All changes will be overwritten when the subscriptions are updated next time.") + \ - NEWLINE + QObject::tr("Are you still going to do so?")) != QMessageBox::Yes) { \ - return; \ - } \ - } \ +#define SUBSCRIPTION_CONFIG_MODIFY_ASK(_item_) \ + if (!CheckConfigType(_item_, REGULAR)) { \ + if (QvMessageBoxAsk(this, QObject::tr("Editing a subscription config"), +QObject::tr("You are trying to edit a config loaded from subscription.") + \ + NEWLINE + QObject::tr("All changes will be +overwritten when the subscriptions are updated next time.") + \ + NEWLINE + QObject::tr("Are you still going to do +so?")) != QMessageBox::Yes) { \ + return; \ + } \ + } \ -#define SUBSCRIPTION_CONFIG_MODIFY_DENY(_item_) \ - if (!CheckConfigType(_item_, REGULAR)) { \ - QvMessageBoxWarn(this, QObject::tr("Editing a subscription config"), QObject::tr("You should not modity this property of a config from a subscription")); \ - return; \ - } \ +#define SUBSCRIPTION_CONFIG_MODIFY_DENY(_item_) \ + if (!CheckConfigType(_item_, REGULAR)) { \ + QvMessageBoxWarn(this, QObject::tr("Editing a subscription config"), +QObject::tr("You should not modity this property of a config from a +subscription")); \ + return; \ + } \ -#define IsConnectableItem(item) (item != nullptr && item->childCount() == 0 && (CheckConfigType(item, REGULAR) || CheckConfigType(item, SUBSCRIPTION))) -#define IsSelectionConnectable (!connectionListWidget->selectedItems().empty() && IsConnectableItem(connectionListWidget->selectedItems().first())) +#define IsConnectableItem(item) (item != nullptr && item->childCount() == 0 && +(CheckConfigType(item, REGULAR) || CheckConfigType(item, SUBSCRIPTION))) #define +IsSelectionConnectable (!connectionListWidget->selectedItems().empty() && +IsConnectableItem(connectionListWidget->selectedItems().first())) */ MainWindow *MainWindow::mwInstance = nullptr; QvMessageBusSlotImpl(MainWindow) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } -MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTray(this), tcpingHelper(3, this) +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), hTray(this), tcpingHelper(3, this) { setupUi(this); MainWindow::mwInstance = this; @@ -86,8 +96,8 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr this->setWindowIcon(QIcon(":/assets/icons/qv2ray.png")); hTray.setIcon(QIcon(GlobalConfig.uiConfig.useDarkTrayIcon ? ":/assets/icons/ui_dark/tray.png" : ":/assets/icons/ui_light/tray.png")); importConfigButton->setIcon(QICON_R("import.png")); - //pingTestBtn->setIcon(QICON_R("ping_gauge.png")); - //shareBtn->setIcon(QICON_R("share.png")); + // pingTestBtn->setIcon(QICON_R("ping_gauge.png")); + // shareBtn->setIcon(QICON_R("share.png")); updownImageBox->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)"); updownImageBox_2->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)"); // @@ -96,7 +106,7 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr this->show(); QvMessageBoxWarn(this, tr("V2ray vcore terminated."), tr("V2ray vcore terminated unexpectedly.") + NEWLINE + NEWLINE + - tr("To solve the problem, read the V2ray log in the log text browser.")); + tr("To solve the problem, read the V2ray log in the log text browser.")); }); connect(ConnectionManager, &QvConnectionHandler::OnConnected, this, &MainWindow::OnConnected); connect(ConnectionManager, &QvConnectionHandler::OnDisConnected, this, &MainWindow::OnDisConnected); @@ -141,9 +151,11 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr // connect(action_Tray_ShowHide, &QAction::triggered, this, &MainWindow::ToggleVisibility); connect(action_Tray_ShowPreferencesWindow, &QAction::triggered, this, &MainWindow::on_preferencesBtn_clicked); - //connect(action_Tray_Start, &QAction::triggered, this, &MainWindow::on_startButton_clicked); - //connect(action_Tray_Stop, &QAction::triggered, this, &MainWindow::on_stopButton_clicked); - //connect(action_Tray_Reconnect, &QAction::triggered, this, &MainWindow::on_reconnectButton_clicked); + // connect(action_Tray_Start, &QAction::triggered, this, + // &MainWindow::on_startButton_clicked); connect(action_Tray_Stop, + // &QAction::triggered, this, &MainWindow::on_stopButton_clicked); + // connect(action_Tray_Reconnect, &QAction::triggered, this, + // &MainWindow::on_reconnectButton_clicked); connect(action_Tray_Quit, &QAction::triggered, this, &MainWindow::on_actionExit_triggered); connect(action_Tray_SetSystemProxy, &QAction::triggered, this, &MainWindow::MWSetSystemProxy); connect(action_Tray_ClearSystemProxy, &QAction::triggered, this, &MainWindow::MWClearSystemProxy); @@ -166,9 +178,11 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered); // // Globally invokable signals. - //connect(this, &MainWindow::Connect, this, &MainWindow::on_startButton_clicked); - //connect(this, &MainWindow::DisConnect, this, &MainWindow::on_stopButton_clicked); - //connect(this, &MainWindow::ReConnect, this, &MainWindow::on_reconnectButton_clicked); + // connect(this, &MainWindow::Connect, this, + // &MainWindow::on_startButton_clicked); connect(this, + // &MainWindow::DisConnect, this, &MainWindow::on_stopButton_clicked); + // connect(this, &MainWindow::ReConnect, this, + // &MainWindow::on_reconnectButton_clicked); // hTray.setContextMenu(tray_RootMenu); hTray.show(); @@ -183,13 +197,15 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr LOG(MODULE_UI, "Loading data...") auto groups = ConnectionManager->AllGroups(); - for (auto group : groups) { + for (auto group : groups) + { auto groupItem = new QTreeWidgetItem(QStringList() << "" << ConnectionManager->GetDisplayName(group)); connectionListWidget->addTopLevelItem(groupItem); connectionListWidget->setItemWidget(groupItem, 0, new ConnectionItemWidget(group, connectionListWidget)); auto connections = ConnectionManager->Connections(group); - for (auto connection : connections) { + for (auto connection : connections) + { auto connectionItem = new QTreeWidgetItem(QStringList() << "" << ConnectionManager->GetDisplayName(connection)); groupItem->addChild(connectionItem); auto widget = new ConnectionItemWidget(connection, connectionListWidget); @@ -202,18 +218,16 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr // Find and start if there is an auto-connection auto needShowWindow = true; - if (!GlobalConfig.autoStartId.isEmpty()) { + if (!GlobalConfig.autoStartId.isEmpty()) + { auto id = ConnectionId(GlobalConfig.autoStartId); needShowWindow = ConnectionManager->StartConnection(id).has_value(); } - if (needShowWindow) { - this->show(); - } + if (needShowWindow) { this->show(); } //// If we are not connected to anything, show the MainWindow. - if (needShowWindow) { - } + if (needShowWindow) {} #ifndef DISABLE_AUTO_UPDATE requestHelper = new QvHttpRequestHelper(); @@ -221,7 +235,8 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr requestHelper->get("https://api.github.com/repos/Qv2ray/Qv2ray/releases/latest"); #endif - if (StartupOption.enableToolbarPlguin) { + if (StartupOption.enableToolbarPlguin) + { LOG(MODULE_UI, "Plugin daemon is enabled.") StartProcessingPlugins(); } @@ -231,33 +246,35 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr splitter->setSizes(QList() << 100 << 300); } - void MainWindow::keyPressEvent(QKeyEvent *e) { - if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) + { // If pressed enter or return on connectionListWidget. // Try to connect to the selected connection. - //if (focusWidget() == connectionListWidget) { + // if (focusWidget() == connectionListWidget) { // if (!IsSelectionConnectable) return; // // auto selections = connectionListWidget->selectedItems(); // QVariant v; // auto vv = v.value(); - // ShowAndSetConnection(ItemConnectionIdentifier(selections.first()), true, true); + // ShowAndSetConnection(ItemConnectionIdentifier(selections.first()), + // true, true); //} } } void MainWindow::on_action_StartThis_triggered() { - //if (!IsSelectionConnectable) { - // QvMessageBoxWarn(this, tr("No connection selected!"), tr("Please select a config from the list.")); - // return; + // if (!IsSelectionConnectable) { + // QvMessageBoxWarn(this, tr("No connection selected!"), tr("Please + // select a config from the list.")); return; //} // - //CurrentSelectedItemPtr = connectionListWidget->selectedItems().first(); - //CurrentConnectionIdentifier = ItemConnectionIdentifier(CurrentSelectedItemPtr); - //on_reconnectButton_clicked(); + // CurrentSelectedItemPtr = connectionListWidget->selectedItems().first(); + // CurrentConnectionIdentifier = + // ItemConnectionIdentifier(CurrentSelectedItemPtr); + // on_reconnectButton_clicked(); } #ifndef DISABLE_AUTO_UPDATE @@ -269,28 +286,27 @@ void MainWindow::VersionUpdate(QByteArray &data) QVersionNumber newVersion = QVersionNumber::fromString(root["tag_name"].toString("v").remove(0, 1)); QVersionNumber currentVersion = QVersionNumber::fromString(QString(QV2RAY_VERSION_STRING).remove(0, 1)); QVersionNumber ignoredVersion = QVersionNumber::fromString(GlobalConfig.ignoredVersion); - LOG(MODULE_UPDATE, "Received update info, Latest: " + newVersion.toString() + " Current: " + currentVersion.toString() + " Ignored: " + ignoredVersion.toString()) + LOG(MODULE_UPDATE, "Received update info, Latest: " + newVersion.toString() + " Current: " + currentVersion.toString() + + " Ignored: " + ignoredVersion.toString()) // If the version is newer than us. // And new version is newer than the ignored version. - if (newVersion > currentVersion && newVersion > ignoredVersion) { + if (newVersion > currentVersion && newVersion > ignoredVersion) + { LOG(MODULE_UPDATE, "New version detected.") auto link = root["html_url"].toString(""); - auto result = QvMessageBoxAsk(this, tr("Update"), - tr("Found a new version: ") + root["tag_name"].toString("") + - "\r\n" + - root["name"].toString("") + - "\r\n------------\r\n" + - root["body"].toString("") + - "\r\n------------\r\n" + - tr("Download Link: ") + link, QMessageBox::Ignore); + auto result = + QvMessageBoxAsk(this, tr("Update"), + tr("Found a new version: ") + root["tag_name"].toString("") + "\r\n" + root["name"].toString("") + + "\r\n------------\r\n" + root["body"].toString("") + "\r\n------------\r\n" + tr("Download Link: ") + link, + QMessageBox::Ignore); - if (result == QMessageBox::Yes) { - QDesktopServices::openUrl(QUrl::fromUserInput(link)); - } else if (result == QMessageBox::Ignore) { + if (result == QMessageBox::Yes) { QDesktopServices::openUrl(QUrl::fromUserInput(link)); } + else if (result == QMessageBox::Ignore) + { // Set and save ingored version. GlobalConfig.ignoredVersion = newVersion.toString(); - //SaveGlobalConfig(GlobalConfig); + // SaveGlobalConfig(GlobalConfig); } } } @@ -309,12 +325,14 @@ void MainWindow::closeEvent(QCloseEvent *event) } void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason) { - switch (reason) { + switch (reason) + { case QSystemTrayIcon::Trigger: // Toggle Show/Hide #ifndef __APPLE__ // Every single click will trigger the Show/Hide toggling. - // So, as what common macOS Apps do, we don't toggle visibility here. + // So, as what common macOS Apps do, we don't toggle visibility + // here. ToggleVisibility(); #endif break; @@ -325,13 +343,13 @@ void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason) #endif break; - default: - break; + default: break; } } void MainWindow::ToggleVisibility() { - if (this->isHidden()) { + if (this->isHidden()) + { this->show(); #ifdef Q_OS_WIN setWindowState(Qt::WindowNoState); @@ -340,7 +358,9 @@ void MainWindow::ToggleVisibility() SetWindowPos(HWND(this->winId()), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); #endif tray_RootMenu->actions()[0]->setText(tr("Hide")); - } else { + } + else + { this->hide(); tray_RootMenu->actions()[0]->setText(tr("Show")); } @@ -348,9 +368,7 @@ void MainWindow::ToggleVisibility() void MainWindow::on_actionExit_triggered() { - if (StartupOption.enableToolbarPlguin) { - StopProcessingPlugins(); - } + if (StartupOption.enableToolbarPlguin) { StopProcessingPlugins(); } ExitQv2ray(); } @@ -366,13 +384,14 @@ void MainWindow::on_clearlogButton_clicked() void MainWindow::on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) { Q_UNUSED(previous) - //CurrentItem = current; - //isRenamingInProgress = false; + // CurrentItem = current; + // isRenamingInProgress = false; // - //if (!IsConnectableItem(current)) return; + // if (!IsConnectableItem(current)) return; // //// no need to check !isRenamingInProgress since it's always true. - //ShowAndSetConnection(ItemConnectionIdentifier(current), !vinstance->KernelStarted, false); + // ShowAndSetConnection(ItemConnectionIdentifier(current), + // !vinstance->KernelStarted, false); ////on_connectionListWidget_itemClicked(current, 0); } void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint &pos) @@ -381,52 +400,55 @@ void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint auto _pos = QCursor::pos(); auto item = connectionListWidget->itemAt(connectionListWidget->mapFromGlobal(_pos)); - if (GetItemWidget(item)->IsConnection()) { - connectionListMenu->popup(_pos); - } + if (GetItemWidget(item)->IsConnection()) { connectionListMenu->popup(_pos); } } void MainWindow::on_action_RCM_RenameConnection_triggered() { - //auto item = connectionListWidget->currentItem(); - //SUBSCRIPTION_CONFIG_MODIFY_DENY(item) - //item->setFlags(item->flags() | Qt::ItemIsEditable); - //isRenamingInProgress = true; - //connectionListWidget->editItem(item); - //renameOriginalIdentifier = ItemConnectionIdentifier(item); + // auto item = connectionListWidget->currentItem(); + // SUBSCRIPTION_CONFIG_MODIFY_DENY(item) + // item->setFlags(item->flags() | Qt::ItemIsEditable); + // isRenamingInProgress = true; + // connectionListWidget->editItem(item); + // renameOriginalIdentifier = ItemConnectionIdentifier(item); } void MainWindow::on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int) { - //DEBUG(UI, "A connection ListViewItem is changed. This should ONLY occur when renaming an connection.") + // DEBUG(UI, "A connection ListViewItem is changed. This should ONLY occur + // when renaming an connection.") // - //if (!isRenamingInProgress) { + // if (!isRenamingInProgress) { // return; //} // - //isRenamingInProgress = false; + // isRenamingInProgress = false; //// In this case it's after we entered the name. //// and tell user you should not rename a config from subscription. - //auto newIdentifier = renameOriginalIdentifier; - //newIdentifier.connectionName = item->text(0); - //LOG(CONNECTION, "RENAME: " + renameOriginalIdentifier.IdentifierString() + " -> " + newIdentifier.IdentifierString()) + // auto newIdentifier = renameOriginalIdentifier; + // newIdentifier.connectionName = item->text(0); + // LOG(CONNECTION, "RENAME: " + renameOriginalIdentifier.IdentifierString() + // + " -> " + newIdentifier.IdentifierString()) // //// If I really did some changes. - //if (renameOriginalIdentifier != newIdentifier) { + // if (renameOriginalIdentifier != newIdentifier) { // bool canContinueRename = true; // // if (newIdentifier.connectionName.trimmed().isEmpty()) { - // QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name cannot be empty")); - // canContinueRename = false; + // QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name + // cannot be empty")); canContinueRename = false; // } // // QvMessageBoxInfo(this, "NOT SUPPORTED", "WIP"); // //if (GlobalConfig.configs.contains(newIdentifier.connectionName)) { - // // QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name has been used already, Please choose another.")); + // // QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name + // has been used already, Please choose another.")); // // canContinueRename = false; // //} // - // if (!IsValidFileName(newIdentifier.connectionName + QV2RAY_CONFIG_FILE_EXTENSION)) { - // QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name you suggested is not valid, please try another.")); - // canContinueRename = false; + // if (!IsValidFileName(newIdentifier.connectionName + + // QV2RAY_CONFIG_FILE_EXTENSION)) { + // QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name you + // suggested is not valid, please try another.")); canContinueRename + // = false; // } // // if (!canContinueRename) { @@ -448,8 +470,10 @@ void MainWindow::on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int) // //GlobalConfig.configs.removeOne(renameOriginalIdentifier.connectionName); // //GlobalConfig.configs.push_back(newIdentifier.connectionName); // // - // //connections[newIdentifier] = connections.take(renameOriginalIdentifier); - // //RenameConnection(renameOriginalIdentifier.connectionName, newIdentifier.connectionName); + // //connections[newIdentifier] = + // connections.take(renameOriginalIdentifier); + // //RenameConnection(renameOriginalIdentifier.connectionName, + // newIdentifier.connectionName); // //LOG(UI, "Saving a global config") // //SaveGlobalConfig(GlobalConfig); // //// @@ -462,35 +486,38 @@ void MainWindow::on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int) // // on_reconnectButton_clicked(); // // } // //} - // //OnConfigListChanged(CurrentConnectionIdentifier.connectionName == renameOriginalName); + // //OnConfigListChanged(CurrentConnectionIdentifier.connectionName == + // renameOriginalName); //} } void MainWindow::on_removeConfigButton_clicked() { QvMessageBoxInfo(this, "NOT SUPPORTED", "WIP"); - //QList connlist; + // QList connlist; // - //for (auto item : connectionListWidget->selectedItems()) { + // for (auto item : connectionListWidget->selectedItems()) { // if (IsConnectableItem(item)) { // connlist.append(ItemConnectionIdentifier(item)); // } //} // - //LOG(UI, "Selected " + QSTRN(connlist.count()) + " items") + // LOG(UI, "Selected " + QSTRN(connlist.count()) + " items") // - //if (connlist.isEmpty()) { + // if (connlist.isEmpty()) { // // Remove nothing means doing nothing. // return; //} // - //if (QvMessageBoxAsk(this, tr("Removing Connection(s)"), tr("Are you sure to remove selected connection(s)?")) != QMessageBox::Yes) { + // if (QvMessageBoxAsk(this, tr("Removing Connection(s)"), tr("Are you sure + // to remove selected connection(s)?")) != QMessageBox::Yes) { // return; //} // - //// A triple-state flag which indicates if the user wants to remove the configs loaded from a subscription. - //int subscriptionRemovalCheckStatus = -1; + //// A triple-state flag which indicates if the user wants to remove the + /// configs loaded from a subscription. + // int subscriptionRemovalCheckStatus = -1; // - //for (auto conn : connlist) { + // for (auto conn : connlist) { // if (conn == CurrentConnectionIdentifier) { // on_stopButton_clicked(); // CurrentConnectionIdentifier = ConnectionIdentifier(); @@ -499,8 +526,10 @@ void MainWindow::on_removeConfigButton_clicked() // auto connData = connections[conn]; // // // Remove auto start config. - // if (GlobalConfig.autoStartConfig.subscriptionName == connData.subscriptionName && - // GlobalConfig.autoStartConfig.connectionName == connData.connectionName) + // if (GlobalConfig.autoStartConfig.subscriptionName == + // connData.subscriptionName && + // GlobalConfig.autoStartConfig.connectionName == + // connData.connectionName) // // If all those settings match. // { // GlobalConfig.autoStartConfig.subscriptionName.clear(); @@ -510,44 +539,53 @@ void MainWindow::on_removeConfigButton_clicked() // if (connData.configType == CONNECTION_REGULAR) { // // Just remove the regular configs. // if (!connData.subscriptionName.isEmpty()) { - // LOG(UI, "Unexpected subscription name in a single regular config.") - // connData.subscriptionName.clear(); + // LOG(UI, "Unexpected subscription name in a single regular + // config.") connData.subscriptionName.clear(); // } // // GlobalConfig.configs.removeOne(conn.connectionName); // // if (!RemoveConnection(conn.connectionName)) { - // QvMessageBoxWarn(this, tr("Removing this Connection"), tr("Failed to delete connection file, please delete manually.")); + // QvMessageBoxWarn(this, tr("Removing this Connection"), + // tr("Failed to delete connection file, please delete + // manually.")); // } // } else if (connData.configType == CONNECTION_SUBSCRIPTION) { // if (subscriptionRemovalCheckStatus == -1) { - // subscriptionRemovalCheckStatus = (QvMessageBoxAsk(this, tr("Removing a subscription config"), tr("Do you want to remove the config loaded from a subscription?")) == QMessageBox::Yes) + // subscriptionRemovalCheckStatus = (QvMessageBoxAsk(this, + // tr("Removing a subscription config"), tr("Do you want to + // remove the config loaded from a subscription?")) == + // QMessageBox::Yes) // ? 1 // Yes i want // : 0; // No please keep // } // // if (subscriptionRemovalCheckStatus == 1) { - // if (!RemoveSubscriptionConnection(connData.subscriptionName, connData.connectionName)) { - // QvMessageBoxWarn(this, tr("Removing this Connection"), tr("Failed to delete connection file, please delete manually.")); + // if (!RemoveSubscriptionConnection(connData.subscriptionName, + // connData.connectionName)) { + // QvMessageBoxWarn(this, tr("Removing this Connection"), + // tr("Failed to delete connection file, please delete + // manually.")); // } // } // } else { - // LOG(SETTINGS, "Unknown config type -> Not regular nor subscription...") + // LOG(SETTINGS, "Unknown config type -> Not regular nor + // subscription...") // } //} // - //LOG(UI, "Saving GlobalConfig") - //SaveGlobalConfig(GlobalConfig); - //OnConfigListChanged(false); - //ShowAndSetConnection(CurrentConnectionIdentifier, false, false); + // LOG(UI, "Saving GlobalConfig") + // SaveGlobalConfig(GlobalConfig); + // OnConfigListChanged(false); + // ShowAndSetConnection(CurrentConnectionIdentifier, false, false); } void MainWindow::on_importConfigButton_clicked() { QvMessageBoxInfo(this, "NOT SUPPORTED", "WIP"); - //ImportConfigWindow w(this); - //auto configs = w.OpenImport(); - //if (!configs.isEmpty()) { + // ImportConfigWindow w(this); + // auto configs = w.OpenImport(); + // if (!configs.isEmpty()) { // for (auto conf : configs) { // auto name = configs.key(conf, ""); // @@ -569,26 +607,26 @@ void MainWindow::on_editConfigButton_clicked() void MainWindow::on_action_RCM_ConvToComplex_triggered() { //// Check if we have a connection selected... - //if (!IsSelectionConnectable) { - // QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a Config")); - // return; + // if (!IsSelectionConnectable) { + // QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a + // Config")); return; //} // - //auto selectedFirst = connectionListWidget->currentItem(); - //auto _identifier = ItemConnectionIdentifier(selectedFirst); - //SUBSCRIPTION_CONFIG_MODIFY_DENY(selectedFirst) + // auto selectedFirst = connectionListWidget->currentItem(); + // auto _identifier = ItemConnectionIdentifier(selectedFirst); + // SUBSCRIPTION_CONFIG_MODIFY_DENY(selectedFirst) //// - //auto outBoundRoot = connections[_identifier].config; - //CONFIGROOT root; - //bool isChanged = false; + // auto outBoundRoot = connections[_identifier].config; + // CONFIGROOT root; + // bool isChanged = false; //// - //LOG(UI, "INFO: Opening route editor.") - //RouteEditor routeWindow(outBoundRoot, this); - //root = routeWindow.OpenEditor(); - //isChanged = routeWindow.result() == QDialog::Accepted; - //QString alias = _identifier.connectionName; + // LOG(UI, "INFO: Opening route editor.") + // RouteEditor routeWindow(outBoundRoot, this); + // root = routeWindow.OpenEditor(); + // isChanged = routeWindow.result() == QDialog::Accepted; + // QString alias = _identifier.connectionName; // - //if (isChanged) { + // if (isChanged) { // connections[_identifier].config = root; // // true indicates the alias will NOT change // SaveConnectionConfig(root, &alias, true); @@ -603,7 +641,7 @@ void MainWindow::on_action_RCM_EditJson_triggered() void MainWindow::on_action_RCM_ShareQR_triggered() { - //on_shareBtn_clicked(); + // on_shareBtn_clicked(); } void MainWindow::on_subsButton_clicked() @@ -616,9 +654,7 @@ void MainWindow::on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item Q_UNUSED(column) auto widget = GetItemWidget(item); - if (widget->IsConnection()) { - widget->BeginConnection(); - } + if (widget->IsConnection()) { widget->BeginConnection(); } } void MainWindow::OnDisConnected(const ConnectionId &id) @@ -628,14 +664,13 @@ void MainWindow::OnDisConnected(const ConnectionId &id) hTray.setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE); connetionStatusLabel->setText(tr("Disconnected")); - if (systemProxyEnabled) { - MWClearSystemProxy(false); - } + if (systemProxyEnabled) { MWClearSystemProxy(false); } - //QFile(QV2RAY_GENERATED_FILE_PATH).remove(); + // QFile(QV2RAY_GENERATED_FILE_PATH).remove(); - if (GlobalConfig.inboundConfig.pacConfig.enablePAC) { - //pacServer.StopServer(); + if (GlobalConfig.inboundConfig.pacConfig.enablePAC) + { + // pacServer.StopServer(); LOG(MODULE_UI, "Stopping PAC server") } } @@ -655,56 +690,64 @@ void MainWindow::OnConnected(const ConnectionId &id) bool httpEnabled = GlobalConfig.inboundConfig.useHTTP; bool socksEnabled = GlobalConfig.inboundConfig.useSocks; - if (usePAC) { + if (usePAC) + { bool canStartPAC = true; - QString pacProxyString; // Something like this --> SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT; http://proxy:8080 + QString pacProxyString; // Something like this --> SOCKS5 127.0.0.1:1080; SOCKS + // 127.0.0.1:1080; DIRECT; http://proxy:8080 auto pacIP = GlobalConfig.inboundConfig.pacConfig.localIP; - if (pacIP.isEmpty()) { + if (pacIP.isEmpty()) + { LOG(MODULE_PROXY, "PAC Local IP is empty, default to 127.0.0.1") pacIP = "127.0.0.1"; } - if (pacUseSocks) { - if (socksEnabled) { - pacProxyString = "SOCKS5 " + pacIP + ":" + QSTRN(GlobalConfig.inboundConfig.socks_port); - } else { + if (pacUseSocks) + { + if (socksEnabled) { pacProxyString = "SOCKS5 " + pacIP + ":" + QSTRN(GlobalConfig.inboundConfig.socks_port); } + else + { LOG(MODULE_UI, "PAC is using SOCKS, but it is not enabled") - QvMessageBoxWarn(this, tr("Configuring PAC"), tr("Could not start PAC server as it is configured to use SOCKS, but it is not enabled")); + QvMessageBoxWarn(this, tr("Configuring PAC"), + tr("Could not start PAC server as it is configured to use SOCKS, but it is not enabled")); canStartPAC = false; } - } else { - if (httpEnabled) { - pacProxyString = "PROXY " + pacIP + ":" + QSTRN(GlobalConfig.inboundConfig.http_port); - } else { + } + else + { + if (httpEnabled) { pacProxyString = "PROXY " + pacIP + ":" + QSTRN(GlobalConfig.inboundConfig.http_port); } + else + { LOG(MODULE_UI, "PAC is using HTTP, but it is not enabled") - QvMessageBoxWarn(this, tr("Configuring PAC"), tr("Could not start PAC server as it is configured to use HTTP, but it is not enabled")); + QvMessageBoxWarn(this, tr("Configuring PAC"), + tr("Could not start PAC server as it is configured to use HTTP, but it is not enabled")); canStartPAC = false; } } - if (canStartPAC) { - //pacServer.SetProxyString(pacProxyString); - //pacServer.StartListen(); - } else { + if (canStartPAC) + { + // pacServer.SetProxyString(pacProxyString); + // pacServer.StartListen(); + } + else + { LOG(MODULE_PROXY, "Not starting PAC due to previous error.") } } - if (GlobalConfig.inboundConfig.setSystemProxy) { - MWSetSystemProxy(); - } + if (GlobalConfig.inboundConfig.setSystemProxy) { MWSetSystemProxy(); } } - void MainWindow::onConnectionWidgetFocusRequested(const ConnectionItemWidget *_widget) { - if (_widget == nullptr) { - return; - } + if (_widget == nullptr) { return; } - for (auto _item_ : connectionListWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard | Qt::MatchRecursive)) { - if (GetItemWidget(_item_) == _widget) { + for (auto _item_ : connectionListWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard | Qt::MatchRecursive)) + { + if (GetItemWidget(_item_) == _widget) + { LOG(MODULE_UI, "Setting current item.") connectionListWidget->setCurrentItem(_item_); connectionListWidget->scrollToItem(_item_); @@ -717,28 +760,31 @@ void MainWindow::onConnectionWidgetFocusRequested(const ConnectionItemWidget *_w void MainWindow::on_connectionFilterTxt_textEdited(const QString &arg1) { // No recursive since we only need top level item - for (auto _top_item_ : connectionListWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard)) { - //auto topWidget = GetItemWidget(_top_item_); + for (auto _top_item_ : connectionListWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard)) + { + // auto topWidget = GetItemWidget(_top_item_); bool isTotallyHide = true; - for (auto i = 0; i < _top_item_->childCount(); i++) { + for (auto i = 0; i < _top_item_->childCount(); i++) + { auto _child_ = _top_item_->child(i); - if (GetItemWidget(_child_)->NameMatched(arg1)) { + if (GetItemWidget(_child_)->NameMatched(arg1)) + { LOG(MODULE_UI, "Setting current item.") // Show the child _child_->setHidden(false); isTotallyHide = false; - } else { + } + else + { _child_->setHidden(true); } } _top_item_->setHidden(isTotallyHide); - if (!isTotallyHide) { - connectionListWidget->expandItem(_top_item_); - } + if (!isTotallyHide) { connectionListWidget->expandItem(_top_item_); } } } @@ -748,11 +794,12 @@ void MainWindow::on_connectionListWidget_itemClicked(QTreeWidgetItem *item, int infoWidget->ShowDetails(GetItemWidget(item)->Identifier()); } -void MainWindow::onConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, const quint64 totalDown) +void MainWindow::onConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, + const quint64 totalDown) { Q_UNUSED(id); - // This may not be, or may not precisely be, speed per second if low-level has "any" latency. - // (Hope not...) + // This may not be, or may not precisely be, speed per second if low-level + // has "any" latency. (Hope not...) speedChartWidget->AddPointData(upSpeed, downSpeed); // auto totalSpeedUp = FormatBytes(upSpeed) + "/s"; @@ -763,7 +810,8 @@ void MainWindow::onConnectionStatsArrived(const ConnectionId &id, const quint64 netspeedLabel->setText(totalSpeedUp + NEWLINE + totalSpeedDown); dataamountLabel->setText(totalDataUp + NEWLINE + totalDataDown); // - hTray.setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected: ") + ConnectionManager->GetDisplayName(id) + NEWLINE "Up: " + totalSpeedUp + " Down: " + totalSpeedDown); + hTray.setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected: ") + ConnectionManager->GetDisplayName(id) + NEWLINE "Up: " + totalSpeedUp + + " Down: " + totalSpeedDown); } void MainWindow::onVCoreLogArrived(const ConnectionId &id, const QString &log) @@ -777,35 +825,40 @@ void MainWindow::onVCoreLogArrived(const ConnectionId &id, const QString &log) auto maxLines = GlobalConfig.uiConfig.maximumLogLines; QTextBlock block = masterLogBrowser->document()->begin(); - while (block.isValid()) { - if (masterLogBrowser->document()->blockCount() > maxLines) { + while (block.isValid()) + { + if (masterLogBrowser->document()->blockCount() > maxLines) + { QTextCursor cursor(block); block = block.next(); cursor.select(QTextCursor::BlockUnderCursor); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); cursor.removeSelectedText(); - } else { + } + else + { break; } } - if (val >= max * 0.8 || val >= max - 20) - bar->setValue(max); + if (val >= max * 0.8 || val >= max - 20) bar->setValue(max); } - void MainWindow::OnEditRequested(const ConnectionId &id) { auto outBoundRoot = ConnectionManager->GetConnectionRoot(id); CONFIGROOT root; bool isChanged = false; - if (IsComplexConfig(outBoundRoot)) { + if (IsComplexConfig(outBoundRoot)) + { LOG(MODULE_UI, "INFO: Opening route editor.") RouteEditor routeWindow(outBoundRoot, this); root = routeWindow.OpenEditor(); isChanged = routeWindow.result() == QDialog::Accepted; - } else { + } + else + { LOG(MODULE_UI, "INFO: Opening single connection edit window.") auto out = OUTBOUND(outBoundRoot["outbounds"].toArray().first().toObject()); OutboundEditor w(out, this); @@ -816,18 +869,21 @@ void MainWindow::OnEditRequested(const ConnectionId &id) root.insert("outbounds", outboundsList); } - if (isChanged) { - //if (CheckConfigType(firstSelected, SUBSCRIPTION)) { + if (isChanged) + { + // if (CheckConfigType(firstSelected, SUBSCRIPTION)) { // auto name = connections[_identifier].connectionName; // // Assume name will not change. - // SaveSubscriptionConfig(root, connections[_identifier].subscriptionName, &name); + // SaveSubscriptionConfig(root, + // connections[_identifier].subscriptionName, &name); //} else { // connections[_identifier].config = root; // // true indicates the alias will NOT change // SaveConnectionConfig(root, &alias, true); //} ConnectionManager->UpdateConnection(id, root); - //OnConfigListChanged(alias == CurrentConnectionIdentifier.connectionName); + // OnConfigListChanged(alias == + // CurrentConnectionIdentifier.connectionName); } } void MainWindow::OnJsonEditRequested(const ConnectionId &id) @@ -835,7 +891,5 @@ void MainWindow::OnJsonEditRequested(const ConnectionId &id) JsonEditor w(ConnectionManager->GetConnectionRoot(id), this); auto root = CONFIGROOT(w.OpenEditor()); - if (w.result() == QDialog::Accepted) { - ConnectionManager->UpdateConnection(id, root); - } + if (w.result() == QDialog::Accepted) { ConnectionManager->UpdateConnection(id, root); } } diff --git a/src/ui/w_MainWindow.hpp b/src/ui/w_MainWindow.hpp index b43ae600..f7b4dc09 100644 --- a/src/ui/w_MainWindow.hpp +++ b/src/ui/w_MainWindow.hpp @@ -1,114 +1,116 @@ #pragma once +#include "common/HTTPRequestHelper.hpp" +#include "common/LogHighlighter.hpp" +#include "components/speedchart/speedwidget.hpp" +#include "core/handler/ConnectionHandler.hpp" +#include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_MainWindow.h" + #include #include #include #include -#include "ui_w_MainWindow.h" - -#include "common/LogHighlighter.hpp" -#include "common/HTTPRequestHelper.hpp" -#include "components/speedchart/speedwidget.hpp" -#include "core/handler/ConnectionHandler.hpp" -#include "ui/messaging/QvMessageBus.hpp" - // ========================================================================================== -#include "ui/widgets/ConnectionItemWidget.hpp" #include "ui/widgets/ConnectionInfoWidget.hpp" +#include "ui/widgets/ConnectionItemWidget.hpp" -class MainWindow : public QMainWindow, Ui::MainWindow +class MainWindow + : public QMainWindow + , Ui::MainWindow { - Q_OBJECT - public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow() override; - signals: - void Connect() const; - void DisConnect() const; - void ReConnect() const; - public slots: - QvMessageBusSlotDecl - private slots: - void on_action_RCM_ShareQR_triggered(); - void on_activatedTray(QSystemTrayIcon::ActivationReason reason); - void on_actionExit_triggered(); - void on_preferencesBtn_clicked(); - void on_clearlogButton_clicked(); - void on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - void on_connectionListWidget_customContextMenuRequested(const QPoint &pos); - void on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int column); - void on_removeConfigButton_clicked(); - void on_importConfigButton_clicked(); - void on_editConfigButton_clicked(); - void on_subsButton_clicked(); - // - void ToggleVisibility(); + Q_OBJECT + public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; + signals: + void Connect() const; + void DisConnect() const; + void ReConnect() const; + public slots: + QvMessageBusSlotDecl; + private slots: + void on_action_RCM_ShareQR_triggered(); + void on_activatedTray(QSystemTrayIcon::ActivationReason reason); + void on_actionExit_triggered(); + void on_preferencesBtn_clicked(); + void on_clearlogButton_clicked(); + void on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void on_connectionListWidget_customContextMenuRequested(const QPoint &pos); + void on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int column); + void on_removeConfigButton_clicked(); + void on_importConfigButton_clicked(); + void on_editConfigButton_clicked(); + void on_subsButton_clicked(); + // + void ToggleVisibility(); #ifndef DISABLE_AUTO_UPDATE - void VersionUpdate(QByteArray &data); + void VersionUpdate(QByteArray &data); #endif - // + // - public: - static MainWindow *mwInstance; + public: + static MainWindow *mwInstance; - protected: - void keyPressEvent(QKeyEvent *e) override; - void closeEvent(QCloseEvent *) override; + protected: + void keyPressEvent(QKeyEvent *e) override; + void closeEvent(QCloseEvent *) override; - private slots: - // - void OnConnected(const ConnectionId &id); - void OnDisConnected(const ConnectionId &id); - void OnEditRequested(const ConnectionId &id); - void OnJsonEditRequested(const ConnectionId &id); + private slots: + // + void OnConnected(const ConnectionId &id); + void OnDisConnected(const ConnectionId &id); + void OnEditRequested(const ConnectionId &id); + void OnJsonEditRequested(const ConnectionId &id); - void onConnectionWidgetFocusRequested(const ConnectionItemWidget *widget); - //void onConnectionConnected(const ConnectionId &id); - //void onConnectionDisConnected(const ConnectionId &id); - void onConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, const quint64 totalDown); - void onVCoreLogArrived(const ConnectionId &id, const QString &log); - // - void on_action_StartThis_triggered(); - void on_action_RCM_EditJson_triggered(); - void on_action_RCM_ConvToComplex_triggered(); - void on_action_RCM_RenameConnection_triggered(); - void on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); - void on_connectionFilterTxt_textEdited(const QString &arg1); - void on_connectionListWidget_itemClicked(QTreeWidgetItem *item, int column); + void onConnectionWidgetFocusRequested(const ConnectionItemWidget *widget); + // void onConnectionConnected(const ConnectionId &id); + // void onConnectionDisConnected(const ConnectionId &id); + void onConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, + const quint64 totalDown); + void onVCoreLogArrived(const ConnectionId &id, const QString &log); + // + void on_action_StartThis_triggered(); + void on_action_RCM_EditJson_triggered(); + void on_action_RCM_ConvToComplex_triggered(); + void on_action_RCM_RenameConnection_triggered(); + void on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); + void on_connectionFilterTxt_textEdited(const QString &arg1); + void on_connectionListWidget_itemClicked(QTreeWidgetItem *item, int column); - private: - QTreeWidgetItem *CurrentItem; - // Charts - SpeedWidget *speedChartWidget; - QMenu *connectionListMenu; + private: + QTreeWidgetItem *CurrentItem; + // Charts + SpeedWidget *speedChartWidget; + QMenu *connectionListMenu; #ifndef DISABLE_AUTO_UPDATE - QvHttpRequestHelper *requestHelper; + QvHttpRequestHelper *requestHelper; #endif - QSystemTrayIcon hTray; - //PACServer pacServer; - //QvTCPingModel tcpingHelper; - SyntaxHighlighter *vCoreLogHighlighter; - ConnectionInfoWidget *infoWidget; - // - // Actions in the system tray menu - // - QMenu *tray_RootMenu = new QMenu(this); - QAction *action_Tray_ShowHide; - QAction *action_Tray_ShowPreferencesWindow; - QAction *action_Tray_Quit; - // --> Connectivities - QAction *action_Tray_Start; - QAction *action_Tray_Reconnect ; - QAction *action_Tray_Stop; - // --> System proxy settings - QMenu *tray_SystemProxyMenu = new QMenu(this); - QAction *action_Tray_SetSystemProxy; - QAction *action_Tray_ClearSystemProxy; - // - // ----------------------------------- Extra Headers For w_MainWindow_extra.cpp Handling V2ray Connectivities. - bool systemProxyEnabled; - void MWSetSystemProxy(); - void MWClearSystemProxy(bool); - void CheckSubscriptionsUpdate(); + QSystemTrayIcon hTray; + // PACServer pacServer; + // QvTCPingModel tcpingHelper; + SyntaxHighlighter *vCoreLogHighlighter; + ConnectionInfoWidget *infoWidget; + // + // Actions in the system tray menu + // + QMenu *tray_RootMenu = new QMenu(this); + QAction *action_Tray_ShowHide; + QAction *action_Tray_ShowPreferencesWindow; + QAction *action_Tray_Quit; + // --> Connectivities + QAction *action_Tray_Start; + QAction *action_Tray_Reconnect; + QAction *action_Tray_Stop; + // --> System proxy settings + QMenu *tray_SystemProxyMenu = new QMenu(this); + QAction *action_Tray_SetSystemProxy; + QAction *action_Tray_ClearSystemProxy; + // + // ----------------------------------- Extra Headers For w_MainWindow_extra.cpp Handling V2ray Connectivities. + bool systemProxyEnabled; + void MWSetSystemProxy(); + void MWClearSystemProxy(bool); + void CheckSubscriptionsUpdate(); }; diff --git a/src/ui/w_MainWindow_extra.cpp b/src/ui/w_MainWindow_extra.cpp index 49bf3779..158c7f82 100644 --- a/src/ui/w_MainWindow_extra.cpp +++ b/src/ui/w_MainWindow_extra.cpp @@ -1,16 +1,19 @@ -// Supplementary file for MainWindow -- Basically the handler for connectivity management -// and components interactions. -// We NEED to include the cpp file to define the macros. -#include "w_MainWindow.cpp" +// Supplementary file for MainWindow -- Basically the handler for connectivity +// management and components interactions. We NEED to include the cpp file to +// define the macros. #include "components/proxy/QvProxyConfigurator.hpp" +#include "w_MainWindow.cpp" -//QTreeWidgetItem *MainWindow::FindItemByIdentifier(QvConnectionObject identifier) +// QTreeWidgetItem *MainWindow::FindItemByIdentifier(QvConnectionObject +// identifier) //{ // //// First filter out all items with our config name. -// //auto items = connectionListWidget->findItems(identifier.connectionName, Qt::MatchExactly | Qt::MatchRecursive); +// //auto items = connectionListWidget->findItems(identifier.connectionName, +// Qt::MatchExactly | Qt::MatchRecursive); // // // //for (auto item : items) { -// // // This connectable prevents the an item with (which is the parent node of a subscription, having the same +// // // This connectable prevents the an item with (which is the parent +// node of a subscription, having the same // // // -- name as our current connected name) // // if (!IsConnectableItem(item)) { // // LOG(UI, "Invalid Item found: " + item->text(0)) @@ -25,8 +28,8 @@ // // } // //} // // -// //LOG(UI, "Warning: Failed to find an item named: " + identifier.IdentifierString()) -// return nullptr; +// //LOG(UI, "Warning: Failed to find an item named: " + +// identifier.IdentifierString()) return nullptr; //} void MainWindow::MWClearSystemProxy(bool showMessage) @@ -35,9 +38,7 @@ void MainWindow::MWClearSystemProxy(bool showMessage) LOG(MODULE_UI, "Clearing System Proxy") systemProxyEnabled = false; - if (showMessage) { - hTray.showMessage("Qv2ray", tr("System proxy cleared."), windowIcon()); - } + if (showMessage) { hTray.showMessage("Qv2ray", tr("System proxy cleared."), windowIcon()); } } void MainWindow::MWSetSystemProxy() @@ -48,45 +49,58 @@ void MainWindow::MWSetSystemProxy() bool socksEnabled = GlobalConfig.inboundConfig.useSocks; // // Set system proxy if necessary - //bool isComplex = IsComplexConfig(connections[CurrentConnectionIdentifier].config); + // bool isComplex = + // IsComplexConfig(connections[CurrentConnectionIdentifier].config); bool isComplex = true; - if (!isComplex) { + if (!isComplex) + { // Is simple config and we will try to set system proxy. LOG(MODULE_UI, "Preparing to set system proxy") // QString proxyAddress; bool canSetSystemProxy = true; - if (usePAC) { - if ((httpEnabled && !pacUseSocks) || (socksEnabled && pacUseSocks)) { + if (usePAC) + { + if ((httpEnabled && !pacUseSocks) || (socksEnabled && pacUseSocks)) + { // If we use PAC and socks/http are properly configured for PAC LOG(MODULE_PROXY, "System proxy uses PAC") - proxyAddress = "http://" + GlobalConfig.inboundConfig.listenip + ":" + QSTRN(GlobalConfig.inboundConfig.pacConfig.port) + "/pac"; - } else { + proxyAddress = "http://" + GlobalConfig.inboundConfig.listenip + ":" + QSTRN(GlobalConfig.inboundConfig.pacConfig.port) + "/pac"; + } + else + { // Not properly configured LOG(MODULE_PROXY, "Failed to process pac due to following reasons:") LOG(MODULE_PROXY, " --> PAC is configured to use socks but socks is not enabled.") LOG(MODULE_PROXY, " --> PAC is configuted to use http but http is not enabled.") - QvMessageBoxWarn(this, tr("PAC Processing Failed"), tr("HTTP or SOCKS inbound is not properly configured for PAC") + - NEWLINE + tr("Qv2ray will continue, but will not set system proxy.")); + QvMessageBoxWarn(this, tr("PAC Processing Failed"), + tr("HTTP or SOCKS inbound is not properly configured for PAC") + NEWLINE + + tr("Qv2ray will continue, but will not set system proxy.")); canSetSystemProxy = false; } - } else { + } + else + { // Not using PAC - if (httpEnabled || socksEnabled) { + if (httpEnabled || socksEnabled) + { // Not use PAC, System proxy should use HTTP or SOCKS LOG(MODULE_PROXY, "Setting up system proxy.") // A 'proxy host' should be a host WITHOUT `http://` uri scheme proxyAddress = "localhost"; - } else { + } + else + { LOG(MODULE_PROXY, "Neither of HTTP nor SOCKS is enabled, cannot set system proxy.") QvMessageBoxWarn(this, tr("Cannot set system proxy"), tr("Both HTTP and SOCKS inbounds are not enabled")); canSetSystemProxy = false; } } - if (canSetSystemProxy) { + if (canSetSystemProxy) + { LOG(MODULE_UI, "Setting system proxy for simple config.") auto httpPort = GlobalConfig.inboundConfig.useHTTP ? GlobalConfig.inboundConfig.http_port : 0; auto socksPort = GlobalConfig.inboundConfig.useSocks ? GlobalConfig.inboundConfig.socks_port : 0; @@ -96,7 +110,9 @@ void MainWindow::MWSetSystemProxy() systemProxyEnabled = true; hTray.showMessage("Qv2ray", tr("System proxy settings applied."), windowIcon()); } - } else { + } + else + { hTray.showMessage("Qv2ray", tr("Cannot set proxy for complex config."), windowIcon()); } } @@ -105,28 +121,29 @@ void MainWindow::CheckSubscriptionsUpdate() { QStringList updateList; - for (auto index = 0; index < GlobalConfig.subscriptions.count(); index++) { + for (auto index = 0; index < GlobalConfig.subscriptions.count(); index++) + { auto subs = GlobalConfig.subscriptions.values()[index]; auto key = GlobalConfig.subscriptions.keys()[index]; // auto lastRenewDate = QDateTime::fromTime_t(subs.lastUpdated); auto renewTime = lastRenewDate.addSecs(subs.updateInterval * 86400); - LOG(MODULE_SUBSCRIPTION, "Subscription \"" + key + "\": " + NEWLINE + - " --> Last renewal time: " + lastRenewDate.toString() + NEWLINE + - " --> Renew interval: " + QSTRN(subs.updateInterval) + NEWLINE + - " --> Ideal renew time: " + renewTime.toString()) + LOG(MODULE_SUBSCRIPTION, "Subscription \"" + key + "\": " + NEWLINE + " --> Last renewal time: " + lastRenewDate.toString() + NEWLINE + + " --> Renew interval: " + QSTRN(subs.updateInterval) + NEWLINE + + " --> Ideal renew time: " + renewTime.toString()) - if (renewTime <= QDateTime::currentDateTime()) { + if (renewTime <= QDateTime::currentDateTime()) + { LOG(MODULE_SUBSCRIPTION, "Subscription: " + key + " needs to be updated.") updateList.append(key); } } - if (!updateList.isEmpty()) { + if (!updateList.isEmpty()) + { QvMessageBoxWarn(this, tr("Update Subscriptions"), - tr("There are subscriptions need to be updated, please go to subscriptions window to update them.") + NEWLINE + NEWLINE + - tr("These subscriptions are out-of-date: ") + NEWLINE + updateList.join(";")); + tr("There are subscriptions need to be updated, please go to subscriptions window to update them.") + NEWLINE + + NEWLINE + tr("These subscriptions are out-of-date: ") + NEWLINE + updateList.join(";")); on_subsButton_clicked(); } } - diff --git a/src/ui/w_PreferencesWindow.cpp b/src/ui/w_PreferencesWindow.cpp index bfb8a8ae..61f9a0e9 100644 --- a/src/ui/w_PreferencesWindow.cpp +++ b/src/ui/w_PreferencesWindow.cpp @@ -1,27 +1,28 @@ #include "w_PreferencesWindow.hpp" -#include -#include -#include -#include -#include - -#include "common/QvHelpers.hpp" #include "common/HTTPRequestHelper.hpp" +#include "common/QvHelpers.hpp" +#include "common/QvTranslator.hpp" +#include "components/autolaunch/QvAutoLaunch.hpp" +#include "components/plugins/toolbar/QvToolbar.hpp" #include "core/config/ConfigBackend.hpp" #include "core/connection/ConnectionIO.hpp" -#include "core/kernel/KernelInteractions.hpp" #include "core/handler/ConnectionHandler.hpp" -#include "components/plugins/toolbar/QvToolbar.hpp" -#include "components/autolaunch/QvAutoLaunch.hpp" -#include "common/QvTranslator.hpp" +#include "core/kernel/KernelInteractions.hpp" + +#include +#include +#include +#include +#include using Qv2ray::common::validation::IsValidIPAddress; -#define LOADINGCHECK if(!finishedLoading) return; -#define NEEDRESTART if(finishedLoading) IsConnectionPropertyChanged = true; +#define LOADINGCHECK \ + if (!finishedLoading) return; +#define NEEDRESTART \ + if (finishedLoading) IsConnectionPropertyChanged = true; -PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), - CurrentConfig() +PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), CurrentConfig() { setupUi(this); QvMessageBusConnect(PreferencesWindow); @@ -31,17 +32,14 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), // Set network Toolbar page state. networkToolbarPage->setEnabled(StartupOption.enableToolbarPlguin); - if (!StartupOption.enableToolbarPlguin) { - networkToolbarInfoLabel->setText(tr("Qv2ray Network Toolbar is disabled and still under test. Add --withToolbarPlugin to enable.")); - } + if (!StartupOption.enableToolbarPlguin) + { networkToolbarInfoLabel->setText(tr("Qv2ray Network Toolbar is disabled and still under test. Add --withToolbarPlugin to enable.")); } // We add locales languageComboBox->clear(); QDirIterator it(":/translations"); - while (it.hasNext()) { - languageComboBox->addItem(it.next().split("/").last().split(".").first()); - } + while (it.hasNext()) { languageComboBox->addItem(it.next().split("/").last().split(".").first()); } // Set auto start button state SetAutoStartButtonsState(GetLaunchAtLoginStatus()); @@ -120,26 +118,30 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), // DNSListTxt->clear(); - for (auto dnsStr : CurrentConfig.connectionConfig.dnsList) { + for (auto dnsStr : CurrentConfig.connectionConfig.dnsList) + { auto str = dnsStr.trimmed(); - if (!str.isEmpty()) { - DNSListTxt->appendPlainText(str); - } + if (!str.isEmpty()) { DNSListTxt->appendPlainText(str); } } // cancelIgnoreVersionBtn->setEnabled(CurrentConfig.ignoredVersion != ""); ignoredNextVersion->setText(CurrentConfig.ignoredVersion); - for (auto i = 0; i < CurrentConfig.toolBarConfig.Pages.size(); i++) { - nsBarPagesList->addItem(tr("Page") + QSTRN(i + 1) + ": " + QSTRN(CurrentConfig.toolBarConfig.Pages[i].Lines.size()) + " " + tr("Item(s)")); + for (auto i = 0; i < CurrentConfig.toolBarConfig.Pages.size(); i++) + { + nsBarPagesList->addItem(tr("Page") + QSTRN(i + 1) + ": " + QSTRN(CurrentConfig.toolBarConfig.Pages[i].Lines.size()) + " " + + tr("Item(s)")); } - if (CurrentConfig.toolBarConfig.Pages.size() > 0) { + if (CurrentConfig.toolBarConfig.Pages.size() > 0) + { nsBarPagesList->setCurrentRow(0); on_nsBarPagesList_currentRowChanged(0); - } else { + } + else + { networkToolbarSettingsFrame->setEnabled(false); nsBarLinesList->setEnabled(false); nsBarLineDelBTN->setEnabled(false); @@ -153,22 +155,17 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), auto autoStartConnId = ConnectionId(CurrentConfig.autoStartId); auto autoStartGroupId = ConnectionManager->GetConnectionGroupId(autoStartConnId); - for (auto group : ConnectionManager->AllGroups()) { - autoStartSubsCombo->addItem(ConnectionManager->GetDisplayName(group)); - } + for (auto group : ConnectionManager->AllGroups()) { autoStartSubsCombo->addItem(ConnectionManager->GetDisplayName(group)); } autoStartSubsCombo->setCurrentText(ConnectionManager->GetDisplayName(autoStartGroupId)); - for (auto conn : ConnectionManager->Connections(autoStartGroupId)) { - autoStartConnCombo->addItem(ConnectionManager->GetDisplayName(conn)); - } + for (auto conn : ConnectionManager->Connections(autoStartGroupId)) { autoStartConnCombo->addItem(ConnectionManager->GetDisplayName(conn)); } autoStartConnCombo->setCurrentText(ConnectionManager->GetDisplayName(autoStartConnId)); // FP Settings - if (CurrentConfig.connectionConfig.forwardProxyConfig.type.trimmed().isEmpty()) { - CurrentConfig.connectionConfig.forwardProxyConfig.type = "http"; - } + if (CurrentConfig.connectionConfig.forwardProxyConfig.type.trimmed().isEmpty()) + { CurrentConfig.connectionConfig.forwardProxyConfig.type = "http"; } fpGroupBox->setChecked(CurrentConfig.connectionConfig.forwardProxyConfig.enableForwardProxy); fpUsernameTx->setText(CurrentConfig.connectionConfig.forwardProxyConfig.username); @@ -182,18 +179,17 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), // maxLogLinesSB->setValue(CurrentConfig.uiConfig.maximumLogLines); // - pacListenAddrLabel->setText("http://" + (pacProxyTxt->text().isEmpty() ? "127.0.0.1" : pacProxyTxt->text()) + ":" + QSTRN(pacPortSB->value()) + "/pac"); + pacListenAddrLabel->setText("http://" + (pacProxyTxt->text().isEmpty() ? "127.0.0.1" : pacProxyTxt->text()) + ":" + + QSTRN(pacPortSB->value()) + "/pac"); // finishedLoading = true; } - QvMessageBusSlotImpl(PreferencesWindow) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } @@ -204,45 +200,57 @@ PreferencesWindow::~PreferencesWindow() void PreferencesWindow::on_buttonBox_accepted() { // Note: - // A signal-slot connection from buttonbox_accpted to QDialog::accepted() has been removed. - // To prevent closing this Dialog. + // A signal-slot connection from buttonbox_accpted to QDialog::accepted() + // has been removed. To prevent closing this Dialog. QSet ports; auto size = 0; - if (CurrentConfig.inboundConfig.useHTTP) { - size ++; + if (CurrentConfig.inboundConfig.useHTTP) + { + size++; ports << CurrentConfig.inboundConfig.http_port; } - if (CurrentConfig.inboundConfig.useSocks) { - size ++; + if (CurrentConfig.inboundConfig.useSocks) + { + size++; ports << CurrentConfig.inboundConfig.socks_port; } - if (CurrentConfig.inboundConfig.pacConfig.enablePAC) { - size ++; + if (CurrentConfig.inboundConfig.pacConfig.enablePAC) + { + size++; ports << CurrentConfig.inboundConfig.pacConfig.port; } - if (!StartupOption.noAPI) { - size ++; + if (!StartupOption.noAPI) + { + size++; ports << CurrentConfig.apiConfig.statsPort; } - if (ports.size() != size) { + if (ports.size() != size) + { // Duplicates detected. QvMessageBoxWarn(this, tr("Preferences"), tr("Duplicated port numbers detected, please check the port number settings.")); - } else if (CurrentConfig.inboundConfig.listenip.toLower() != "localhost" && !IsValidIPAddress(CurrentConfig.inboundConfig.listenip)) { - QvMessageBoxWarn(this, tr("Preferences"), tr("Invalid inbound listening address."));; - } else { - if (CurrentConfig.uiConfig.language != GlobalConfig.uiConfig.language) { + } + else if (CurrentConfig.inboundConfig.listenip.toLower() != "localhost" && !IsValidIPAddress(CurrentConfig.inboundConfig.listenip)) + { + QvMessageBoxWarn(this, tr("Preferences"), tr("Invalid inbound listening address.")); + ; + } + else + { + if (CurrentConfig.uiConfig.language != GlobalConfig.uiConfig.language) + { qApp->removeTranslator(Qv2rayTranslator.get()); Qv2rayTranslator = std::move(QvTranslator(CurrentConfig.uiConfig.language).pTranslator); // Install translator - if (!qApp->installTranslator(Qv2rayTranslator.get())) { - LOG(MODULE_UI, "Failed to translate UI to: " + CurrentConfig.uiConfig.language) - } else { + if (!qApp->installTranslator(Qv2rayTranslator.get())) + { LOG(MODULE_UI, "Failed to translate UI to: " + CurrentConfig.uiConfig.language) } + else + { messageBus.EmitGlobalSignal(QvMBMessage::RETRANSLATE); QApplication::processEvents(); } @@ -296,13 +304,14 @@ void PreferencesWindow::on_listenIPTxt_textEdited(const QString &arg1) NEEDRESTART CurrentConfig.inboundConfig.listenip = arg1; - if (IsValidIPAddress(arg1)) { - BLACK(listenIPTxt) - } else { + if (IsValidIPAddress(arg1)) { BLACK(listenIPTxt) } + else + { RED(listenIPTxt) } - //pacAccessPathTxt->setText("http://" + arg1 + ":" + QSTRN(pacPortSB->value()) + "/pac"); + // pacAccessPathTxt->setText("http://" + arg1 + ":" + + // QSTRN(pacPortSB->value()) + "/pac"); } void PreferencesWindow::on_httpAuthUsernameTxt_textEdited(const QString &arg1) @@ -346,7 +355,8 @@ void PreferencesWindow::on_selectVAssetBtn_clicked() NEEDRESTART QString dir = QFileDialog::getExistingDirectory(this, tr("Open V2ray assets folder"), QDir::currentPath()); - if (!dir.isEmpty()) { + if (!dir.isEmpty()) + { vCoreAssetsPathTxt->setText(dir); on_vCoreAssetsPathTxt_textEdited(dir); } @@ -356,7 +366,8 @@ void PreferencesWindow::on_selectVCoreBtn_clicked() { QString core = QFileDialog::getOpenFileName(this, tr("Open V2ray core file"), QDir::currentPath()); - if (!core.isEmpty()) { + if (!core.isEmpty()) + { vCorePathTxt->setText(core); on_vCorePathTxt_textEdited(core); } @@ -370,13 +381,17 @@ void PreferencesWindow::on_vCorePathTxt_textEdited(const QString &arg1) void PreferencesWindow::on_DNSListTxt_textChanged() { - if (finishedLoading) { - try { + if (finishedLoading) + { + try + { QStringList hosts = DNSListTxt->toPlainText().replace("\r", "").split("\n"); CurrentConfig.connectionConfig.dnsList.clear(); - foreach (auto host, hosts) { - if (host != "" && host != "\r") { + foreach (auto host, hosts) + { + if (host != "" && host != "\r") + { // Not empty, so we save. CurrentConfig.connectionConfig.dnsList.push_back(host); NEEDRESTART @@ -384,7 +399,9 @@ void PreferencesWindow::on_DNSListTxt_textChanged() } BLACK(DNSListTxt) - } catch (...) { + } + catch (...) + { RED(DNSListTxt) } } @@ -408,19 +425,25 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) // Setting up tProxy for linux // Steps: - // --> 1. Copy V2ray core files to the QV2RAY_TPROXY_VCORE_PATH and QV2RAY_TPROXY_VCTL_PATH dir. + // --> 1. Copy V2ray core files to the QV2RAY_TPROXY_VCORE_PATH and + // QV2RAY_TPROXY_VCTL_PATH dir. // --> 2. Change GlobalConfig.v2CorePath. - // --> 3. Call `pkexec setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE=eip` on the V2ray core. - if (arg1 == Qt::Checked) { + // --> 3. Call `pkexec setcap + // CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE=eip` on the V2ray core. + if (arg1 == Qt::Checked) + { // We enable it! if (QvMessageBoxAsk(this, tr("Enable tProxy Support"), - tr("This will append capabilities to the V2ray executable.") + NEWLINE + NEWLINE + - tr("Qv2ray will copy your V2ray core to this path: ") + NEWLINE + QV2RAY_TPROXY_VCORE_PATH + NEWLINE + NEWLINE + - tr("If anything goes wrong after enabling this, please check issue #57 or the link below:") + NEWLINE + - " https://github.com/Qv2ray/Qv2ray/wiki/FAQ ") != QMessageBox::Yes) { + tr("This will append capabilities to the V2ray executable.") + NEWLINE + NEWLINE + + tr("Qv2ray will copy your V2ray core to this path: ") + NEWLINE + QV2RAY_TPROXY_VCORE_PATH + NEWLINE + NEWLINE + + tr("If anything goes wrong after enabling this, please check issue #57 or the link below:") + NEWLINE + + " https://github.com/Qv2ray/Qv2ray/wiki/FAQ ") != QMessageBox::Yes) + { tProxyCheckBox->setChecked(false); LOG(MODULE_UI, "Canceled enabling tProxy feature.") - } else { + } + else + { LOG(MODULE_VCORE, "ENABLING tProxy Support") LOG(MODULE_FILEIO, " --> Origin V2ray core file is at: " + CurrentConfig.v2CorePath) auto v2ctlPath = QFileInfo(CurrentConfig.v2CorePath).absolutePath() + "/v2ctl"; @@ -433,17 +456,22 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) // LOG(MODULE_FILEIO, " --> Copying files....") - if (QFileInfo(CurrentConfig.v2CorePath).absoluteFilePath() != QFileInfo(QV2RAY_TPROXY_VCORE_PATH).absoluteFilePath()) { - // Only trying to remove file when they are not in the default dir. - // (In other words...) Keep using the current files. + if (QFileInfo(CurrentConfig.v2CorePath).absoluteFilePath() != QFileInfo(QV2RAY_TPROXY_VCORE_PATH).absoluteFilePath()) + { + // Only trying to remove file when they are not in the default + // dir. (In other words...) Keep using the current files. + // // - if (QFile(QV2RAY_TPROXY_VCORE_PATH).exists()) { + if (QFile(QV2RAY_TPROXY_VCORE_PATH).exists()) + { LOG(MODULE_FILEIO, QString(QV2RAY_TPROXY_VCORE_PATH) + ": File already exists.") LOG(MODULE_FILEIO, QString(QV2RAY_TPROXY_VCORE_PATH) + ": Deleting file.") QFile(QV2RAY_TPROXY_VCORE_PATH).remove(); } - if (QFile(QV2RAY_TPROXY_VCTL_PATH).exists()) { + if (QFile(QV2RAY_TPROXY_VCTL_PATH).exists()) + { LOG(MODULE_FILEIO, QV2RAY_TPROXY_VCTL_PATH + ": File already exists.") LOG(MODULE_FILEIO, QV2RAY_TPROXY_VCTL_PATH + ": Deleting file.") QFile(QV2RAY_TPROXY_VCTL_PATH).remove(); @@ -456,18 +484,22 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) LOG(MODULE_FILEIO, " --> V2ray Ctl: " + vCtlresult) // - if (vCoreresult == "OK" && vCtlresult == "OK") { + if (vCoreresult == "OK" && vCtlresult == "OK") + { LOG(MODULE_VCORE, " --> Done copying files.") on_vCorePathTxt_textEdited(QV2RAY_TPROXY_VCORE_PATH); - } else { + } + else + { LOG(MODULE_VCORE, "FAILED to copy V2ray files. Aborting.") QvMessageBoxWarn(this, tr("Enable tProxy Support"), - tr("Qv2ray cannot copy one or both V2ray files from: ") + NEWLINE + NEWLINE + - CurrentConfig.v2CorePath + NEWLINE + v2ctlPath + NEWLINE + NEWLINE + - tr("to this path: ") + NEWLINE + newPath); + tr("Qv2ray cannot copy one or both V2ray files from: ") + NEWLINE + NEWLINE + CurrentConfig.v2CorePath + + NEWLINE + v2ctlPath + NEWLINE + NEWLINE + tr("to this path: ") + NEWLINE + newPath); return; } - } else { + } + else + { LOG(MODULE_VCORE, "Skipped removing files since the current V2ray core is in the default path.") LOG(MODULE_VCORE, " --> Actually because we don't know where else to obtain the files.") } @@ -475,7 +507,8 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) LOG(MODULE_UI, "Calling pkexec and setcap...") int ret = QProcess::execute("pkexec setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE=eip " + CurrentConfig.v2CorePath); - if (ret != 0) { + if (ret != 0) + { LOG(MODULE_UI, "WARN: setcap exits with code: " + QSTRN(ret)) QvMessageBoxWarn(this, tr("Preferences"), tr("Failed to setcap onto V2ray executable. You may need to run `setcap` manually.")); } @@ -483,10 +516,13 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) CurrentConfig.tProxySupport = true; NEEDRESTART } - } else { + } + else + { int ret = QProcess::execute("pkexec setcap -r " + CurrentConfig.v2CorePath); - if (ret != 0) { + if (ret != 0) + { LOG(MODULE_UI, "WARN: setcap exits with code: " + QSTRN(ret)) QvMessageBoxWarn(this, tr("Preferences"), tr("Failed to setcap onto V2ray executable. You may need to run `setcap` manually.")); } @@ -540,14 +576,15 @@ void PreferencesWindow::on_socksUDPIP_textEdited(const QString &arg1) NEEDRESTART CurrentConfig.inboundConfig.socksLocalIP = arg1; - if (IsValidIPAddress(arg1)) { - BLACK(socksUDPIP) - } else { + if (IsValidIPAddress(arg1)) { BLACK(socksUDPIP) } + else + { RED(socksUDPIP) } } -// ------------------- NET SPEED PLUGIN OPERATIONS ----------------------------------------------------------------- +// ------------------- NET SPEED PLUGIN OPERATIONS +// ----------------------------------------------------------------- #define CurrentBarPage CurrentConfig.toolBarConfig.Pages[this->CurrentBarPageId] #define CurrentBarLine CurrentBarPage.Lines[this->CurrentBarLineId] @@ -557,7 +594,7 @@ void PreferencesWindow::on_nsBarPageAddBTN_clicked() { QvBarPage page; CurrentConfig.toolBarConfig.Pages.push_back(page); - CurrentBarPageId = CurrentConfig.toolBarConfig.Pages.size() - 1 ; + CurrentBarPageId = CurrentConfig.toolBarConfig.Pages.size() - 1; // Add default line. QvBarLine line; CurrentBarPage.Lines.push_back(line); @@ -576,11 +613,13 @@ void PreferencesWindow::on_nsBarPageAddBTN_clicked() void PreferencesWindow::on_nsBarPageDelBTN_clicked() { - if (nsBarPagesList->currentRow() >= 0) { + if (nsBarPagesList->currentRow() >= 0) + { CurrentConfig.toolBarConfig.Pages.removeAt(nsBarPagesList->currentRow()); nsBarPagesList->takeItem(nsBarPagesList->currentRow()); - if (nsBarPagesList->count() <= 0) { + if (nsBarPagesList->count() <= 0) + { nsBarPageDelBTN->setEnabled(false); nsBarLineAddBTN->setEnabled(false); nsBarLineDelBTN->setEnabled(false); @@ -613,12 +652,14 @@ void PreferencesWindow::on_nsBarLineAddBTN_clicked() void PreferencesWindow::on_nsBarLineDelBTN_clicked() { - if (nsBarLinesList->currentRow() >= 0) { + if (nsBarLinesList->currentRow() >= 0) + { CurrentBarPage.Lines.removeAt(nsBarLinesList->currentRow()); nsBarLinesList->takeItem(nsBarLinesList->currentRow()); CurrentBarLineId = 0; - if (nsBarLinesList->count() <= 0) { + if (nsBarLinesList->count() <= 0) + { networkToolbarSettingsFrame->setEnabled(false); nsBarLineDelBTN->setEnabled(false); } @@ -639,15 +680,19 @@ void PreferencesWindow::on_nsBarPagesList_currentRowChanged(int currentRow) nsBarPageYOffset->setValue(CurrentBarPage.OffsetYpx); nsBarLinesList->clear(); - if (!CurrentBarPage.Lines.empty()) { - for (auto line : CurrentBarPage.Lines) { + if (!CurrentBarPage.Lines.empty()) + { + for (auto line : CurrentBarPage.Lines) + { auto description = GetBarLineDescription(line); nsBarLinesList->addItem(description); } nsBarLinesList->setCurrentRow(0); ShowLineParameters(CurrentBarLine); - } else { + } + else + { networkToolbarSettingsFrame->setEnabled(false); } } @@ -725,11 +770,9 @@ QString PreferencesWindow::GetBarLineDescription(QvBarLine barLine) QString result = "Empty"; result = NetSpeedPluginMessages[barLine.ContentType]; - if (barLine.ContentType == 0) { - result += " (" + barLine.Message + ")"; - } + if (barLine.ContentType == 0) { result += " (" + barLine.Message + ")"; } - result = result.append(barLine.Bold ? ", " + tr("Bold") : ""); + result = result.append(barLine.Bold ? ", " + tr("Bold") : ""); result = result.append(barLine.Italic ? ", " + tr("Italic") : ""); return result; } @@ -738,9 +781,7 @@ void PreferencesWindow::ShowLineParameters(QvBarLine &barLine) { finishedLoading = false; - if (!barLine.Family.isEmpty()) { - fontComboBox->setCurrentFont(QFont(barLine.Family)); - } + if (!barLine.Family.isEmpty()) { fontComboBox->setCurrentFont(QFont(barLine.Family)); } // Colors nsBarFontASB->setValue(barLine.ColorA); @@ -749,10 +790,9 @@ void PreferencesWindow::ShowLineParameters(QvBarLine &barLine) nsBarFontRSB->setValue(barLine.ColorR); // QColor color = QColor::fromRgb(barLine.ColorR, barLine.ColorG, barLine.ColorB, barLine.ColorA); - QString s(QStringLiteral("background: #") - + ((color.red() < 16) ? "0" : "") + QString::number(color.red(), 16) - + ((color.green() < 16) ? "0" : "") + QString::number(color.green(), 16) - + ((color.blue() < 16) ? "0" : "") + QString::number(color.blue(), 16) + ";"); + QString s(QStringLiteral("background: #") + ((color.red() < 16) ? "0" : "") + QString::number(color.red(), 16) + + ((color.green() < 16) ? "0" : "") + QString::number(color.green(), 16) + ((color.blue() < 16) ? "0" : "") + + QString::number(color.blue(), 16) + ";"); chooseColorBtn->setStyleSheet(s); nsBarFontSizeSB->setValue(barLine.Size); nsBarFontBoldCB->setChecked(barLine.Bold); @@ -769,7 +809,8 @@ void PreferencesWindow::on_chooseColorBtn_clicked() QColorDialog d(QColor::fromRgb(CurrentBarLine.ColorR, CurrentBarLine.ColorG, CurrentBarLine.ColorB, CurrentBarLine.ColorA), this); d.exec(); - if (d.result() == QDialog::DialogCode::Accepted) { + if (d.result() == QDialog::DialogCode::Accepted) + { d.selectedColor().getRgb(&CurrentBarLine.ColorR, &CurrentBarLine.ColorG, &CurrentBarLine.ColorB, &CurrentBarLine.ColorA); ShowLineParameters(CurrentBarLine); SET_LINE_LIST_TEXT @@ -792,9 +833,10 @@ void PreferencesWindow::on_nsBarContentCombo_currentIndexChanged(const QString & void PreferencesWindow::on_applyNSBarSettingsBtn_clicked() { - if (QvMessageBoxAsk(this, tr("Apply network toolbar settings"), tr("All other modified settings will be applied as well after this object.") + - NEWLINE + - tr("Do you want to continue?")) == QMessageBox::Yes) { + if (QvMessageBoxAsk(this, tr("Apply network toolbar settings"), + tr("All other modified settings will be applied as well after this object.") + NEWLINE + + tr("Do you want to continue?")) == QMessageBox::Yes) + { auto conf = GlobalConfig; conf.toolBarConfig = CurrentConfig.toolBarConfig; SaveGlobalConfig(conf); @@ -815,7 +857,8 @@ void PreferencesWindow::on_darkThemeCB_stateChanged(int arg1) #ifdef QV2RAY_USE_BUILTIN_DARKTHEME themeCombo->setEnabled(arg1 != Qt::Checked); - if (arg1 == Qt::Checked) { + if (arg1 == Qt::Checked) + { themeCombo->setCurrentIndex(QStyleFactory::keys().indexOf("Fusion")); CurrentConfig.uiConfig.theme = "Fusion"; } @@ -840,7 +883,8 @@ void PreferencesWindow::on_pacGoBtn_clicked() LOG(MODULE_PROXY, "Downloading GFWList file.") bool withProxy = getGFWListWithProxyCB->isChecked(); - switch (gfwListCB->currentIndex()) { + switch (gfwListCB->currentIndex()) + { case 0: gfwLocation = "https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt"; fileContent = QString::fromUtf8(request.syncget(gfwLocation, withProxy)); @@ -874,7 +918,8 @@ void PreferencesWindow::on_pacGoBtn_clicked() case 6: auto file = QFileDialog::getOpenFileName(this, tr("Select GFWList in base64")); - if (file.isEmpty()) { + if (file.isEmpty()) + { QvMessageBoxWarn(this, tr("Download GFWList"), tr("Operation is cancelled.")); return; } @@ -888,9 +933,7 @@ void PreferencesWindow::on_pacGoBtn_clicked() pacGoBtn->setEnabled(true); gfwListCB->setEnabled(true); - if (!QDir(QV2RAY_RULES_DIR).exists()) { - QDir(QV2RAY_RULES_DIR).mkpath(QV2RAY_RULES_DIR); - } + if (!QDir(QV2RAY_RULES_DIR).exists()) { QDir(QV2RAY_RULES_DIR).mkpath(QV2RAY_RULES_DIR); } StringToFile(fileContent, QV2RAY_RULES_GFWLIST_PATH); } @@ -900,7 +943,8 @@ void PreferencesWindow::on_pacPortSB_valueChanged(int arg1) LOADINGCHECK NEEDRESTART CurrentConfig.inboundConfig.pacConfig.port = arg1; - pacListenAddrLabel->setText("http://" + (pacProxyTxt->text().isEmpty() ? "127.0.0.1" : pacProxyTxt->text()) + ":" + QSTRN(pacPortSB->value()) + "/pac"); + pacListenAddrLabel->setText("http://" + (pacProxyTxt->text().isEmpty() ? "127.0.0.1" : pacProxyTxt->text()) + ":" + + QSTRN(pacPortSB->value()) + "/pac"); } void PreferencesWindow::on_setSysProxyCB_stateChanged(int arg1) @@ -939,9 +983,7 @@ void PreferencesWindow::on_autoStartSubsCombo_currentIndexChanged(const QString auto list = ConnectionManager->Connections(groupId); autoStartConnCombo->clear(); - for (auto id : list) { - autoStartConnCombo->addItem(ConnectionManager->GetDisplayName(id)); - } + for (auto id : list) { autoStartConnCombo->addItem(ConnectionManager->GetDisplayName(id)); } } void PreferencesWindow::on_autoStartConnCombo_currentIndexChanged(const QString &arg1) @@ -955,9 +997,7 @@ void PreferencesWindow::on_startWithLoginCB_stateChanged(int arg1) bool isEnabled = arg1 == Qt::Checked; SetLaunchAtLoginStatus(isEnabled); - if (GetLaunchAtLoginStatus() != isEnabled) { - QvMessageBoxWarn(this, tr("Start with boot"), tr("Failed to set auto start option.")); - } + if (GetLaunchAtLoginStatus() != isEnabled) { QvMessageBoxWarn(this, tr("Start with boot"), tr("Failed to set auto start option.")); } SetAutoStartButtonsState(GetLaunchAtLoginStatus()); } @@ -978,9 +1018,9 @@ void PreferencesWindow::on_fpAddressTx_textEdited(const QString &arg1) LOADINGCHECK CurrentConfig.connectionConfig.forwardProxyConfig.serverAddress = arg1; - if (IsValidIPAddress(arg1)) { - BLACK(fpAddressTx) - } else { + if (IsValidIPAddress(arg1)) { BLACK(fpAddressTx) } + else + { RED(fpAddressTx) } } @@ -1021,13 +1061,14 @@ void PreferencesWindow::on_pacProxyTxt_textChanged(const QString &arg1) { Q_UNUSED(arg1) - if (IsValidIPAddress(arg1)) { - BLACK(pacProxyTxt) - } else { + if (IsValidIPAddress(arg1)) { BLACK(pacProxyTxt) } + else + { RED(pacProxyTxt) } - pacListenAddrLabel->setText("http://" + (pacProxyTxt->text().isEmpty() ? "127.0.0.1" : pacProxyTxt->text()) + ":" + QSTRN(pacPortSB->value()) + "/pac"); + pacListenAddrLabel->setText("http://" + (pacProxyTxt->text().isEmpty() ? "127.0.0.1" : pacProxyTxt->text()) + ":" + + QSTRN(pacPortSB->value()) + "/pac"); } void PreferencesWindow::on_checkVCoreSettings_clicked() @@ -1036,11 +1077,12 @@ void PreferencesWindow::on_checkVCoreSettings_clicked() auto vAssetsPath = vCoreAssetsPathTxt->text(); QString result; - if (!V2rayKernelInstance::ValidateKernel(vcorePath, vAssetsPath, &result)) { - QvMessageBoxWarn(this, tr("V2ray Core Settings"), result); - } else { - QvMessageBoxInfo(this, tr("V2ray Core Settings"), tr("V2ray path configuration check passed.") + NEWLINE + NEWLINE + - tr("Current version of V2ray is: ") + NEWLINE + result); + if (!V2rayKernelInstance::ValidateKernel(vcorePath, vAssetsPath, &result)) { QvMessageBoxWarn(this, tr("V2ray Core Settings"), result); } + else + { + QvMessageBoxInfo(this, tr("V2ray Core Settings"), + tr("V2ray path configuration check passed.") + NEWLINE + NEWLINE + tr("Current version of V2ray is: ") + NEWLINE + + result); } } diff --git a/src/ui/w_PreferencesWindow.hpp b/src/ui/w_PreferencesWindow.hpp index 5fba2a5c..06348abe 100644 --- a/src/ui/w_PreferencesWindow.hpp +++ b/src/ui/w_PreferencesWindow.hpp @@ -1,180 +1,183 @@ #pragma once -#include -#include #include "base/Qv2rayBase.hpp" #include "ui/messaging/QvMessageBus.hpp" -class PreferencesWindow : public QDialog, private Ui::PreferencesWindow +#include +#include + +class PreferencesWindow + : public QDialog + , private Ui::PreferencesWindow { - Q_OBJECT + Q_OBJECT - public: - explicit PreferencesWindow(QWidget *parent = nullptr); - ~PreferencesWindow(); - signals: - void s_reload_config(bool need_restart); + public: + explicit PreferencesWindow(QWidget *parent = nullptr); + ~PreferencesWindow(); + signals: + void s_reload_config(bool need_restart); - public slots: - QvMessageBusSlotDecl + public slots: + QvMessageBusSlotDecl; - private slots: - void on_buttonBox_accepted(); + private slots: + void on_buttonBox_accepted(); - void on_httpAuthCB_stateChanged(int arg1); + void on_httpAuthCB_stateChanged(int arg1); - void on_socksAuthCB_stateChanged(int arg1); + void on_socksAuthCB_stateChanged(int arg1); - void on_languageComboBox_currentTextChanged(const QString &arg1); + void on_languageComboBox_currentTextChanged(const QString &arg1); - void on_logLevelComboBox_currentIndexChanged(int index); + void on_logLevelComboBox_currentIndexChanged(int index); - void on_vCoreAssetsPathTxt_textEdited(const QString &arg1); + void on_vCoreAssetsPathTxt_textEdited(const QString &arg1); - void on_listenIPTxt_textEdited(const QString &arg1); + void on_listenIPTxt_textEdited(const QString &arg1); - void on_socksPortLE_valueChanged(int arg1); + void on_socksPortLE_valueChanged(int arg1); - void on_httpPortLE_valueChanged(int arg1); + void on_httpPortLE_valueChanged(int arg1); - void on_httpAuthUsernameTxt_textEdited(const QString &arg1); + void on_httpAuthUsernameTxt_textEdited(const QString &arg1); - void on_httpAuthPasswordTxt_textEdited(const QString &arg1); + void on_httpAuthPasswordTxt_textEdited(const QString &arg1); - void on_socksAuthUsernameTxt_textEdited(const QString &arg1); + void on_socksAuthUsernameTxt_textEdited(const QString &arg1); - void on_socksAuthPasswordTxt_textEdited(const QString &arg1); + void on_socksAuthPasswordTxt_textEdited(const QString &arg1); - void on_proxyDefaultCb_stateChanged(int arg1); + void on_proxyDefaultCb_stateChanged(int arg1); - void on_localDNSCb_stateChanged(int arg1); + void on_localDNSCb_stateChanged(int arg1); - void on_selectVAssetBtn_clicked(); + void on_selectVAssetBtn_clicked(); - void on_DNSListTxt_textChanged(); + void on_DNSListTxt_textChanged(); - void on_aboutQt_clicked(); + void on_aboutQt_clicked(); - void on_cancelIgnoreVersionBtn_clicked(); + void on_cancelIgnoreVersionBtn_clicked(); - void on_tProxyCheckBox_stateChanged(int arg1); + void on_tProxyCheckBox_stateChanged(int arg1); - void on_bypassCNCb_stateChanged(int arg1); + void on_bypassCNCb_stateChanged(int arg1); - void on_statsPortBox_valueChanged(int arg1); + void on_statsPortBox_valueChanged(int arg1); - void on_socksUDPCB_stateChanged(int arg1); + void on_socksUDPCB_stateChanged(int arg1); - void on_socksUDPIP_textEdited(const QString &arg1); + void on_socksUDPIP_textEdited(const QString &arg1); - void on_nsBarPageAddBTN_clicked(); + void on_nsBarPageAddBTN_clicked(); - void on_nsBarPageDelBTN_clicked(); + void on_nsBarPageDelBTN_clicked(); - void on_nsBarPageYOffset_valueChanged(int arg1); + void on_nsBarPageYOffset_valueChanged(int arg1); - void on_nsBarLineAddBTN_clicked(); + void on_nsBarLineAddBTN_clicked(); - void on_nsBarLineDelBTN_clicked(); + void on_nsBarLineDelBTN_clicked(); - void on_nsBarPagesList_currentRowChanged(int currentRow); + void on_nsBarPagesList_currentRowChanged(int currentRow); - void on_nsBarLinesList_currentRowChanged(int currentRow); + void on_nsBarLinesList_currentRowChanged(int currentRow); - void on_fontComboBox_currentFontChanged(const QFont &f); + void on_fontComboBox_currentFontChanged(const QFont &f); - void on_nsBarFontBoldCB_stateChanged(int arg1); + void on_nsBarFontBoldCB_stateChanged(int arg1); - void on_nsBarFontItalicCB_stateChanged(int arg1); + void on_nsBarFontItalicCB_stateChanged(int arg1); - void on_nsBarFontASB_valueChanged(int arg1); + void on_nsBarFontASB_valueChanged(int arg1); - void on_nsBarFontRSB_valueChanged(int arg1); + void on_nsBarFontRSB_valueChanged(int arg1); - void on_nsBarFontGSB_valueChanged(int arg1); + void on_nsBarFontGSB_valueChanged(int arg1); - void on_nsBarFontBSB_valueChanged(int arg1); + void on_nsBarFontBSB_valueChanged(int arg1); - void on_nsBarFontSizeSB_valueChanged(double arg1); + void on_nsBarFontSizeSB_valueChanged(double arg1); - void on_chooseColorBtn_clicked(); + void on_chooseColorBtn_clicked(); - void on_nsBarTagTxt_textEdited(const QString &arg1); + void on_nsBarTagTxt_textEdited(const QString &arg1); - void on_nsBarContentCombo_currentIndexChanged(const QString &arg1); + void on_nsBarContentCombo_currentIndexChanged(const QString &arg1); - void on_applyNSBarSettingsBtn_clicked(); + void on_applyNSBarSettingsBtn_clicked(); - void on_selectVCoreBtn_clicked(); + void on_selectVCoreBtn_clicked(); - void on_vCorePathTxt_textEdited(const QString &arg1); + void on_vCorePathTxt_textEdited(const QString &arg1); - void on_themeCombo_currentTextChanged(const QString &arg1); + void on_themeCombo_currentTextChanged(const QString &arg1); - void on_darkThemeCB_stateChanged(int arg1); + void on_darkThemeCB_stateChanged(int arg1); - void on_darkTrayCB_stateChanged(int arg1); + void on_darkTrayCB_stateChanged(int arg1); - void on_pacGoBtn_clicked(); + void on_pacGoBtn_clicked(); - void on_pacPortSB_valueChanged(int arg1); + void on_pacPortSB_valueChanged(int arg1); - void on_setSysProxyCB_stateChanged(int arg1); + void on_setSysProxyCB_stateChanged(int arg1); - void on_pacProxyCB_currentIndexChanged(int index); + void on_pacProxyCB_currentIndexChanged(int index); - void on_pushButton_clicked(); + void on_pushButton_clicked(); - void on_pacProxyTxt_textEdited(const QString &arg1); + void on_pacProxyTxt_textEdited(const QString &arg1); - void on_autoStartSubsCombo_currentIndexChanged(const QString &arg1); + void on_autoStartSubsCombo_currentIndexChanged(const QString &arg1); - void on_autoStartConnCombo_currentIndexChanged(const QString &arg1); + void on_autoStartConnCombo_currentIndexChanged(const QString &arg1); - void on_fpTypeCombo_currentIndexChanged(const QString &arg1); + void on_fpTypeCombo_currentIndexChanged(const QString &arg1); - void on_fpAddressTx_textEdited(const QString &arg1); + void on_fpAddressTx_textEdited(const QString &arg1); - void on_spPortSB_valueChanged(int arg1); + void on_spPortSB_valueChanged(int arg1); - void on_fpUseAuthCB_stateChanged(int arg1); + void on_fpUseAuthCB_stateChanged(int arg1); - void on_fpUsernameTx_textEdited(const QString &arg1); + void on_fpUsernameTx_textEdited(const QString &arg1); - void on_fpPasswordTx_textEdited(const QString &arg1); + void on_fpPasswordTx_textEdited(const QString &arg1); - void on_fpPortSB_valueChanged(int arg1); + void on_fpPortSB_valueChanged(int arg1); - void on_pacProxyTxt_textChanged(const QString &arg1); + void on_pacProxyTxt_textChanged(const QString &arg1); - void on_checkVCoreSettings_clicked(); + void on_checkVCoreSettings_clicked(); - void on_httpGroupBox_clicked(bool checked); + void on_httpGroupBox_clicked(bool checked); - void on_socksGroupBox_clicked(bool checked); + void on_socksGroupBox_clicked(bool checked); - void on_pacGroupBox_clicked(bool checked); + void on_pacGroupBox_clicked(bool checked); - void on_fpGroupBox_clicked(bool checked); + void on_fpGroupBox_clicked(bool checked); - void on_maxLogLinesSB_valueChanged(int arg1); + void on_maxLogLinesSB_valueChanged(int arg1); - void on_enableAPI_stateChanged(int arg1); + void on_enableAPI_stateChanged(int arg1); - void on_startWithLoginCB_stateChanged(int arg1); + void on_startWithLoginCB_stateChanged(int arg1); - void on_tProxyGroupBox_clicked(bool checked); + void on_tProxyGroupBox_clicked(bool checked); - private: - void SetAutoStartButtonsState(bool isAutoStart); - // Set ui parameters for a line; - void ShowLineParameters(QvBarLine &line); - QString GetBarLineDescription(QvBarLine line); - // - int CurrentBarLineId; - int CurrentBarPageId; - // - bool IsConnectionPropertyChanged = false; - bool finishedLoading = false; - Qv2rayConfig CurrentConfig; + private: + void SetAutoStartButtonsState(bool isAutoStart); + // Set ui parameters for a line; + void ShowLineParameters(QvBarLine &line); + QString GetBarLineDescription(QvBarLine line); + // + int CurrentBarLineId; + int CurrentBarPageId; + // + bool IsConnectionPropertyChanged = false; + bool finishedLoading = false; + Qv2rayConfig CurrentConfig; }; diff --git a/src/ui/w_ScreenShot_Core.cpp b/src/ui/w_ScreenShot_Core.cpp index 598562ca..1af073f0 100644 --- a/src/ui/w_ScreenShot_Core.cpp +++ b/src/ui/w_ScreenShot_Core.cpp @@ -1,15 +1,18 @@ #include "w_ScreenShot_Core.hpp" + #include "common/QvHelpers.hpp" + #include -#include #include +#include #define QV2RAY_SCREENSHOT_DIM_RATIO 0.6f ScreenShotWindow::ScreenShotWindow() : QDialog(), rubber(new QRubberBand(QRubberBand::Rectangle, this)) { setupUi(this); - // Fusion prevents the KDE Plasma Breeze's "Move window when dragging in the empty area" issue + // Fusion prevents the KDE Plasma Breeze's "Move window when dragging in the + // empty area" issue this->setStyle(QStyleFactory::create("Fusion")); // label->setAttribute(Qt::WA_TranslucentBackground); @@ -30,8 +33,9 @@ ScreenShotWindow::ScreenShotWindow() : QDialog(), rubber(new QRubberBand(QRubber QImage ScreenShotWindow::DoScreenShot() { LOG(MODULE_IMPORT, "We currently only support the current screen.") - // The msleep is the only solution which prevent capturing our windows again. - // It works on KDE, https://www.qtcentre.org/threads/55708-Get-Desktop-Screenshot-Without-Application-Window-Being-Shown?p=248993#post248993 + // The msleep is the only solution which prevent capturing our windows + // again. It works on KDE, + // https://www.qtcentre.org/threads/55708-Get-Desktop-Screenshot-Without-Application-Window-Being-Shown?p=248993#post248993 QThread::msleep(100); QApplication::processEvents(); // @@ -45,8 +49,10 @@ QImage ScreenShotWindow::DoScreenShot() int r, g, b; auto _xdesktopImg = desktopImage.toImage(); - for (int i = 0; i < w; i++) { - for (int j = 0; j < h; j++) { + for (int i = 0; i < w; i++) + { + for (int j = 0; j < h; j++) + { r = static_cast(qRed(_xdesktopImg.pixel(i, j)) * QV2RAY_SCREENSHOT_DIM_RATIO); g = static_cast(qGreen(_xdesktopImg.pixel(i, j)) * QV2RAY_SCREENSHOT_DIM_RATIO); b = static_cast(qBlue(_xdesktopImg.pixel(i, j)) * QV2RAY_SCREENSHOT_DIM_RATIO); @@ -72,16 +78,18 @@ void ScreenShotWindow::pSize() imgH = abs(end.y() - origin.y()); imgX = origin.x() < end.x() ? origin.x() : end.x(); imgY = origin.y() < end.y() ? origin.y() : end.y(); - DEBUG("Capture Mouse Position", QSTRN(imgW) + " " + QSTRN(imgH) + " " + QSTRN(imgX) + " " + QSTRN(imgY)) + DEBUG("Capture Mouse Position", QSTRN(imgW) + " " + QSTRN(imgH) + " " + QSTRN(imgX) + " " + QSTRN(imgY)) rubber->setGeometry(imgX, imgY, imgW, imgH); fg->setGeometry(rubber->geometry()); - auto copied = desktopImage.copy(fg->x() * devicePixelRatio(), fg->y() * devicePixelRatio(), fg->width() * devicePixelRatio(), fg->height() * devicePixelRatio()); + auto copied = desktopImage.copy(fg->x() * devicePixelRatio(), fg->y() * devicePixelRatio(), fg->width() * devicePixelRatio(), + fg->height() * devicePixelRatio()); fg->setPixmap(copied); } bool ScreenShotWindow::event(QEvent *e) { - if (e->type() == QEvent::Move) { + if (e->type() == QEvent::Move) + { // } @@ -90,9 +98,9 @@ bool ScreenShotWindow::event(QEvent *e) void ScreenShotWindow::keyPressEvent(QKeyEvent *e) { - if (e->key() == Qt::Key_Escape) { - reject(); - } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + if (e->key() == Qt::Key_Escape) { reject(); } + else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) + { on_startBtn_clicked(); } } @@ -103,13 +111,14 @@ void ScreenShotWindow::mousePressEvent(QMouseEvent *e) rubber->setGeometry(origin.x(), origin.y(), 0, 0); rubber->show(); rubber->raise(); - //label->hide(); - //startBtn->hide(); + // label->hide(); + // startBtn->hide(); } void ScreenShotWindow::mouseMoveEvent(QMouseEvent *e) { - if (e->buttons() & Qt::LeftButton) { + if (e->buttons() & Qt::LeftButton) + { end = e->pos(); pSize(); // @@ -120,15 +129,15 @@ void ScreenShotWindow::mouseMoveEvent(QMouseEvent *e) QRect labelRect(label->contentsRect()); QRect btnRect(startBtn->contentsRect()); - if (imgY > labelRect.height()) { - label->move(imgX, imgY - labelRect.height()); - } else { + if (imgY > labelRect.height()) { label->move(imgX, imgY - labelRect.height()); } + else + { label->move(imgX, imgY); } - if (height() - imgY - imgH > btnRect.height()) { - startBtn->move(imgX + imgW - btnRect.width(), imgY + imgH); - } else { + if (height() - imgY - imgH > btnRect.height()) { startBtn->move(imgX + imgW - btnRect.width(), imgY + imgH); } + else + { startBtn->move(imgX + imgW - btnRect.width(), imgY + imgH - btnRect.height()); } @@ -137,12 +146,9 @@ void ScreenShotWindow::mouseMoveEvent(QMouseEvent *e) } } - void ScreenShotWindow::mouseReleaseEvent(QMouseEvent *e) { - if (e->button() == Qt::RightButton) { - reject(); - } + if (e->button() == Qt::RightButton) { reject(); } } ScreenShotWindow::~ScreenShotWindow() diff --git a/src/ui/w_ScreenShot_Core.hpp b/src/ui/w_ScreenShot_Core.hpp index 747e7394..b74da91b 100644 --- a/src/ui/w_ScreenShot_Core.hpp +++ b/src/ui/w_ScreenShot_Core.hpp @@ -1,46 +1,48 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "ui_w_ScreenShot_Core.h" -class ScreenShotWindow : public QDialog, private Ui::ScreenShot +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ScreenShotWindow + : public QDialog + , private Ui::ScreenShot { - Q_OBJECT + Q_OBJECT - public: - ScreenShotWindow(); - ~ScreenShotWindow(); - QImage DoScreenShot(); - // - void mouseMoveEvent(QMouseEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void keyPressEvent(QKeyEvent *e) override; + public: + ScreenShotWindow(); + ~ScreenShotWindow(); + QImage DoScreenShot(); + // + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; - protected: - bool event(QEvent *e) override; + protected: + bool event(QEvent *e) override; - private slots: - void on_startBtn_clicked(); + private slots: + void on_startBtn_clicked(); - private: - QRubberBand *rubber; - // Desktop Image - QPixmap desktopImage; - QImage windowBg; - QImage resultImage; - // - QPoint origin; - QPoint end; - int imgW, imgH, imgX, imgY; + private: + QRubberBand *rubber; + // Desktop Image + QPixmap desktopImage; + QImage windowBg; + QImage resultImage; + // + QPoint origin; + QPoint end; + int imgW, imgH, imgX, imgY; - void pSize(); + void pSize(); }; diff --git a/src/ui/w_SubscriptionManager.cpp b/src/ui/w_SubscriptionManager.cpp index 84236a40..d07a4b10 100644 --- a/src/ui/w_SubscriptionManager.cpp +++ b/src/ui/w_SubscriptionManager.cpp @@ -1,33 +1,31 @@ #include "w_SubscriptionManager.hpp" + #include "common/QvHelpers.hpp" #include "core/config/ConfigBackend.hpp" #include "core/handler/ConnectionHandler.hpp" -SubscribeEditor::SubscribeEditor(QWidget *parent) : - QDialog(parent) +SubscribeEditor::SubscribeEditor(QWidget *parent) : QDialog(parent) { setupUi(this); QvMessageBusConnect(SubscribeEditor); addSubsButton->setIcon(QICON_R("add.png")); removeSubsButton->setIcon(QICON_R("delete.png")); - for (auto subs : ConnectionManager->Subscriptions()) { - subscriptionList->addTopLevelItem(new QTreeWidgetItem(QStringList() << ConnectionManager->GetDisplayName(subs) << subs.toString())); - } + for (auto subs : ConnectionManager->Subscriptions()) + { subscriptionList->addTopLevelItem(new QTreeWidgetItem(QStringList() << ConnectionManager->GetDisplayName(subs) << subs.toString())); } } QvMessageBusSlotImpl(SubscribeEditor) { - switch (msg) { - MBShowDefaultImpl - MBHideDefaultImpl - MBRetranslateDefaultImpl + switch (msg) + { + MBShowDefaultImpl MBHideDefaultImpl MBRetranslateDefaultImpl } } QPair SubscribeEditor::GetSelectedConfig() { - return QPair (); + return QPair(); } SubscribeEditor::~SubscribeEditor() @@ -46,22 +44,26 @@ void SubscribeEditor::on_addSubsButton_clicked() void SubscribeEditor::on_updateButton_clicked() { - //auto newName = subNameTxt->text().trimmed(); - //auto newAddress = subAddrTxt->text().trimmed(); - //auto newUpdateInterval = updateIntervalSB->value(); - //if (currentSubId != newName) { + ConnectionManager->UpdateSubscription(currentSubId, withProxyCB->isChecked()); + // auto newName = subNameTxt->text().trimmed(); + // auto newAddress = subAddrTxt->text().trimmed(); + // auto newUpdateInterval = updateIntervalSB->value(); + // if (currentSubId != newName) { // // Rename needed. - // LOG(MODULE_SUBSCRIPTION, "Renaming a subscription, from " + currentSubId + " to: " + newName) - // bool canGo = true; + // LOG(MODULE_SUBSCRIPTION, "Renaming a subscription, from " + + // currentSubId + " to: " + newName) bool canGo = true; // // if (newName.isEmpty() || !IsValidFileName(newName)) { - // QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("The subscription name is invalid, please try another.")); - // canGo = false; + // QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("The + // subscription name is invalid, please try another.")); canGo = + // false; // } // - // if (subscriptionList->findItems(newName, Qt::MatchExactly).count() > 0) { - // QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("New name of this subscription has been used already, please suggest another one")); - // canGo = false; + // if (subscriptionList->findItems(newName, Qt::MatchExactly).count() > + // 0) { + // QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("New name + // of this subscription has been used already, please suggest another + // one")); canGo = false; // } // // if (!canGo) { @@ -72,7 +74,8 @@ void SubscribeEditor::on_updateButton_clicked() // ////bool result = RenameSubscription(currentSubName, newName); // // // //if (!result) { - // // QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("Failed to rename a subscription, this is an unknown error.")); + // // QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("Failed + // to rename a subscription, this is an unknown error.")); // // return; // //} // subscriptions[newName] = subscriptions[currentSubId]; @@ -93,68 +96,45 @@ void SubscribeEditor::on_updateButton_clicked() // // Update thing still down // subAddrTxt->setText(newAddress); // updateIntervalSB->setValue(newUpdateInterval); - // QvMessageBoxInfo(this, tr("Renaming a subscription"), tr("Successfully renamed a subscription")); + // QvMessageBoxInfo(this, tr("Renaming a subscription"), tr("Successfully + // renamed a subscription")); //} // - //subscriptions[currentSubId].updateInterval = newUpdateInterval; + // subscriptions[currentSubId].updateInterval = newUpdateInterval; // - //if (subscriptions[currentSubId].address != newAddress) { - // LOG(MODULE_SUBSCRIPTION, "Setting new address, from " + subscriptions[currentSubId].address + " to: " + newAddress) + // if (subscriptions[currentSubId].address != newAddress) { + // LOG(MODULE_SUBSCRIPTION, "Setting new address, from " + + // subscriptions[currentSubId].address + " to: " + newAddress) // subscriptions[currentSubId].address = newAddress; //} // ////SaveConfig(); // - ////if (QvMessageBoxAsk(this, tr("Update Subscription"), tr("Would you like to reload this subscription from the Url?")) == QMessageBox::Yes) { - //// StartUpdateSubscription(currentSubId); + ////if (QvMessageBoxAsk(this, tr("Update Subscription"), tr("Would you like + /// to reload this subscription from the Url?")) == QMessageBox::Yes) { / + /// StartUpdateSubscription(currentSubId); ////} } void SubscribeEditor::StartUpdateSubscription(const QString &subscriptionName) { this->setEnabled(false); - // auto data = helper.syncget(subscriptions[subscriptionName].address, withProxyCB->isChecked()); - // auto content = DecodeSubscriptionString(data).trimmed(); - //if (!content.isEmpty()) { - // connectionsList->clear(); - // auto vmessList = SplitLines(content); - // QDir(QV2RAY_SUBSCRIPTION_DIR + subscriptionName).removeRecursively(); - // QDir().mkpath(QV2RAY_SUBSCRIPTION_DIR + subscriptionName); - // - // for (auto vmess : vmessList) { - // QString errMessage; - // QString _alias; - // auto config = ConvertConfigFromString(vmess.trimmed(), &_alias, &errMessage); - // - // if (!errMessage.isEmpty()) { - // LOG(MODULE_SUBSCRIPTION, "Processing a subscription with following error: " + errMessage) - // } else { - // //SaveSubscriptionConfig(config, subscriptionName, &_alias); - // connectionsList->addItem(_alias); - // } - // } - // - // subscriptions[subscriptionName].lastUpdated = system_clock::to_time_t(system_clock::now()); - // lastUpdatedLabel->setText(timeToString(subscriptions[subscriptionName].lastUpdated)); - // isUpdateInProgress = false; - //} else { - // LOG(MODULE_NETWORK, "We have received an empty string from the URL.") - // QvMessageBoxWarn(this, tr("Updating subscriptions"), tr("Failed to process the result from the upstream, please check your Url.")); - //} - // + // auto data = helper.syncget(subscriptions[subscriptionName].address, + // withProxyCB->isChecked()); auto content = + this->setEnabled(true); } void SubscribeEditor::on_removeSubsButton_clicked() { - //if (subscriptionList->currentRow() < 0) + // if (subscriptionList->currentRow() < 0) // return; // - //auto name = subscriptionList->currentItem()->text(); - //subscriptionList->takeItem(subscriptionList->currentRow()); - //subscriptions.remove(name); + // auto name = subscriptionList->currentItem()->text(); + // subscriptionList->takeItem(subscriptionList->currentRow()); + // subscriptions.remove(name); // - //if (!name.isEmpty()) { + // if (!name.isEmpty()) { // QDir(QV2RAY_SUBSCRIPTION_DIR + name).removeRecursively(); //} // @@ -163,22 +143,22 @@ void SubscribeEditor::on_removeSubsButton_clicked() //// GlobalConfig.autoStartConfig = QvConnectionObject(); //// SaveGlobalConfig(GlobalConfig); ////} - //groupBox_2->setEnabled(subscriptionList->count() > 0); - //SaveConfig(); + // groupBox_2->setEnabled(subscriptionList->count() > 0); + // SaveConfig(); } void SubscribeEditor::SaveConfig() { - //QMap newConf; + // QMap newConf; // - //for (auto _ : subscriptions.toStdMap()) { + // for (auto _ : subscriptions.toStdMap()) { // if (!_.second.address.isEmpty()) { // newConf[_.first] = _.second; // } //} // - //GlobalConfig.subscriptions = newConf; - //SaveGlobalConfig(GlobalConfig); + // GlobalConfig.subscriptions = newConf; + // SaveGlobalConfig(GlobalConfig); } void SubscribeEditor::on_buttonBox_accepted() @@ -195,9 +175,7 @@ void SubscribeEditor::on_subscriptionList_itemClicked(QTreeWidgetItem *item, int { Q_UNUSED(column) - if (item == nullptr) { - return; - } + if (item == nullptr) { return; } currentSubId = GroupId(item->text(1)); // @@ -209,7 +187,5 @@ void SubscribeEditor::on_subscriptionList_itemClicked(QTreeWidgetItem *item, int // connectionsList->clear(); - for (auto conn : ConnectionManager->Connections(currentSubId)) { - connectionsList->addItem(ConnectionManager->GetDisplayName(conn)); - } + for (auto conn : ConnectionManager->Connections(currentSubId)) { connectionsList->addItem(ConnectionManager->GetDisplayName(conn)); } } diff --git a/src/ui/w_SubscriptionManager.hpp b/src/ui/w_SubscriptionManager.hpp index b8e8a7db..b0e5350c 100644 --- a/src/ui/w_SubscriptionManager.hpp +++ b/src/ui/w_SubscriptionManager.hpp @@ -1,40 +1,43 @@ #pragma once -#include #include "base/Qv2rayBase.hpp" -#include "ui_w_SubscriptionManager.h" -#include "ui/messaging/QvMessageBus.hpp" #include "core/CoreSafeTypes.hpp" +#include "ui/messaging/QvMessageBus.hpp" +#include "ui_w_SubscriptionManager.h" -class SubscribeEditor : public QDialog, private Ui::w_SubscribeEditor +#include + +class SubscribeEditor + : public QDialog + , private Ui::w_SubscribeEditor { - Q_OBJECT + Q_OBJECT - public: - explicit SubscribeEditor(QWidget *parent = nullptr); - ~SubscribeEditor(); - QPair GetSelectedConfig(); + public: + explicit SubscribeEditor(QWidget *parent = nullptr); + ~SubscribeEditor(); + QPair GetSelectedConfig(); - public slots: - QvMessageBusSlotDecl + public slots: + QvMessageBusSlotDecl; - private slots: - void on_addSubsButton_clicked(); + private slots: + void on_addSubsButton_clicked(); - void on_updateButton_clicked(); + void on_updateButton_clicked(); - void on_removeSubsButton_clicked(); + void on_removeSubsButton_clicked(); - void on_buttonBox_accepted(); + void on_buttonBox_accepted(); - void on_subscriptionList_itemSelectionChanged(); + void on_subscriptionList_itemSelectionChanged(); - void on_subscriptionList_itemClicked(QTreeWidgetItem *item, int column); + void on_subscriptionList_itemClicked(QTreeWidgetItem *item, int column); - private: - void StartUpdateSubscription(const QString &subscriptionName); - void SaveConfig(); + private: + void StartUpdateSubscription(const QString &subscriptionName); + void SaveConfig(); - bool isUpdateInProgress = false; - GroupId currentSubId = NullGroupId; + bool isUpdateInProgress = false; + GroupId currentSubId = NullGroupId; }; diff --git a/src/ui/widgets/ConnectionInfoWidget.cpp b/src/ui/widgets/ConnectionInfoWidget.cpp index 5e3143b7..bd96f337 100644 --- a/src/ui/widgets/ConnectionInfoWidget.cpp +++ b/src/ui/widgets/ConnectionInfoWidget.cpp @@ -1,9 +1,10 @@ #include "ConnectionInfoWidget.hpp" + +#include "3rdparty/qzxing/src/QZXing.h" #include "core/CoreUtils.hpp" #include "core/connection/Serialization.hpp" -#include "3rdparty/qzxing/src/QZXing.h" -ConnectionInfoWidget::ConnectionInfoWidget(QWidget *parent): QWidget(parent) +ConnectionInfoWidget::ConnectionInfoWidget(QWidget *parent) : QWidget(parent) { setupUi(this); duplicateBtn->setIcon(QICON_R("duplicate.png")); @@ -12,7 +13,8 @@ ConnectionInfoWidget::ConnectionInfoWidget(QWidget *parent): QWidget(parent) editJsonBtn->setIcon(QICON_R("json.png")); // shareLinkTxt->setAutoFillBackground(true); - shareLinkTxt->setStyleSheet("border-bottom: 1px solid gray; border-radius: 0px; padding: 2px; background-color: " + this->palette().color(this->backgroundRole()).name(QColor::HexRgb)); + shareLinkTxt->setStyleSheet("border-bottom: 1px solid gray; border-radius: 0px; padding: 2px; background-color: " + + this->palette().color(this->backgroundRole()).name(QColor::HexRgb)); shareLinkTxt->setCursor(QCursor(Qt::CursorShape::IBeamCursor)); shareLinkTxt->installEventFilter(this); // @@ -30,10 +32,12 @@ void ConnectionInfoWidget::ShowDetails(const tuple &_iden duplicateBtn->setEnabled(isConnection); editBtn->setEnabled(isConnection); - if (isConnection) { + if (isConnection) + { groupLabel->setText(ConnectionManager->GetDisplayName(groupId, 175)); protocolLabel->setText(ConnectionManager->GetConnectionProtocolString(connectionId)); - auto [host, port] = ConnectionManager->GetConnectionInfo(connectionId); + auto [protocol, host, port] = ConnectionManager->GetConnectionData(connectionId); + Q_UNUSED(protocol) addressLabel->setText(host); portLabel->setNum(port); // @@ -48,7 +52,9 @@ void ConnectionInfoWidget::ShowDetails(const tuple &_iden qrLabel->setPixmap(QPixmap::fromImage(img)); // connectBtn->setIcon(ConnectionManager->IsConnected(connectionId) ? QICON_R("stop.png") : QICON_R("connect.png")); - } else { + } + else + { connectBtn->setIcon(QICON_R("connect.png")); groupLabel->setText(tr("N/A")); protocolLabel->setText(tr("N/A")); @@ -66,9 +72,9 @@ ConnectionInfoWidget::~ConnectionInfoWidget() void ConnectionInfoWidget::on_connectBtn_clicked() { - if (ConnectionManager->IsConnected(connectionId)) { - ConnectionManager->StopConnection(); - } else { + if (ConnectionManager->IsConnected(connectionId)) { ConnectionManager->StopConnection(); } + else + { ConnectionManager->StartConnection(connectionId); } } @@ -90,11 +96,11 @@ void ConnectionInfoWidget::on_deleteBtn_clicked() bool ConnectionInfoWidget::eventFilter(QObject *object, QEvent *event) { - if (event->type() == QEvent::MouseButtonRelease) { - if (shareLinkTxt->underMouse()) { - if (!shareLinkTxt->hasSelectedText()) { - shareLinkTxt->selectAll(); - } + if (event->type() == QEvent::MouseButtonRelease) + { + if (shareLinkTxt->underMouse()) + { + if (!shareLinkTxt->hasSelectedText()) { shareLinkTxt->selectAll(); } } } @@ -103,51 +109,50 @@ bool ConnectionInfoWidget::eventFilter(QObject *object, QEvent *event) void ConnectionInfoWidget::OnConnected(const ConnectionId &id) { - if (connectionId == id) { - connectBtn->setIcon(QICON_R("stop.png")); - } + if (connectionId == id) { connectBtn->setIcon(QICON_R("stop.png")); } } void ConnectionInfoWidget::OnDisConnected(const ConnectionId &id) { - if (connectionId == id) { - connectBtn->setIcon(QICON_R("connect.png")); - } + if (connectionId == id) { connectBtn->setIcon(QICON_R("connect.png")); } } -//MWTryPingConnection(CurrentConnectionIdentifier); +// MWTryPingConnection(CurrentConnectionIdentifier); void ConnectionInfoWidget::on_duplicateBtn_clicked() { - //QvMessageBoxInfo(this, "NOT SUPPORTED", "WIP"); - //if (!IsSelectionConnectable) { + // QvMessageBoxInfo(this, "NOT SUPPORTED", "WIP"); + // if (!IsSelectionConnectable) { // return; //} // - //auto selectedFirst = connectionListWidget->currentItem(); - //auto _identifier = ItemConnectionIdentifier(selectedFirst); - //SUBSCRIPTION_CONFIG_MODIFY_ASK(selectedFirst) - //CONFIGROOT conf; + // auto selectedFirst = connectionListWidget->currentItem(); + // auto _identifier = ItemConnectionIdentifier(selectedFirst); + // SUBSCRIPTION_CONFIG_MODIFY_ASK(selectedFirst) + // CONFIGROOT conf; //// Alias may change. - //QString alias = _identifier.connectionName; - //bool isComplex = IsComplexConfig(connections[_identifier].config); + // QString alias = _identifier.connectionName; + // bool isComplex = IsComplexConfig(connections[_identifier].config); // - //if (connections[_identifier].configType == CONNECTION_REGULAR) { - // conf = ConvertConfigFromFile(QV2RAY_CONFIG_DIR + _identifier.connectionName + QV2RAY_CONFIG_FILE_EXTENSION, isComplex); + // if (connections[_identifier].configType == CONNECTION_REGULAR) { + // conf = ConvertConfigFromFile(QV2RAY_CONFIG_DIR + + // _identifier.connectionName + QV2RAY_CONFIG_FILE_EXTENSION, isComplex); //} else { - // conf = ConvertConfigFromFile(QV2RAY_SUBSCRIPTION_DIR + _identifier.subscriptionName + "/" + _identifier.connectionName + QV2RAY_CONFIG_FILE_EXTENSION, isComplex); - // alias = _identifier.subscriptionName + "_" + _identifier.connectionName; + // conf = ConvertConfigFromFile(QV2RAY_SUBSCRIPTION_DIR + + // _identifier.subscriptionName + "/" + _identifier.connectionName + + // QV2RAY_CONFIG_FILE_EXTENSION, isComplex); alias = + // _identifier.subscriptionName + "_" + _identifier.connectionName; //} // - //SaveConnectionConfig(conf, &alias, false); - //GlobalConfig.configs.push_back(alias); - //SaveGlobalConfig(GlobalConfig); - //this->OnConfigListChanged(false);} + // SaveConnectionConfig(conf, &alias, false); + // GlobalConfig.configs.push_back(alias); + // SaveGlobalConfig(GlobalConfig); + // this->OnConfigListChanged(false);} } void ConnectionInfoWidget::on_latencyBtn_clicked() { - if (connectionId != NullConnectionId) { - ConnectionManager->StartLatencyTest(connectionId); - } else { + if (connectionId != NullConnectionId) { ConnectionManager->StartLatencyTest(connectionId); } + else + { ConnectionManager->StartLatencyTest(groupId); } } diff --git a/src/ui/widgets/ConnectionInfoWidget.hpp b/src/ui/widgets/ConnectionInfoWidget.hpp index 968b88e1..2d87e0e8 100644 --- a/src/ui/widgets/ConnectionInfoWidget.hpp +++ b/src/ui/widgets/ConnectionInfoWidget.hpp @@ -1,39 +1,41 @@ #pragma once -#include -#include "ui_ConnectionInfoWidget.h" #include "core/handler/ConnectionHandler.hpp" +#include "ui_ConnectionInfoWidget.h" -class ConnectionInfoWidget : public QWidget, private Ui::ConnectionInfoWidget +#include + +class ConnectionInfoWidget + : public QWidget + , private Ui::ConnectionInfoWidget { - Q_OBJECT + Q_OBJECT - public: - explicit ConnectionInfoWidget(QWidget *parent = nullptr); - void ShowDetails(const tuple &_identifier); - ~ConnectionInfoWidget(); + public: + explicit ConnectionInfoWidget(QWidget *parent = nullptr); + void ShowDetails(const tuple &_identifier); + ~ConnectionInfoWidget(); - signals: - void OnEditRequested(const ConnectionId &id); - void OnJsonEditRequested(const ConnectionId &id); + signals: + void OnEditRequested(const ConnectionId &id); + void OnJsonEditRequested(const ConnectionId &id); - private slots: - void on_connectBtn_clicked(); - void on_editBtn_clicked(); - void on_editJsonBtn_clicked(); - void on_deleteBtn_clicked(); + private slots: + void on_connectBtn_clicked(); + void on_editBtn_clicked(); + void on_editJsonBtn_clicked(); + void on_deleteBtn_clicked(); - protected: - bool eventFilter(QObject *object, QEvent *event) override; + protected: + bool eventFilter(QObject *object, QEvent *event) override; - private slots: - void OnConnected(const ConnectionId &id); - void OnDisConnected(const ConnectionId &id); - void on_duplicateBtn_clicked(); - void on_latencyBtn_clicked(); + private slots: + void OnConnected(const ConnectionId &id); + void OnDisConnected(const ConnectionId &id); + void on_duplicateBtn_clicked(); + void on_latencyBtn_clicked(); - private: - ConnectionId connectionId = NullConnectionId; - GroupId groupId = NullGroupId; + private: + ConnectionId connectionId = NullConnectionId; + GroupId groupId = NullGroupId; }; - diff --git a/src/ui/widgets/ConnectionItemWidget.cpp b/src/ui/widgets/ConnectionItemWidget.cpp index 6e52bffc..483b76fb 100644 --- a/src/ui/widgets/ConnectionItemWidget.cpp +++ b/src/ui/widgets/ConnectionItemWidget.cpp @@ -1,4 +1,5 @@ #include "ConnectionItemWidget.hpp" + #include "common/QvHelpers.hpp" ConnectionItemWidget::ConnectionItemWidget(QWidget *parent) : QWidget(parent), connectionId("null"), groupId("null") @@ -11,7 +12,7 @@ ConnectionItemWidget::ConnectionItemWidget(QWidget *parent) : QWidget(parent), c connect(ConnectionManager, &QvConnectionHandler::OnLatencyTestFinished, this, &ConnectionItemWidget::OnLatencyTestFinished); } -ConnectionItemWidget::ConnectionItemWidget(const ConnectionId &id, QWidget *parent): ConnectionItemWidget(parent) +ConnectionItemWidget::ConnectionItemWidget(const ConnectionId &id, QWidget *parent) : ConnectionItemWidget(parent) { connectionId = id; groupId = ConnectionManager->GetConnectionGroupId(id); @@ -21,9 +22,9 @@ ConnectionItemWidget::ConnectionItemWidget(const ConnectionId &id, QWidget *pare // TODO auto latency = ConnectionManager->GetConnectionLatency(id); - if (latency == 0) { - latencyLabel->setText(tr("Not Tested")); - } else { + if (latency == 0) { latencyLabel->setText(tr("Not Tested")); } + else + { latencyLabel->setText(QSTRN(latency) + " " + tr("ms")); } @@ -52,16 +53,17 @@ ConnectionItemWidget::ConnectionItemWidget(const GroupId &id, QWidget *parent) : void ConnectionItemWidget::BeginConnection() { - if (itemType == NODE_ITEM) { - ConnectionManager->StartConnection(connectionId); - } else { + if (itemType == NODE_ITEM) { ConnectionManager->StartConnection(connectionId); } + else + { LOG(MODULE_UI, "Trying to start a non-connection entry, this call is illegal.") } } void ConnectionItemWidget::OnConnected(const ConnectionId &id) { - if (id == connectionId) { + if (id == connectionId) + { connNameLabel->setText("• " + originalConnectionName); LOG(MODULE_UI, "OnConnected signal received for: " + id.toString()) emit RequestWidgetFocus(this); @@ -70,34 +72,33 @@ void ConnectionItemWidget::OnConnected(const ConnectionId &id) void ConnectionItemWidget::OnDisConnected(const ConnectionId &id) { - if (id == connectionId) { - connNameLabel->setText(originalConnectionName); - } + if (id == connectionId) { connNameLabel->setText(originalConnectionName); } } -void ConnectionItemWidget::OnConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, const quint64 totalDown) +void ConnectionItemWidget::OnConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, + const quint64 totalUp, const quint64 totalDown) { Q_UNUSED(upSpeed) Q_UNUSED(downSpeed) - if (id == connectionId) { - dataLabel->setText(FormatBytes(totalUp) + " / " + FormatBytes(totalDown)); - } + if (id == connectionId) { dataLabel->setText(FormatBytes(totalUp) + " / " + FormatBytes(totalDown)); } } void ConnectionItemWidget::OnLatencyTestStart(const ConnectionId &id) { - if (id == connectionId) { - latencyLabel->setText(tr("Testing...")); - } + if (id == connectionId) { latencyLabel->setText(tr("Testing...")); } } void ConnectionItemWidget::OnLatencyTestFinished(const ConnectionId &id, const uint average) { - if (id == connectionId) { - if (average == 0) { + if (id == connectionId) + { + if (average == 0) + { latencyLabel->setText(tr("Error")); RED(latencyLabel) - } else { + } + else + { latencyLabel->setText(QSTRN(average) + tr("ms")); BLACK(latencyLabel) } diff --git a/src/ui/widgets/ConnectionItemWidget.hpp b/src/ui/widgets/ConnectionItemWidget.hpp index 9aad5c8c..05b1b0d3 100644 --- a/src/ui/widgets/ConnectionItemWidget.hpp +++ b/src/ui/widgets/ConnectionItemWidget.hpp @@ -1,57 +1,63 @@ #pragma once -#include -#include "ui_ConnectionItemWidget.h" #include "core/handler/ConnectionHandler.hpp" +#include "ui_ConnectionItemWidget.h" -enum ITEM_TYPE { +#include + +enum ITEM_TYPE +{ GROUP_HEADER_ITEM, NODE_ITEM }; -class ConnectionItemWidget : public QWidget, private Ui::ConnectionWidget +class ConnectionItemWidget + : public QWidget + , private Ui::ConnectionWidget { - Q_OBJECT - public: - explicit ConnectionItemWidget(const ConnectionId &connecionId, QWidget *parent = nullptr); - explicit ConnectionItemWidget(const GroupId &groupId, QWidget *parent = nullptr); - // - void BeginConnection(); - ~ConnectionItemWidget(); - // - inline bool NameMatched(const QString &arg) - { - auto searchString = arg.toLower(); - auto headerMatched = ConnectionManager->GetDisplayName(groupId).toLower().contains(arg); + Q_OBJECT + public: + explicit ConnectionItemWidget(const ConnectionId &connecionId, QWidget *parent = nullptr); + explicit ConnectionItemWidget(const GroupId &groupId, QWidget *parent = nullptr); + // + void BeginConnection(); + ~ConnectionItemWidget(); + // + inline bool NameMatched(const QString &arg) + { + auto searchString = arg.toLower(); + auto headerMatched = ConnectionManager->GetDisplayName(groupId).toLower().contains(arg); - if (itemType != NODE_ITEM) { - return headerMatched; - } else { - return headerMatched || ConnectionManager->GetDisplayName(connectionId).toLower().contains(searchString); - } - } - inline const tuple Identifier() const + if (itemType != NODE_ITEM) { return headerMatched; } + else { - return make_tuple(groupId, connectionId); + return headerMatched || ConnectionManager->GetDisplayName(connectionId).toLower().contains(searchString); } - inline bool IsConnection() const - { - return itemType == NODE_ITEM; - } - signals: - void RequestWidgetFocus(const ConnectionItemWidget *me); - private slots: - void OnConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, const quint64 totalDown); - void OnConnected(const ConnectionId &id); - void OnDisConnected(const ConnectionId &id); - void OnLatencyTestStart(const ConnectionId &id); - void OnLatencyTestFinished(const ConnectionId &id, const uint average); - private: - QString originalConnectionName; - explicit ConnectionItemWidget(QWidget *parent = nullptr); - ITEM_TYPE itemType; - ConnectionId connectionId; - GroupId groupId; + } + inline const tuple Identifier() const + { + return make_tuple(groupId, connectionId); + } + inline bool IsConnection() const + { + return itemType == NODE_ITEM; + } + signals: + void RequestWidgetFocus(const ConnectionItemWidget *me); + private slots: + void OnConnectionStatsArrived(const ConnectionId &id, const quint64 upSpeed, const quint64 downSpeed, const quint64 totalUp, + const quint64 totalDown); + void OnConnected(const ConnectionId &id); + void OnDisConnected(const ConnectionId &id); + void OnLatencyTestStart(const ConnectionId &id); + void OnLatencyTestFinished(const ConnectionId &id, const uint average); - Q_DISABLE_COPY_MOVE(ConnectionItemWidget) + private: + QString originalConnectionName; + explicit ConnectionItemWidget(QWidget *parent = nullptr); + ITEM_TYPE itemType; + ConnectionId connectionId; + GroupId groupId; + + Q_DISABLE_COPY_MOVE(ConnectionItemWidget) }; diff --git a/src/ui/widgets/QvAutoCompleteTextEdit.cpp b/src/ui/widgets/QvAutoCompleteTextEdit.cpp index 3ab7e571..87d781e0 100644 --- a/src/ui/widgets/QvAutoCompleteTextEdit.cpp +++ b/src/ui/widgets/QvAutoCompleteTextEdit.cpp @@ -49,17 +49,17 @@ ****************************************************************************/ #include "textedit.h" + +#include +#include +#include #include #include -#include -#include -#include #include -#include #include +#include -TextEdit::TextEdit(QWidget *parent) - : QTextEdit(parent) +TextEdit::TextEdit(QWidget *parent) : QTextEdit(parent) { setPlainText(tr("This TextEdit provides autocompletions for words that have more than" " 3 characters. You can trigger autocompletion using ") + @@ -72,14 +72,11 @@ TextEdit::~TextEdit() void TextEdit::setCompleter(QCompleter *completer) { - if (c) - c->disconnect(this); + if (c) c->disconnect(this); c = completer; - if (!c) { - return; - } + if (!c) { return; } c->setWidget(this); c->setCompletionMode(QCompleter::PopupCompletion); @@ -94,8 +91,7 @@ QCompleter *TextEdit::completer() const void TextEdit::insertCompletion(const QString &completion) { - if (c->widget() != this) - return; + if (c->widget() != this) return; QTextCursor tc = textCursor(); int extra = completion.length() - c->completionPrefix().length(); @@ -121,43 +117,43 @@ void TextEdit::focusInEvent(QFocusEvent *e) void TextEdit::keyPressEvent(QKeyEvent *e) { - if (c && c->popup()->isVisible()) { + if (c && c->popup()->isVisible()) + { // The following keys are forwarded by the completer to the widget - switch (e->key()) { + switch (e->key()) + { case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_Escape: case Qt::Key_Tab: - case Qt::Key_Backtab: - e->ignore(); - return; // let the completer do default behavior + case Qt::Key_Backtab: e->ignore(); return; // let the completer do default behavior - default: - break; + default: break; } } const bool isShortcut = (e->modifiers().testFlag(Qt::ControlModifier) && e->key() == Qt::Key_Space); // CTRL+Space - if (!c || !isShortcut) // do not process the shortcut when we have a completer + if (!c || !isShortcut) // do not process the shortcut when we have a + // completer QTextEdit::keyPressEvent(e); - const bool ctrlOrShift = e->modifiers().testFlag(Qt::ControlModifier) || - e->modifiers().testFlag(Qt::ShiftModifier); + const bool ctrlOrShift = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::ShiftModifier); - if (!c || (ctrlOrShift && e->text().isEmpty())) - return; + if (!c || (ctrlOrShift && e->text().isEmpty())) return; static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word const bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; QString completionPrefix = textUnderCursor(); - if (!isShortcut && (hasModifier || e->text().isEmpty() || completionPrefix.length() < 2 || eow.contains(e->text().right(1)))) { + if (!isShortcut && (hasModifier || e->text().isEmpty() || completionPrefix.length() < 2 || eow.contains(e->text().right(1)))) + { c->popup()->hide(); return; } - if (completionPrefix != c->completionPrefix()) { + if (completionPrefix != c->completionPrefix()) + { c->setCompletionPrefix(completionPrefix); c->popup()->setCurrentIndex(c->completionModel()->index(0, 0)); } diff --git a/src/ui/widgets/QvAutoCompleteTextEdit.h b/src/ui/widgets/QvAutoCompleteTextEdit.h index 788cb74a..847168fd 100644 --- a/src/ui/widgets/QvAutoCompleteTextEdit.h +++ b/src/ui/widgets/QvAutoCompleteTextEdit.h @@ -62,27 +62,26 @@ class TextEdit : public QTextEdit { Q_OBJECT -public: + public: TextEdit(QWidget *parent = nullptr); ~TextEdit(); void setCompleter(QCompleter *c); QCompleter *completer() const; -protected: + protected: void keyPressEvent(QKeyEvent *e) override; void focusInEvent(QFocusEvent *e) override; -private slots: + private slots: void insertCompletion(const QString &completion); -private: + private: QString textUnderCursor() const; -private: + private: QCompleter *c = nullptr; }; //! [0] #endif // TEXTEDIT_H - diff --git a/src/ui/widgets/StreamSettingsWidget.cpp b/src/ui/widgets/StreamSettingsWidget.cpp index c1e74945..6e0c5d32 100644 --- a/src/ui/widgets/StreamSettingsWidget.cpp +++ b/src/ui/widgets/StreamSettingsWidget.cpp @@ -1,9 +1,9 @@ #include "StreamSettingsWidget.hpp" + #include "common/QvHelpers.hpp" #include "ui/editors/w_JsonEditor.hpp" -StreamSettingsWidget::StreamSettingsWidget(QWidget *parent) : - QWidget(parent) +StreamSettingsWidget::StreamSettingsWidget(QWidget *parent) : QWidget(parent) { setupUi(this); } @@ -34,9 +34,8 @@ void StreamSettingsWidget::SetStreamObject(StreamSettingsObject sso) wsPathTxt->setText(stream.wsSettings.path); QString wsHeaders; - for (auto item = stream.wsSettings.headers.begin(); item != stream.wsSettings.headers.end(); item++) { - wsHeaders += item.key() + "|" + item.value() + NEWLINE; - } + for (auto item = stream.wsSettings.headers.begin(); item != stream.wsSettings.headers.end(); item++) + { wsHeaders += item.key() + "|" + item.value() + NEWLINE; } wsHeadersTxt->setPlainText(wsHeaders); // mKCP @@ -60,7 +59,6 @@ void StreamSettingsWidget::SetStreamObject(StreamSettingsObject sso) soMarkSpinBox->setValue(stream.sockopt.mark); } - void StreamSettingsWidget::on_transportCombo_currentIndexChanged(int index) { v2rayStackView->setCurrentIndex(index); @@ -73,29 +71,33 @@ void StreamSettingsWidget::on_httpPathTxt_textEdited(const QString &arg1) void StreamSettingsWidget::on_httpHostTxt_textChanged() { - try { + try + { QStringList hosts = httpHostTxt->toPlainText().replace("\r", "").split("\n"); stream.httpSettings.host.clear(); - for (auto host : hosts) { - if (!host.trimmed().isEmpty()) { - stream.httpSettings.host.push_back(host.trimmed()); - } + for (auto host : hosts) + { + if (!host.trimmed().isEmpty()) { stream.httpSettings.host.push_back(host.trimmed()); } } BLACK(httpHostTxt) - } catch (...) { + } + catch (...) + { RED(httpHostTxt) } } void StreamSettingsWidget::on_wsHeadersTxt_textChanged() { - try { + try + { QStringList headers = SplitLines(wsHeadersTxt->toPlainText()); stream.wsSettings.headers.clear(); - for (auto header : headers) { + for (auto header : headers) + { if (header.isEmpty()) continue; auto index = header.indexOf("|"); @@ -108,12 +110,13 @@ void StreamSettingsWidget::on_wsHeadersTxt_textChanged() } BLACK(wsHeadersTxt) - } catch (...) { + } + catch (...) + { RED(wsHeadersTxt) } } - void StreamSettingsWidget::on_tcpRequestDefBtn_clicked() { tcpRequestTxt->clear(); @@ -130,7 +133,8 @@ void StreamSettingsWidget::on_tcpRequestDefBtn_clicked() void StreamSettingsWidget::on_tcpRespDefBtn_clicked() { tcpRespTxt->clear(); - tcpRespTxt->setPlainText("{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}"); + tcpRespTxt->setPlainText( + "{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}"); } void StreamSettingsWidget::on_tlsCB_stateChanged(int arg1) @@ -185,7 +189,7 @@ void StreamSettingsWidget::on_kcpMTU_valueChanged(int arg1) void StreamSettingsWidget::on_kcpTTI_valueChanged(int arg1) { - stream.kcpSettings.tti = arg1; + stream.kcpSettings.tti = arg1; } void StreamSettingsWidget::on_kcpUploadCapacSB_valueChanged(int arg1) diff --git a/src/ui/widgets/StreamSettingsWidget.hpp b/src/ui/widgets/StreamSettingsWidget.hpp index ddca1458..5fd4a688 100644 --- a/src/ui/widgets/StreamSettingsWidget.hpp +++ b/src/ui/widgets/StreamSettingsWidget.hpp @@ -4,77 +4,78 @@ #include "base/Qv2rayBase.hpp" #include "ui_StreamSettingsWidget.h" -class StreamSettingsWidget : public QWidget, private Ui::StreamSettingsWidget +class StreamSettingsWidget + : public QWidget + , private Ui::StreamSettingsWidget { - Q_OBJECT + Q_OBJECT - public: - explicit StreamSettingsWidget(QWidget *parent = nullptr); - void SetStreamObject(StreamSettingsObject sso); - StreamSettingsObject GetStreamSettings(); + public: + explicit StreamSettingsWidget(QWidget *parent = nullptr); + void SetStreamObject(StreamSettingsObject sso); + StreamSettingsObject GetStreamSettings(); - private slots: - void on_httpPathTxt_textEdited(const QString &arg1); + private slots: + void on_httpPathTxt_textEdited(const QString &arg1); - void on_httpHostTxt_textChanged(); + void on_httpHostTxt_textChanged(); - void on_wsHeadersTxt_textChanged(); + void on_wsHeadersTxt_textChanged(); - void on_tcpRequestDefBtn_clicked(); + void on_tcpRequestDefBtn_clicked(); - void on_tcpRespDefBtn_clicked(); + void on_tcpRespDefBtn_clicked(); - void on_tlsCB_stateChanged(int arg1); + void on_tlsCB_stateChanged(int arg1); - void on_soMarkSpinBox_valueChanged(int arg1); + void on_soMarkSpinBox_valueChanged(int arg1); - void on_tcpFastOpenCB_stateChanged(int arg1); + void on_tcpFastOpenCB_stateChanged(int arg1); - void on_tProxyCB_currentIndexChanged(const QString &arg1); + void on_tProxyCB_currentIndexChanged(const QString &arg1); - void on_quicSecurityCB_currentTextChanged(const QString &arg1); + void on_quicSecurityCB_currentTextChanged(const QString &arg1); - void on_quicKeyTxt_textEdited(const QString &arg1); + void on_quicKeyTxt_textEdited(const QString &arg1); - void on_quicHeaderTypeCB_currentIndexChanged(const QString &arg1); + void on_quicHeaderTypeCB_currentIndexChanged(const QString &arg1); - void on_tcpHeaderTypeCB_currentIndexChanged(const QString &arg1); + void on_tcpHeaderTypeCB_currentIndexChanged(const QString &arg1); - void on_wsPathTxt_textEdited(const QString &arg1); + void on_wsPathTxt_textEdited(const QString &arg1); - void on_kcpMTU_valueChanged(int arg1); + void on_kcpMTU_valueChanged(int arg1); - void on_kcpTTI_valueChanged(int arg1); + void on_kcpTTI_valueChanged(int arg1); - void on_kcpUploadCapacSB_valueChanged(int arg1); + void on_kcpUploadCapacSB_valueChanged(int arg1); - void on_kcpCongestionCB_stateChanged(int arg1); + void on_kcpCongestionCB_stateChanged(int arg1); - void on_kcpDownCapacitySB_valueChanged(int arg1); + void on_kcpDownCapacitySB_valueChanged(int arg1); - void on_kcpReadBufferSB_valueChanged(int arg1); + void on_kcpReadBufferSB_valueChanged(int arg1); - void on_kcpWriteBufferSB_valueChanged(int arg1); + void on_kcpWriteBufferSB_valueChanged(int arg1); - void on_kcpHeaderType_currentTextChanged(const QString &arg1); + void on_kcpHeaderType_currentTextChanged(const QString &arg1); - void on_dsPathTxt_textEdited(const QString &arg1); + void on_dsPathTxt_textEdited(const QString &arg1); - void on_tcpRequestEditBtn_clicked(); + void on_tcpRequestEditBtn_clicked(); - void on_tcpResponseEditBtn_clicked(); + void on_tcpResponseEditBtn_clicked(); - void on_transportCombo_currentIndexChanged(int index); + void on_transportCombo_currentIndexChanged(int index); - void on_transportCombo_currentIndexChanged(const QString &arg1); + void on_transportCombo_currentIndexChanged(const QString &arg1); - void on_serverNameTxt_textEdited(const QString &arg1); + void on_serverNameTxt_textEdited(const QString &arg1); - void on_allowInsecureCB_stateChanged(int arg1); + void on_allowInsecureCB_stateChanged(int arg1); - void on_alpnTxt_textChanged(); + void on_alpnTxt_textChanged(); - private: - StreamSettingsObject stream; + private: + StreamSettingsObject stream; }; -