chore: change qt version

This commit is contained in:
arm64v8a
2022-11-26 16:41:31 +09:00
parent 09d37fa898
commit b2ebd0e432
20 changed files with 408 additions and 177 deletions

View File

@@ -77,12 +77,14 @@ jobs:
# 14.1 is for vs2017, 14.2 is vs2019, following the upstream vcpkg build from Qv2ray-deps repo
toolset: 14.2
arch: ${{ matrix.arch }}
- name: Download Artifacts
- name: Download Artifacts for macOS
if: matrix.platform == 'macos-10.15'
uses: actions/download-artifact@v3
with:
path: download-artifact
- name: Install Qt
# ========================================================================================================= Qt Install
- name: macOS - Install Qt 5.15
if: matrix.platform == 'macos-10.15'
uses: jurplel/install-qt-action@v3
with:
version: ${{ matrix.qt_version }}
@@ -91,10 +93,24 @@ jobs:
setup-python: false
cache: true
cache-key-prefix: QtCache-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.qt_version }}
# ========================================================================================================= Other install
- name: Windows - Download Custom Qt 5.15 SDK
shell: bash
if: matrix.platform == 'windows-2022'
run: |
mkdir qtsdk ; cd qtsdk
curl -LSO https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/Qt5.15.7-Windows-x86_64-VS2019-16.11.20-20221103.7z
7z x *.7z
rm *.7z
mv Qt* Qt
- name: Linux - Install Qt 5.12 via apt
shell: bash
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y zlib1g-dev fcitx-frontend-qt5 qtbase5-dev qttools5-dev libqt5svg5-dev libqt5x11extras5-dev
# ========================================================================================================= 编译与 Qt 无关的依赖
- name: Install ninja-build tool
uses: seanmiddleditch/gha-setup-ninja@v3
# ========================================================================================================= 编译与 Qt 无关的依赖
- name: Cache Download
id: cache-deps
uses: actions/cache@v3
@@ -114,6 +130,7 @@ jobs:
CC: cl.exe
CXX: cl.exe
run: |
source libs/env_qtsdk.sh $PWD/qtsdk/Qt
mkdir build
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..

1
.gitignore vendored
View File

@@ -81,3 +81,4 @@ CMakeLists.txt.user*
# Deploy
/deployment
/neko*.sh
/qtsdk/

88
3rdparty/base64.cpp vendored Normal file
View File

@@ -0,0 +1,88 @@
#include "base64.h"
namespace Qt515Base64 {
namespace {
struct fromBase64_helper_result {
qsizetype decodedLength;
Base64DecodingStatus status;
};
fromBase64_helper_result fromBase64_helper(const char *input, qsizetype inputSize,
char *output /* may alias input */,
Base64Options options) {
fromBase64_helper_result result{0, Base64DecodingStatus::Ok};
unsigned int buf = 0;
int nbits = 0;
qsizetype offset = 0;
for (qsizetype i = 0; i < inputSize; ++i) {
int ch = input[i];
int d;
if (ch >= 'A' && ch <= 'Z') {
d = ch - 'A';
} else if (ch >= 'a' && ch <= 'z') {
d = ch - 'a' + 26;
} else if (ch >= '0' && ch <= '9') {
d = ch - '0' + 52;
} else if (ch == '+' && (options & Base64UrlEncoding) == 0) {
d = 62;
} else if (ch == '-' && (options & Base64UrlEncoding) != 0) {
d = 62;
} else if (ch == '/' && (options & Base64UrlEncoding) == 0) {
d = 63;
} else if (ch == '_' && (options & Base64UrlEncoding) != 0) {
d = 63;
} else {
if (options & AbortOnBase64DecodingErrors) {
if (ch == '=') {
// can have 1 or 2 '=' signs, in both cases padding base64Size to
// a multiple of 4. Any other case is illegal.
if ((inputSize % 4) != 0) {
result.status = Base64DecodingStatus::IllegalInputLength;
return result;
} else if ((i == inputSize - 1) ||
(i == inputSize - 2 && input[++i] == '=')) {
d = -1; // ... and exit the loop, normally
} else {
result.status = Base64DecodingStatus::IllegalPadding;
return result;
}
} else {
result.status = Base64DecodingStatus::IllegalCharacter;
return result;
}
} else {
d = -1;
}
}
if (d != -1) {
buf = (buf << 6) | d;
nbits += 6;
if (nbits >= 8) {
nbits -= 8;
Q_ASSERT(offset < i);
output[offset++] = buf >> nbits;
buf &= (1 << nbits) - 1;
}
}
}
result.decodedLength = offset;
return result;
}
} // namespace
FromBase64Result QByteArray_fromBase64Encoding(const QByteArray &base64, Base64Options options) {
const auto base64Size = base64.size();
QByteArray result((base64Size * 3) / 4, Qt::Uninitialized);
const auto base64result = fromBase64_helper(base64.data(),
base64Size,
const_cast<char *>(result.constData()),
options);
result.truncate(int(base64result.decodedLength));
return {std::move(result), base64result.status};
}
} // namespace Qt515Base64

47
3rdparty/base64.h vendored Normal file
View File

@@ -0,0 +1,47 @@
#include <QByteArray>
namespace Qt515Base64 {
enum Base64Option {
Base64Encoding = 0,
Base64UrlEncoding = 1,
KeepTrailingEquals = 0,
OmitTrailingEquals = 2,
IgnoreBase64DecodingErrors = 0,
AbortOnBase64DecodingErrors = 4,
};
Q_DECLARE_FLAGS(Base64Options, Base64Option)
Q_DECLARE_OPERATORS_FOR_FLAGS(Base64Options)
enum class Base64DecodingStatus {
Ok,
IllegalInputLength,
IllegalCharacter,
IllegalPadding,
};
class FromBase64Result {
public:
QByteArray decoded;
Base64DecodingStatus decodingStatus;
void swap(FromBase64Result &other) noexcept {
qSwap(decoded, other.decoded);
qSwap(decodingStatus, other.decodingStatus);
}
explicit operator bool() const noexcept { return decodingStatus == Base64DecodingStatus::Ok; }
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_QDOC)
QByteArray &operator*() &noexcept { return decoded; }
const QByteArray &operator*() const &noexcept { return decoded; }
QByteArray &&operator*() &&noexcept { return std::move(decoded); }
#else
QByteArray &operator*() noexcept { return decoded; }
const QByteArray &operator*() const noexcept { return decoded; }
#endif
};
FromBase64Result QByteArray_fromBase64Encoding(const QByteArray &base64, Base64Options options);
} // namespace Qt515Base64

View File

@@ -40,10 +40,16 @@ include("cmake/fuck_windows/fuck.cmake")
# default prefix path
if (NKR_PACKAGE)
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libs/deps/package)
list(APPEND NKR_LIBS ${CMAKE_SOURCE_DIR}/libs/deps/package)
else ()
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libs/deps/built)
list(APPEND NKR_LIBS ${CMAKE_SOURCE_DIR}/libs/deps/built)
endif ()
if (NKR_DISABLE_LIBS)
else ()
list(APPEND CMAKE_PREFIX_PATH ${NKR_LIBS})
endif ()
message("[CMAKE_PREFIX_PATH] ${CMAKE_PREFIX_PATH}")
# for some cross toolchain
@@ -100,6 +106,7 @@ set(PROJECT_SOURCES
main/NekoRay.cpp
main/NekoRay_Utils.cpp
3rdparty/base64.cpp
3rdparty/qrcodegen.cpp
3rdparty/QtExtKeySequenceEdit.cpp
@@ -207,14 +214,6 @@ set(PROJECT_SOURCES
${QV2RAY_RC}
)
# Translations
set(TS_FILES
translations/zh_CN.ts
)
qt_create_translation(QM_FILES ${PROJECT_SOURCES} ${TS_FILES} OPTIONS -locations none)
configure_file(translations/translations.qrc ${CMAKE_BINARY_DIR} COPYONLY)
set(PROJECT_SOURCES ${PROJECT_SOURCES} ${TS_FILES} ${QM_FILES} ${CMAKE_BINARY_DIR}/translations.qrc)
# Qt exe
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(nekoray
@@ -245,21 +244,12 @@ set_property(TARGET nekoray PROPERTY AUTOUIC ON)
set_property(TARGET nekoray PROPERTY AUTOMOC ON)
set_property(TARGET nekoray PROPERTY AUTORCC ON)
# Target Link
target_link_libraries(nekoray PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg
Threads::Threads
${NKR_EXTERNAL_TARGETS}
${PLATFORM_FUCKING_LIBRARIES}
)
# Target Source macOS
set(MACOSX_ICON ${CMAKE_SOURCE_DIR}/res/nekoray.icns)
if (APPLE)
target_sources(nekoray PRIVATE ${MACOSX_ICON})
endif ()
set_target_properties(nekoray PROPERTIES
MACOSX_BUNDLE_ICON_FILE "nekoray.icns"
RESOURCE ${MACOSX_ICON}
@@ -269,6 +259,29 @@ set_target_properties(nekoray PROPERTIES
WIN32_EXECUTABLE TRUE
)
# Target Source Translations
set(TS_FILES
translations/zh_CN.ts
)
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_lupdate(nekoray TS_FILES ${TS_FILES})
qt_add_lrelease(nekoray TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
else ()
qt5_create_translation(QM_FILES ${PROJECT_SOURCES} ${TS_FILES} OPTIONS -locations none)
endif ()
configure_file(translations/translations.qrc ${CMAKE_BINARY_DIR} COPYONLY)
target_sources(nekoray PRIVATE ${CMAKE_BINARY_DIR}/translations.qrc)
# Target Link
target_link_libraries(nekoray PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg
Threads::Threads
${NKR_EXTERNAL_TARGETS}
${PLATFORM_FUCKING_LIBRARIES}
)
if (QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(nekoray)
endif ()

View File

@@ -60,22 +60,7 @@ https://matsuridayo.github.io
## Linux 运行
**使用 Linux 系统相信您已具备基本的排错能力,
本项目不提供特定发行版/架构的支持,预编译文件不能满足您的需求时,请自行编译/适配。**
要求:已安装主流的发行版和 xcb 桌面环境。
运行: `./launcher` 或 部分系统可双击打开
launcher 参数
* `./launcher -- -appdata` ( `--` 后的参数传递给主程序 )
* `-debug` Debug mode
* `-theme` Use local QT theme (unstable) (1.0+)
已知部分 Linux 发行版无法使用预编译版、非 x86_64 暂无适配,可以尝试自行编译。
Ubuntu 22.04: `sudo apt install libxcb-xinerama0`
[Linux 运行教程](examples/docs/Run_Linux.md)
## 编译教程

View File

@@ -4,6 +4,10 @@
#include "ui/mainwindow_interface.h"
#include <QThread>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QElapsedTimer>
namespace NekoRay::traffic {

View File

@@ -0,0 +1,30 @@
## Linux 运行
**使用 Linux 系统相信您已具备基本的排错能力,
本项目不提供特定发行版/架构的支持,预编译文件不能满足您的需求时,请自行编译/适配。**
已知部分 Linux 发行版无法使用、非 x86_64 暂无适配,可以尝试自行编译。
目前 Release 便携包解压后,有两种使用方法:
1. System: 若要使用系统的 Qt5 运行库,请执行 `./nekoray`
2. Bundle: 若要使用预编译的 Qt 运行库,请执行 `./launcher`
### Bundle
要求:已安装主流的发行版和 xcb 桌面环境。
运行: `./launcher` 或 部分系统可双击打开
launcher 参数
* `./launcher -- -appdata` ( `--` 后的参数传递给主程序 )
* `-debug` Debug mode
Ubuntu 22.04: `sudo apt install libxcb-xinerama0`
### System
要求:已安装主流的发行版和 xcb 桌面环境,已安装 Qt5.12 ~ Qt5.15 环境。
运行: `./nekoray` 或 部分系统可双击打开。如果无法运行,建议使用 Bundle 版。

View File

@@ -1,9 +1,8 @@
#include "includes.h"
#include <functional>
#include <QApplication>
#include <QHostInfo>
#include <QUrl>
namespace NekoRay::fmt {
AbstractBean::AbstractBean(int version) {

View File

@@ -1,5 +1,8 @@
#pragma once
#include <QJsonObject>
#include <QJsonArray>
#include "main/NekoRay.hpp"
namespace NekoRay::fmt {

View File

@@ -6,7 +6,6 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
)
var local_qt_theme bool
@@ -16,18 +15,19 @@ func Launcher() {
wd, _ := filepath.Abs(".")
_debug := flag.Bool("debug", false, "Debug mode")
flag.BoolVar(&local_qt_theme, "theme", false, "Use local QT theme (unstable)")
flag.Parse()
// Find & symlink some Qt Plugin to enable system theme
tryLinkQtPlugin("styles", !local_qt_theme)
tryLinkQtPlugin("platformthemes", !local_qt_theme)
cmd := exec.Command("./nekoray", flag.Args()...)
cmd.Env = os.Environ()
ld_env := "LD_LIBRARY_PATH=" + filepath.Join(wd, "./usr/lib")
cmd.Env = append(cmd.Env, ld_env)
log.Println(ld_env, cmd)
qt_plugin_env := "QT_PLUGIN_PATH=" + filepath.Join(wd, "./usr/plugins")
// Qt 5.12 abi is usually compatible with system Qt 5.15
// But use package Qt 5.12 by default.
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "NKR_FROM_LAUNCHER=1")
cmd.Env = append(cmd.Env, ld_env, qt_plugin_env)
log.Println(ld_env, qt_plugin_env, cmd)
if *_debug {
cmd.Env = append(cmd.Env, "QT_DEBUG_PLUGINS=1")
@@ -39,39 +39,3 @@ func Launcher() {
cmd.Start()
}
}
func tryLinkQtPlugin(sub string, remove bool) {
wd_plugins_sub := filepath.Join("./usr/plugins", sub)
if Exist(wd_plugins_sub) {
if remove {
os.RemoveAll(wd_plugins_sub)
}
} else {
if remove {
return
}
arch := "x86_64"
if runtime.GOARCH == "arm64" {
arch = "aarch64"
}
paths := []string{
filepath.Join("/usr/lib/qt5/plugins", sub),
filepath.Join("/usr/lib64/qt5/plugins", sub),
filepath.Join("/usr/lib/"+arch+"-linux-gnu/qt5/plugins", sub),
filepath.Join("/usr/lib/qt/plugins", sub),
}
path := FindExist(paths)
if path == "" {
log.Println("warning:", sub, "not found")
return
}
err := os.Symlink(path, wd_plugins_sub)
if err != nil {
log.Println("symlink failed:", err.Error())
}
}
}

View File

@@ -9,8 +9,33 @@ mkdir -p $DEST
#### copy binary ####
cp $BUILD/nekoray $DEST
#### Download: prebuilt runtime ####
curl -Lso usr.zip https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/20220705-5.15.2-linux64.zip
unzip usr.zip
rm usr.zip
#### copy so ####
USR_LIB=/usr/lib/x86_64-linux-gnu
mkdir usr
pushd usr
mkdir lib
pushd lib
cp $USR_LIB/libQt5Core.so.5 .
cp $USR_LIB/libQt5DBus.so.5 .
cp $USR_LIB/libQt5Gui.so.5 .
cp $USR_LIB/libQt5Network.so.5 .
cp $USR_LIB/libQt5Svg.so.5 .
cp $USR_LIB/libQt5Widgets.so.5 .
cp $USR_LIB/libQt5X11Extras.so.5 .
cp $USR_LIB/libQt5XcbQpa.so.5 .
cp $USR_LIB/libxcb-util.so.1 .
cp $USR_LIB/libicuuc.so.?? .
cp $USR_LIB/libicui18n.so.?? .
cp $USR_LIB/libicudata.so.?? .
popd
mkdir plugins
pushd plugins
cp -r $USR_LIB/qt5/plugins/bearer .
cp -r $USR_LIB/qt5/plugins/iconengines .
cp -r $USR_LIB/qt5/plugins/imageformats .
cp -r $USR_LIB/qt5/plugins/platforminputcontexts .
cp -r $USR_LIB/qt5/plugins/platforms .
cp -r $USR_LIB/qt5/plugins/xcbglintegrations .
popd
popd
mv usr $DEST

View File

@@ -12,8 +12,6 @@ cp $BUILD/nekoray.exe $DEST
#### deploy qt & DLL runtime ####
pushd $DEST
windeployqt nekoray.exe --no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --verbose 2
curl -LSsO https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/libcrypto-1_1-x64.dll
curl -LSsO https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/libssl-1_1-x64.dll
rm -rf translations
popd

8
libs/env_qtsdk.sh Normal file
View File

@@ -0,0 +1,8 @@
echo "Setting Qt Sdk Dir to" "$1"
export Qt5_DIR="$1"
export Qt6_DIR=$Qt5_DIR
export PATH=$PATH:$Qt5_DIR/bin
export LD_LIBRARY_PATH=$Qt5_DIR/lib
export PKG_CONFIG_PATH=$Qt5_DIR/lib/pkgconfig
export QT_PLUGIN_PATH=$Qt5_DIR/plugins
export QML2_IMPORT_PATH=$Qt5_DIR/lib/qml

View File

@@ -4,6 +4,10 @@
#include <QDir>
#include <QApplication>
#include <QFileInfo>
#include <QSharedPointer>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
namespace NekoRay {

View File

@@ -1,5 +1,6 @@
#include "NekoRay_Utils.hpp"
#include "3rdparty/base64.h"
#include "3rdparty/QThreadCreateThread.hpp"
#include <random>
@@ -9,6 +10,40 @@
#include <QTimer>
#include <QMessageBox>
#include <QFile>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QRegularExpression>
#include <QDateTime>
#include <QLocale>
QStringList SplitLines(const QString &_string) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
return _string.split(QRegularExpression("[\r\n]"), Qt::SplitBehaviorFlags::SkipEmptyParts);
#else
return _string.split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
#endif
}
QString DecodeB64IfValid(const QString &input, QByteArray::Base64Options options) {
Qt515Base64::Base64Options newOptions = Qt515Base64::Base64Option::AbortOnBase64DecodingErrors;
if (options.testFlag(QByteArray::Base64UrlEncoding)) newOptions |= Qt515Base64::Base64Option::Base64UrlEncoding;
if (options.testFlag(QByteArray::OmitTrailingEquals)) newOptions |= Qt515Base64::Base64Option::OmitTrailingEquals;
auto result = Qt515Base64::QByteArray_fromBase64Encoding(input.toUtf8(), newOptions);
if (result) {
return result.decoded;
}
return {};
}
QString QStringList2Command(const QStringList &list) {
QStringList new_list;
for (auto str: list) {
auto q = "\"" + str.replace("\"", "\\\"") + "\"";
new_list << q;
}
return new_list.join(" ");
}
QString GetQueryValue(const QUrlQuery &q, const QString &key, const QString &def) {
auto a = q.queryItemValue(key);
@@ -34,6 +69,43 @@ QString GetRandomString(int randomStringLength) {
return randomString;
}
// QString >> QJson
QJsonObject QString2QJsonObject(const QString &jsonString) {
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
QJsonObject jsonObject = jsonDocument.object();
return jsonObject;
}
// QJson >> QString
QString QJsonObject2QString(const QJsonObject &jsonObject, bool compact) {
return QJsonDocument(jsonObject).toJson(compact ? QJsonDocument::Compact : QJsonDocument::Indented);
}
template<typename T>
QJsonArray QList2QJsonArray(const QList<T> &list) {
QVariantList list2;
for (auto &item: list)
list2.append(item);
return QJsonArray::fromVariantList(list2);
}
template QJsonArray QList2QJsonArray<int>(const QList<int> &list);
template QJsonArray QList2QJsonArray<QString>(const QList<QString> &list);
QList<int> QJsonArray2QListInt(const QJsonArray &arr) {
QList<int> list2;
for (auto item: arr)
list2.append(item.toInt());
return list2;
}
QList<QString> QJsonArray2QListString(const QJsonArray &arr) {
QList<QString> list2;
for (auto item: arr)
list2.append(item.toString());
return list2;
}
QByteArray ReadFile(const QString &path) {
QFile file(path);
file.open(QFile::ReadOnly);
@@ -76,6 +148,12 @@ bool IsIpAddressV6(const QString &str) {
return false;
}
QString DisplayTime(long long time, int formatType) {
QDateTime t;
t.setSecsSinceEpoch(time);
return QLocale().toString(t, QLocale::FormatType(formatType));
}
QWidget *GetMessageBoxParent() {
if (mainwindow == nullptr) return nullptr;
if (mainwindow->isVisible()) return mainwindow;

View File

@@ -1,9 +1,10 @@
// DO NOT INCLUDE THIS
#include <functional>
#include <memory>
#include <QObject>
#include <QString>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QDebug>
//
@@ -15,23 +16,14 @@ inline QString software_core_name = "V2Ray";
inline std::function<void()> MF_release_runguard;
// MainWindow functions
class QWidget;
inline QWidget *mainwindow;
inline std::function<void(QString)> MW_show_log;
inline std::function<void(QString, QString)> MW_show_log_ext;
inline std::function<void(QString)> MW_show_log_ext_vt100;
inline std::function<void(QString, QString)> MW_dialog_message;
// Utils
#define QJSONARRAY_ADD(arr, add) \
for (const auto &a: (add)) { \
(arr) += a; \
}
#define QJSONOBJECT_COPY(src, dst, key) \
if (src.contains(key)) dst[key] = src[key];
#define QJSONOBJECT_COPY2(src, dst, src_key, dst_key) \
if (src.contains(src_key)) dst[dst_key] = src[src_key];
// String
#define Int2String(num) QString::number(num)
@@ -45,24 +37,17 @@ inline QString SubStrAfter(QString str, const QString &sub) {
return str.right(str.length() - str.indexOf(sub) - sub.length());
}
inline QString QStringList2Command(const QStringList &list) {
QStringList new_list;
for (auto str: list) {
auto q = "\"" + str.replace("\"", "\\\"") + "\"";
new_list << q;
}
return new_list.join(" ");
}
QString QStringList2Command(const QStringList &list);
inline QString
DecodeB64IfValid(const QString &input, QByteArray::Base64Option options = QByteArray::Base64Option::Base64Encoding) {
auto result = QByteArray::fromBase64Encoding(input.toUtf8(),
options | QByteArray::Base64Option::AbortOnBase64DecodingErrors);
if (result) {
return result.decoded;
}
return "";
}
QStringList SplitLines(const QString &_string);
// Base64
QString DecodeB64IfValid(const QString &input, QByteArray::Base64Options options = QByteArray::Base64Option::Base64Encoding);
// URL
class QUrlQuery;
#define GetQuery(url) QUrlQuery((url).query(QUrl::ComponentFormattingOption::FullyDecoded));
@@ -70,51 +55,34 @@ QString GetQueryValue(const QUrlQuery &q, const QString &key, const QString &def
QString GetRandomString(int randomStringLength);
// QString >> QJson
inline QJsonObject QString2QJsonObject(const QString &jsonString) {
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
QJsonObject jsonObject = jsonDocument.object();
return jsonObject;
}
// QJson >> QString
inline QString QJsonObject2QString(const QJsonObject &jsonObject, bool compact) {
return QString(QJsonDocument(jsonObject).toJson(compact ? QJsonDocument::Compact : QJsonDocument::Indented));
}
template<typename T>
inline QJsonArray QList2QJsonArray(const QList<T> &list) {
QVariantList list2;
for (auto &item: list)
list2.append(item);
return QJsonArray::fromVariantList(list2);
}
inline QList<int> QJsonArray2QListInt(const QJsonArray &arr) {
QList<int> list2;
for (auto item: arr)
list2.append(item.toInt());
return list2;
}
inline QList<QString> QJsonArray2QListString(const QJsonArray &arr) {
QList<QString> list2;
for (auto item: arr)
list2.append(item.toString());
return list2;
}
inline QString UrlSafe_encode(const QString &s) {
return s.toUtf8().toPercentEncoding().replace(" ", "%20");
}
inline bool InRange(unsigned x, unsigned low, unsigned high) {
return (low <= x && x <= high);
}
// JSON
inline QStringList SplitLines(const QString &_string) {
return _string.split(QRegularExpression("[\r\n]"), Qt::SplitBehaviorFlags::SkipEmptyParts);
}
class QJsonObject;
class QJsonArray;
QJsonObject QString2QJsonObject(const QString &jsonString);
QString QJsonObject2QString(const QJsonObject &jsonObject, bool compact);
template<typename T>
QJsonArray QList2QJsonArray(const QList<T> &list);
QList<int> QJsonArray2QListInt(const QJsonArray &arr);
#define QJSONARRAY_ADD(arr, add) \
for (const auto &a: (add)) { \
(arr) += a; \
}
#define QJSONOBJECT_COPY(src, dst, key) \
if (src.contains(key)) dst[key] = src[key];
#define QJSONOBJECT_COPY2(src, dst, src_key, dst_key) \
if (src.contains(src_key)) dst[dst_key] = src[src_key];
QList<QString> QJsonArray2QListString(const QJsonArray &arr);
// Files
@@ -122,10 +90,6 @@ QByteArray ReadFile(const QString &path);
QString ReadFileText(const QString &path);
// Net
int MkPort();
// Validators
bool IsIpAddress(const QString &str);
@@ -150,13 +114,11 @@ inline QString DisplayAddress(QString serverAddress, int serverPort) {
return WrapIPV6Host(serverAddress) + ":" + Int2String(serverPort);
};
// Format
// Format & Misc
inline QString DisplayTime(long long time, QLocale::FormatType formatType = QLocale::LongFormat) {
QDateTime t;
t.setSecsSinceEpoch(time);
return QLocale().toString(t, formatType);
}
int MkPort();
QString DisplayTime(long long time, int formatType = 0);
inline QString ReadableSize(const qint64 &size) {
double sizeAsDouble = size;
@@ -180,6 +142,10 @@ inline QString ReadableSize(const qint64 &size) {
return QString::fromLatin1("%1 %2").arg(sizeAsDouble, 0, 'f', 2).arg(measure);
}
inline bool InRange(unsigned x, unsigned low, unsigned high) {
return (low <= x && x <= high);
}
// UI
QWidget *GetMessageBoxParent();

View File

@@ -3,6 +3,7 @@
// Qv2ray wrapper
#include <QJsonDocument>
#include <QDebug>
#define LOG(...) Qv2ray::base::log_internal(__VA_ARGS__)
#define DEBUG(...) Qv2ray::base::log_internal(__VA_ARGS__)

View File

@@ -167,9 +167,8 @@ void AutoRun_SetEnabled(bool enable) {
QStringList appCmdList = {QApplication::applicationFilePath(), "-tray"};
// nekoray: launcher
auto launcherPath = QApplication::applicationDirPath() + "/launcher";
if (QFile::exists(launcherPath)) {
appCmdList = QStringList{launcherPath, "--", "-tray"};
if (qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1") {
appCmdList = QStringList{QApplication::applicationDirPath() + "/launcher", "--", "-tray"};
}
if (enable) {

View File

@@ -6,6 +6,7 @@
#ifndef MW_INTERFACE
#include <QTime>
#include <QTableWidgetItem>
#include <QKeyEvent>
#include <QSystemTrayIcon>