mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 20:44:38 +03:00
chore: change qt version
This commit is contained in:
25
.github/workflows/build-qv2ray-cmake.yml
vendored
25
.github/workflows/build-qv2ray-cmake.yml
vendored
@@ -77,12 +77,14 @@ jobs:
|
|||||||
# 14.1 is for vs2017, 14.2 is vs2019, following the upstream vcpkg build from Qv2ray-deps repo
|
# 14.1 is for vs2017, 14.2 is vs2019, following the upstream vcpkg build from Qv2ray-deps repo
|
||||||
toolset: 14.2
|
toolset: 14.2
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
- name: Download Artifacts
|
- name: Download Artifacts for macOS
|
||||||
if: matrix.platform == 'macos-10.15'
|
if: matrix.platform == 'macos-10.15'
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: download-artifact
|
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
|
uses: jurplel/install-qt-action@v3
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.qt_version }}
|
version: ${{ matrix.qt_version }}
|
||||||
@@ -91,10 +93,24 @@ jobs:
|
|||||||
setup-python: false
|
setup-python: false
|
||||||
cache: true
|
cache: true
|
||||||
cache-key-prefix: QtCache-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.qt_version }}
|
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
|
- name: Install ninja-build tool
|
||||||
uses: seanmiddleditch/gha-setup-ninja@v3
|
uses: seanmiddleditch/gha-setup-ninja@v3
|
||||||
# ========================================================================================================= 编译与 Qt 无关的依赖
|
|
||||||
- name: Cache Download
|
- name: Cache Download
|
||||||
id: cache-deps
|
id: cache-deps
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
@@ -114,6 +130,7 @@ jobs:
|
|||||||
CC: cl.exe
|
CC: cl.exe
|
||||||
CXX: cl.exe
|
CXX: cl.exe
|
||||||
run: |
|
run: |
|
||||||
|
source libs/env_qtsdk.sh $PWD/qtsdk/Qt
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..
|
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -81,3 +81,4 @@ CMakeLists.txt.user*
|
|||||||
# Deploy
|
# Deploy
|
||||||
/deployment
|
/deployment
|
||||||
/neko*.sh
|
/neko*.sh
|
||||||
|
/qtsdk/
|
||||||
|
|||||||
88
3rdparty/base64.cpp
vendored
Normal file
88
3rdparty/base64.cpp
vendored
Normal 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
47
3rdparty/base64.h
vendored
Normal 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
|
||||||
@@ -40,10 +40,16 @@ include("cmake/fuck_windows/fuck.cmake")
|
|||||||
|
|
||||||
# default prefix path
|
# default prefix path
|
||||||
if (NKR_PACKAGE)
|
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 ()
|
else ()
|
||||||
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libs/deps/built)
|
list(APPEND NKR_LIBS ${CMAKE_SOURCE_DIR}/libs/deps/built)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (NKR_DISABLE_LIBS)
|
||||||
|
else ()
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH ${NKR_LIBS})
|
||||||
|
endif ()
|
||||||
|
|
||||||
message("[CMAKE_PREFIX_PATH] ${CMAKE_PREFIX_PATH}")
|
message("[CMAKE_PREFIX_PATH] ${CMAKE_PREFIX_PATH}")
|
||||||
|
|
||||||
# for some cross toolchain
|
# for some cross toolchain
|
||||||
@@ -100,6 +106,7 @@ set(PROJECT_SOURCES
|
|||||||
main/NekoRay.cpp
|
main/NekoRay.cpp
|
||||||
main/NekoRay_Utils.cpp
|
main/NekoRay_Utils.cpp
|
||||||
|
|
||||||
|
3rdparty/base64.cpp
|
||||||
3rdparty/qrcodegen.cpp
|
3rdparty/qrcodegen.cpp
|
||||||
3rdparty/QtExtKeySequenceEdit.cpp
|
3rdparty/QtExtKeySequenceEdit.cpp
|
||||||
|
|
||||||
@@ -207,14 +214,6 @@ set(PROJECT_SOURCES
|
|||||||
${QV2RAY_RC}
|
${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
|
# Qt exe
|
||||||
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
qt_add_executable(nekoray
|
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 AUTOMOC ON)
|
||||||
set_property(TARGET nekoray PROPERTY AUTORCC ON)
|
set_property(TARGET nekoray PROPERTY AUTORCC ON)
|
||||||
|
|
||||||
# Target Link
|
# Target Source macOS
|
||||||
|
|
||||||
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}
|
|
||||||
)
|
|
||||||
|
|
||||||
set(MACOSX_ICON ${CMAKE_SOURCE_DIR}/res/nekoray.icns)
|
set(MACOSX_ICON ${CMAKE_SOURCE_DIR}/res/nekoray.icns)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
target_sources(nekoray PRIVATE ${MACOSX_ICON})
|
target_sources(nekoray PRIVATE ${MACOSX_ICON})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set_target_properties(nekoray PROPERTIES
|
set_target_properties(nekoray PROPERTIES
|
||||||
MACOSX_BUNDLE_ICON_FILE "nekoray.icns"
|
MACOSX_BUNDLE_ICON_FILE "nekoray.icns"
|
||||||
RESOURCE ${MACOSX_ICON}
|
RESOURCE ${MACOSX_ICON}
|
||||||
@@ -269,6 +259,29 @@ set_target_properties(nekoray PROPERTIES
|
|||||||
WIN32_EXECUTABLE TRUE
|
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)
|
if (QT_VERSION_MAJOR EQUAL 6)
|
||||||
qt_finalize_executable(nekoray)
|
qt_finalize_executable(nekoray)
|
||||||
endif ()
|
endif ()
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -60,22 +60,7 @@ https://matsuridayo.github.io
|
|||||||
|
|
||||||
## Linux 运行
|
## Linux 运行
|
||||||
|
|
||||||
**使用 Linux 系统相信您已具备基本的排错能力,
|
[Linux 运行教程](examples/docs/Run_Linux.md)
|
||||||
本项目不提供特定发行版/架构的支持,预编译文件不能满足您的需求时,请自行编译/适配。**
|
|
||||||
|
|
||||||
要求:已安装主流的发行版和 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`
|
|
||||||
|
|
||||||
## 编译教程
|
## 编译教程
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
#include "ui/mainwindow_interface.h"
|
#include "ui/mainwindow_interface.h"
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
namespace NekoRay::traffic {
|
namespace NekoRay::traffic {
|
||||||
|
|
||||||
|
|||||||
30
examples/docs/Run_Linux.md
Normal file
30
examples/docs/Run_Linux.md
Normal 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 版。
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
namespace NekoRay::fmt {
|
namespace NekoRay::fmt {
|
||||||
AbstractBean::AbstractBean(int version) {
|
AbstractBean::AbstractBean(int version) {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
#include "main/NekoRay.hpp"
|
#include "main/NekoRay.hpp"
|
||||||
|
|
||||||
namespace NekoRay::fmt {
|
namespace NekoRay::fmt {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var local_qt_theme bool
|
var local_qt_theme bool
|
||||||
@@ -16,18 +15,19 @@ func Launcher() {
|
|||||||
wd, _ := filepath.Abs(".")
|
wd, _ := filepath.Abs(".")
|
||||||
|
|
||||||
_debug := flag.Bool("debug", false, "Debug mode")
|
_debug := flag.Bool("debug", false, "Debug mode")
|
||||||
flag.BoolVar(&local_qt_theme, "theme", false, "Use local QT theme (unstable)")
|
|
||||||
flag.Parse()
|
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 := exec.Command("./nekoray", flag.Args()...)
|
||||||
cmd.Env = os.Environ()
|
|
||||||
ld_env := "LD_LIBRARY_PATH=" + filepath.Join(wd, "./usr/lib")
|
ld_env := "LD_LIBRARY_PATH=" + filepath.Join(wd, "./usr/lib")
|
||||||
cmd.Env = append(cmd.Env, ld_env)
|
qt_plugin_env := "QT_PLUGIN_PATH=" + filepath.Join(wd, "./usr/plugins")
|
||||||
log.Println(ld_env, cmd)
|
|
||||||
|
// 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 {
|
if *_debug {
|
||||||
cmd.Env = append(cmd.Env, "QT_DEBUG_PLUGINS=1")
|
cmd.Env = append(cmd.Env, "QT_DEBUG_PLUGINS=1")
|
||||||
@@ -39,39 +39,3 @@ func Launcher() {
|
|||||||
cmd.Start()
|
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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,8 +9,33 @@ mkdir -p $DEST
|
|||||||
#### copy binary ####
|
#### copy binary ####
|
||||||
cp $BUILD/nekoray $DEST
|
cp $BUILD/nekoray $DEST
|
||||||
|
|
||||||
#### Download: prebuilt runtime ####
|
#### copy so ####
|
||||||
curl -Lso usr.zip https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/20220705-5.15.2-linux64.zip
|
USR_LIB=/usr/lib/x86_64-linux-gnu
|
||||||
unzip usr.zip
|
mkdir usr
|
||||||
rm usr.zip
|
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
|
mv usr $DEST
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ cp $BUILD/nekoray.exe $DEST
|
|||||||
#### deploy qt & DLL runtime ####
|
#### deploy qt & DLL runtime ####
|
||||||
pushd $DEST
|
pushd $DEST
|
||||||
windeployqt nekoray.exe --no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --verbose 2
|
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
|
rm -rf translations
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
|||||||
8
libs/env_qtsdk.sh
Normal file
8
libs/env_qtsdk.sh
Normal 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
|
||||||
@@ -4,6 +4,10 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
namespace NekoRay {
|
namespace NekoRay {
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "NekoRay_Utils.hpp"
|
#include "NekoRay_Utils.hpp"
|
||||||
|
|
||||||
|
#include "3rdparty/base64.h"
|
||||||
#include "3rdparty/QThreadCreateThread.hpp"
|
#include "3rdparty/QThreadCreateThread.hpp"
|
||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
@@ -9,6 +10,40 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFile>
|
#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) {
|
QString GetQueryValue(const QUrlQuery &q, const QString &key, const QString &def) {
|
||||||
auto a = q.queryItemValue(key);
|
auto a = q.queryItemValue(key);
|
||||||
@@ -34,6 +69,43 @@ QString GetRandomString(int randomStringLength) {
|
|||||||
return randomString;
|
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) {
|
QByteArray ReadFile(const QString &path) {
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
file.open(QFile::ReadOnly);
|
file.open(QFile::ReadOnly);
|
||||||
@@ -76,6 +148,12 @@ bool IsIpAddressV6(const QString &str) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DisplayTime(long long time, int formatType) {
|
||||||
|
QDateTime t;
|
||||||
|
t.setSecsSinceEpoch(time);
|
||||||
|
return QLocale().toString(t, QLocale::FormatType(formatType));
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *GetMessageBoxParent() {
|
QWidget *GetMessageBoxParent() {
|
||||||
if (mainwindow == nullptr) return nullptr;
|
if (mainwindow == nullptr) return nullptr;
|
||||||
if (mainwindow->isVisible()) return mainwindow;
|
if (mainwindow->isVisible()) return mainwindow;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// DO NOT INCLUDE THIS
|
// DO NOT INCLUDE THIS
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QJsonObject>
|
#include <QDebug>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonArray>
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -15,23 +16,14 @@ inline QString software_core_name = "V2Ray";
|
|||||||
inline std::function<void()> MF_release_runguard;
|
inline std::function<void()> MF_release_runguard;
|
||||||
|
|
||||||
// MainWindow functions
|
// MainWindow functions
|
||||||
|
class QWidget;
|
||||||
inline QWidget *mainwindow;
|
inline QWidget *mainwindow;
|
||||||
inline std::function<void(QString)> MW_show_log;
|
inline std::function<void(QString)> MW_show_log;
|
||||||
inline std::function<void(QString, QString)> MW_show_log_ext;
|
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)> MW_show_log_ext_vt100;
|
||||||
inline std::function<void(QString, QString)> MW_dialog_message;
|
inline std::function<void(QString, QString)> MW_dialog_message;
|
||||||
|
|
||||||
// Utils
|
// String
|
||||||
|
|
||||||
#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];
|
|
||||||
|
|
||||||
#define Int2String(num) QString::number(num)
|
#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());
|
return str.right(str.length() - str.indexOf(sub) - sub.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString QStringList2Command(const QStringList &list) {
|
QString QStringList2Command(const QStringList &list);
|
||||||
QStringList new_list;
|
|
||||||
for (auto str: list) {
|
|
||||||
auto q = "\"" + str.replace("\"", "\\\"") + "\"";
|
|
||||||
new_list << q;
|
|
||||||
}
|
|
||||||
return new_list.join(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString
|
QStringList SplitLines(const QString &_string);
|
||||||
DecodeB64IfValid(const QString &input, QByteArray::Base64Option options = QByteArray::Base64Option::Base64Encoding) {
|
|
||||||
auto result = QByteArray::fromBase64Encoding(input.toUtf8(),
|
// Base64
|
||||||
options | QByteArray::Base64Option::AbortOnBase64DecodingErrors);
|
|
||||||
if (result) {
|
QString DecodeB64IfValid(const QString &input, QByteArray::Base64Options options = QByteArray::Base64Option::Base64Encoding);
|
||||||
return result.decoded;
|
|
||||||
}
|
// URL
|
||||||
return "";
|
|
||||||
}
|
class QUrlQuery;
|
||||||
|
|
||||||
#define GetQuery(url) QUrlQuery((url).query(QUrl::ComponentFormattingOption::FullyDecoded));
|
#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 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) {
|
inline QString UrlSafe_encode(const QString &s) {
|
||||||
return s.toUtf8().toPercentEncoding().replace(" ", "%20");
|
return s.toUtf8().toPercentEncoding().replace(" ", "%20");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool InRange(unsigned x, unsigned low, unsigned high) {
|
// JSON
|
||||||
return (low <= x && x <= high);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QStringList SplitLines(const QString &_string) {
|
class QJsonObject;
|
||||||
return _string.split(QRegularExpression("[\r\n]"), Qt::SplitBehaviorFlags::SkipEmptyParts);
|
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
|
// Files
|
||||||
|
|
||||||
@@ -122,10 +90,6 @@ QByteArray ReadFile(const QString &path);
|
|||||||
|
|
||||||
QString ReadFileText(const QString &path);
|
QString ReadFileText(const QString &path);
|
||||||
|
|
||||||
// Net
|
|
||||||
|
|
||||||
int MkPort();
|
|
||||||
|
|
||||||
// Validators
|
// Validators
|
||||||
|
|
||||||
bool IsIpAddress(const QString &str);
|
bool IsIpAddress(const QString &str);
|
||||||
@@ -150,13 +114,11 @@ inline QString DisplayAddress(QString serverAddress, int serverPort) {
|
|||||||
return WrapIPV6Host(serverAddress) + ":" + Int2String(serverPort);
|
return WrapIPV6Host(serverAddress) + ":" + Int2String(serverPort);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Format
|
// Format & Misc
|
||||||
|
|
||||||
inline QString DisplayTime(long long time, QLocale::FormatType formatType = QLocale::LongFormat) {
|
int MkPort();
|
||||||
QDateTime t;
|
|
||||||
t.setSecsSinceEpoch(time);
|
QString DisplayTime(long long time, int formatType = 0);
|
||||||
return QLocale().toString(t, formatType);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString ReadableSize(const qint64 &size) {
|
inline QString ReadableSize(const qint64 &size) {
|
||||||
double sizeAsDouble = 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);
|
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
|
// UI
|
||||||
|
|
||||||
QWidget *GetMessageBoxParent();
|
QWidget *GetMessageBoxParent();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Qv2ray wrapper
|
// Qv2ray wrapper
|
||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#define LOG(...) Qv2ray::base::log_internal(__VA_ARGS__)
|
#define LOG(...) Qv2ray::base::log_internal(__VA_ARGS__)
|
||||||
#define DEBUG(...) Qv2ray::base::log_internal(__VA_ARGS__)
|
#define DEBUG(...) Qv2ray::base::log_internal(__VA_ARGS__)
|
||||||
|
|||||||
@@ -167,9 +167,8 @@ void AutoRun_SetEnabled(bool enable) {
|
|||||||
QStringList appCmdList = {QApplication::applicationFilePath(), "-tray"};
|
QStringList appCmdList = {QApplication::applicationFilePath(), "-tray"};
|
||||||
|
|
||||||
// nekoray: launcher
|
// nekoray: launcher
|
||||||
auto launcherPath = QApplication::applicationDirPath() + "/launcher";
|
if (qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1") {
|
||||||
if (QFile::exists(launcherPath)) {
|
appCmdList = QStringList{QApplication::applicationDirPath() + "/launcher", "--", "-tray"};
|
||||||
appCmdList = QStringList{launcherPath, "--", "-tray"};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#ifndef MW_INTERFACE
|
#ifndef MW_INTERFACE
|
||||||
|
|
||||||
|
#include <QTime>
|
||||||
#include <QTableWidgetItem>
|
#include <QTableWidgetItem>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
|
|||||||
Reference in New Issue
Block a user