10
.github/workflows/aur.yml
vendored
@ -1,7 +1,13 @@
|
|||||||
name: AUR Test Build
|
name: Build Qv2ray AUR
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths-ignore: [README.md]
|
paths-ignore:
|
||||||
|
- '.github'
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- dev
|
||||||
|
tags:
|
||||||
|
- 'v**'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 19 * * *"
|
- cron: "0 19 * * *"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
name: Qv2ray build matrix
|
name: Qv2ray build matrix - cmake
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -9,17 +9,31 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
qt_version: [5.12.6, 5.13.2, 5.14.1]
|
qt_version: [5.11.3, 5.12.7, 5.13.2, 5.14.2]
|
||||||
platform: [ubuntu-16.04, macos-latest, windows-latest]
|
platform: [ubuntu-16.04, macos-latest, windows-latest]
|
||||||
arch: [x86, x64]
|
arch: [x86, x64]
|
||||||
|
include:
|
||||||
|
- platform: windows-latest
|
||||||
|
arch: x86
|
||||||
|
qtarch: win32_msvc2017
|
||||||
|
- platform: windows-latest
|
||||||
|
arch: x64
|
||||||
|
qtarch: win64_msvc2017_64
|
||||||
exclude:
|
exclude:
|
||||||
- platform: ubuntu-16.04
|
- platform: ubuntu-16.04
|
||||||
arch: x86
|
arch: x86
|
||||||
- platform: macos-latest
|
- platform: macos-latest
|
||||||
arch: x86
|
arch: x86
|
||||||
|
- platform: windows-latest
|
||||||
|
qt_version: 5.11.3
|
||||||
|
- platform: windows-latest
|
||||||
|
qt_version: 5.12.7
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
env:
|
||||||
|
_QV2RAY_BUILD_INFO_: "Qv2ray built from Github Action"
|
||||||
|
_QV2RAY_BUILD_EXTRA_INFO_: "qt${{ matrix.qt_version }}-${{ github.sha }}-ci.${{ matrix.platform }}"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Get the version
|
- name: Get the version
|
||||||
@ -28,9 +42,14 @@ jobs:
|
|||||||
run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)
|
run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)
|
||||||
- name: Checking out sources
|
- name: Checking out sources
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
|
- name: Install Python 3.7 version
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: '3.7'
|
||||||
|
architecture: ${{ matrix.arch }}
|
||||||
- name: Restoring submodules
|
- name: Restoring submodules
|
||||||
run: git submodule update --init
|
run: git submodule update --init
|
||||||
# --------------------------------------------------------
|
# =========================================================================================================
|
||||||
- name: Install MSVC compiler
|
- name: Install MSVC compiler
|
||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
@ -38,58 +57,85 @@ 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: Cache Qt
|
||||||
|
id: cache-qt
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ../Qt
|
||||||
|
key: QtCache-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.qt_version }}
|
||||||
- name: Installing Qt - ${{ matrix.arch }}
|
- name: Installing Qt - ${{ matrix.arch }}
|
||||||
uses: Qv2ray/install-qt-action@master
|
uses: jurplel/install-qt-action@v2.5.0
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.qt_version }}
|
version: ${{ matrix.qt_version }}
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.qtarch }}
|
||||||
# --------------------------------------------------------
|
mirror: 'http://mirrors.ocf.berkeley.edu/qt/'
|
||||||
- name: Linux - Install Packages
|
cached: ${{ steps.cache-qt.outputs.cache-hit }}
|
||||||
|
# =========================================================================================================
|
||||||
|
- name: Linux - ${{ matrix.qt_version }} - Build preparation - Install Packages
|
||||||
if: matrix.platform == 'ubuntu-16.04'
|
if: matrix.platform == 'ubuntu-16.04'
|
||||||
run: |
|
run: |
|
||||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
|
||||||
sudo add-apt-repository ppa:webispy/grpc
|
sudo add-apt-repository ppa:webispy/grpc
|
||||||
sudo add-apt-repository ppa:carsten-uppenbrink-net/openssl
|
sudo add-apt-repository ppa:carsten-uppenbrink-net/openssl
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y gcc-7 libgl-dev openssl libx11-dev libxkbcommon-x11-dev libprotobuf-dev protobuf-compiler protobuf-c-compiler
|
sudo apt install -y libgl-dev libx11-dev libxkbcommon-x11-dev libssl-dev libprotobuf-dev protobuf-compiler protobuf-c-compiler libgrpc++-dev protobuf-compiler-grpc tree ninja-build
|
||||||
|
|
||||||
- name: macOS - Install Packages
|
|
||||||
if: matrix.platform == 'macos-latest'
|
|
||||||
run: brew install protobuf
|
|
||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
- name: Cross-platform - Download libraries
|
- name: macOS - ${{ matrix.qt_version }} - Build preparation - Install Packages
|
||||||
shell: bash
|
if: matrix.platform == 'macos-latest'
|
||||||
run: |
|
run: |
|
||||||
curl -o ./libs/libqvb-linux64.a -L https://github.com/Qv2ray/QvRPCBridge/releases/download/v1.1/libqvb-linux64.a
|
brew install protobuf
|
||||||
curl -o ./libs/libqvb-darwin.a -L https://github.com/Qv2ray/QvRPCBridge/releases/download/v1.1/libqvb-darwin.a
|
brew install grpc
|
||||||
curl -o ./libs/Qv2ray-deps-${{ matrix.arch }}-windows.7z -L https://github.com/Qv2ray/Qv2ray-deps/releases/download/release/Qv2ray-deps-${{ matrix.arch }}-windows.7z
|
brew install ninja
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Extract Windows Dependencies
|
# --------------------------------------------------------
|
||||||
|
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Build preparation - Download Dependencies
|
||||||
|
shell: bash
|
||||||
|
if: matrix.platform == 'windows-latest'
|
||||||
|
run: |
|
||||||
|
choco install -y ninja
|
||||||
|
curl -o ./libs/Qv2ray-deps-grpc-${{ matrix.arch }}-windows.7z -L https://github.com/Qv2ray/Qv2ray-deps/releases/download/release/Qv2ray-deps-grpc-${{ matrix.arch }}-windows.7z
|
||||||
|
- name: Win-${{ matrix.arch }} - Build preparation - Extract Dependencies
|
||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
uses: DuckSoft/extract-7z-action@v1.0
|
uses: DuckSoft/extract-7z-action@v1.0
|
||||||
with:
|
with:
|
||||||
pathSource: ./libs/Qv2ray-deps-${{ matrix.arch }}-windows.7z
|
pathSource: ./libs/Qv2ray-deps-grpc-${{ matrix.arch }}-windows.7z
|
||||||
pathTarget: ./libs
|
pathTarget: ./libs
|
||||||
# -------------------------------------------------------- Generate MakeFile
|
# ========================================================================================================= Generate MakeFile and Build
|
||||||
- name: Cross-platform - ${{ matrix.qt_version }} - Generate Dependencies and Makefile
|
- name: macOS - ${{ matrix.qt_version }} - Generate Dependencies and Build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
if: matrix.platform == 'macos-latest'
|
||||||
run: |
|
run: |
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
export _QV2RAY_BUILD_INFO_="Qv2ray built from Github Action"
|
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
|
||||||
export _QV2RAY_BUILD_EXTRA_INFO_="qt${{ matrix.qt_version }}-${{ github.sha }}"
|
cmake --build . --parallel $(sysctl -n hw.logicalcpu)
|
||||||
qmake .. CONFIG+="debug_and_release no_increase_build_number" PREFIX=/usr
|
sudo cmake --install .
|
||||||
# -------------------------------------------------------- Build
|
sudo chmod -Rv a+rw ./
|
||||||
- name: Unix - ${{ matrix.qt_version }} - Build Qv2ray
|
# --------------------------------------------------------
|
||||||
if: matrix.platform != 'windows-latest'
|
- name: Windows - ${{ matrix.qt_version }} - Generate Dependencies and Build
|
||||||
run: |
|
shell: bash
|
||||||
cd build
|
|
||||||
make -j2 release $([ "${{ matrix.platform }}" == "ubuntu-16.04" ] && echo "CC=gcc-7 CXX=g++-7" LINK="g++-7" || echo "")
|
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Build Qv2ray
|
|
||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
|
env:
|
||||||
|
CC: cl.exe
|
||||||
|
CXX: cl.exe
|
||||||
run: |
|
run: |
|
||||||
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
nmake release
|
cmake .. -GNinja -DCMAKE_INSTALL_PREFIX=./deployment -DCMAKE_BUILD_TYPE=Release
|
||||||
# -------------------------------------------------------- Deployments
|
cmake --build . --parallel $(nproc)
|
||||||
|
cmake --install .
|
||||||
|
# --------------------------------------------------------
|
||||||
|
- name: Linux - ${{ matrix.qt_version }} - Generate Dependencies and Build
|
||||||
|
if: matrix.platform == 'ubuntu-16.04'
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
CC: /usr/bin/gcc-9
|
||||||
|
CXX: /usr/bin/g++-9
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -GNinja -DCMAKE_INSTALL_PREFIX=./AppDir/usr -DCMAKE_BUILD_TYPE=Release -DQV2RAY_TRANSLATION_PATH=QApplication::applicationDirPath\(\)+"/../share/qv2ray/lang"
|
||||||
|
cmake --build . --parallel $(nproc)
|
||||||
|
cmake --install .
|
||||||
|
# ========================================================================================================= Deployments
|
||||||
- name: Linux - ${{ matrix.qt_version }} - Generating AppImage
|
- name: Linux - ${{ matrix.qt_version }} - Generating AppImage
|
||||||
if: matrix.platform == 'ubuntu-16.04'
|
if: matrix.platform == 'ubuntu-16.04'
|
||||||
run: |
|
run: |
|
||||||
@ -97,7 +143,6 @@ jobs:
|
|||||||
wget https://github.com/probonopd/linuxdeployqt/releases/download/6/linuxdeployqt-6-x86_64.AppImage
|
wget https://github.com/probonopd/linuxdeployqt/releases/download/6/linuxdeployqt-6-x86_64.AppImage
|
||||||
chmod +x ./linuxdeployqt-6-x86_64.AppImage
|
chmod +x ./linuxdeployqt-6-x86_64.AppImage
|
||||||
./linuxdeployqt-6-x86_64.AppImage --appimage-extract
|
./linuxdeployqt-6-x86_64.AppImage --appimage-extract
|
||||||
make install INSTALL_ROOT=AppDir
|
|
||||||
cd AppDir
|
cd AppDir
|
||||||
wget -c https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/AppRun-patched-x86_64 -O AppRun
|
wget -c https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/AppRun-patched-x86_64 -O AppRun
|
||||||
chmod a+x AppRun
|
chmod a+x AppRun
|
||||||
@ -118,22 +163,19 @@ jobs:
|
|||||||
path: build/AppDir/Qv2ray.AppImage
|
path: build/AppDir/Qv2ray.AppImage
|
||||||
- name: Linux - ${{ matrix.qt_version }} - Upload binaries to release
|
- name: Linux - ${{ matrix.qt_version }} - Upload binaries to release
|
||||||
uses: svenstaro/upload-release-action@v1-release
|
uses: svenstaro/upload-release-action@v1-release
|
||||||
if: github.event_name == 'release' && matrix.platform == 'ubuntu-16.04'
|
if: github.event_name == 'release' && matrix.platform == 'ubuntu-16.04' && matrix.qt_version == '5.14.2'
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: build/AppDir/Qv2ray.AppImage
|
file: build/AppDir/Qv2ray.AppImage
|
||||||
asset_name: Qv2ray.${{ steps.get_version.outputs.VERSION }}.linux-${{ matrix.arch }}.qt${{ matrix.qt_version }}.AppImage
|
asset_name: Qv2ray.${{ steps.get_version.outputs.VERSION }}.linux-${{ matrix.arch }}.AppImage
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
# ==
|
# --------------------------------------------------------
|
||||||
- name: macOS - ${{ matrix.qt_version }} - Making release tarball
|
- name: macOS - ${{ matrix.qt_version }} - Making release tarball
|
||||||
if: matrix.platform == 'macos-latest'
|
if: matrix.platform == 'macos-latest'
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
cd qv2ray.app
|
tar czvf Qv2ray.app.tar.gz qv2ray.app
|
||||||
macdeployqt ./
|
|
||||||
cd ..
|
|
||||||
tar czf Qv2ray.app.tar.gz qv2ray.app
|
|
||||||
- name: macOS - ${{ matrix.qt_version }} - Uploading Artifact
|
- name: macOS - ${{ matrix.qt_version }} - Uploading Artifact
|
||||||
if: matrix.platform == 'macos-latest'
|
if: matrix.platform == 'macos-latest'
|
||||||
uses: actions/upload-artifact@master
|
uses: actions/upload-artifact@master
|
||||||
@ -142,31 +184,19 @@ jobs:
|
|||||||
path: build/Qv2ray.app.tar.gz
|
path: build/Qv2ray.app.tar.gz
|
||||||
- name: macOS - ${{ matrix.qt_version }} - Upload binaries to release
|
- name: macOS - ${{ matrix.qt_version }} - Upload binaries to release
|
||||||
uses: svenstaro/upload-release-action@v1-release
|
uses: svenstaro/upload-release-action@v1-release
|
||||||
if: github.event_name == 'release' && matrix.platform == 'macos-latest'
|
if: github.event_name == 'release' && matrix.platform == 'macos-latest' && matrix.qt_version == '5.14.2'
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: build/Qv2ray.app.tar.gz
|
file: build/Qv2ray.app.tar.gz
|
||||||
asset_name: Qv2ray.${{ steps.get_version.outputs.VERSION }}.macOS-${{ matrix.arch }}.qt${{ matrix.qt_version }}.tar.gz
|
asset_name: Qv2ray.${{ steps.get_version.outputs.VERSION }}.macOS-${{ matrix.arch }}.tar.gz
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
# ==
|
# --------------------------------------------------------
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Copying DLLs to build output folders
|
|
||||||
if: matrix.platform == 'windows-latest'
|
|
||||||
run: .\.github\workflows\copy_DLLs.bat
|
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Running windeployqt
|
|
||||||
if: matrix.platform == 'windows-latest'
|
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
cd release
|
|
||||||
del *.cpp *.h *.o *.qrc *.qm *.hpp *.obj
|
|
||||||
set VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\
|
|
||||||
windeployqt ./qv2ray.exe --compiler-runtime --verbose 2
|
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Create 7z Release
|
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Create 7z Release
|
||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
uses: DuckSoft/create-7z-action@v1.0
|
uses: DuckSoft/create-7z-action@v1.0
|
||||||
with:
|
with:
|
||||||
pathSource: ./build/release/
|
pathSource: ./build/deployment/
|
||||||
pathTarget: ./release.7z
|
pathTarget: ./release.7z
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Uploading artifact
|
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Uploading artifact
|
||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
@ -176,10 +206,10 @@ jobs:
|
|||||||
path: release.7z
|
path: release.7z
|
||||||
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Upload binaries to release
|
- name: Win-${{ matrix.arch }} - ${{ matrix.qt_version }} - Upload binaries to release
|
||||||
uses: svenstaro/upload-release-action@v1-release
|
uses: svenstaro/upload-release-action@v1-release
|
||||||
if: github.event_name == 'release' && matrix.platform == 'windows-latest'
|
if: github.event_name == 'release' && matrix.platform == 'windows-latest' && matrix.qt_version == '5.14.2'
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: release.7z
|
file: release.7z
|
||||||
asset_name: Qv2ray.${{ steps.get_version.outputs.VERSION }}.Windows-${{ matrix.arch }}.qt${{ matrix.qt_version }}.7z
|
asset_name: Qv2ray.${{ steps.get_version.outputs.VERSION }}.Windows-${{ matrix.arch }}.7z
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
overwrite: true
|
overwrite: true
|
5
.github/workflows/copy_DLLs.bat
vendored
@ -1,5 +0,0 @@
|
|||||||
@echo off
|
|
||||||
echo Copying DLLs for Windows
|
|
||||||
forfiles /s /p %GITHUB_WORKSPACE%\libs\x86-windows\bin\ /m "*.dll" /c "cmd.exe /c copy @file %GITHUB_WORKSPACE%\build\release\"
|
|
||||||
forfiles /s /p %GITHUB_WORKSPACE%\libs\x64-windows\bin\ /m "*.dll" /c "cmd.exe /c copy @file %GITHUB_WORKSPACE%\build\release\"
|
|
||||||
exit 0
|
|
4
.gitignore
vendored
@ -1,6 +1,8 @@
|
|||||||
# Some files
|
# Some files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.pro.user
|
*.pro.user
|
||||||
|
*.user
|
||||||
|
.vs/
|
||||||
*.qm
|
*.qm
|
||||||
./.vscode
|
./.vscode
|
||||||
|
|
||||||
@ -11,4 +13,4 @@ libs/x64-windows/
|
|||||||
libs/x86-windows/
|
libs/x86-windows/
|
||||||
libs/libqvb-*
|
libs/libqvb-*
|
||||||
|
|
||||||
build/
|
build**/
|
||||||
|
9
.gitmodules
vendored
@ -1,9 +1,6 @@
|
|||||||
[submodule "3rdparty/x2struct"]
|
[submodule "3rdparty/x2struct"]
|
||||||
path = 3rdparty/x2struct
|
path = 3rdparty/x2struct
|
||||||
url = https://github.com/xyz347/x2struct
|
url = https://github.com/xyz347/x2struct
|
||||||
[submodule "3rdparty/qhttpserver"]
|
|
||||||
path = 3rdparty/qhttpserver
|
|
||||||
url = https://github.com/nikhilm/qhttpserver
|
|
||||||
[submodule "3rdparty/SingleApplication"]
|
[submodule "3rdparty/SingleApplication"]
|
||||||
path = 3rdparty/SingleApplication
|
path = 3rdparty/SingleApplication
|
||||||
url = https://github.com/itay-grudev/SingleApplication
|
url = https://github.com/itay-grudev/SingleApplication
|
||||||
@ -16,3 +13,9 @@
|
|||||||
[submodule "libs/libqvb"]
|
[submodule "libs/libqvb"]
|
||||||
path = libs/libqvb
|
path = libs/libqvb
|
||||||
url = https://github.com/Qv2ray/QvRPCBridge
|
url = https://github.com/Qv2ray/QvRPCBridge
|
||||||
|
[submodule "3rdparty/cpp-httplib"]
|
||||||
|
path = 3rdparty/cpp-httplib
|
||||||
|
url = https://github.com/yhirose/cpp-httplib
|
||||||
|
[submodule "libs/puresource"]
|
||||||
|
path = libs/puresource
|
||||||
|
url = https://github.com/Qv2ray/PureSource/
|
||||||
|
14
.travis.yml
@ -1,4 +1,5 @@
|
|||||||
language: bash
|
language: shell
|
||||||
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
|
|
||||||
git:
|
git:
|
||||||
@ -15,14 +16,15 @@ env:
|
|||||||
|
|
||||||
addons:
|
addons:
|
||||||
snaps:
|
snaps:
|
||||||
- name: snapcraft
|
- name: snapcraft
|
||||||
channel: stable
|
channel: stable
|
||||||
confinement: classic
|
confinement: classic
|
||||||
- name: lxd
|
- name: lxd
|
||||||
channel: stable
|
channel: stable
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- sudo apt autoremove lxd --purge
|
- sudo apt autoremove lxd --purge
|
||||||
|
- sudo /snap/bin/lxd waitready
|
||||||
- sudo /snap/bin/lxd init --auto
|
- sudo /snap/bin/lxd init --auto
|
||||||
- sudo snapcraft --use-lxd
|
- sudo snapcraft --use-lxd
|
||||||
|
|
||||||
|
2
3rdparty/QNodeEditor
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 0f368335943cc8b84a8b52c5ad7cfd9c25ebb6d6
|
Subproject commit c93f1c1826d46d5d60f118688cd830b39af8b9c6
|
2
3rdparty/SingleApplication
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 0f6695e2a9d8fdaa336e7ad941855c46c61f218a
|
Subproject commit 4abe20afbfa5695ac7a9bce1298943b645aeffe9
|
1
3rdparty/cpp-httplib
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 26deffe0c6a1e177e393416b94cdc0f340ca79bd
|
1
3rdparty/qhttpserver
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit 02a6e7174b5be76e2c0e74a109817e39a141b9fd
|
|
2
3rdparty/qzxing
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ee50acba1f10e70ef23c593971621ed7a9f4c5a1
|
Subproject commit dac9480a652d591c41ec9ef6f6c966c59a252142
|
382
CMakeLists.txt
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10.1)
|
||||||
|
|
||||||
|
file(STRINGS "${CMAKE_SOURCE_DIR}/makespec/VERSION" QV2RAY_VERSION)
|
||||||
|
file(STRINGS "${CMAKE_SOURCE_DIR}/makespec/BUILDVERSION" QV2RAY_BUILD_VERSION)
|
||||||
|
|
||||||
|
if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Release")
|
||||||
|
math(EXPR QV2RAY_BUILD_VERSION "1 + ${QV2RAY_BUILD_VERSION}")
|
||||||
|
message("Increasing BUILDVERSION")
|
||||||
|
file(WRITE "${CMAKE_SOURCE_DIR}/makespec/BUILDVERSION" ${QV2RAY_BUILD_VERSION})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PACKAGE_VERSION "${QV2RAY_VERSION}.${QV2RAY_BUILD_VERSION}")
|
||||||
|
project(qv2ray)
|
||||||
|
|
||||||
|
set(VERSION_LIST ${PACKAGE_VERSION})
|
||||||
|
string(REPLACE "." ";" VERSION_LIST ${VERSION_LIST})
|
||||||
|
separate_arguments(VERSION_LIST)
|
||||||
|
|
||||||
|
list(GET VERSION_LIST 0 QV2RAY_VERSION_MAJOR)
|
||||||
|
list(GET VERSION_LIST 1 QV2RAY_VERSION_MINOR)
|
||||||
|
list(GET VERSION_LIST 2 QV2RAY_VERSION_BUGFIX)
|
||||||
|
list(GET VERSION_LIST 3 QV2RAY_VERSION_BUILD)
|
||||||
|
|
||||||
|
add_definitions(-DQV2RAY_VERSION_MAJOR=${QV2RAY_VERSION_MAJOR})
|
||||||
|
add_definitions(-DQV2RAY_VERSION_MINOR=${QV2RAY_VERSION_MINOR})
|
||||||
|
add_definitions(-DQV2RAY_VERSION_BUGFIX=${QV2RAY_VERSION_BUGFIX})
|
||||||
|
add_definitions(-DQV2RAY_VERSION_BUILD=${QV2RAY_VERSION_BUILD})
|
||||||
|
|
||||||
|
add_definitions(-DQV2RAY_VERSION_STRING="v${PACKAGE_VERSION}")
|
||||||
|
add_definitions(-DXTOSTRUCT_QT)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0071 NEW)
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_LESS "3.7.0")
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(" ")
|
||||||
|
message("Qv2ray Version: v${PACKAGE_VERSION}")
|
||||||
|
message("|-------------------------------------------------|")
|
||||||
|
message("| Qv2ray, A Cross Platform v2ray Qt GUI Client. |")
|
||||||
|
message("| Licenced under GPLv3 |")
|
||||||
|
message("| |")
|
||||||
|
message("| You may only use this program to the extent |")
|
||||||
|
message("| permitted by local law. |")
|
||||||
|
message("| |")
|
||||||
|
message("| See: https://www.gnu.org/licenses/gpl-3.0.html |")
|
||||||
|
message("|-------------------------------------------------|")
|
||||||
|
message("| Project Homepage: https://github.com/Qv2ray |")
|
||||||
|
message("| Welcome to contribute! |")
|
||||||
|
message("|-------------------------------------------------|")
|
||||||
|
message(" ")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
add_compile_options("/std:c++17")
|
||||||
|
add_definitions(-DUNICODE -D_UNICODE)
|
||||||
|
add_definitions(-D_HAS_STD_BYTE=0 -D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
set(GUI_TYPE WIN32)
|
||||||
|
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||||
|
if(CMAKE_CL_64)
|
||||||
|
include(${CMAKE_SOURCE_DIR}/libs/x64-windows/scripts/buildsystems/vcpkg.cmake)
|
||||||
|
else()
|
||||||
|
include(${CMAKE_SOURCE_DIR}/libs/x86-windows/scripts/buildsystems/vcpkg.cmake)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UNIX AND NOT APPLE)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(cmake/translations.cmake)
|
||||||
|
include(cmake/qnodeeditor.cmake)
|
||||||
|
include(cmake/singleapplication.cmake)
|
||||||
|
include(cmake/qzxing.cmake)
|
||||||
|
include(cmake/protobuf.cmake)
|
||||||
|
include(cmake/cpp-httplib.cmake)
|
||||||
|
include(cmake/backend.cmake)
|
||||||
|
|
||||||
|
if(QV2RAY_BUILD_INFO)
|
||||||
|
set(_QV2RAY_BUILD_INFO_STR_ "${QV2RAY_BUILD_INFO}")
|
||||||
|
elseif(DEFINED ENV{_QV2RAY_BUILD_INFO_})
|
||||||
|
set(_QV2RAY_BUILD_INFO_STR_ "$ENV{_QV2RAY_BUILD_INFO_}")
|
||||||
|
else()
|
||||||
|
set(_QV2RAY_BUILD_INFO_STR_ "Qv2ray from manual build")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QV2RAY_BUILD_EXTRA_INFO)
|
||||||
|
set(_QV2RAY_BUILD_EXTRA_INFO_STR_ "${QV2RAY_BUILD_EXTRA_INFO}")
|
||||||
|
elseif(DEFINED ENV{_QV2RAY_BUILD_EXTRA_INFO_})
|
||||||
|
set(_QV2RAY_BUILD_EXTRA_INFO_STR_ "$ENV{_QV2RAY_BUILD_EXTRA_INFO_}")
|
||||||
|
else()
|
||||||
|
set(_QV2RAY_BUILD_EXTRA_INFO_STR_ "Qv2ray v${PACKAGE_VERSION}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QV2RAY_BUILD_INFO ${_QV2RAY_BUILD_INFO_STR_} CACHE STRING "Qv2ray build info")
|
||||||
|
set(QV2RAY_BUILD_EXTRA_INFO ${_QV2RAY_BUILD_EXTRA_INFO_STR_} CACHE STRING "Qv2ray build extra info")
|
||||||
|
|
||||||
|
add_definitions(-D_QV2RAY_BUILD_INFO_STR_="${_QV2RAY_BUILD_INFO_STR_}")
|
||||||
|
add_definitions(-D_QV2RAY_BUILD_EXTRA_INFO_STR_="${_QV2RAY_BUILD_EXTRA_INFO_STR_}")
|
||||||
|
message("Qv2ray build info: ${_QV2RAY_BUILD_INFO_STR_}")
|
||||||
|
message("Qv2ray build info ex: ${_QV2RAY_BUILD_EXTRA_INFO_STR_}")
|
||||||
|
|
||||||
|
set(QV2RAY_DEFAULT_VASSETS_PATH "unset" CACHE STRING "v2ray assets path")
|
||||||
|
set(QV2RAY_DEFAULT_VCORE_PATH "unset" CACHE STRING "v2ray core path")
|
||||||
|
set(QV2RAY_TRANSLATION_PATH "unset" CACHE STRING "Qv2ray translations path")
|
||||||
|
set(QV2RAY_DISABLE_AUTO_UPDATE OFF CACHE BOOL "Disable update checker")
|
||||||
|
if(UNIX AND NOT APPLE)
|
||||||
|
set(QV2RAY_USE_BUILTIN_DARKTHEME OFF CACHE BOOL "Use built-in dark theme instead of followed by the system settings")
|
||||||
|
else()
|
||||||
|
set(QV2RAY_USE_BUILTIN_DARKTHEME ON CACHE BOOL "Use built-in dark theme instead of followed by the system settings")
|
||||||
|
endif()
|
||||||
|
set(EMBED_TRANSLATIONS OFF CACHE BOOL "Embed translations")
|
||||||
|
|
||||||
|
if(QV2RAY_DEFAULT_VASSETS_PATH AND NOT STREQUAL "unset")
|
||||||
|
add_definitions(-DQV2RAY_DEFAULT_VASSETS_PATH="${QV2RAY_DEFAULT_VASSETS_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QV2RAY_DEFAULT_VCORE_PATH AND NOT STREQUAL "unset")
|
||||||
|
add_definitions(-DQV2RAY_DEFAULT_VCORE_PATH="${QV2RAY_DEFAULT_VCORE_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QV2RAY_TRANSLATION_PATH AND NOT STREQUAL "unset")
|
||||||
|
add_definitions(-DQV2RAY_TRANSLATION_PATH="${QV2RAY_TRANSLATION_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QV2RAY_USE_BUILTIN_DARKTHEME)
|
||||||
|
add_definitions(-DQV2RAY_USE_BUILTIN_DARKTHEME=true)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QV2RAY_DISABLE_AUTO_UPDATE)
|
||||||
|
add_definitions(-DDISABLE_AUTO_UPDATE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QV2RAY_SOURCES
|
||||||
|
src/base/Qv2rayLog.cpp
|
||||||
|
src/common/CommandArgs.cpp
|
||||||
|
src/common/HTTPRequestHelper.cpp
|
||||||
|
src/common/LogHighlighter.cpp
|
||||||
|
src/common/JsonHighlighter.cpp
|
||||||
|
src/common/QJsonModel.cpp
|
||||||
|
src/common/QvHelpers.cpp
|
||||||
|
src/common/QvTranslator.cpp
|
||||||
|
src/components/autolaunch/QvAutoLaunch.cpp
|
||||||
|
src/components/geosite/QvGeositeReader.cpp
|
||||||
|
src/components/icmping/win/ICMPPinger.cpp
|
||||||
|
src/components/pac/QvGFWPACConverter.cpp
|
||||||
|
src/components/pac/QvPACHandler.cpp
|
||||||
|
src/components/plugins/toolbar/QvToolbar.cpp
|
||||||
|
src/components/plugins/toolbar/QvToolbar_linux.cpp
|
||||||
|
src/components/plugins/toolbar/QvToolbar_win.cpp
|
||||||
|
src/components/proxy/QvProxyConfigurator.cpp
|
||||||
|
src/components/speedchart/speedplotview.cpp
|
||||||
|
src/components/speedchart/speedwidget.cpp
|
||||||
|
src/components/darkmode/DarkmodeDetector.cpp
|
||||||
|
src/core/connection/ConnectionIO.cpp
|
||||||
|
src/core/connection/Generation.cpp
|
||||||
|
src/core/connection/Serialization.cpp
|
||||||
|
src/core/connection/Serialization_ss.cpp
|
||||||
|
src/core/connection/Serialization_ssd.cpp
|
||||||
|
src/core/connection/Serialization_vmess.cpp
|
||||||
|
src/core/CoreUtils.cpp
|
||||||
|
src/core/handler/ConfigHandler.cpp
|
||||||
|
src/core/handler/V2rayInstanceHandler.cpp
|
||||||
|
src/core/kernel/APIBackend.cpp
|
||||||
|
src/core/kernel/KernelInteractions.cpp
|
||||||
|
src/core/settings/SettingsBackend.cpp
|
||||||
|
src/core/settings/SettingsUpgrade.cpp
|
||||||
|
src/core/tcping/QvTCPing.cpp
|
||||||
|
src/main.cpp
|
||||||
|
src/ui/editors/w_InboundEditor.cpp
|
||||||
|
src/ui/editors/w_JsonEditor.cpp
|
||||||
|
src/ui/editors/w_OutboundEditor.cpp
|
||||||
|
src/ui/editors/w_RoutesEditor.cpp
|
||||||
|
src/ui/editors/w_RoutesEditor_extra.cpp
|
||||||
|
src/ui/messaging/QvMessageBus.cpp
|
||||||
|
src/ui/models/InboundNodeModel.cpp
|
||||||
|
src/ui/models/OutboundNodeModel.cpp
|
||||||
|
src/ui/models/RuleNodeModel.cpp
|
||||||
|
src/ui/widgets/ConnectionInfoWidget.cpp
|
||||||
|
src/ui/widgets/ConnectionItemWidget.cpp
|
||||||
|
src/ui/widgets/QvAutoCompleteTextEdit.cpp
|
||||||
|
src/ui/widgets/StreamSettingsWidget.cpp
|
||||||
|
src/ui/w_ImportConfig.cpp
|
||||||
|
src/ui/w_MainWindow.cpp
|
||||||
|
src/ui/w_MainWindow_extra.cpp
|
||||||
|
src/ui/w_PreferencesWindow.cpp
|
||||||
|
src/ui/w_ScreenShot_Core.cpp
|
||||||
|
src/ui/w_SubscriptionManager.cpp
|
||||||
|
# ui files
|
||||||
|
src/ui/w_SubscriptionManager.ui
|
||||||
|
src/ui/editors/w_OutboundEditor.ui
|
||||||
|
src/ui/editors/w_InboundEditor.ui
|
||||||
|
src/ui/editors/w_JsonEditor.ui
|
||||||
|
src/ui/editors/w_RoutesEditor.ui
|
||||||
|
src/ui/w_ImportConfig.ui
|
||||||
|
src/ui/widgets/StreamSettingsWidget.ui
|
||||||
|
src/ui/widgets/ConnectionInfoWidget.ui
|
||||||
|
src/ui/widgets/ConnectionItemWidget.ui
|
||||||
|
src/ui/w_MainWindow.ui
|
||||||
|
src/ui/w_PreferencesWindow.ui
|
||||||
|
src/ui/w_ScreenShot_Core.ui
|
||||||
|
# headers
|
||||||
|
src/base/JsonHelpers.hpp
|
||||||
|
src/base/models/CoreObjectModels.hpp
|
||||||
|
src/base/models/QvConfigIdentifier.hpp
|
||||||
|
src/base/models/QvRuntimeConfig.hpp
|
||||||
|
src/base/models/QvSafeType.hpp
|
||||||
|
src/base/models/QvSettingsObject.hpp
|
||||||
|
src/base/models/QvStartupConfig.hpp
|
||||||
|
src/base/Qv2rayBase.hpp
|
||||||
|
src/base/Qv2rayFeatures.hpp
|
||||||
|
src/base/Qv2rayLog.hpp
|
||||||
|
src/common/CommandArgs.hpp
|
||||||
|
src/common/HTTPRequestHelper.hpp
|
||||||
|
src/common/JsonHighlighter.hpp
|
||||||
|
src/common/LogHighlighter.hpp
|
||||||
|
src/common/QJsonModel.hpp
|
||||||
|
src/common/QvHelpers.hpp
|
||||||
|
src/common/QvTranslator.hpp
|
||||||
|
src/components/autolaunch/QvAutoLaunch.hpp
|
||||||
|
src/components/darkmode/DarkmodeDetector.hpp
|
||||||
|
src/components/geosite/QvGeositeReader.hpp
|
||||||
|
src/components/icmping/win/ICMPPinger.hpp
|
||||||
|
src/components/pac/QvPACHandler.hpp
|
||||||
|
src/components/plugins/toolbar/QvToolbar.hpp
|
||||||
|
src/components/proxy/QvProxyConfigurator.hpp
|
||||||
|
src/components/speedchart/speedplotview.hpp
|
||||||
|
src/components/speedchart/speedwidget.hpp
|
||||||
|
src/core/connection/ConnectionIO.hpp
|
||||||
|
src/core/connection/Generation.hpp
|
||||||
|
src/core/connection/Serialization.hpp
|
||||||
|
src/core/CoreSafeTypes.hpp
|
||||||
|
src/core/CoreUtils.hpp
|
||||||
|
src/core/handler/ConfigHandler.hpp
|
||||||
|
src/core/kernel/APIBackend.hpp
|
||||||
|
src/core/kernel/KernelInteractions.hpp
|
||||||
|
src/core/settings/SettingsBackend.hpp
|
||||||
|
src/core/tcping/QvTCPing.hpp
|
||||||
|
src/ui/editors/w_InboundEditor.hpp
|
||||||
|
src/ui/editors/w_JsonEditor.hpp
|
||||||
|
src/ui/editors/w_OutboundEditor.hpp
|
||||||
|
src/ui/editors/w_RoutesEditor.hpp
|
||||||
|
src/ui/messaging/QvMessageBus.hpp
|
||||||
|
src/ui/models/InboundNodeModel.hpp
|
||||||
|
src/ui/models/NodeModelsBase.hpp
|
||||||
|
src/ui/models/OutboundNodeModel.hpp
|
||||||
|
src/ui/models/RuleNodeModel.hpp
|
||||||
|
src/ui/widgets/ConnectionInfoWidget.hpp
|
||||||
|
src/ui/widgets/ConnectionItemWidget.hpp
|
||||||
|
src/ui/widgets/StreamSettingsWidget.hpp
|
||||||
|
src/ui/w_ImportConfig.hpp
|
||||||
|
src/ui/w_MainWindow.hpp
|
||||||
|
src/ui/w_PreferencesWindow.hpp
|
||||||
|
src/ui/w_ScreenShot_Core.hpp
|
||||||
|
src/ui/w_SubscriptionManager.hpp
|
||||||
|
assets/qv2ray.rc
|
||||||
|
)
|
||||||
|
|
||||||
|
if(EMBED_TRANSLATIONS)
|
||||||
|
add_definitions(-DEMBED_TRANSLATIONS)
|
||||||
|
configure_file(translations/translations.qrc ${CMAKE_BINARY_DIR} COPYONLY)
|
||||||
|
list(APPEND QV2RAY_SOURCES ${CMAKE_BINARY_DIR}/translations.qrc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_target(lupdate
|
||||||
|
COMMAND lupdate ${QV2RAY_SOURCES} -ts ${TRANSLATIONS_TS} -no-ui-lines
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
|
set_target_properties(lupdate PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||||
|
|
||||||
|
set(QRC_RESOURCES ${CMAKE_SOURCE_DIR}/resources.qrc)
|
||||||
|
|
||||||
|
set(QT_LIBRARY
|
||||||
|
Qt5::Core
|
||||||
|
Qt5::Gui
|
||||||
|
Qt5::Widgets
|
||||||
|
Qt5::Network
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME}
|
||||||
|
${GUI_TYPE}
|
||||||
|
${QV2RAY_SOURCES}
|
||||||
|
${QNODEEDITOR_SOURCES}
|
||||||
|
${QNODEEDITOR_QRC_RESOURCES}
|
||||||
|
${SINGLEAPPLICATION_SOURCES}
|
||||||
|
${QZXING_SOURCES}
|
||||||
|
${PROTO_SRCS}
|
||||||
|
${PROTO_HDRS}
|
||||||
|
${API_GRPC_SRCS}
|
||||||
|
${API_PROTO_SRCS}
|
||||||
|
${QRC_RESOURCES}
|
||||||
|
${QM_FILES}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
${QT_LIBRARY}
|
||||||
|
${QV2RAY_PROTOBUF_LIBRARY}
|
||||||
|
${QV2RAY_BACKEND_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
${CMAKE_BINARY_DIR}
|
||||||
|
${QHTTPSERVER_DIR}
|
||||||
|
${QNODEEDITOR_INCLUDE_PATH}
|
||||||
|
${QZXING_INCLUDE_PATH}
|
||||||
|
${SINGLEAPPLICATION_DIR}
|
||||||
|
${Protobuf_INCLUDE_DIRS}
|
||||||
|
${cpp-httplib_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
find_package(Iconv REQUIRED)
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
Iconv::Iconv
|
||||||
|
"-framework Carbon"
|
||||||
|
"-framework Cocoa"
|
||||||
|
"-framework Security"
|
||||||
|
)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||||
|
${Iconv_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
|
||||||
|
set(prefix "${PROJECT_NAME}.app/Contents")
|
||||||
|
set(INSTALL_RUNTIME_DIR "${prefix}/MacOS")
|
||||||
|
set(INSTALL_CMAKE_DIR "${prefix}/Resources")
|
||||||
|
|
||||||
|
# Destination paths below are relative to ${CMAKE_INSTALL_PREFIX}
|
||||||
|
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} )
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/assets/Info.plist DESTINATION "${prefix}" )
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/assets/icons/qv2ray.icns DESTINATION "${INSTALL_CMAKE_DIR}" )
|
||||||
|
if(NOT EMBED_TRANSLATIONS)
|
||||||
|
install(FILES ${QM_FILES} DESTINATION ${INSTALL_CMAKE_DIR}/lang)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Call macdeployqt
|
||||||
|
install(CODE "execute_process(COMMAND macdeployqt ${PROJECT_NAME}.app)")
|
||||||
|
set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app")
|
||||||
|
include(cmake/deployment.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UNIX AND NOT APPLE AND NOT WIN32)
|
||||||
|
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
|
||||||
|
install(FILES assets/qv2ray.metainfo.xml DESTINATION share/metainfo)
|
||||||
|
install(FILES assets/qv2ray.desktop DESTINATION share/applications)
|
||||||
|
install(FILES assets/icons/qv2ray.png DESTINATION share/icons/hicolor/256x256/apps)
|
||||||
|
if(NOT EMBED_TRANSLATIONS)
|
||||||
|
install(FILES ${QM_FILES} DESTINATION share/qv2ray/lang)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(${PROJECT_NAME} wininet wsock32 ws2_32 user32)
|
||||||
|
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION .)
|
||||||
|
if(NOT EMBED_TRANSLATIONS)
|
||||||
|
install(FILES ${QM_FILES} DESTINATION lang)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_CL_64)
|
||||||
|
install(FILES ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libssl-1_1-x64.dll DESTINATION .)
|
||||||
|
install(FILES ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libcrypto-1_1-x64.dll DESTINATION .)
|
||||||
|
else()
|
||||||
|
install(FILES ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libssl-1_1.dll DESTINATION .)
|
||||||
|
install(FILES ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libcrypto-1_1.dll DESTINATION .)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(CODE "execute_process(COMMAND windeployqt ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.exe --compiler-runtime --verbose 2)")
|
||||||
|
set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.exe")
|
||||||
|
include(cmake/deployment.cmake)
|
||||||
|
endif()
|
306
Qv2ray.astylerc
@ -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
|
|
168
Qv2ray.pro
@ -1,168 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project created by QtCreator 2019-03-28T08:45:32
|
|
||||||
#
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
QT += core gui widgets network
|
|
||||||
|
|
||||||
TARGET = qv2ray
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
# Now read build number file.
|
|
||||||
QV2RAY_VERSION=$$cat($$PWD/makespec/VERSION)
|
|
||||||
QV2RAY_BUILD_VERSION=$$cat($$PWD/makespec/BUILDVERSION)
|
|
||||||
|
|
||||||
VERSION = $${QV2RAY_VERSION}.$${QV2RAY_BUILD_VERSION}
|
|
||||||
|
|
||||||
message(" ")
|
|
||||||
message("Qv2ray Version: $${VERSION}")
|
|
||||||
message("|-------------------------------------------------|")
|
|
||||||
message("| Qv2ray, A Cross Platform v2ray Qt GUI Client. |")
|
|
||||||
message("| Licenced under GPLv3 |")
|
|
||||||
message("| |")
|
|
||||||
message("| You may only use this program to the extent |")
|
|
||||||
message("| permitted by local law. |")
|
|
||||||
message("| |")
|
|
||||||
message("| See: https://www.gnu.org/licenses/gpl-3.0.html |")
|
|
||||||
message("|-------------------------------------------------|")
|
|
||||||
message("| Project Homepage: https://github.com/Qv2ray |")
|
|
||||||
message("| Welcome to contribute! |")
|
|
||||||
message("|-------------------------------------------------|")
|
|
||||||
message(" ")
|
|
||||||
|
|
||||||
# Distinguish debug and release builds.
|
|
||||||
CONFIG(release, debug|release) {
|
|
||||||
CONFIG+=Qv2ray_release no_increase_build_number
|
|
||||||
}
|
|
||||||
CONFIG(debug, debug|release) {
|
|
||||||
CONFIG+=Qv2ray_debug
|
|
||||||
}
|
|
||||||
|
|
||||||
# Qv2ray basic configuration
|
|
||||||
CONFIG += qt c++17 openssl-linked
|
|
||||||
include($$PWD/makespec/00-deps.pri)
|
|
||||||
|
|
||||||
# lrelease will not work when adding BEFORE 00-deps.pri
|
|
||||||
CONFIG += lrelease embed_translations
|
|
||||||
DEFINES += QT_DEPRECATED_WARNINGS QV2RAY_VERSION_STRING=\"\\\"v$${VERSION}\\\"\" QAPPLICATION_CLASS=QApplication
|
|
||||||
|
|
||||||
# Source file parser
|
|
||||||
include($$PWD/makespec/01-sourcesparser.pri)
|
|
||||||
|
|
||||||
# Main config
|
|
||||||
Qv2rayAddSource(base, _, GlobalInstances, hpp)
|
|
||||||
Qv2rayAddSource(base, _, JsonHelpers, hpp)
|
|
||||||
Qv2rayAddSource(base, _, Qv2rayBase, hpp)
|
|
||||||
Qv2rayAddSource(base, _, Qv2rayFeatures, hpp)
|
|
||||||
Qv2rayAddSource(base, _, Qv2rayLog, cpp, hpp)
|
|
||||||
Qv2rayAddSource(base, models, CoreObjectModels, hpp)
|
|
||||||
Qv2rayAddSource(base, models, QvConfigModel, hpp)
|
|
||||||
Qv2rayAddSource(base, models, QvConfigIdentifier, hpp)
|
|
||||||
Qv2rayAddSource(base, models, QvSafeType, hpp)
|
|
||||||
Qv2rayAddSource(base, models, QvRuntimeConfig, hpp)
|
|
||||||
Qv2rayAddSource(base, models, QvStartupConfig, hpp)
|
|
||||||
Qv2rayAddSource(common, _, CommandArgs, cpp, hpp)
|
|
||||||
Qv2rayAddSource(common, _, HTTPRequestHelper, cpp, hpp)
|
|
||||||
Qv2rayAddSource(common, _, LogHighlighter, cpp, hpp)
|
|
||||||
Qv2rayAddSource(common, _, QJsonModel, cpp, hpp)
|
|
||||||
Qv2rayAddSource(common, _, QvHelpers, cpp, hpp)
|
|
||||||
Qv2rayAddSource(common, _, QvTranslator, hpp)
|
|
||||||
Qv2rayAddSource(components, autolaunch, QvAutoLaunch, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, pac, QvGFWPACConverter, cpp)
|
|
||||||
Qv2rayAddSource(components, pac, QvPACHandler, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, plugins/toolbar, QvToolbar, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, plugins/toolbar, QvToolbar_linux, cpp)
|
|
||||||
Qv2rayAddSource(components, plugins/toolbar, QvToolbar_win, cpp)
|
|
||||||
Qv2rayAddSource(components, proxy, QvProxyConfigurator, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, tcping, QvTCPing, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, speedchart, speedwidget, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, speedchart, speedplotview, cpp, hpp)
|
|
||||||
Qv2rayAddSource(components, geosite, QvGeositeReader, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, config, ConfigBackend, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, config, ConfigUpgrade, cpp)
|
|
||||||
Qv2rayAddSource(core, connection, ConnectionIO, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, connection, Generation, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, connection, Serialization, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, _, CoreUtils, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, kernel, KernelInteractions, cpp, hpp)
|
|
||||||
Qv2rayAddSource(core, kernel, APIBackend, cpp, hpp)
|
|
||||||
Qv2rayAddSource(ui, editors, w_InboundEditor, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, editors, w_JsonEditor, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, editors, w_OutboundEditor, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, editors, w_RoutesEditor, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, editors, w_RoutesEditor_extra, cpp)
|
|
||||||
Qv2rayAddSource(ui, nodemodels, InboundNodeModel, cpp, hpp)
|
|
||||||
Qv2rayAddSource(ui, nodemodels, OutboundNodeModel, cpp, hpp)
|
|
||||||
Qv2rayAddSource(ui, nodemodels, RuleNodeModel, cpp, hpp)
|
|
||||||
Qv2rayAddSource(ui, nodemodels, NodeModelsBase, hpp)
|
|
||||||
Qv2rayAddSource(ui, messaging, QvMessageBus, cpp, hpp)
|
|
||||||
Qv2rayAddSource(ui, _, w_ExportConfig, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, _, w_ImportConfig, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, _, w_MainWindow, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, _, w_MainWindow_extra, cpp)
|
|
||||||
Qv2rayAddSource(ui, _, w_PreferencesWindow, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, _, w_ScreenShot_Core, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, _, w_SubscriptionManager, cpp, hpp, ui)
|
|
||||||
Qv2rayAddSource(ui, widgets, StreamSettingsWidget, cpp, hpp, ui)
|
|
||||||
|
|
||||||
SOURCES += $$PWD/src/main.cpp
|
|
||||||
HEADERS +=
|
|
||||||
FORMS +=
|
|
||||||
INCLUDEPATH += $$PWD/src
|
|
||||||
RESOURCES += $$PWD/resources.qrc
|
|
||||||
ICON = $$PWD/assets/icons/qv2ray.icns
|
|
||||||
RC_ICONS += $$PWD/assets/icons/qv2ray.ico
|
|
||||||
|
|
||||||
include($$PWD/makespec/02-translations.pri)
|
|
||||||
|
|
||||||
unix {
|
|
||||||
include($$PWD/makespec/03-unix.pri)
|
|
||||||
# Sub-process of Qv2ray per-OS build
|
|
||||||
!macx: include($$PWD/makespec/04-unix-linux.pri)
|
|
||||||
macx: include($$PWD/makespec/04-unix-macOS.pri)
|
|
||||||
} else {
|
|
||||||
include($$PWD/makespec/03-Windows.pri)
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------ Begin checking protobuf domain list headers.
|
|
||||||
!exists($$PWD/libs/gen/v2ray_geosite.pb.cc) || !exists($$PWD/libs/gen/v2ray_geosite.pb.cc) {
|
|
||||||
Qv2rayQMakeError("Protobuf headers for v2ray geosite is missing.")
|
|
||||||
}
|
|
||||||
|
|
||||||
SOURCES += $$PWD/libs/gen/v2ray_geosite.pb.cc
|
|
||||||
HEADERS += $$PWD/libs/gen/v2ray_geosite.pb.h
|
|
||||||
|
|
||||||
# General header and source files for gRPC and libQvb
|
|
||||||
message(" ")
|
|
||||||
use_grpc {
|
|
||||||
DEFINES += WITH_LIB_GRPCPP
|
|
||||||
message("Qv2ray will use gRPC as API backend")
|
|
||||||
|
|
||||||
!exists($$PWD/libs/gen/v2ray_api.grpc.pb.h) || !exists($$PWD/libs/gen/v2ray_api.grpc.pb.cc) || !exists($$PWD/libs/gen/v2ray_api.pb.h) || !exists($$PWD/libs/gen/v2ray_api.pb.cc) {
|
|
||||||
Qv2rayQMakeError("gRPC and protobuf headers for v2ray API is missing.")
|
|
||||||
}
|
|
||||||
|
|
||||||
SOURCES += $$PWD/libs/gen/v2ray_api.pb.cc $$PWD/libs/gen/v2ray_api.grpc.pb.cc
|
|
||||||
HEADERS += $$PWD/libs/gen/v2ray_api.pb.h $$PWD/libs/gen/v2ray_api.grpc.pb.h
|
|
||||||
} else {
|
|
||||||
message("Qv2ray will use libqvb as API backend")
|
|
||||||
!exists($$PWD/libs/libqvb/build/libqvb.h) {
|
|
||||||
Qv2rayQMakeError("libs/libqvb/build/libqvb.h is missing.")
|
|
||||||
}
|
|
||||||
HEADERS += $$PWD/libs/libqvb/build/libqvb.h
|
|
||||||
}
|
|
||||||
|
|
||||||
# Misc steps to build Qv2ray.
|
|
||||||
include($$PWD/makespec/99-others.pri)
|
|
||||||
|
|
||||||
message(" ")
|
|
||||||
message("This Qv2ray build contains: ")
|
|
||||||
message(" --> $${size(SOURCES)} source files")
|
|
||||||
message(" --> $${size(HEADERS)} header files")
|
|
||||||
message(" --> $${size(FORMS)} ui files")
|
|
||||||
message(" --> $${size(TRANSLATIONS)} translation files")
|
|
||||||
message(" --> $${size(EXTRA_TRANSLATIONS)} extra translation files")
|
|
||||||
message(" ")
|
|
||||||
message("Finished configuring Qv2ray project. Build output will be at:" $$OUT_PWD)
|
|
||||||
message("Type 'make' or 'nmake' to start building Qv2ray")
|
|
50
_clang-format
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
BasedOnStyle: Microsoft
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
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
|
||||||
|
|
||||||
|
...
|
BIN
assets/icons/ui_dark/connect.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
1
assets/icons/ui_dark/design/locate.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg t="1583066988697" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7967" width="128" height="128"><path d="M524.474182 1024l-24.901818 0-6.958545-10.053818C481.652364 998.097455 223.837091 624.407273 187.485091 540.974545c-37.026909-84.968727-43.52-110.917818-43.52-173.428364C143.965091 164.864 308.852364 0 511.511273 0c203.682909 0 368.546909 164.864 368.546909 367.546182 0 62.533818-6.493091 88.459636-43.52 173.428364-36.375273 83.432727-294.144 457.099636-305.082182 472.971636L524.474182 1024zM512.512 46.545455C334.498909 46.545455 190.510545 190.557091 190.510545 367.546182c0 56.064 4.817455 74.891636 39.656727 154.833455 29.090909 66.792727 220.485818 348.020364 281.856 437.620364C573.416727 870.4 764.741818 589.172364 793.832727 522.379636c34.839273-79.965091 39.656727-98.769455 39.656727-154.833455C833.489455 190.557091 689.501091 46.545455 512.512 46.545455z" p-id="7968" fill="#e6e6e6"></path><path d="M512 565.364364c-93.835636 0-170.193455-76.334545-170.193455-170.193455S418.164364 225.000727 512 225.000727s170.193455 76.334545 170.193455 170.193455S605.835636 565.364364 512 565.364364zM512 271.546182c-68.189091 0-123.648 55.458909-123.648 123.648S443.810909 518.818909 512 518.818909s123.648-55.458909 123.648-123.648S580.189091 271.546182 512 271.546182z" p-id="7969" fill="#e6e6e6"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
assets/icons/ui_dark/design/sort.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583165428350" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2286" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M128 553.984l0-84.010667 512 0 0 84.010667-512 0zM128 256l768 0 0 86.016-768 0 0-86.016zM128 768l0-86.016 256 0 0 86.016-256 0z" p-id="2287" fill="#e6e6e6"></path></svg>
|
After Width: | Height: | Size: 546 B |
@ -17,8 +17,8 @@
|
|||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg8"
|
id="svg8"
|
||||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||||
sodipodi:docname="Qv2ray_System_Tray_Light.svg"
|
sodipodi:docname="tray.svg"
|
||||||
inkscape:export-filename="/home/axionl/Desktop/Qv2ray_Design/qv2ray.png"
|
inkscape:export-filename=""
|
||||||
inkscape:export-xdpi="558.54999"
|
inkscape:export-xdpi="558.54999"
|
||||||
inkscape:export-ydpi="558.54999">
|
inkscape:export-ydpi="558.54999">
|
||||||
<defs
|
<defs
|
||||||
@ -171,17 +171,17 @@
|
|||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="22.627417"
|
inkscape:zoom="22.627417"
|
||||||
inkscape:cx="5.9585184"
|
inkscape:cx="-1.0241611"
|
||||||
inkscape:cy="11.144438"
|
inkscape:cy="11.144438"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="true"
|
showgrid="true"
|
||||||
units="px"
|
units="px"
|
||||||
inkscape:window-width="1874"
|
inkscape:window-width="1316"
|
||||||
inkscape:window-height="1050"
|
inkscape:window-height="814"
|
||||||
inkscape:window-x="46"
|
inkscape:window-x="270"
|
||||||
inkscape:window-y="30"
|
inkscape:window-y="90"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="0"
|
||||||
inkscape:snap-bbox="true"
|
inkscape:snap-bbox="true"
|
||||||
inkscape:bbox-paths="true"
|
inkscape:bbox-paths="true"
|
||||||
inkscape:bbox-nodes="true"
|
inkscape:bbox-nodes="true"
|
||||||
@ -271,7 +271,7 @@
|
|||||||
<path
|
<path
|
||||||
id="path1962"
|
id="path1962"
|
||||||
transform="matrix(0.26458333,0,0,0.26458333,1.9173392,290.74464)"
|
transform="matrix(0.26458333,0,0,0.26458333,1.9173392,290.74464)"
|
||||||
style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
d="M 7,11 6.2929688,11.707031 8.5859375,14 H 18 V 13 H 9 Z M 6.2929688,11.707031 5,13 H 4 v 1 H 5.4140625 L 7,12.414062 Z M 3,3 V 18.999988 H 19 V 3 Z M 3.9999999,3.9999875 H 18 V 18 H 3.9999999 Z" />
|
d="M 7,11 6.2929688,11.707031 8.5859375,14 H 18 V 13 H 9 Z M 6.2929688,11.707031 5,13 H 4 v 1 H 5.4140625 L 7,12.414062 Z M 3,3 V 18.999988 H 19 V 3 Z M 3.9999999,3.9999875 H 18 V 18 H 3.9999999 Z" />
|
||||||
<rect
|
<rect
|
||||||
style="opacity:0.5;fill:none;fill-opacity:1;stroke:none;stroke-width:0.04583338;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
style="opacity:0.5;fill:none;fill-opacity:1;stroke:none;stroke-width:0.04583338;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
@ -283,7 +283,7 @@
|
|||||||
inkscape:export-xdpi="64"
|
inkscape:export-xdpi="64"
|
||||||
inkscape:export-ydpi="64" />
|
inkscape:export-ydpi="64" />
|
||||||
<path
|
<path
|
||||||
style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="fill:#ececec;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
d="m 4.5631726,292.06756 -0.2645834,0.26459 v 0.52916 l 0.2645834,-0.26458 v 0.26458 0.52917 l 0.5291666,0.79375 0.5291667,1.32291 v -0.79374 l 0.2645833,-0.26459 -0.2645833,-0.52916 v -0.79375 l -0.2645833,-0.52917 z"
|
d="m 4.5631726,292.06756 -0.2645834,0.26459 v 0.52916 l 0.2645834,-0.26458 v 0.26458 0.52917 l 0.5291666,0.79375 0.5291667,1.32291 v -0.79374 l 0.2645833,-0.26459 -0.2645833,-0.52916 v -0.79375 l -0.2645833,-0.52917 z"
|
||||||
id="path1934"
|
id="path1934"
|
||||||
inkscape:connector-curvature="0"
|
inkscape:connector-curvature="0"
|
||||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
BIN
assets/icons/ui_dark/locate.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/icons/ui_dark/sort.png
Normal file
After Width: | Height: | Size: 304 B |
BIN
assets/icons/ui_dark/stop.png
Normal file
After Width: | Height: | Size: 508 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
assets/icons/ui_light/connect.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
1
assets/icons/ui_light/design/locate.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg t="1583066988697" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7967" width="128" height="128"><path d="M524.474182 1024l-24.901818 0-6.958545-10.053818C481.652364 998.097455 223.837091 624.407273 187.485091 540.974545c-37.026909-84.968727-43.52-110.917818-43.52-173.428364C143.965091 164.864 308.852364 0 511.511273 0c203.682909 0 368.546909 164.864 368.546909 367.546182 0 62.533818-6.493091 88.459636-43.52 173.428364-36.375273 83.432727-294.144 457.099636-305.082182 472.971636L524.474182 1024zM512.512 46.545455C334.498909 46.545455 190.510545 190.557091 190.510545 367.546182c0 56.064 4.817455 74.891636 39.656727 154.833455 29.090909 66.792727 220.485818 348.020364 281.856 437.620364C573.416727 870.4 764.741818 589.172364 793.832727 522.379636c34.839273-79.965091 39.656727-98.769455 39.656727-154.833455C833.489455 190.557091 689.501091 46.545455 512.512 46.545455z" p-id="7968" fill="#515151"></path><path d="M512 565.364364c-93.835636 0-170.193455-76.334545-170.193455-170.193455S418.164364 225.000727 512 225.000727s170.193455 76.334545 170.193455 170.193455S605.835636 565.364364 512 565.364364zM512 271.546182c-68.189091 0-123.648 55.458909-123.648 123.648S443.810909 518.818909 512 518.818909s123.648-55.458909 123.648-123.648S580.189091 271.546182 512 271.546182z" p-id="7969" fill="#515151"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
assets/icons/ui_light/design/sort.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583165428350" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2286" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M128 553.984l0-84.010667 512 0 0 84.010667-512 0zM128 256l768 0 0 86.016-768 0 0-86.016zM128 768l0-86.016 256 0 0 86.016-256 0z" p-id="2287" fill="#2c2c2c"></path></svg>
|
After Width: | Height: | Size: 546 B |
BIN
assets/icons/ui_light/locate.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/icons/ui_light/sort.png
Normal file
After Width: | Height: | Size: 303 B |
BIN
assets/icons/ui_light/stop.png
Normal file
After Width: | Height: | Size: 511 B |
26
assets/info.plist
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>qv2ray</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>Created by Qv2ray development team</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>qv2ray.icns</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.qv2ray.qv2ray</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.12</string>
|
||||||
|
<key>NOTE</key>
|
||||||
|
<string>Qv2ray</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
48
assets/qv2ray.rc
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#ifdef _WIN32
|
||||||
|
#include <WINDOWS.H>
|
||||||
|
#include <WINGDI.H>
|
||||||
|
#include <WINUSER.H>
|
||||||
|
|
||||||
|
#define xstr(s) str(s)
|
||||||
|
#define str(s) #s
|
||||||
|
|
||||||
|
#define VER_FILEVERSION QV2RAY_VERSION_MAJOR,QV2RAY_VERSION_MINOR,QV2RAY_VERSION_BUGFIX,QV2RAY_VERSION_BUILD
|
||||||
|
#define VER_FILEVERSION_STR xstr(VER_FILEVERSION)
|
||||||
|
#define VER_PRODUCTVERSION VER_FILEVERSION
|
||||||
|
#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
|
||||||
|
|
||||||
|
IDI_ICON1 ICON DISCARDABLE "assets\\icons\\qv2ray.ico"
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION VER_FILEVERSION
|
||||||
|
PRODUCTVERSION VER_PRODUCTVERSION
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS VS_FF_DEBUG
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS VOS__WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "Qv2ray Workgroup\0"
|
||||||
|
VALUE "FileDescription", "Qv2ray, a cross-platform v2ray GUI client.\0"
|
||||||
|
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||||
|
VALUE "LegalCopyright", "Qv2ray is being distributed under GPLv3\0"
|
||||||
|
VALUE "OriginalFilename", "qv2ray.exe\0"
|
||||||
|
VALUE "ProductName", "Qv2ray\0"
|
||||||
|
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
/* End of Version info */
|
||||||
|
#endif
|
50
cmake/backend.cmake
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
if(NOT USE_LIBQVB)
|
||||||
|
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
|
||||||
|
|
||||||
|
find_library(GRPC_LIBRARY NAMES grpc)
|
||||||
|
find_library(GRPCPP_LIBRARY NAMES grpc++)
|
||||||
|
|
||||||
|
if(UNIX AND NOT APPLE)
|
||||||
|
set(QV2RAY_BACKEND_LIBRARIES ${GRPCPP_LIBRARY} ${GRPC_LIBRARY})
|
||||||
|
elseif(APPLE)
|
||||||
|
find_library(UPB_LIBRARY NAMES upb)
|
||||||
|
set(QV2RAY_BACKEND_LIBRARIES ${GRPCPP_LIBRARY} ${GRPC_LIBRARY} ${UPB_LIBRARY})
|
||||||
|
elseif(WIN32)
|
||||||
|
find_library(ADDRESS_SORTING NAMES address_sorting)
|
||||||
|
find_library(ABSL_BASE NAMES absl_base)
|
||||||
|
find_library(ABSL_STR NAMES absl_strings)
|
||||||
|
find_library(ABSL_THROW_DELEGATE NAMES absl_throw_delegate)
|
||||||
|
find_library(GPR_LIBRARY NAMES gpr)
|
||||||
|
find_library(ZLIB_LIBRARY NAMES zlib)
|
||||||
|
find_library(UPB_LIBRARY NAMES upb)
|
||||||
|
find_library(CARES_LIBRARY NAMES cares)
|
||||||
|
find_library(GRPC_INSECURE_LIBRARY NAMES grpc_unsecure)
|
||||||
|
find_library(GRPCPP_INSECURE_LIBRARY NAMES grpc++_unsecure)
|
||||||
|
set(QV2RAY_BACKEND_LIBRARIES ${GRPC_INSECURE_LIBRARY} ${GRPCPP_INSECURE_LIBRARY} ${ABSL_BASE} ${ABSL_STR} ${ADDRESS_SORTING}
|
||||||
|
${ABSL_THROW_DELEGATE} ${GPR_LIBRARY} ${ZLIB_LIBRARY} ${UPB_LIBRARY} ${CARES_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(API_PROTO "${CMAKE_SOURCE_DIR}/tools/v2ray_api.proto")
|
||||||
|
set(API_PROTO_PATH "${CMAKE_SOURCE_DIR}/tools")
|
||||||
|
set(API_PROTO_SRCS "${CMAKE_CURRENT_BINARY_DIR}/v2ray_api.pb.cc")
|
||||||
|
set(API_PROTO_HDRS "${CMAKE_CURRENT_BINARY_DIR}/v2ray_api.pb.h")
|
||||||
|
set(API_GRPC_SRCS "${CMAKE_CURRENT_BINARY_DIR}/v2ray_api.grpc.pb.cc")
|
||||||
|
set(API_GRPC_HDRS "${CMAKE_CURRENT_BINARY_DIR}/v2ray_api.grpc.pb.h")
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${API_GRPC_SRCS}" "${API_GRPC_HDRS}" "${API_PROTO_HDRS}" "${API_PROTO_SRCS}"
|
||||||
|
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
|
||||||
|
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
-I "${API_PROTO_PATH}"
|
||||||
|
--plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}"
|
||||||
|
"${API_PROTO}"
|
||||||
|
DEPENDS "${API_PROTO}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_definitions(-DBACKEND_LIBQVB)
|
||||||
|
if(UNIX AND NOT APPLE)
|
||||||
|
set(QV2RAY_BACKEND_LIBRARIES ${CMAKE_SOURCE_DIR}/libs/libqvb-linux64.a)
|
||||||
|
elseif(APPLE)
|
||||||
|
set(QV2RAY_BACKEND_LIBRARIES ${CMAKE_SOURCE_DIR}/libs/libqvb-darwin.a)
|
||||||
|
endif()
|
||||||
|
endif()
|
1
cmake/cpp-httplib.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
set(cpp-httplib_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/3rdparty/cpp-httplib)
|
23
cmake/deployment.cmake
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Directories to look for dependencies
|
||||||
|
set(DIRS "${CMAKE_BINARY_DIR}")
|
||||||
|
|
||||||
|
# Path used for searching by FIND_XXX(), with appropriate suffixes added
|
||||||
|
if(CMAKE_PREFIX_PATH)
|
||||||
|
foreach(dir ${CMAKE_PREFIX_PATH})
|
||||||
|
list(APPEND DIRS "${dir}/bin" "${dir}/lib")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Append Qt's lib folder which is two levels above Qt5Widgets_DIR
|
||||||
|
list(APPEND DIRS "${Qt5Widgets_DIR}/../..")
|
||||||
|
list(APPEND DIRS "/usr/local/lib")
|
||||||
|
list(APPEND DIRS "/usr/lib")
|
||||||
|
|
||||||
|
include(InstallRequiredSystemLibraries)
|
||||||
|
|
||||||
|
message(STATUS "APPS: ${APPS}")
|
||||||
|
message(STATUS "QT_PLUGINS: ${QT_PLUGINS}")
|
||||||
|
message(STATUS "DIRS: ${DIRS}")
|
||||||
|
|
||||||
|
install(CODE "include(BundleUtilities)
|
||||||
|
fixup_bundle(\"${APPS}\" \"${QT_PLUGINS}\" \"${DIRS}\")")
|
5
cmake/protobuf.cmake
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
find_package(Protobuf REQUIRED)
|
||||||
|
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_SOURCE_DIR}/tools/v2ray_geosite.proto)
|
||||||
|
set(QV2RAY_PROTOBUF_LIBRARY
|
||||||
|
protobuf::libprotobuf
|
||||||
|
)
|
69
cmake/qnodeeditor.cmake
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
set(QNODEEDITOR_DIR ${CMAKE_SOURCE_DIR}/3rdparty/QNodeEditor)
|
||||||
|
add_definitions(-DNODE_EDITOR_SHARED -DNODE_EDITOR_EXPORTS)
|
||||||
|
set(QNODEEDITOR_SOURCES
|
||||||
|
${QNODEEDITOR_DIR}/src/Connection.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/ConnectionBlurEffect.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/ConnectionGeometry.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/ConnectionGraphicsObject.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/ConnectionPainter.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/ConnectionState.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/ConnectionStyle.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/DataModelRegistry.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/FlowScene.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/FlowView.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/FlowViewStyle.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/Node.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodeConnectionInteraction.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodeDataModel.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodeGeometry.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodeGraphicsObject.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodePainter.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodeState.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/NodeStyle.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/Properties.cpp
|
||||||
|
${QNODEEDITOR_DIR}/src/StyleCollection.cpp
|
||||||
|
)
|
||||||
|
set(QNODEEDITOR_INCLUDE_PATH
|
||||||
|
${QNODEEDITOR_DIR}/src/
|
||||||
|
${QNODEEDITOR_DIR}/include/
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal
|
||||||
|
)
|
||||||
|
|
||||||
|
set(HEADERS_TO_MOC
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/Compiler.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/Connection.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/ConnectionGeometry.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/ConnectionGraphicsObject.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/ConnectionState.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/ConnectionStyle.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/DataModelRegistry.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/Export.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/FlowScene.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/FlowView.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/FlowViewStyle.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/memory.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/Node.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodeData.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodeDataModel.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodeGeometry.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodeGraphicsObject.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodePainterDelegate.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodeState.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/NodeStyle.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/OperatingSystem.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/PortType.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/QStringStdHash.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/QUuidStdHash.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/Serializable.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/Style.hpp
|
||||||
|
${QNODEEDITOR_DIR}/include/nodes/internal/TypeConverter.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
qt5_wrap_cpp(QNODEEDITOR_SOURCES
|
||||||
|
${HEADERS_TO_MOC}
|
||||||
|
TARGET qv2ray
|
||||||
|
OPTIONS --no-notes # Don't display a note for the headers which don't produce a moc_*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(QNODEEDITOR_QRC_RESOURCES ${QNODEEDITOR_DIR}/resources/QNodeEditor_resources.qrc)
|
97
cmake/qzxing.cmake
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
add_definitions(-DQZXING_LIBRARY -DZXING_ICONV_CONST -DDISABLE_LIBRARY_FEATURES -DENABLE_DECODER_QR_CODE -DENABLE_ENCODER_QR_CODE -DENABLE_ENCODER_GENERIC)
|
||||||
|
set(QZXING_DIR ${CMAKE_SOURCE_DIR}/3rdparty/qzxing/src)
|
||||||
|
set(QZXING_SOURCES
|
||||||
|
${QZXING_DIR}/CameraImageWrapper.cpp
|
||||||
|
${QZXING_DIR}/QZXing.cpp
|
||||||
|
${QZXING_DIR}/ImageHandler.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/ResultIO.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/InvertedLuminanceSource.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/ChecksumException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/ResultPointCallback.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/ResultPoint.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/Result.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/ResultMetadata.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/Reader.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/MultiFormatReader.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/LuminanceSource.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/FormatException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/Exception.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/DecodeHints.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/BinaryBitmap.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/Binarizer.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/BarcodeFormat.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/ReaderException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/IllegalStateException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/NotFoundException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/WriterException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/Counted.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/StringUtils.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/Str.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/PerspectiveTransform.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/IllegalArgumentException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/HybridBinarizer.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/GridSampler.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/GreyscaleRotatedLuminanceSource.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/GreyscaleLuminanceSource.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/GlobalHistogramBinarizer.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/DetectorResult.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/DecoderResult.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/CharacterSetECI.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/BitSource.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/BitMatrix.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/BitArray.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/BitArrayIO.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/detector/WhiteRectangleDetector.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/detector/MonochromeRectangleDetector.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/reedsolomon/ReedSolomonException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/reedsolomon/ReedSolomonDecoder.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/reedsolomon/GenericGFPoly.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/reedsolomon/GenericGF.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/multi/MultipleBarcodeReader.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/multi/GenericMultipleBarcodeReader.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/multi/ByQuadrantReader.cpp
|
||||||
|
${QZXING_DIR}/zxing/bigint/BigUnsignedInABase.cc
|
||||||
|
${QZXING_DIR}/zxing/bigint/BigUnsigned.cc
|
||||||
|
${QZXING_DIR}/zxing/bigint/BigIntegerUtils.cc
|
||||||
|
${QZXING_DIR}/zxing/bigint/BigIntegerAlgorithms.cc
|
||||||
|
${QZXING_DIR}/zxing/bigint/BigInteger.cc
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/decoder/QRBitMatrixParser.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/decoder/QRDataBlock.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/decoder/QRDataMask.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/decoder/QRDecodedBitStreamParser.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/decoder/QRDecoder.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/detector/QRAlignmentPattern.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/detector/QRAlignmentPatternFinder.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/detector/QRDetector.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/detector/QRFinderPattern.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/detector/QRFinderPatternInfo.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/QRCodeReader.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/multi/qrcode/QRCodeMultiReader.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/multi/qrcode/detector/MultiFinderPatternFinder.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/multi/qrcode/detector/MultiDetector.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/encoder/ByteMatrix.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/encoder/QREncoder.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/encoder/MaskUtil.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/encoder/MatrixUtil.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/encoder/QRCode.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/QRVersion.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/QRFormatInformation.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/QRErrorCorrectionLevel.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/qrcode/decoder/QRMode.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/EncodeHint.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/UnsupportedEncodingException.cpp
|
||||||
|
${QZXING_DIR}/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.cpp
|
||||||
|
)
|
||||||
|
set(QZXING_INCLUDE_PATH
|
||||||
|
${QZXING_DIR}
|
||||||
|
${QZXING_DIR}/zxing
|
||||||
|
)
|
||||||
|
if(MSVC)
|
||||||
|
add_definitions(-D__STDC_LIMIT_MACROS)
|
||||||
|
list(APPEND QZXING_SOURCES ${QZXING_DIR}/zxing/win32/zxing/win_iconv.c)
|
||||||
|
list(APPEND QZXING_INCLUDE_PATH
|
||||||
|
${QZXING_DIR}/zxing/win32/zxing
|
||||||
|
${QZXING_DIR}/zxing/win32/zxing/msvc
|
||||||
|
)
|
||||||
|
endif()
|
6
cmake/singleapplication.cmake
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
add_definitions(-DQAPPLICATION_CLASS=QApplication)
|
||||||
|
set(SINGLEAPPLICATION_DIR ${CMAKE_SOURCE_DIR}/3rdparty/SingleApplication)
|
||||||
|
set(SINGLEAPPLICATION_SOURCES
|
||||||
|
${SINGLEAPPLICATION_DIR}/singleapplication.cpp
|
||||||
|
${SINGLEAPPLICATION_DIR}/singleapplication_p.cpp
|
||||||
|
)
|
4
cmake/translations.cmake
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
find_package(Qt5 COMPONENTS LinguistTools)
|
||||||
|
set(TRANSLATIONS_DIR ${CMAKE_SOURCE_DIR}/translations)
|
||||||
|
file(GLOB TRANSLATIONS_TS ${TRANSLATIONS_DIR}/**.ts)
|
||||||
|
qt5_add_translation(QM_FILES ${TRANSLATIONS_TS})
|
1
libs/puresource
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit bd4f9335bb89e7b1199282c685d49dd5ae4ce1fa
|
@ -1,48 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
message("Configuring Qv2ray Dependencies...")
|
|
||||||
|
|
||||||
defineTest(Qv2rayQMakeError) {
|
|
||||||
message(" ")
|
|
||||||
message("-----------------------------------------------")
|
|
||||||
message("Cannot continue: ")
|
|
||||||
message(" --> Qv2ray is not properly configured yet: ")
|
|
||||||
message(" $$ARGS")
|
|
||||||
message(" --> Please read the build wiki: https://github.com/Qv2ray/Qv2ray/wiki/Manually-Build-Qv2ray")
|
|
||||||
message("-----------------------------------------------")
|
|
||||||
message(" ")
|
|
||||||
warning("IF YOU THINK IT'S A MISTAKE, PLEASE OPEN AN ISSUE")
|
|
||||||
error("! ABORTING THE BUILD !")
|
|
||||||
message(" ")
|
|
||||||
}
|
|
||||||
|
|
||||||
CONFIG += enable_decoder_qr_code enable_encoder_qr_code
|
|
||||||
include($$PWD/../3rdparty/qzxing/src/QZXing-components.pri)
|
|
||||||
include($$PWD/../3rdparty/SingleApplication/singleapplication.pri)
|
|
||||||
include($$PWD/../3rdparty/QNodeEditor/QNodeEditor.pri)
|
|
||||||
|
|
||||||
#include(3rdparty/x2struct/x2struct.pri)
|
|
||||||
|
|
||||||
message("Adding QHttpServer Support")
|
|
||||||
message(" --> Adding qhttpserver")
|
|
||||||
HEADERS += \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpconnection.h \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttprequest.h \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpresponse.h \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpserver.h \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpserverapi.h \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpserverfwd.h
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpconnection.cpp \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttprequest.cpp \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpresponse.cpp \
|
|
||||||
$$PWD/../3rdparty/qhttpserver/src/qhttpserver.cpp
|
|
||||||
|
|
||||||
INCLUDEPATH += 3rdparty/qhttpserver/src/
|
|
||||||
|
|
||||||
message(" --> Adding http parser")
|
|
||||||
HEADERS += $$PWD/../3rdparty/qhttpserver/http-parser/http_parser.h
|
|
||||||
SOURCES += $$PWD/../3rdparty/qhttpserver/http-parser/http_parser.c
|
|
||||||
INCLUDEPATH += $$PWD/../3rdparty/qhttpserver/http-parser/
|
|
||||||
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
defineTest(Qv2rayAddFile) {
|
|
||||||
ext = $$take_last(ARGS)
|
|
||||||
filename = $${take_first(ARGS)}.$${ext}
|
|
||||||
qmake_debug: message("Qv2rayAddFile: filename: $$filename")
|
|
||||||
!exists($$filename) {
|
|
||||||
error("File: \"$$filename\" is not found, Qv2ray build preparation cannot continue")
|
|
||||||
}
|
|
||||||
equals(ext, "cpp") {
|
|
||||||
SOURCES += $$filename
|
|
||||||
} else {
|
|
||||||
equals(ext, "hpp") {
|
|
||||||
HEADERS += $$filename
|
|
||||||
} else {
|
|
||||||
equals(ext, "ui") {
|
|
||||||
FORMS += $$filename
|
|
||||||
} else {
|
|
||||||
error("Unknown extension: $${ext}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export(SOURCES)
|
|
||||||
export(HEADERS)
|
|
||||||
export(FORMS)
|
|
||||||
}
|
|
||||||
|
|
||||||
defineTest(Qv2rayAddSource) {
|
|
||||||
# Module Compnent Filename extlist
|
|
||||||
module = $$take_first(ARGS)
|
|
||||||
component = $$take_first(ARGS)
|
|
||||||
filename = $$take_first(ARGS)
|
|
||||||
extlist = $$ARGS
|
|
||||||
FILEPATH = "$$PWD/src/$${module}"
|
|
||||||
qmake_debug: message(Qv2rayAddSource: Adding \"$${filename}\" of module \"$${module}\", component \"$${component}\" to the project)
|
|
||||||
equals(component, "_") {
|
|
||||||
qmake_debug: message("Qv2rayAddSource: Component is empty, ignore")
|
|
||||||
FILEPATH += "/$${filename}"
|
|
||||||
FILEPATH=$$join(FILEPATH)
|
|
||||||
} else {
|
|
||||||
FILEPATH += "/$${component}/$${filename}"
|
|
||||||
FILEPATH=$$join(FILEPATH)
|
|
||||||
}
|
|
||||||
qmake_debug: message("Qv2rayAddSource: filepath: $${FILEPATH}, extlist: $${extlist}")
|
|
||||||
for(iterate, extlist) {
|
|
||||||
Qv2rayAddFile($$FILEPATH, $$iterate)
|
|
||||||
}
|
|
||||||
export(SOURCES)
|
|
||||||
export(HEADERS)
|
|
||||||
export(FORMS)
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
message("Looking for language support.")
|
|
||||||
QM_FILES_RESOURCE_PREFIX = "translations"
|
|
||||||
for(var, $$list($$files("$$PWD/../translations/*.ts", true))) {
|
|
||||||
LOCALE_FILENAME = $$basename(var)
|
|
||||||
message(" --> Found:" $$LOCALE_FILENAME)
|
|
||||||
!equals(LOCALE_FILENAME, "en_US.ts") {
|
|
||||||
# ONLY USED IN LRELEASE CONTEXT
|
|
||||||
# en_US is not EXTRA...
|
|
||||||
EXTRA_TRANSLATIONS += $$PWD/../translations/$$LOCALE_FILENAME
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TRANSLATIONS += $$PWD/../translations/en_US.ts
|
|
||||||
message("Qv2ray will build with" $${replace(EXTRA_TRANSLATIONS, "$$PWD/../translations/", "")} and $${replace(TRANSLATIONS, "$$PWD/../translations/", "")})
|
|
||||||
|
|
||||||
qmake_lupdate {
|
|
||||||
message(" ")
|
|
||||||
message("Running lupdate...")
|
|
||||||
message("TRANSLATIONS: $$TRANSLATIONS")
|
|
||||||
lupdate_output = $$system(lupdate -no-ui-lines $$SOURCES $$HEADERS $$FORMS -ts $$TRANSLATIONS)
|
|
||||||
message(" $$lupdate_output")
|
|
||||||
message("lupdate finished.")
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
message("Configuring for Windows environment")
|
|
||||||
QMAKE_CXXFLAGS += /MP /wo4251
|
|
||||||
DEFINES += QHTTPSERVER_EXPORT
|
|
||||||
|
|
||||||
CONFIG += Qv2ray_Windows use_grpc
|
|
||||||
!contains(QMAKE_TARGET.arch, x86_64) {
|
|
||||||
CONFIG+=Qv2ray_win32
|
|
||||||
GRPC_DEPS_PATH=$$PWD/../libs/x86-windows
|
|
||||||
#
|
|
||||||
!no_generate_headers: message(" --> Generating gRPC and protobuf headers for Windows x86")
|
|
||||||
!no_generate_headers: system("$$PWD/../tools/win32-generate-pb.bat")
|
|
||||||
} else {
|
|
||||||
CONFIG+=Qv2ray_win64
|
|
||||||
GRPC_DEPS_PATH=$$PWD/../libs/x64-windows
|
|
||||||
#
|
|
||||||
!no_generate_headers: message(" --> Generating gRPC and protobuf headers for Windows x64")
|
|
||||||
!no_generate_headers: system("$$PWD/../tools/win64-generate-pb.bat")
|
|
||||||
}
|
|
||||||
|
|
||||||
message(" --> Applying a hack for protobuf header")
|
|
||||||
DEFINES += _WIN32_WINNT=0x600
|
|
||||||
|
|
||||||
DEPENDPATH += $$GRPC_DEPS_PATH/include
|
|
||||||
INCLUDEPATH += $$GRPC_DEPS_PATH/include
|
|
||||||
|
|
||||||
message(" --> Setting up target descriptions")
|
|
||||||
QMAKE_TARGET_DESCRIPTION = "Qv2ray, a cross-platform v2ray GUI client."
|
|
||||||
QMAKE_TARGET_PRODUCT = "Qv2ray"
|
|
||||||
|
|
||||||
Qv2ray_debug: GRPC_LIB_PATH=$$GRPC_DEPS_PATH/debug
|
|
||||||
Qv2ray_release: GRPC_LIB_PATH=$$GRPC_DEPS_PATH
|
|
||||||
|
|
||||||
message(" --> WIN32: Linking against gRPC library: $$GRPC_LIB_PATH")
|
|
||||||
Qv2ray_debug: LIBS += -L$$GRPC_LIB_PATH/lib/ -laddress_sorting -lcares -lgrpc++_unsecure -lupb -lzlibd -lgrpc_unsecure -lgpr -labsl_base -labsl_strings -labsl_throw_delegate
|
|
||||||
Qv2ray_release: LIBS += -L$$GRPC_LIB_PATH/lib/ -laddress_sorting -lcares -lgrpc++_unsecure -lupb -lzlib -lgrpc_unsecure -lgpr -labsl_base -labsl_strings -labsl_throw_delegate
|
|
||||||
|
|
||||||
message(" --> WIN32: Linking against protobuf library: $$GRPC_LIB_PATH")
|
|
||||||
Qv2ray_release: LIBS += -lmsvcrt -L$$GRPC_LIB_PATH/lib/ -llibprotobuf
|
|
||||||
Qv2ray_debug: LIBS += -lmsvcrtd -L$$GRPC_LIB_PATH/lib/ -llibprotobufd
|
|
||||||
|
|
||||||
message(" --> Linking against winHTTP and winSock2.")
|
|
||||||
LIBS += -lwinhttp -lwininet -lws2_32 -luser32
|
|
@ -1,28 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
win32: Qv2rayQMakeError("Do not include this file in Windows platform.")
|
|
||||||
|
|
||||||
# For Linux and macOS
|
|
||||||
message("Configuring for unix-like environment")
|
|
||||||
|
|
||||||
message(" --> Setting up QMAKE_CXXFLAGS")
|
|
||||||
QMAKE_CXXFLAGS += -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable
|
|
||||||
|
|
||||||
# macOS homebrew include path
|
|
||||||
message(" --> Adding local include folder to search path")
|
|
||||||
INCLUDEPATH += /usr/local/include/
|
|
||||||
|
|
||||||
# For protobuf in linux and macOS
|
|
||||||
message(" --> Linking against protobuf library.")
|
|
||||||
LIBS += -L/usr/local/lib -lprotobuf
|
|
||||||
|
|
||||||
message(" --> Generating geosite headers for Unix")
|
|
||||||
system("$$PWD/../tools/unix-generate-geosite.sh $$PWD")
|
|
||||||
|
|
||||||
use_grpc {
|
|
||||||
no_generate_headers {
|
|
||||||
message(" --> Skipped generation of protobuf and/or gRPC header files")
|
|
||||||
} else {
|
|
||||||
message(" --> Generating gRPC and protobuf headers for Unix")
|
|
||||||
system("$$PWD/../tools/unix-generate-api.sh $$PWD")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
message("Configuring Qv2ray build for Linux")
|
|
||||||
isEmpty(PREFIX) {
|
|
||||||
PREFIX=/usr/local
|
|
||||||
}
|
|
||||||
|
|
||||||
use_grpc {
|
|
||||||
# For gRPC and protobuf in linux
|
|
||||||
message(" --> Linking against gRPC and protobuf library.")
|
|
||||||
LIBS += -L/usr/local/lib -lgrpc++ -lgrpc
|
|
||||||
} else {
|
|
||||||
message(" --> Linking libqvb static library, for Linux platform.")
|
|
||||||
LIBS += -L$$PWD/../libs/ -lqvb-linux64
|
|
||||||
}
|
|
||||||
|
|
||||||
message(" --> Generating desktop dependency.")
|
|
||||||
desktop.files += $$PWD/../assets/qv2ray.desktop
|
|
||||||
desktop.path = $$PREFIX/share/applications/
|
|
||||||
|
|
||||||
message(" --> Generating icons dependency.")
|
|
||||||
icon.files += $$PWD/../assets/icons/qv2ray.png
|
|
||||||
icon.path = $$PREFIX/share/icons/hicolor/256x256/apps/
|
|
||||||
|
|
||||||
target.path = $$PREFIX/bin/
|
|
||||||
INSTALLS += target desktop icon
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
|
|
||||||
# For Linux and macOS
|
|
||||||
message("Configuring for macOS specific environment")
|
|
||||||
LIBS += -framework Carbon -framework Cocoa
|
|
||||||
|
|
||||||
use_grpc: error("The use of gRPC backend is not supported on macOS platform.")
|
|
||||||
|
|
||||||
message(" --> Linking libqvb static library and Security framework, for macOS platform.")
|
|
||||||
LIBS += -L$$PWD/../libs/ -lqvb-darwin
|
|
||||||
LIBS += -framework Security
|
|
@ -1,39 +0,0 @@
|
|||||||
message(" ")
|
|
||||||
with_metainfo {
|
|
||||||
message(" --> Generating metainfo dependency.")
|
|
||||||
appdataXml.files += ./assets/qv2ray.metainfo.xml
|
|
||||||
appdataXml.path = $$PREFIX/share/metainfo/
|
|
||||||
INSTALLS += appdataXml
|
|
||||||
DEFINES += WITH_FLATHUB_CONFIG_PATH
|
|
||||||
}
|
|
||||||
|
|
||||||
# Automatically increase build number.
|
|
||||||
no_increase_build_number | qmake_lupdate {
|
|
||||||
message("QV2RAY_BUILD_VERSION will not be increased")
|
|
||||||
} else {
|
|
||||||
QV2RAY_BUILD_VERSION = $$num_add($$QV2RAY_BUILD_VERSION, 1)
|
|
||||||
write_file($$PWD/BUILDVERSION, QV2RAY_BUILD_VERSION)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Qv2ray manual build info
|
|
||||||
!no_build_info {
|
|
||||||
_QV2RAY_BUILD_INFO_STR_=$$getenv(_QV2RAY_BUILD_INFO_)
|
|
||||||
_QV2RAY_BUILD_EXTRA_INFO_STR_=$$getenv(_QV2RAY_BUILD_EXTRA_INFO_)
|
|
||||||
|
|
||||||
isEmpty(_QV2RAY_BUILD_INFO_STR_) {
|
|
||||||
_QV2RAY_BUILD_INFO_STR_ = "Qv2ray from manual build"
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty(_QV2RAY_BUILD_EXTRA_INFO_STR_) {
|
|
||||||
_QV2RAY_BUILD_EXTRA_INFO_STR_ = "Qv2ray $$VERSION"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_QV2RAY_BUILD_INFO_STR_ = "No Info"
|
|
||||||
_QV2RAY_BUILD_EXTRA_INFO_STR_ = "No Extra Info"
|
|
||||||
}
|
|
||||||
|
|
||||||
message("Qv2ray build info:")
|
|
||||||
message(" --> $$_QV2RAY_BUILD_INFO_STR_")
|
|
||||||
message(" --> $$_QV2RAY_BUILD_EXTRA_INFO_STR_")
|
|
||||||
|
|
||||||
DEFINES += _QV2RAY_BUILD_INFO_STR_=\"\\\"$${_QV2RAY_BUILD_INFO_STR_}\\\"\" _QV2RAY_BUILD_EXTRA_INFO_STR_=\"\\\"$${_QV2RAY_BUILD_EXTRA_INFO_STR_}\\\"\"
|
|
@ -1 +1 @@
|
|||||||
3861
|
4685
|
||||||
|
294
qv2ray-config-models.qmodel
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<qmt>
|
||||||
|
<project>
|
||||||
|
<uid>{e33c4c89-9b5b-44c4-9790-17cef05732d8}</uid>
|
||||||
|
<root-package>
|
||||||
|
<instance>
|
||||||
|
<MPackage>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{6035e8ea-cf65-4a95-b11b-59d640802d5e}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>Qv2ray-config-models</name>
|
||||||
|
<children>
|
||||||
|
<handles>
|
||||||
|
<handles>
|
||||||
|
<qlist>
|
||||||
|
<item>
|
||||||
|
<handle>
|
||||||
|
<uid>{0a303cb9-6681-4f79-9779-e61a34ac44ea}</uid>
|
||||||
|
<target>
|
||||||
|
<instance type="MCanvasDiagram">
|
||||||
|
<MCanvasDiagram>
|
||||||
|
<base-MDiagram>
|
||||||
|
<MDiagram>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{0a303cb9-6681-4f79-9779-e61a34ac44ea}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>Qv2ray-config-models</name>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
<elements>
|
||||||
|
<qlist>
|
||||||
|
<item>
|
||||||
|
<instance type="DItem">
|
||||||
|
<DItem>
|
||||||
|
<base-DObject>
|
||||||
|
<DObject>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{89aa1d96-388b-49c0-a4e6-bf55bb570889}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<object>{314756b5-bc93-49b8-ae97-957fe8b30d44}</object>
|
||||||
|
<name>BaseGroupObject</name>
|
||||||
|
<pos>x:410;y:235</pos>
|
||||||
|
<rect>x:-75;y:-50;w:150;h:100</rect>
|
||||||
|
<auto-sized>false</auto-sized>
|
||||||
|
<visual-role>0</visual-role>
|
||||||
|
</DObject>
|
||||||
|
</base-DObject>
|
||||||
|
<shape-editable>false</shape-editable>
|
||||||
|
</DItem>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DAnnotation">
|
||||||
|
<DAnnotation>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{7dd68311-11eb-43d0-9e64-91daeae12d97}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<text>Display Name</text>
|
||||||
|
<pos>x:350;y:215</pos>
|
||||||
|
<rect>x:0;y:0;w:84.2031;h:30</rect>
|
||||||
|
</DAnnotation>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DBoundary">
|
||||||
|
<DBoundary>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{e51a8692-6ecb-4052-8e09-f1b1ee3a2b92}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<text>Connection Groups</text>
|
||||||
|
<pos>x:260;y:230</pos>
|
||||||
|
<rect>x:-235;y:-75;w:470;h:150</rect>
|
||||||
|
</DBoundary>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DAnnotation">
|
||||||
|
<DAnnotation>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{b4dc36e8-31f6-4637-9f8f-c27ee155e301}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<text>List<ConnectionId></text>
|
||||||
|
<pos>x:350;y:235</pos>
|
||||||
|
<rect>x:0;y:0;w:111.391;h:30</rect>
|
||||||
|
</DAnnotation>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DBoundary">
|
||||||
|
<DBoundary>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{ffc9dfd5-2441-4b3b-b814-3ac76fb03c7e}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<text>Subscriptions</text>
|
||||||
|
<pos>x:565;y:230</pos>
|
||||||
|
<rect>x:-240;y:-75;w:480;h:150</rect>
|
||||||
|
</DBoundary>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DAnnotation">
|
||||||
|
<DAnnotation>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{3634dcd7-fac8-4993-b3e7-c10450dae1de}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<text>Nothing here since the base group
|
||||||
|
is enough</text>
|
||||||
|
<pos>x:85;y:215</pos>
|
||||||
|
<rect>x:0;y:0;w:186.047;h:44</rect>
|
||||||
|
</DAnnotation>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DAnnotation">
|
||||||
|
<DAnnotation>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{41e1ca4e-8395-472f-8470-912cf2c7b9d1}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<text>Some other metadata of subscription</text>
|
||||||
|
<pos>x:535;y:220</pos>
|
||||||
|
<rect>x:0;y:0;w:199.766;h:30</rect>
|
||||||
|
</DAnnotation>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<instance type="DItem">
|
||||||
|
<DItem>
|
||||||
|
<base-DObject>
|
||||||
|
<DObject>
|
||||||
|
<base-DElement>
|
||||||
|
<DElement>
|
||||||
|
<uid>{d27ab510-0eda-4d06-ac71-cd8b1d68571f}</uid>
|
||||||
|
</DElement>
|
||||||
|
</base-DElement>
|
||||||
|
<object>{48b1692c-e2da-49cb-b1da-dd1030084013}</object>
|
||||||
|
<name>Address, last-renewed......</name>
|
||||||
|
<pos>x:610;y:205</pos>
|
||||||
|
<rect>x:-75;y:-15;w:150;h:30</rect>
|
||||||
|
<visual-role>0</visual-role>
|
||||||
|
</DObject>
|
||||||
|
</base-DObject>
|
||||||
|
<shape-editable>false</shape-editable>
|
||||||
|
</DItem>
|
||||||
|
</instance>
|
||||||
|
</item>
|
||||||
|
</qlist>
|
||||||
|
</elements>
|
||||||
|
<last-modified>1581683831371</last-modified>
|
||||||
|
<toolbarid>General</toolbarid>
|
||||||
|
</MDiagram>
|
||||||
|
</base-MDiagram>
|
||||||
|
</MCanvasDiagram>
|
||||||
|
</instance>
|
||||||
|
</target>
|
||||||
|
</handle>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<handle>
|
||||||
|
<uid>{314756b5-bc93-49b8-ae97-957fe8b30d44}</uid>
|
||||||
|
<target>
|
||||||
|
<instance type="MItem">
|
||||||
|
<MItem>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{314756b5-bc93-49b8-ae97-957fe8b30d44}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>BaseGroupObject</name>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
</MItem>
|
||||||
|
</instance>
|
||||||
|
</target>
|
||||||
|
</handle>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<handle>
|
||||||
|
<uid>{e2922977-d357-43f0-822a-624245d6b470}</uid>
|
||||||
|
<target>
|
||||||
|
<instance type="MItem">
|
||||||
|
<MItem>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{e2922977-d357-43f0-822a-624245d6b470}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>New Item</name>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
</MItem>
|
||||||
|
</instance>
|
||||||
|
</target>
|
||||||
|
</handle>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<handle>
|
||||||
|
<uid>{8a788e13-b40c-4a33-8121-f0a4817428b1}</uid>
|
||||||
|
<target>
|
||||||
|
<instance type="MItem">
|
||||||
|
<MItem>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{8a788e13-b40c-4a33-8121-f0a4817428b1}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>Address</name>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
</MItem>
|
||||||
|
</instance>
|
||||||
|
</target>
|
||||||
|
</handle>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<handle>
|
||||||
|
<uid>{ec54fd48-400e-4e7d-9e74-b6333d2101c1}</uid>
|
||||||
|
<target>
|
||||||
|
<instance type="MItem">
|
||||||
|
<MItem>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{ec54fd48-400e-4e7d-9e74-b6333d2101c1}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>Some other metadata of subscription</name>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
</MItem>
|
||||||
|
</instance>
|
||||||
|
</target>
|
||||||
|
</handle>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<handle>
|
||||||
|
<uid>{48b1692c-e2da-49cb-b1da-dd1030084013}</uid>
|
||||||
|
<target>
|
||||||
|
<instance type="MItem">
|
||||||
|
<MItem>
|
||||||
|
<base-MObject>
|
||||||
|
<MObject>
|
||||||
|
<base-MElement>
|
||||||
|
<MElement>
|
||||||
|
<uid>{48b1692c-e2da-49cb-b1da-dd1030084013}</uid>
|
||||||
|
</MElement>
|
||||||
|
</base-MElement>
|
||||||
|
<name>Address, last-renewed......</name>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
</MItem>
|
||||||
|
</instance>
|
||||||
|
</target>
|
||||||
|
</handle>
|
||||||
|
</item>
|
||||||
|
</qlist>
|
||||||
|
</handles>
|
||||||
|
</handles>
|
||||||
|
</children>
|
||||||
|
</MObject>
|
||||||
|
</base-MObject>
|
||||||
|
</MPackage>
|
||||||
|
</instance>
|
||||||
|
</root-package>
|
||||||
|
</project>
|
||||||
|
</qmt>
|
2321
qv2ray-new.qmodel
Normal file
2187
qv2ray.qmodel
Normal file
@ -24,5 +24,13 @@
|
|||||||
<file>assets/icons/qv2ray.ico</file>
|
<file>assets/icons/qv2ray.ico</file>
|
||||||
<file>assets/icons/qv2ray.png</file>
|
<file>assets/icons/qv2ray.png</file>
|
||||||
<file>assets/credit.html</file>
|
<file>assets/credit.html</file>
|
||||||
|
<file>assets/icons/ui_dark/connect.png</file>
|
||||||
|
<file>assets/icons/ui_light/connect.png</file>
|
||||||
|
<file>assets/icons/ui_dark/stop.png</file>
|
||||||
|
<file>assets/icons/ui_light/stop.png</file>
|
||||||
|
<file>assets/icons/ui_dark/locate.png</file>
|
||||||
|
<file>assets/icons/ui_light/locate.png</file>
|
||||||
|
<file>assets/icons/ui_dark/sort.png</file>
|
||||||
|
<file>assets/icons/ui_light/sort.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
174
snap/plugins/x_cmake.py
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015-2016 Canonical Ltd
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""The cmake plugin is useful for building cmake based parts.
|
||||||
|
|
||||||
|
These are projects that have a CMakeLists.txt that drives the build.
|
||||||
|
The plugin requires a CMakeLists.txt in the root of the source tree.
|
||||||
|
|
||||||
|
If the part has a list of build-snaps listed, the part will be set up in
|
||||||
|
such a way that the paths to those snaps are used as paths for find_package
|
||||||
|
and find_library by use of `CMAKE_FIND_ROOT_PATH``.
|
||||||
|
This plugin uses the common plugin keywords as well as those for "sources".
|
||||||
|
For more information check the 'plugins' topic for the former and the
|
||||||
|
'sources' topic for the latter.
|
||||||
|
|
||||||
|
Additionally, this plugin uses the following plugin-specific keywords:
|
||||||
|
|
||||||
|
- configflags:
|
||||||
|
(list of strings)
|
||||||
|
configure flags to pass to the build using the common cmake semantics.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from typing import List, Optional
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import snapcraft
|
||||||
|
from snapcraft.internal import errors
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(name=__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class _Flag:
|
||||||
|
def __str__(self) -> str:
|
||||||
|
if self.value is None:
|
||||||
|
flag = self.name
|
||||||
|
else:
|
||||||
|
flag = "{}={}".format(self.name, self.value)
|
||||||
|
return flag
|
||||||
|
|
||||||
|
def __init__(self, flag: str) -> None:
|
||||||
|
parts = flag.split("=")
|
||||||
|
self.name = parts[0]
|
||||||
|
try:
|
||||||
|
self.value: Optional[str] = parts[1]
|
||||||
|
except IndexError:
|
||||||
|
self.value = None
|
||||||
|
|
||||||
|
|
||||||
|
class CMakePlugin(snapcraft.BasePlugin):
|
||||||
|
@classmethod
|
||||||
|
def schema(cls):
|
||||||
|
schema = super().schema()
|
||||||
|
schema["properties"]["configflags"] = {
|
||||||
|
"type": "array",
|
||||||
|
"minitems": 1,
|
||||||
|
"uniqueItems": True,
|
||||||
|
"items": {"type": "string"},
|
||||||
|
"default": [],
|
||||||
|
}
|
||||||
|
# For backwards compatibility
|
||||||
|
schema["properties"]["make-parameters"] = {
|
||||||
|
"type": "array",
|
||||||
|
"minitems": 1,
|
||||||
|
"uniqueItems": True,
|
||||||
|
"items": {"type": "string"},
|
||||||
|
"default": [],
|
||||||
|
}
|
||||||
|
schema["required"] = ["source"]
|
||||||
|
|
||||||
|
return schema
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_build_properties(cls):
|
||||||
|
# Inform Snapcraft of the properties associated with building. If these
|
||||||
|
# change in the YAML Snapcraft will consider the build step dirty.
|
||||||
|
return super().get_build_properties() + ["configflags"]
|
||||||
|
|
||||||
|
def __init__(self, name, options, project):
|
||||||
|
super().__init__(name, options, project)
|
||||||
|
self.build_packages.append("cmake")
|
||||||
|
self.build_packages.append("ninja-build")
|
||||||
|
self.out_of_source_build = True
|
||||||
|
|
||||||
|
cmd = '''
|
||||||
|
echo 'deb http://archive.neon.kde.org/unstable bionic main' > /etc/apt/sources.list.d/neon.list
|
||||||
|
echo 'deb http://ppa.launchpad.net/ymshenyu/grpc-1/ubuntu bionic main' > /etc/apt/sources.list.d/grpc.list
|
||||||
|
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E6D4736255751E5D
|
||||||
|
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 281f24e574404629aa3bda1a4f10c386c55cdb04
|
||||||
|
sudo apt update -qq
|
||||||
|
'''
|
||||||
|
|
||||||
|
subprocess.call(cmd, shell=True)
|
||||||
|
|
||||||
|
if project.info.get_build_base() not in ("core", "core16", "core18"):
|
||||||
|
raise errors.PluginBaseError(
|
||||||
|
part_name=self.name, base=project.info.get_build_base()
|
||||||
|
)
|
||||||
|
|
||||||
|
if options.make_parameters:
|
||||||
|
logger.warning("make-paramaters is deprecated, ignoring.")
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
source_subdir = getattr(self.options, "source_subdir", None)
|
||||||
|
if source_subdir:
|
||||||
|
sourcedir = os.path.join(self.sourcedir, source_subdir)
|
||||||
|
else:
|
||||||
|
sourcedir = self.sourcedir
|
||||||
|
|
||||||
|
env = self._build_environment()
|
||||||
|
configflags = self._get_processed_flags()
|
||||||
|
|
||||||
|
self.run(["cmake", sourcedir, "-DCMAKE_INSTALL_PREFIX="] + configflags, env=env)
|
||||||
|
|
||||||
|
# TODO: there is a better way to specify the job count on newer versions of cmake
|
||||||
|
# https://github.com/Kitware/CMake/commit/1ab3881ec9e809ac5f6cad5cd84048310b8683e2
|
||||||
|
self.run(
|
||||||
|
["cmake", "--build", ".", "--", "-j{}".format(self.parallel_build_count)],
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.run(["cmake", "--build", ".", "--target", "install"], env=env)
|
||||||
|
|
||||||
|
def _get_processed_flags(self) -> List[str]:
|
||||||
|
# Return the original if no build_snaps are in options.
|
||||||
|
if not self.options.build_snaps:
|
||||||
|
return self.options.configflags
|
||||||
|
|
||||||
|
build_snap_paths = [
|
||||||
|
os.path.join(os.path.sep, "snap", snap_name.split("/")[0], "current")
|
||||||
|
for snap_name in self.options.build_snaps
|
||||||
|
]
|
||||||
|
|
||||||
|
flags = [_Flag(f) for f in self.options.configflags]
|
||||||
|
for flag in flags:
|
||||||
|
if flag.name == "-DCMAKE_FIND_ROOT_PATH":
|
||||||
|
flag.value = "{};{}".format(flag.value, ";".join(build_snap_paths))
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
flags.append(
|
||||||
|
_Flag("-DCMAKE_FIND_ROOT_PATH={}".format(";".join(build_snap_paths)))
|
||||||
|
)
|
||||||
|
|
||||||
|
return [str(f) for f in flags]
|
||||||
|
|
||||||
|
def _build_environment(self):
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["DESTDIR"] = self.installdir
|
||||||
|
env["CMAKE_PREFIX_PATH"] = "$CMAKE_PREFIX_PATH:{}".format(
|
||||||
|
self.project.stage_dir
|
||||||
|
)
|
||||||
|
env["CMAKE_INCLUDE_PATH"] = "$CMAKE_INCLUDE_PATH:" + ":".join(
|
||||||
|
["{0}/include", "{0}/usr/include", "{0}/include/{1}", "{0}/usr/include/{1}"]
|
||||||
|
).format(self.project.stage_dir, self.project.arch_triplet)
|
||||||
|
env["CMAKE_LIBRARY_PATH"] = "$CMAKE_LIBRARY_PATH:" + ":".join(
|
||||||
|
["{0}/lib", "{0}/usr/lib", "{0}/lib/{1}", "{0}/usr/lib/{1}"]
|
||||||
|
).format(self.project.stage_dir, self.project.arch_triplet)
|
||||||
|
|
||||||
|
return env
|
@ -3,8 +3,8 @@ base: core18
|
|||||||
adopt-info: qv2ray
|
adopt-info: qv2ray
|
||||||
icon: assets/icons/qv2ray.png
|
icon: assets/icons/qv2ray.png
|
||||||
|
|
||||||
grade: devel
|
grade: stable
|
||||||
confinement: devmode
|
confinement: strict
|
||||||
|
|
||||||
plugs:
|
plugs:
|
||||||
gsettings:
|
gsettings:
|
||||||
@ -26,18 +26,33 @@ apps:
|
|||||||
command: bin/desktop-launch qv2ray
|
command: bin/desktop-launch qv2ray
|
||||||
environment:
|
environment:
|
||||||
QT_QPA_PLATFORMTHEME: gtk3
|
QT_QPA_PLATFORMTHEME: gtk3
|
||||||
|
plugs:
|
||||||
|
- home
|
||||||
|
- x11
|
||||||
|
- wayland
|
||||||
|
- opengl
|
||||||
|
- network
|
||||||
|
- network-bind
|
||||||
|
- unity7
|
||||||
|
- pulseaudio
|
||||||
|
- desktop
|
||||||
|
- desktop-legacy
|
||||||
|
- gsettings
|
||||||
|
- network-control
|
||||||
|
- network-manager
|
||||||
common-id: com.github.Qv2ray
|
common-id: com.github.Qv2ray
|
||||||
desktop: "usr/share/applications/qv2ray.desktop"
|
desktop: "usr/share/applications/qv2ray.desktop"
|
||||||
|
|
||||||
parts:
|
parts:
|
||||||
qv2ray:
|
qv2ray:
|
||||||
plugin: qmake
|
plugin: x-cmake
|
||||||
source-type: git
|
source-type: git
|
||||||
source: .
|
source: .
|
||||||
parse-info: [usr/share/metainfo/qv2ray.metainfo.xml]
|
parse-info: [usr/share/metainfo/qv2ray.metainfo.xml]
|
||||||
build-packages:
|
build-packages:
|
||||||
- build-essential
|
- build-essential
|
||||||
- qttools5-dev-tools
|
- qttools5-dev-tools
|
||||||
|
- qttools5-dev
|
||||||
- qt5-default
|
- qt5-default
|
||||||
- libgrpc++-dev
|
- libgrpc++-dev
|
||||||
- libprotobuf-dev
|
- libprotobuf-dev
|
||||||
@ -52,12 +67,12 @@ parts:
|
|||||||
- libqt5gui5
|
- libqt5gui5
|
||||||
- libqt5network5
|
- libqt5network5
|
||||||
- libqt5widgets5
|
- libqt5widgets5
|
||||||
- fonts-noto-cjk
|
|
||||||
- libglib2.0-bin
|
- libglib2.0-bin
|
||||||
options:
|
configflags:
|
||||||
- PREFIX=/usr
|
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
- CONFIG+=with_metainfo
|
- -DCMAKE_BUILD_TYPE=Release
|
||||||
- CONFIG+=use_grpc
|
- -GNinja
|
||||||
|
- -DEMBED_TRANSLATIONS=ON
|
||||||
override-pull: |
|
override-pull: |
|
||||||
snapcraftctl pull
|
snapcraftctl pull
|
||||||
build_number=$(cat makespec/BUILDVERSION)
|
build_number=$(cat makespec/BUILDVERSION)
|
||||||
@ -66,7 +81,6 @@ parts:
|
|||||||
snapcraftctl set-version "$version"
|
snapcraftctl set-version "$version"
|
||||||
sed -i 's|^Icon=.*|Icon=/usr/share/icons/hicolor/256x256/apps/qv2ray.png|g' assets/qv2ray.desktop
|
sed -i 's|^Icon=.*|Icon=/usr/share/icons/hicolor/256x256/apps/qv2ray.png|g' assets/qv2ray.desktop
|
||||||
after:
|
after:
|
||||||
- mytools
|
|
||||||
- desktop-qt5
|
- desktop-qt5
|
||||||
|
|
||||||
desktop-qt5:
|
desktop-qt5:
|
||||||
@ -93,28 +107,8 @@ parts:
|
|||||||
- locales-all
|
- locales-all
|
||||||
- xdg-user-dirs
|
- xdg-user-dirs
|
||||||
- fcitx-frontend-qt5
|
- fcitx-frontend-qt5
|
||||||
after:
|
|
||||||
- mytools
|
|
||||||
|
|
||||||
qt5-gtk-platform:
|
qt5-gtk-platform:
|
||||||
plugin: nil
|
plugin: nil
|
||||||
stage-packages:
|
stage-packages:
|
||||||
- qt5-gtk-platformtheme
|
- qt5-gtk-platformtheme
|
||||||
after:
|
|
||||||
- mytools
|
|
||||||
|
|
||||||
mytools:
|
|
||||||
plugin: nil
|
|
||||||
build-packages:
|
|
||||||
- dirmngr
|
|
||||||
override-pull: |
|
|
||||||
echo 'deb http://archive.neon.kde.org/unstable bionic main' > /etc/apt/sources.list.d/neon.list
|
|
||||||
echo 'deb http://ppa.launchpad.net/ymshenyu/grpc-1/ubuntu bionic main' >> /etc/apt/sources.list.d/tools.list
|
|
||||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E6D4736255751E5D
|
|
||||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 281f24e574404629aa3bda1a4f10c386c55cdb04
|
|
||||||
sudo apt-get update
|
|
||||||
snapcraftctl pull
|
|
||||||
override-build: |
|
|
||||||
snapcraftctl build
|
|
||||||
sudo apt upgrade -y
|
|
||||||
sudo apt dist-upgrade -y
|
|
@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "base/models/QvRuntimeConfig.hpp"
|
|
||||||
#include "base/models/QvStartupConfig.hpp"
|
|
||||||
#include "base/models/QvConfigModel.hpp"
|
|
||||||
|
|
||||||
#include <QTranslator>
|
|
||||||
|
|
||||||
// Instantiation for Qv2ray global objects.
|
|
||||||
#ifdef QT_DEBUG
|
|
||||||
const bool isDebugBuild = true;
|
|
||||||
#else
|
|
||||||
const bool isDebugBuild = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Qv2ray
|
|
||||||
{
|
|
||||||
// Qv2ray runtime config
|
|
||||||
inline bool isExiting = false;
|
|
||||||
inline QString Qv2rayConfigPath = "/";
|
|
||||||
inline base::Qv2rayRuntimeConfig RuntimeConfig = base::Qv2rayRuntimeConfig();
|
|
||||||
inline base::config::Qv2rayConfig GlobalConfig = base::config::Qv2rayConfig();
|
|
||||||
inline base::QvStartupOptions StartupOption = base::QvStartupOptions();
|
|
||||||
//
|
|
||||||
inline std::unique_ptr<QTranslator> Qv2rayTranslator;
|
|
||||||
}
|
|
@ -1,42 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define STRINGIZE(arg) STRINGIZE1(arg)
|
#define STRINGIZE(arg) STRINGIZE1(arg)
|
||||||
#define STRINGIZE1(arg) STRINGIZE2(arg)
|
#define STRINGIZE1(arg) STRINGIZE2(arg)
|
||||||
#define STRINGIZE2(arg) #arg
|
#define STRINGIZE2(arg) #arg
|
||||||
|
|
||||||
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
|
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
|
||||||
#define CONCATENATE2(arg1, arg2) arg1##arg2
|
#define CONCATENATE2(arg1, arg2) arg1##arg2
|
||||||
|
|
||||||
#define EXPAND(x) x
|
#define EXPAND(x) x
|
||||||
#define FOR_EACH_1(what, x, ...) what(x)
|
#define FOR_EACH_1(what, x, ...) what(x)
|
||||||
|
|
||||||
#define FOR_EACH_2(what, x, ...)\
|
#define FOR_EACH_2(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_1(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_1(what, __VA_ARGS__))
|
||||||
#define FOR_EACH_3(what, x, ...)\
|
#define FOR_EACH_3(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_2(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_2(what, __VA_ARGS__))
|
||||||
#define FOR_EACH_4(what, x, ...)\
|
#define FOR_EACH_4(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_3(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_3(what, __VA_ARGS__))
|
||||||
#define FOR_EACH_5(what, x, ...)\
|
#define FOR_EACH_5(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_4(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_4(what, __VA_ARGS__))
|
||||||
#define FOR_EACH_6(what, x, ...)\
|
#define FOR_EACH_6(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_5(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_5(what, __VA_ARGS__))
|
||||||
#define FOR_EACH_7(what, x, ...)\
|
#define FOR_EACH_7(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_6(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_6(what, __VA_ARGS__))
|
||||||
#define FOR_EACH_8(what, x, ...)\
|
#define FOR_EACH_8(what, x, ...) \
|
||||||
what(x);\
|
what(x); \
|
||||||
EXPAND(FOR_EACH_7(what, __VA_ARGS__))
|
EXPAND(FOR_EACH_7(what, __VA_ARGS__))
|
||||||
|
|
||||||
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N())
|
#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_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_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 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_(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 FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
|
||||||
#define JADDEx_(jsonObj, field) jsonObj.insert(#field, field);
|
#define JADDEx_(jsonObj, field) jsonObj.insert(#field, field);
|
||||||
|
@ -1,28 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
//
|
//
|
||||||
#ifndef XTOSTRUCT_QT
|
|
||||||
# define XTOSTRUCT_QT
|
|
||||||
#endif
|
|
||||||
//
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QtGui>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <vector>
|
#include <QtCore>
|
||||||
|
#include <QtGui>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
// Base support.
|
// Base support.
|
||||||
#include "base/Qv2rayLog.hpp"
|
|
||||||
#include "base/Qv2rayFeatures.hpp"
|
|
||||||
#include "base/JsonHelpers.hpp"
|
#include "base/JsonHelpers.hpp"
|
||||||
#include "base/GlobalInstances.hpp"
|
#include "base/Qv2rayFeatures.hpp"
|
||||||
|
#include "base/Qv2rayLog.hpp"
|
||||||
// Code Models
|
// Code Models
|
||||||
#include "base/models/QvSafeType.hpp"
|
|
||||||
#include "base/models/CoreObjectModels.hpp"
|
#include "base/models/CoreObjectModels.hpp"
|
||||||
#include "base/models/QvConfigModel.hpp"
|
|
||||||
#include "base/models/QvConfigIdentifier.hpp"
|
#include "base/models/QvConfigIdentifier.hpp"
|
||||||
#include "base/models/QvStartupConfig.hpp"
|
|
||||||
#include "base/models/QvRuntimeConfig.hpp"
|
#include "base/models/QvRuntimeConfig.hpp"
|
||||||
|
#include "base/models/QvSafeType.hpp"
|
||||||
|
#include "base/models/QvSettingsObject.hpp"
|
||||||
|
#include "base/models/QvStartupConfig.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
@ -34,27 +31,20 @@ using namespace Qv2ray::base::objects;
|
|||||||
using namespace Qv2ray::base::objects::protocol;
|
using namespace Qv2ray::base::objects::protocol;
|
||||||
using namespace Qv2ray::base::objects::transfer;
|
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
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define QV2RAY_BUILD_INFO QString(_QV2RAY_BUILD_INFO_STR_)
|
#define QV2RAY_BUILD_INFO QString(_QV2RAY_BUILD_INFO_STR_)
|
||||||
#define QV2RAY_BUILD_EXTRA_INFO QString(_QV2RAY_BUILD_EXTRA_INFO_STR_)
|
#define QV2RAY_BUILD_EXTRA_INFO QString(_QV2RAY_BUILD_EXTRA_INFO_STR_)
|
||||||
|
|
||||||
extern const bool isDebugBuild;
|
|
||||||
// Base folder suffix.
|
// Base folder suffix.
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
# define QV2RAY_CONFIG_DIR_SUFFIX "_debug/"
|
#define QV2RAY_CONFIG_DIR_SUFFIX "_debug/"
|
||||||
#else
|
#else
|
||||||
# define QV2RAY_CONFIG_DIR_SUFFIX "/"
|
#define QV2RAY_CONFIG_DIR_SUFFIX "/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get Configured Config Dir Path
|
// Get Configured Config Dir Path
|
||||||
#define QV2RAY_CONFIG_DIR (Qv2ray::Qv2rayConfigPath)
|
#define QV2RAY_CONFIG_DIR (Qv2ray::Qv2rayConfigPath)
|
||||||
#define QV2RAY_CONFIG_FILE (QV2RAY_CONFIG_DIR + "Qv2ray.conf")
|
#define QV2RAY_CONFIG_FILE (QV2RAY_CONFIG_DIR + "Qv2ray.conf")
|
||||||
|
#define QV2RAY_CONNECTIONS_DIR (QV2RAY_CONFIG_DIR + "connections/")
|
||||||
#define QV2RAY_SUBSCRIPTION_DIR (QV2RAY_CONFIG_DIR + "subscriptions/")
|
#define QV2RAY_SUBSCRIPTION_DIR (QV2RAY_CONFIG_DIR + "subscriptions/")
|
||||||
|
|
||||||
// Get GFWList and PAC file path.
|
// Get GFWList and PAC file path.
|
||||||
@ -66,17 +56,17 @@ extern const bool isDebugBuild;
|
|||||||
#define QV2RAY_GENERATED_DIR (QV2RAY_CONFIG_DIR + "generated/")
|
#define QV2RAY_GENERATED_DIR (QV2RAY_CONFIG_DIR + "generated/")
|
||||||
#define QV2RAY_GENERATED_FILE_PATH (QV2RAY_GENERATED_DIR + "config.gen.json")
|
#define QV2RAY_GENERATED_FILE_PATH (QV2RAY_GENERATED_DIR + "config.gen.json")
|
||||||
|
|
||||||
#if ! 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/")
|
#define QV2RAY_DEFAULT_VASSETS_PATH (QV2RAY_CONFIG_DIR + "vcore/")
|
||||||
# ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe")
|
#define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe")
|
||||||
# else
|
#else
|
||||||
# define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray")
|
#define QV2RAY_DEFAULT_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray")
|
||||||
# endif
|
#endif
|
||||||
#elif defined (QV2RAY_DEFAULT_VCORE_PATH) && defined (QV2RAY_DEFAULT_VASSETS_PATH)
|
#elif defined(QV2RAY_DEFAULT_VCORE_PATH) && defined(QV2RAY_DEFAULT_VASSETS_PATH)
|
||||||
// ---- Using user-specified VCore and VAssets path
|
// ---- Using user-specified VCore and VAssets path
|
||||||
#else
|
#else
|
||||||
# error Both QV2RAY_DEFAULT_VCORE_PATH and QV2RAY_DEFAULT_VASSETS_PATH need to present when specifying the paths.
|
#error Both QV2RAY_DEFAULT_VCORE_PATH and QV2RAY_DEFAULT_VASSETS_PATH need to be presented when using manually specify the paths.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@ -84,8 +74,8 @@ extern const bool isDebugBuild;
|
|||||||
//# define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe")
|
//# define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray.exe")
|
||||||
//# define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl.exe")
|
//# define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl.exe")
|
||||||
#else
|
#else
|
||||||
# define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray")
|
#define QV2RAY_TPROXY_VCORE_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ray")
|
||||||
# define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl")
|
#define QV2RAY_TPROXY_VCTL_PATH (QV2RAY_CONFIG_DIR + "vcore/v2ctl")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define QV2RAY_VCORE_LOG_DIRNAME "logs/"
|
#define QV2RAY_VCORE_LOG_DIRNAME "logs/"
|
||||||
@ -93,20 +83,19 @@ extern const bool isDebugBuild;
|
|||||||
#define QV2RAY_VCORE_ERROR_LOG_FILENAME "error.log"
|
#define QV2RAY_VCORE_ERROR_LOG_FILENAME "error.log"
|
||||||
|
|
||||||
// GUI TOOLS
|
// GUI TOOLS
|
||||||
#define RED(obj) \
|
#define RED(obj) \
|
||||||
auto _temp = obj->palette(); \
|
auto _temp = obj->palette(); \
|
||||||
_temp.setColor(QPalette::Text, Qt::red); \
|
_temp.setColor(QPalette::Text, Qt::red); \
|
||||||
obj->setPalette(_temp);
|
obj->setPalette(_temp);
|
||||||
|
|
||||||
#define BLACK(obj) \
|
#define BLACK(obj) obj->setPalette(QWidget::palette());
|
||||||
obj->setPalette(this->palette());
|
|
||||||
|
|
||||||
#define QV2RAY_UI_RESOURCES_ROOT ((GlobalConfig.uiConfig.useDarkTheme) ? QStringLiteral(":/assets/icons/ui_dark/") : QStringLiteral(":/assets/icons/ui_light/"))
|
#define QV2RAY_UI_COLORSCHEME_ROOT \
|
||||||
#define QICON_R(file) QIcon(QV2RAY_UI_RESOURCES_ROOT + file)
|
((GlobalConfig.uiConfig.useDarkTheme) ? QStringLiteral(":/assets/icons/ui_dark/") : QStringLiteral(":/assets/icons/ui_light/"))
|
||||||
|
#define QICON_R(file) QIcon(QV2RAY_UI_COLORSCHEME_ROOT + file)
|
||||||
|
|
||||||
#define QSTRN(num) QString::number(num)
|
#define QSTRN(num) QString::number(num)
|
||||||
|
|
||||||
|
|
||||||
#define OUTBOUND_TAG_DIRECT "outBound_DIRECT"
|
#define OUTBOUND_TAG_DIRECT "outBound_DIRECT"
|
||||||
#define OUTBOUND_TAG_PROXY "outBound_PROXY"
|
#define OUTBOUND_TAG_PROXY "outBound_PROXY"
|
||||||
#define OUTBOUND_TAG_FORWARD_PROXY "_QV2RAY_FORWARD_PROXY_"
|
#define OUTBOUND_TAG_FORWARD_PROXY "_QV2RAY_FORWARD_PROXY_"
|
||||||
@ -116,16 +105,25 @@ extern const bool isDebugBuild;
|
|||||||
|
|
||||||
#define QV2RAY_USE_FPROXY_KEY "_QV2RAY_USE_GLOBAL_FORWARD_PROXY_"
|
#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
|
namespace Qv2ray
|
||||||
{
|
{
|
||||||
// Extra header for QvConfigUpgrade.cpp
|
// Extra header for QvConfigUpgrade.cpp
|
||||||
QJsonObject UpgradeConfig(int fromVersion, int toVersion, QJsonObject root);
|
QJsonObject UpgradeSettingsVersion(int fromVersion, int toVersion, QJsonObject root);
|
||||||
|
|
||||||
|
// Qv2ray runtime config
|
||||||
|
inline bool isExiting = false;
|
||||||
|
inline QString Qv2rayConfigPath = "";
|
||||||
|
inline base::config::Qv2rayConfig GlobalConfig = base::config::Qv2rayConfig();
|
||||||
|
//
|
||||||
inline void ExitQv2ray()
|
inline void ExitQv2ray()
|
||||||
{
|
{
|
||||||
isExiting = true;
|
isExiting = true;
|
||||||
QApplication::quit();
|
QApplication::quit();
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// Qv2ray build features.
|
// Qv2ray build features.
|
||||||
//
|
//
|
||||||
// Always use libgRPC++ on windows platform.
|
// Always use libgRPC++ on windows platform.
|
||||||
#ifndef WITH_LIB_GRPCPP
|
#ifdef BACKEND_LIBQVB
|
||||||
# ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define WITH_LIB_GRPCPP
|
#error "libQvb is not supported on Windows Platform"
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "Qv2rayLog.hpp"
|
#include "Qv2rayLog.hpp"
|
||||||
#include "GlobalInstances.hpp"
|
|
||||||
|
#include "Qv2rayBase.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace Qv2ray::base
|
namespace Qv2ray::base
|
||||||
{
|
{
|
||||||
@ -11,42 +14,48 @@ namespace Qv2ray::base
|
|||||||
|
|
||||||
void __QV2RAY_LOG_FUNC__(int type, const std::string &func, int line, const QString &module, const QString &log)
|
void __QV2RAY_LOG_FUNC__(int type, const std::string &func, int line, const QString &module, const QString &log)
|
||||||
{
|
{
|
||||||
auto logString = "[" + module + "]: " + log;
|
auto logString = QString("[" % module % "]: " % log);
|
||||||
auto funcPrepend = QString::fromStdString(func + ":" + to_string(line) + " ");
|
auto funcPrepend = QString::fromStdString(func + ":" + to_string(line) + " ");
|
||||||
|
|
||||||
if (isDebugBuild) {
|
#ifdef QT_DEBUG
|
||||||
// Debug build version, we only print info for DEBUG logs and print ALL info when debugLog presents,
|
// Debug build version, we only print info for DEBUG logs and print
|
||||||
if (type == QV2RAY_LOG_DEBUG || StartupOption.debugLog) {
|
// ALL info when debugLog presents,
|
||||||
logString = logString.prepend(funcPrepend);
|
if (type == QV2RAY_LOG_DEBUG || StartupOption.debugLog)
|
||||||
|
{
|
||||||
|
logString.prepend(funcPrepend);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// We only process DEBUG log in Release mode
|
||||||
|
if (type == QV2RAY_LOG_DEBUG)
|
||||||
|
{
|
||||||
|
if (StartupOption.debugLog)
|
||||||
|
{
|
||||||
|
logString.prepend(funcPrepend);
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
// We only process DEBUG log in Release mode
|
{
|
||||||
if (type == QV2RAY_LOG_DEBUG) {
|
// Discard debug log in non-debug Qv2ray version with
|
||||||
if (StartupOption.debugLog) {
|
// no-debugLog mode.
|
||||||
logString = logString.prepend(funcPrepend);
|
return;
|
||||||
} else {
|
|
||||||
// Discard debug log in non-debug Qv2ray version with no-debugLog mode.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
cout << logString.toStdString() << endl;
|
cout << logString.toStdString() << endl;
|
||||||
{
|
{
|
||||||
QMutexLocker _(&__loggerMutex);
|
QMutexLocker _(&__loggerMutex);
|
||||||
__loggerBuffer->append(logString + NEWLINE);
|
__loggerBuffer->append(logString + NEWLINE);
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::base
|
||||||
|
|
||||||
const QString readLastLog()
|
QString readLastLog()
|
||||||
{
|
{
|
||||||
QMutexLocker _(&__purgerMutex);
|
QMutexLocker _(&__purgerMutex);
|
||||||
{
|
{
|
||||||
QMutexLocker _(&__loggerMutex);
|
QMutexLocker locker(&__loggerMutex);
|
||||||
__loggerBuffer.swap(__purgerBuffer);
|
__loggerBuffer.swap(__purgerBuffer);
|
||||||
}
|
}
|
||||||
auto result = __purgerBuffer->join("");
|
auto result = __purgerBuffer->join("");
|
||||||
__purgerBuffer->clear();
|
__purgerBuffer->clear();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::base
|
||||||
|
@ -1,28 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
#include <QString>
|
||||||
#include <QtDebug>
|
|
||||||
#include <QBuffer>
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tiny log module.
|
* Tiny log module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Qv2ray::base
|
namespace Qv2ray::base
|
||||||
{
|
{
|
||||||
void __QV2RAY_LOG_FUNC__(int type, const std::string &func, int line, const QString &module, const QString &log);
|
void __QV2RAY_LOG_FUNC__(int type, const std::string &func, int line, const QString &module, const QString &log);
|
||||||
const QString readLastLog();
|
QString readLastLog();
|
||||||
}
|
} // namespace Qv2ray::base
|
||||||
|
|
||||||
#define NEWLINE "\r\n"
|
#define NEWLINE "\r\n"
|
||||||
|
|
||||||
#define QV2RAY_LOG_NORMAL 0
|
#define QV2RAY_LOG_NORMAL 0
|
||||||
#define QV2RAY_LOG_DEBUG 1
|
#define QV2RAY_LOG_DEBUG 1
|
||||||
|
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
#define Qv2ray_PRETTY_FUNCTION __PRETTY_FUNCTION__
|
#define Qv2ray_PRETTY_FUNCTION __PRETTY_FUNCTION__
|
||||||
#else
|
#else
|
||||||
#define Qv2ray_PRETTY_FUNCTION __FUNCSIG__
|
#define Qv2ray_PRETTY_FUNCTION __FUNCSIG__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __LOG_IMPL(LEVEL, MODULE, MSG) __QV2RAY_LOG_FUNC__(LEVEL, Qv2ray_PRETTY_FUNCTION, __LINE__, MODULE, MSG);
|
#define __LOG_IMPL(LEVEL, MODULE, MSG) __QV2RAY_LOG_FUNC__(LEVEL, Qv2ray_PRETTY_FUNCTION, __LINE__, MODULE, MSG);
|
||||||
@ -31,21 +30,23 @@ namespace Qv2ray::base
|
|||||||
#define DEBUG(MODULE, MSG) __LOG_IMPL(QV2RAY_LOG_DEBUG, (MODULE), (MSG));
|
#define DEBUG(MODULE, MSG) __LOG_IMPL(QV2RAY_LOG_DEBUG, (MODULE), (MSG));
|
||||||
|
|
||||||
// Log modules used by Qv2ray
|
// Log modules used by Qv2ray
|
||||||
const inline QString INIT = "INIT" ;
|
const inline QString MODULE_INIT = "INIT";
|
||||||
const inline QString MESSAGING = "BASE-MESSAGING" ;
|
const inline QString MODULE_MESSAGING = "BASE-MESSAGING";
|
||||||
const inline QString UI = "CORE-UI" ;
|
const inline QString MODULE_UI = "CORE-UI";
|
||||||
const inline QString GRAPH = "CORE-UI-GRAPH" ;
|
const inline QString MODULE_GRAPH = "CORE-UI-GRAPH";
|
||||||
const inline QString SETTINGS = "CORE-SETTINGS" ;
|
const inline QString MODULE_SETTINGS = "CORE-SETTINGS";
|
||||||
const inline QString VCORE = "CORE-VCORE" ;
|
const inline QString MODULE_VCORE = "CORE-VCORE";
|
||||||
//
|
//
|
||||||
const inline QString CONNECTION = "CORE-CONNECTION" ;
|
const inline QString MODULE_CONNECTION = "CORE-CONNECTION";
|
||||||
const inline QString SUBSCRIPTION = "CORE-SUBSCRIPTION" ;
|
const inline QString MODULE_SUBSCRIPTION = "CORE-SUBSCRIPTION";
|
||||||
const inline QString IMPORT = "CORE-IMPORT" ;
|
const inline QString MODULE_IMPORT = "CORE-IMPORT";
|
||||||
const inline QString EXPORT = "CORE-EXPORT" ;
|
const inline QString MODULE_EXPORT = "CORE-EXPORT";
|
||||||
//
|
//
|
||||||
const inline QString NETWORK = "COMMON-NETWORK" ;
|
const inline QString MODULE_NETWORK = "COMMON-NETWORK";
|
||||||
const inline QString FILEIO = "COMMON-FILEIO" ;
|
const inline QString MODULE_FILEIO = "COMMON-FILEIO";
|
||||||
//
|
//
|
||||||
const inline QString PROXY = "COMPONENT-PROXY" ;
|
const inline QString MODULE_PROXY = "COMPONENT-PROXY";
|
||||||
const inline QString UPDATE = "COMPONENT-UPDATE" ;
|
const inline QString MODULE_UPDATE = "COMPONENT-UPDATE";
|
||||||
const inline QString PLUGIN = "COMPONENT-PLUGIN" ;
|
const inline QString MODULE_PLUGIN = "COMPONENT-PLUGIN";
|
||||||
|
// ================================================================
|
||||||
|
const inline QString MODULE_CORE_HANDLER = "QV2RAY-CORE";
|
||||||
|
@ -1,37 +1,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <QString>
|
#include "3rdparty/x2struct/x2struct.hpp"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include "3rdparty/x2struct/x2struct.hpp"
|
#include <QString>
|
||||||
|
|
||||||
namespace Qv2ray::base::objects
|
namespace Qv2ray::base::objects
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Used in config generation
|
// Used in config generation
|
||||||
struct AccountObject {
|
struct AccountObject
|
||||||
|
{
|
||||||
QString user;
|
QString user;
|
||||||
QString pass;
|
QString pass;
|
||||||
XTOSTRUCT(O(user, pass))
|
XTOSTRUCT(O(user, pass))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct ApiObject {
|
struct ApiObject
|
||||||
|
{
|
||||||
QString tag;
|
QString tag;
|
||||||
QList<QString> services;
|
QList<QString> services;
|
||||||
ApiObject() : tag("api"), services() {}
|
ApiObject() : tag("api"), services()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(tag, services))
|
XTOSTRUCT(O(tag, services))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct SystemPolicyObject {
|
struct SystemPolicyObject
|
||||||
|
{
|
||||||
bool statsInboundUplink;
|
bool statsInboundUplink;
|
||||||
bool statsInboundDownlink;
|
bool statsInboundDownlink;
|
||||||
SystemPolicyObject() : statsInboundUplink(), statsInboundDownlink() {}
|
SystemPolicyObject() : statsInboundUplink(), statsInboundDownlink()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(statsInboundUplink, statsInboundDownlink))
|
XTOSTRUCT(O(statsInboundUplink, statsInboundDownlink))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct LevelPolicyObject {
|
struct LevelPolicyObject
|
||||||
|
{
|
||||||
int handshake;
|
int handshake;
|
||||||
int connIdle;
|
int connIdle;
|
||||||
int uplinkOnly;
|
int uplinkOnly;
|
||||||
@ -39,20 +48,26 @@ namespace Qv2ray::base::objects
|
|||||||
bool statsUserUplink;
|
bool statsUserUplink;
|
||||||
bool statsUserDownlink;
|
bool statsUserDownlink;
|
||||||
int bufferSize;
|
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))
|
XTOSTRUCT(O(handshake, connIdle, uplinkOnly, downlinkOnly, statsUserUplink, statsUserDownlink, bufferSize))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct PolicyObject {
|
struct PolicyObject
|
||||||
|
{
|
||||||
QMap<QString, LevelPolicyObject> level;
|
QMap<QString, LevelPolicyObject> level;
|
||||||
QList<SystemPolicyObject> system;
|
QList<SystemPolicyObject> system;
|
||||||
PolicyObject(): level(), system() {}
|
PolicyObject() : level(), system()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(level, system))
|
XTOSTRUCT(O(level, system))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct RuleObject {
|
struct RuleObject
|
||||||
|
{
|
||||||
// Added due to the request of @aliyuchang33
|
// Added due to the request of @aliyuchang33
|
||||||
bool QV2RAY_RULE_ENABLED;
|
bool QV2RAY_RULE_ENABLED;
|
||||||
bool QV2RAY_RULE_USE_BALANCER;
|
bool QV2RAY_RULE_USE_BALANCER;
|
||||||
@ -70,65 +85,89 @@ namespace Qv2ray::base::objects
|
|||||||
QString attrs;
|
QString attrs;
|
||||||
QString outboundTag;
|
QString outboundTag;
|
||||||
QString balancerTag;
|
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("") {}
|
RuleObject()
|
||||||
XTOSTRUCT(O(QV2RAY_RULE_ENABLED, QV2RAY_RULE_USE_BALANCER, QV2RAY_RULE_TAG, type, domain, ip, port, network, source, user, inboundTag, protocol, attrs, outboundTag, balancerTag))
|
: 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 {
|
struct BalancerObject
|
||||||
QString tag ;
|
{
|
||||||
|
QString tag;
|
||||||
QList<QString> selector;
|
QList<QString> selector;
|
||||||
BalancerObject() : tag(), selector() {}
|
BalancerObject() : tag(), selector()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(tag, selector))
|
XTOSTRUCT(O(tag, selector))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
namespace transfer
|
namespace transfer
|
||||||
{
|
{
|
||||||
struct HTTPRequestObject {
|
struct HTTPRequestObject
|
||||||
|
{
|
||||||
QString version;
|
QString version;
|
||||||
QString method;
|
QString method;
|
||||||
QList<QString> path;
|
QList<QString> path;
|
||||||
QMap<QString, QList<QString>> headers;
|
QMap<QString, QList<QString>> headers;
|
||||||
HTTPRequestObject(): version("1.1"), method("GET"), path(), headers() {}
|
HTTPRequestObject() : version("1.1"), method("GET"), path(), headers()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(version, method, path, headers))
|
XTOSTRUCT(O(version, method, path, headers))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct HTTPResponseObject {
|
struct HTTPResponseObject
|
||||||
|
{
|
||||||
QString version;
|
QString version;
|
||||||
QString status;
|
QString status;
|
||||||
QString reason;
|
QString reason;
|
||||||
QMap<QString, QList<QString>> headers;
|
QMap<QString, QList<QString>> 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))
|
XTOSTRUCT(O(version, status, reason, headers))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct TCPHeader_M_Object {
|
struct TCPHeader_M_Object
|
||||||
|
{
|
||||||
QString type;
|
QString type;
|
||||||
HTTPRequestObject request;
|
HTTPRequestObject request;
|
||||||
HTTPResponseObject response;
|
HTTPResponseObject response;
|
||||||
TCPHeader_M_Object(): type("none"), request(), response() {}
|
TCPHeader_M_Object() : type("none"), request(), response()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(type, request, response))
|
XTOSTRUCT(O(type, request, response))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct HeaderObject {
|
struct HeaderObject
|
||||||
|
{
|
||||||
QString type;
|
QString type;
|
||||||
HeaderObject(): type("none") {}
|
HeaderObject() : type("none")
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(type))
|
XTOSTRUCT(O(type))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct TCPObject {
|
struct TCPObject
|
||||||
|
{
|
||||||
TCPHeader_M_Object header;
|
TCPHeader_M_Object header;
|
||||||
TCPObject(): header() {}
|
TCPObject() : header()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(header))
|
XTOSTRUCT(O(header))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct KCPObject {
|
struct KCPObject
|
||||||
|
{
|
||||||
int mtu = 1350;
|
int mtu = 1350;
|
||||||
int tti = 20;
|
int tti = 20;
|
||||||
int uplinkCapacity = 5;
|
int uplinkCapacity = 5;
|
||||||
@ -137,84 +176,111 @@ namespace Qv2ray::base::objects
|
|||||||
int readBufferSize = 1;
|
int readBufferSize = 1;
|
||||||
int writeBufferSize = 1;
|
int writeBufferSize = 1;
|
||||||
HeaderObject header;
|
HeaderObject header;
|
||||||
KCPObject(): header() {}
|
KCPObject() : header()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(mtu, tti, uplinkCapacity, downlinkCapacity, congestion, readBufferSize, writeBufferSize, header))
|
XTOSTRUCT(O(mtu, tti, uplinkCapacity, downlinkCapacity, congestion, readBufferSize, writeBufferSize, header))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct WebSocketObject {
|
struct WebSocketObject
|
||||||
|
{
|
||||||
QString path;
|
QString path;
|
||||||
QMap<QString, QString> headers;
|
QMap<QString, QString> headers;
|
||||||
WebSocketObject(): path("/"), headers() {}
|
WebSocketObject() : path("/"), headers()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(path, headers))
|
XTOSTRUCT(O(path, headers))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct HttpObject {
|
struct HttpObject
|
||||||
|
{
|
||||||
QList<QString> host;
|
QList<QString> host;
|
||||||
QString path;
|
QString path;
|
||||||
HttpObject() : host(), path("/") {}
|
HttpObject() : host(), path("/")
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(host, path))
|
XTOSTRUCT(O(host, path))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct DomainSocketObject {
|
struct DomainSocketObject
|
||||||
|
{
|
||||||
QString path;
|
QString path;
|
||||||
DomainSocketObject(): path("/") {}
|
DomainSocketObject() : path("/")
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(path))
|
XTOSTRUCT(O(path))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct QuicObject {
|
struct QuicObject
|
||||||
|
{
|
||||||
QString security;
|
QString security;
|
||||||
QString key;
|
QString key;
|
||||||
HeaderObject header;
|
HeaderObject header;
|
||||||
QuicObject(): security(""), key(""), header() {}
|
QuicObject() : security(""), key(""), header()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(security, key, header))
|
XTOSTRUCT(O(security, key, header))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct SockoptObject {
|
struct SockoptObject
|
||||||
|
{
|
||||||
int mark;
|
int mark;
|
||||||
bool tcpFastOpen;
|
bool tcpFastOpen;
|
||||||
QString tproxy;
|
QString tproxy;
|
||||||
SockoptObject(): mark(0), tcpFastOpen(false), tproxy("off") {}
|
SockoptObject() : mark(0), tcpFastOpen(false), tproxy("off")
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(mark, tcpFastOpen, tproxy))
|
XTOSTRUCT(O(mark, tcpFastOpen, tproxy))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct CertificateObject {
|
struct CertificateObject
|
||||||
|
{
|
||||||
QString usage;
|
QString usage;
|
||||||
QString certificateFile;
|
QString certificateFile;
|
||||||
QString keyFile;
|
QString keyFile;
|
||||||
QList<QString> certificate;
|
QList<QString> certificate;
|
||||||
QList<QString> key;
|
QList<QString> key;
|
||||||
CertificateObject(): usage(), certificateFile(), keyFile(), certificate(), key() {}
|
CertificateObject() : usage(), certificateFile(), keyFile(), certificate(), key()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(usage, certificateFile, keyFile, certificate, key))
|
XTOSTRUCT(O(usage, certificateFile, keyFile, certificate, key))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct TLSObject {
|
struct TLSObject
|
||||||
|
{
|
||||||
QString serverName;
|
QString serverName;
|
||||||
bool allowInsecure;
|
bool allowInsecure;
|
||||||
QList<QString> alpn;
|
QList<QString> alpn;
|
||||||
QList<CertificateObject> certificates;
|
QList<CertificateObject> certificates;
|
||||||
bool disableSystemRoot;
|
bool disableSystemRoot;
|
||||||
TLSObject(): serverName(), allowInsecure(), certificates(), disableSystemRoot() {}
|
TLSObject() : serverName(), allowInsecure(), certificates(), disableSystemRoot()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(serverName, allowInsecure, alpn, certificates, disableSystemRoot))
|
XTOSTRUCT(O(serverName, allowInsecure, alpn, certificates, disableSystemRoot))
|
||||||
};
|
};
|
||||||
}
|
} // namespace transfer
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct SniffingObject {
|
struct SniffingObject
|
||||||
|
{
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
QList<QString> destOverride;
|
QList<QString> destOverride;
|
||||||
SniffingObject(): enabled(), destOverride() {}
|
SniffingObject() : enabled(), destOverride()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(enabled, destOverride))
|
XTOSTRUCT(O(enabled, destOverride))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct StreamSettingsObject {
|
struct StreamSettingsObject
|
||||||
|
{
|
||||||
QString network;
|
QString network;
|
||||||
QString security;
|
QString security;
|
||||||
transfer::SockoptObject sockopt;
|
transfer::SockoptObject sockopt;
|
||||||
@ -225,15 +291,22 @@ namespace Qv2ray::base::objects
|
|||||||
transfer::HttpObject httpSettings;
|
transfer::HttpObject httpSettings;
|
||||||
transfer::DomainSocketObject dsSettings;
|
transfer::DomainSocketObject dsSettings;
|
||||||
transfer::QuicObject quicSettings;
|
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))
|
XTOSTRUCT(O(network, security, sockopt, tcpSettings, tlsSettings, kcpSettings, wsSettings, httpSettings, dsSettings, quicSettings))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
struct MuxObject {
|
struct MuxObject
|
||||||
|
{
|
||||||
bool enabled;
|
bool enabled;
|
||||||
int concurrency;
|
int concurrency;
|
||||||
MuxObject(): enabled(), concurrency() {}
|
MuxObject() : enabled(), concurrency()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(enabled, concurrency))
|
XTOSTRUCT(O(enabled, concurrency))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
@ -241,21 +314,28 @@ namespace Qv2ray::base::objects
|
|||||||
namespace protocol
|
namespace protocol
|
||||||
{
|
{
|
||||||
// DNS, OutBound
|
// DNS, OutBound
|
||||||
struct DNSOut {
|
struct DNSOut
|
||||||
|
{
|
||||||
QString network;
|
QString network;
|
||||||
QString address;
|
QString address;
|
||||||
int port;
|
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))
|
XTOSTRUCT(O(network, address, port))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
// MTProto, InBound || OutBound
|
// MTProto, InBound || OutBound
|
||||||
struct MTProtoIn {
|
struct MTProtoIn
|
||||||
struct UserObject {
|
{
|
||||||
|
struct UserObject
|
||||||
|
{
|
||||||
QString email;
|
QString email;
|
||||||
int level;
|
int level;
|
||||||
QString secret;
|
QString secret;
|
||||||
UserObject() : email("user@domain.com"), level(0), secret("") {}
|
UserObject() : email("user@domain.com"), level(0), secret("")
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(email, level, secret))
|
XTOSTRUCT(O(email, level, secret))
|
||||||
};
|
};
|
||||||
QList<UserObject> users;
|
QList<UserObject> users;
|
||||||
@ -263,42 +343,55 @@ namespace Qv2ray::base::objects
|
|||||||
};
|
};
|
||||||
//
|
//
|
||||||
// Socks, OutBound
|
// Socks, OutBound
|
||||||
struct SocksServerObject {
|
struct SocksServerObject
|
||||||
struct UserObject {
|
{
|
||||||
|
struct UserObject
|
||||||
|
{
|
||||||
QString user;
|
QString user;
|
||||||
QString pass;
|
QString pass;
|
||||||
int level;
|
int level;
|
||||||
UserObject(): user("username"), pass("password"), level(0) {}
|
UserObject() : user("username"), pass("password"), level(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(user, pass, level))
|
XTOSTRUCT(O(user, pass, level))
|
||||||
};
|
};
|
||||||
|
|
||||||
QString address;
|
QString address;
|
||||||
int port;
|
int port;
|
||||||
QList<UserObject> users;
|
QList<UserObject> users;
|
||||||
SocksServerObject(): address("0.0.0.0"), port(0), users() {}
|
SocksServerObject() : address("0.0.0.0"), port(0), users()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(address, port, users))
|
XTOSTRUCT(O(address, port, users))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
// VMess Server
|
// VMess Server
|
||||||
struct VMessServerObject {
|
struct VMessServerObject
|
||||||
struct UserObject {
|
{
|
||||||
|
struct UserObject
|
||||||
|
{
|
||||||
QString id;
|
QString id;
|
||||||
int alterId;
|
int alterId;
|
||||||
QString security;
|
QString security;
|
||||||
int level;
|
int level;
|
||||||
UserObject() : id(""), alterId(64), security("auto"), level(0) {}
|
UserObject() : id(""), alterId(64), security("auto"), level(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(id, alterId, security, level))
|
XTOSTRUCT(O(id, alterId, security, level))
|
||||||
};
|
};
|
||||||
|
|
||||||
QString address;
|
QString address;
|
||||||
int port;
|
int port;
|
||||||
QList<UserObject> users;
|
QList<UserObject> users;
|
||||||
VMessServerObject(): address(""), port(0), users() {}
|
VMessServerObject() : address(""), port(0), users()
|
||||||
|
{
|
||||||
|
}
|
||||||
XTOSTRUCT(O(address, port, users))
|
XTOSTRUCT(O(address, port, users))
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
// ShadowSocks Server
|
// ShadowSocks Server
|
||||||
struct ShadowSocksServerObject {
|
struct ShadowSocksServerObject
|
||||||
|
{
|
||||||
QString email;
|
QString email;
|
||||||
QString address;
|
QString address;
|
||||||
QString method;
|
QString method;
|
||||||
@ -306,8 +399,11 @@ namespace Qv2ray::base::objects
|
|||||||
bool ota;
|
bool ota;
|
||||||
int level;
|
int level;
|
||||||
int port;
|
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))
|
XTOSTRUCT(O(email, address, port, method, password, ota, level))
|
||||||
};
|
};
|
||||||
}
|
} // namespace protocol
|
||||||
}
|
} // namespace Qv2ray::base::objects
|
||||||
|
@ -1,56 +1,50 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "3rdparty/x2struct/x2struct.hpp"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include "3rdparty/x2struct/x2struct.hpp"
|
|
||||||
namespace Qv2ray::base
|
namespace Qv2ray::base
|
||||||
{
|
{
|
||||||
struct ConnectionIdentifier {
|
using namespace std::chrono;
|
||||||
QString subscriptionName;
|
// Common struct for Groups and Subscriptions
|
||||||
QString connectionName;
|
struct GroupObject_Config
|
||||||
ConnectionIdentifier() { };
|
{
|
||||||
bool isEmpty()
|
QString displayName;
|
||||||
|
QList<QString> connections;
|
||||||
|
int64_t importDate;
|
||||||
|
GroupObject_Config() : displayName(), connections(), importDate()
|
||||||
{
|
{
|
||||||
return connectionName.isEmpty();
|
|
||||||
}
|
}
|
||||||
ConnectionIdentifier(QString connectionName)
|
XTOSTRUCT(O(displayName, connections, importDate))
|
||||||
{
|
|
||||||
this->connectionName = connectionName;
|
|
||||||
}
|
|
||||||
ConnectionIdentifier(QString connectionName, QString subscriptionName)
|
|
||||||
{
|
|
||||||
this->connectionName = connectionName;
|
|
||||||
this->subscriptionName = subscriptionName;
|
|
||||||
}
|
|
||||||
const QString IdentifierString() const
|
|
||||||
{
|
|
||||||
return connectionName + (subscriptionName.isEmpty() ? "" : " (" + subscriptionName + ")");
|
|
||||||
}
|
|
||||||
friend bool operator==(ConnectionIdentifier &left, ConnectionIdentifier &right)
|
|
||||||
{
|
|
||||||
return left.subscriptionName == right.subscriptionName && left.connectionName == right.connectionName;
|
|
||||||
}
|
|
||||||
friend bool operator!=(ConnectionIdentifier &left, ConnectionIdentifier &right)
|
|
||||||
{
|
|
||||||
return !(left == right);
|
|
||||||
}
|
|
||||||
friend bool operator==(ConnectionIdentifier &left, QString &right)
|
|
||||||
{
|
|
||||||
return left.IdentifierString() == right;
|
|
||||||
}
|
|
||||||
friend bool operator!=(ConnectionIdentifier &left, QString &right)
|
|
||||||
{
|
|
||||||
return !(left.IdentifierString() == right);
|
|
||||||
}
|
|
||||||
// To make QMap happy
|
|
||||||
friend bool operator<(const ConnectionIdentifier left, const ConnectionIdentifier right)
|
|
||||||
{
|
|
||||||
return left.IdentifierString() < right.IdentifierString();
|
|
||||||
}
|
|
||||||
friend bool operator>(const ConnectionIdentifier left, const ConnectionIdentifier right)
|
|
||||||
{
|
|
||||||
return left.IdentifierString() > right.IdentifierString();
|
|
||||||
}
|
|
||||||
XTOSTRUCT(O(subscriptionName, connectionName))
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
Q_DECLARE_METATYPE(Qv2ray::base::ConnectionIdentifier);
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(lastUpdated, updateInterval, address, connections, displayName, importDate))
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(displayName, importDate, lastConnected, latency, upLinkData, downLinkData))
|
||||||
|
};
|
||||||
|
} // namespace Qv2ray::base
|
||||||
|
|
||||||
|
using namespace Qv2ray::base;
|
||||||
|
@ -1,184 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "3rdparty/x2struct/x2struct.hpp"
|
|
||||||
#include "base/models/CoreObjectModels.hpp"
|
|
||||||
#include "base/models/QvConfigIdentifier.hpp"
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
const int QV2RAY_CONFIG_VERSION = 8;
|
|
||||||
|
|
||||||
namespace Qv2ray::base
|
|
||||||
{
|
|
||||||
namespace config
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
struct QvBarLine {
|
|
||||||
QString Family;
|
|
||||||
bool Bold;
|
|
||||||
bool Italic;
|
|
||||||
int ColorA;
|
|
||||||
int ColorR;
|
|
||||||
int ColorG;
|
|
||||||
int 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("") { }
|
|
||||||
XTOSTRUCT(O(Bold, Italic, ColorA, ColorR, ColorG, ColorB, Size, Family, Message, ContentType))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QvBarPage {
|
|
||||||
int OffsetYpx;
|
|
||||||
QList<QvBarLine> Lines;
|
|
||||||
QvBarPage() : OffsetYpx(5) { }
|
|
||||||
XTOSTRUCT(O(OffsetYpx, Lines))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayToolBarConfig {
|
|
||||||
QList<QvBarPage> Pages;
|
|
||||||
XTOSTRUCT(O(Pages))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2raySubscriptionConfig {
|
|
||||||
time_t lastUpdated;
|
|
||||||
float updateInterval;
|
|
||||||
QString address;
|
|
||||||
Qv2raySubscriptionConfig() : lastUpdated(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())), updateInterval(5), address("") { }
|
|
||||||
XTOSTRUCT(O(lastUpdated, updateInterval, address))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayPACConfig {
|
|
||||||
bool enablePAC;
|
|
||||||
int port;
|
|
||||||
QString localIP;
|
|
||||||
bool useSocksProxy;
|
|
||||||
Qv2rayPACConfig() : enablePAC(false), port(8989), useSocksProxy(false) { }
|
|
||||||
XTOSTRUCT(O(enablePAC, port, localIP, useSocksProxy))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayForwardProxyConfig {
|
|
||||||
bool enableForwardProxy;
|
|
||||||
QString type;
|
|
||||||
QString serverAddress;
|
|
||||||
int port;
|
|
||||||
bool useAuth;
|
|
||||||
QString username;
|
|
||||||
QString password;
|
|
||||||
|
|
||||||
Qv2rayForwardProxyConfig() :
|
|
||||||
enableForwardProxy(false),
|
|
||||||
type("http"), serverAddress("127.0.0.1"), port(8008), useAuth(false),
|
|
||||||
username("username"), password("password")
|
|
||||||
{ }
|
|
||||||
|
|
||||||
XTOSTRUCT(O(enableForwardProxy, type, serverAddress, port, useAuth, username, password))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayInboundsConfig {
|
|
||||||
QString listenip;
|
|
||||||
bool setSystemProxy;
|
|
||||||
Qv2rayPACConfig pacConfig;
|
|
||||||
|
|
||||||
// SOCKS
|
|
||||||
bool useSocks;
|
|
||||||
int socks_port;
|
|
||||||
bool socks_useAuth;
|
|
||||||
bool socksUDP;
|
|
||||||
QString socksLocalIP;
|
|
||||||
objects::AccountObject socksAccount;
|
|
||||||
// HTTP
|
|
||||||
bool useHTTP;
|
|
||||||
int http_port;
|
|
||||||
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() {}
|
|
||||||
|
|
||||||
XTOSTRUCT(O(setSystemProxy, pacConfig, listenip, useSocks, useHTTP, socks_port, socks_useAuth, socksAccount, socksUDP, socksLocalIP, http_port, http_useAuth, httpAccount))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayUIConfig {
|
|
||||||
QString theme;
|
|
||||||
QString language;
|
|
||||||
bool useDarkTheme;
|
|
||||||
bool useDarkTrayIcon;
|
|
||||||
int maximumLogLines;
|
|
||||||
Qv2rayUIConfig() : theme("Fusion"), language("en_US"), useDarkTheme(false), useDarkTrayIcon(true), maximumLogLines(500) { }
|
|
||||||
XTOSTRUCT(O(theme, language, useDarkTheme, useDarkTrayIcon, maximumLogLines))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayConnectionConfig {
|
|
||||||
bool bypassCN;
|
|
||||||
bool enableProxy;
|
|
||||||
bool withLocalDNS;
|
|
||||||
QList<QString> dnsList;
|
|
||||||
Qv2rayForwardProxyConfig forwardProxyConfig;
|
|
||||||
|
|
||||||
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 {
|
|
||||||
bool enableAPI;
|
|
||||||
int statsPort;
|
|
||||||
Qv2rayAPIConfig(): enableAPI(true), statsPort(15490) { }
|
|
||||||
XTOSTRUCT(O(enableAPI, statsPort))
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Qv2rayConfig {
|
|
||||||
int config_version;
|
|
||||||
bool tProxySupport;
|
|
||||||
int logLevel;
|
|
||||||
//
|
|
||||||
QString v2CorePath;
|
|
||||||
QString v2AssetsPath;
|
|
||||||
ConnectionIdentifier autoStartConfig;
|
|
||||||
QString ignoredVersion;
|
|
||||||
//
|
|
||||||
QList<QString> configs;
|
|
||||||
QMap<QString, Qv2raySubscriptionConfig> subscriptions;
|
|
||||||
//
|
|
||||||
Qv2rayUIConfig uiConfig;
|
|
||||||
Qv2rayAPIConfig apiConfig;
|
|
||||||
Qv2rayInboundsConfig inboundConfig;
|
|
||||||
Qv2rayConnectionConfig connectionConfig;
|
|
||||||
Qv2rayToolBarConfig toolBarConfig;
|
|
||||||
|
|
||||||
Qv2rayConfig():
|
|
||||||
config_version(QV2RAY_CONFIG_VERSION),
|
|
||||||
tProxySupport(false),
|
|
||||||
logLevel(),
|
|
||||||
v2CorePath(),
|
|
||||||
v2AssetsPath(),
|
|
||||||
autoStartConfig(),
|
|
||||||
ignoredVersion(),
|
|
||||||
configs(),
|
|
||||||
subscriptions(),
|
|
||||||
uiConfig(),
|
|
||||||
apiConfig(),
|
|
||||||
inboundConfig(),
|
|
||||||
connectionConfig(),
|
|
||||||
toolBarConfig() { }
|
|
||||||
|
|
||||||
XTOSTRUCT(O(config_version,
|
|
||||||
ignoredVersion,
|
|
||||||
tProxySupport,
|
|
||||||
logLevel,
|
|
||||||
autoStartConfig,
|
|
||||||
v2CorePath, v2AssetsPath,
|
|
||||||
configs,
|
|
||||||
uiConfig,
|
|
||||||
subscriptions, inboundConfig, connectionConfig, toolBarConfig, apiConfig))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
namespace Qv2ray::base
|
namespace Qv2ray::base
|
||||||
{
|
{
|
||||||
struct Qv2rayRuntimeConfig {
|
struct Qv2rayRuntimeConfig
|
||||||
//
|
{
|
||||||
bool screenShotHideQv2ray = false;
|
bool screenShotHideQv2ray = false;
|
||||||
};
|
};
|
||||||
}
|
inline base::Qv2rayRuntimeConfig RuntimeConfig = base::Qv2rayRuntimeConfig();
|
||||||
|
} // namespace Qv2ray::base
|
||||||
|
@ -1,17 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#define SAFE_TYPEDEF(Base, name) \
|
#define SAFE_TYPEDEF_EXTRA(Base, name, extra) \
|
||||||
class name : public Base { \
|
class name : public Base \
|
||||||
public: \
|
{ \
|
||||||
template <class... Args> \
|
public: \
|
||||||
explicit name (Args... args) : Base(args...) {} \
|
template<class... Args> \
|
||||||
const Base& raw() const { return *this; } \
|
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)
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
namespace Qv2ray::base::safetype
|
namespace Qv2ray::base::safetype
|
||||||
{
|
{
|
||||||
// To prevent anonying QJsonObject misuse
|
// To prevent anonying QJsonObject misuse
|
||||||
@ -22,10 +32,10 @@ namespace Qv2ray::base::safetype
|
|||||||
SAFE_TYPEDEF(QJsonObject, CONFIGROOT)
|
SAFE_TYPEDEF(QJsonObject, CONFIGROOT)
|
||||||
SAFE_TYPEDEF(QJsonObject, PROXYSETTING)
|
SAFE_TYPEDEF(QJsonObject, PROXYSETTING)
|
||||||
//
|
//
|
||||||
|
SAFE_TYPEDEF(QJsonArray, ROUTERULELIST)
|
||||||
SAFE_TYPEDEF(QJsonArray, INOUTLIST)
|
SAFE_TYPEDEF(QJsonArray, INOUTLIST)
|
||||||
SAFE_TYPEDEF(INOUTLIST, OUTBOUNDS)
|
|
||||||
SAFE_TYPEDEF(INOUTLIST, INBOUNDS)
|
|
||||||
SAFE_TYPEDEF(QJsonObject, ROUTING)
|
SAFE_TYPEDEF(QJsonObject, ROUTING)
|
||||||
SAFE_TYPEDEF(QJsonObject, ROUTERULE)
|
SAFE_TYPEDEF(QJsonObject, ROUTERULE)
|
||||||
SAFE_TYPEDEF(QJsonArray, ROUTERULELIST)
|
SAFE_TYPEDEF(INOUTLIST, OUTBOUNDS)
|
||||||
}
|
SAFE_TYPEDEF(INOUTLIST, INBOUNDS)
|
||||||
|
} // namespace Qv2ray::base::safetype
|
||||||
|
209
src/base/models/QvSettingsObject.hpp
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "3rdparty/x2struct/x2struct.hpp"
|
||||||
|
#include "base/models/CoreObjectModels.hpp"
|
||||||
|
#include "base/models/QvConfigIdentifier.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
const int QV2RAY_CONFIG_VERSION = 10;
|
||||||
|
|
||||||
|
namespace Qv2ray::base::config
|
||||||
|
{
|
||||||
|
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("")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(Bold, Italic, ColorA, ColorR, ColorG, ColorB, Size, Family, Message, ContentType))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QvBarPage
|
||||||
|
{
|
||||||
|
int OffsetYpx;
|
||||||
|
QList<QvBarLine> Lines;
|
||||||
|
QvBarPage() : OffsetYpx(5)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(OffsetYpx, Lines))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayToolBarConfig
|
||||||
|
{
|
||||||
|
QList<QvBarPage> Pages;
|
||||||
|
XTOSTRUCT(O(Pages))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayPACConfig
|
||||||
|
{
|
||||||
|
bool enablePAC;
|
||||||
|
int port;
|
||||||
|
QString localIP;
|
||||||
|
bool useSocksProxy;
|
||||||
|
Qv2rayPACConfig() : enablePAC(false), port(8989), useSocksProxy(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(enablePAC, port, localIP, useSocksProxy))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayForwardProxyConfig
|
||||||
|
{
|
||||||
|
bool enableForwardProxy;
|
||||||
|
QString type;
|
||||||
|
QString serverAddress;
|
||||||
|
int port;
|
||||||
|
bool useAuth;
|
||||||
|
QString username;
|
||||||
|
QString 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
|
||||||
|
{
|
||||||
|
QString listenip;
|
||||||
|
bool setSystemProxy;
|
||||||
|
Qv2rayPACConfig pacConfig;
|
||||||
|
|
||||||
|
// SOCKS
|
||||||
|
bool useSocks;
|
||||||
|
int socks_port;
|
||||||
|
bool socks_useAuth;
|
||||||
|
bool socksUDP;
|
||||||
|
QString socksLocalIP;
|
||||||
|
objects::AccountObject socksAccount;
|
||||||
|
// HTTP
|
||||||
|
bool useHTTP;
|
||||||
|
int http_port;
|
||||||
|
bool http_useAuth;
|
||||||
|
objects::AccountObject httpAccount;
|
||||||
|
|
||||||
|
Qv2rayInboundsConfig()
|
||||||
|
: listenip("127.0.0.1"), setSystemProxy(true), 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))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayUIConfig
|
||||||
|
{
|
||||||
|
QString theme;
|
||||||
|
QString language;
|
||||||
|
bool useDarkTheme;
|
||||||
|
bool useDarkTrayIcon;
|
||||||
|
int maximumLogLines;
|
||||||
|
Qv2rayUIConfig() : theme("Fusion"), language("en_US"), useDarkTheme(false), useDarkTrayIcon(true), maximumLogLines(500)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(theme, language, useDarkTheme, useDarkTrayIcon, maximumLogLines))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayConnectionConfig
|
||||||
|
{
|
||||||
|
bool bypassCN;
|
||||||
|
bool enableProxy;
|
||||||
|
bool withLocalDNS;
|
||||||
|
QList<QString> dnsList;
|
||||||
|
Qv2rayForwardProxyConfig forwardProxyConfig;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
bool enableAPI;
|
||||||
|
int statsPort;
|
||||||
|
Qv2rayAPIConfig() : enableAPI(true), statsPort(15490)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
XTOSTRUCT(O(enableAPI, statsPort))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayKernelConfig
|
||||||
|
{
|
||||||
|
QString v2CorePath_linux;
|
||||||
|
QString v2AssetsPath_linux;
|
||||||
|
QString v2CorePath_macx;
|
||||||
|
QString v2AssetsPath_macx;
|
||||||
|
QString v2CorePath_win;
|
||||||
|
QString v2AssetsPath_win; //
|
||||||
|
Qv2rayKernelConfig()
|
||||||
|
: v2CorePath_linux(), v2AssetsPath_linux(), //
|
||||||
|
v2CorePath_macx(), v2AssetsPath_macx(), //
|
||||||
|
v2CorePath_win(), v2AssetsPath_win() //
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#define _VARNAME_VCOREPATH_ v2CorePath_linux
|
||||||
|
#define _VARNAME_VASSETSPATH_ v2AssetsPath_linux
|
||||||
|
#elif defined(Q_OS_MACOS)
|
||||||
|
#define _VARNAME_VCOREPATH_ v2CorePath_macx
|
||||||
|
#define _VARNAME_VASSETSPATH_ v2AssetsPath_macx
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
#define _VARNAME_VCOREPATH_ v2CorePath_win
|
||||||
|
#define _VARNAME_VASSETSPATH_ v2AssetsPath_win
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline const QString KernelPath(const QString &path = "")
|
||||||
|
{
|
||||||
|
return path.isEmpty() ? _VARNAME_VCOREPATH_ : _VARNAME_VCOREPATH_ = path;
|
||||||
|
}
|
||||||
|
inline const QString AssetsPath(const QString &path = "")
|
||||||
|
{
|
||||||
|
return path.isEmpty() ? _VARNAME_VASSETSPATH_ : _VARNAME_VASSETSPATH_ = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef _VARNAME_VCOREPATH_
|
||||||
|
#undef _VARNAME_VASSETSPATH_
|
||||||
|
|
||||||
|
XTOSTRUCT(O(v2CorePath_linux, v2AssetsPath_linux, v2CorePath_macx, v2AssetsPath_macx, v2CorePath_win, v2AssetsPath_win))
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Qv2rayConfig
|
||||||
|
{
|
||||||
|
int config_version;
|
||||||
|
bool tProxySupport;
|
||||||
|
int logLevel;
|
||||||
|
//
|
||||||
|
QString ignoredVersion;
|
||||||
|
QString autoStartId;
|
||||||
|
//
|
||||||
|
// Key = groupId, connectionId
|
||||||
|
QMap<QString, GroupObject_Config> groups;
|
||||||
|
QMap<QString, SubscriptionObject_Config> subscriptions;
|
||||||
|
/// Connections are used privately.
|
||||||
|
QMap<QString, ConnectionObject_Config> connections;
|
||||||
|
//
|
||||||
|
Qv2rayUIConfig uiConfig;
|
||||||
|
Qv2rayAPIConfig apiConfig;
|
||||||
|
Qv2rayKernelConfig kernelConfig;
|
||||||
|
Qv2rayToolBarConfig toolBarConfig;
|
||||||
|
Qv2rayInboundsConfig inboundConfig;
|
||||||
|
Qv2rayConnectionConfig connectionConfig;
|
||||||
|
|
||||||
|
Qv2rayConfig()
|
||||||
|
: config_version(QV2RAY_CONFIG_VERSION), tProxySupport(false), logLevel(), ignoredVersion(), autoStartId("null"), groups(),
|
||||||
|
subscriptions(), connections(), uiConfig(), apiConfig(), kernelConfig(), toolBarConfig(), inboundConfig(), connectionConfig()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
XTOSTRUCT(O(config_version, ignoredVersion, tProxySupport, logLevel, uiConfig, kernelConfig, groups, connections, subscriptions,
|
||||||
|
autoStartId, inboundConfig, connectionConfig, toolBarConfig, apiConfig))
|
||||||
|
};
|
||||||
|
} // namespace Qv2ray::base::config
|
@ -4,7 +4,8 @@ namespace Qv2ray
|
|||||||
{
|
{
|
||||||
namespace base
|
namespace base
|
||||||
{
|
{
|
||||||
struct QvStartupOptions {
|
struct QvStartupOptions
|
||||||
|
{
|
||||||
/// No API subsystem
|
/// No API subsystem
|
||||||
bool noAPI;
|
bool noAPI;
|
||||||
/// Explicitly run as root user.
|
/// Explicitly run as root user.
|
||||||
@ -14,5 +15,6 @@ namespace Qv2ray
|
|||||||
/// Enable Network toolbar plugin.
|
/// Enable Network toolbar plugin.
|
||||||
bool enableToolbarPlguin;
|
bool enableToolbarPlguin;
|
||||||
};
|
};
|
||||||
}
|
} // namespace base
|
||||||
}
|
inline base::QvStartupOptions StartupOption = base::QvStartupOptions();
|
||||||
|
} // namespace Qv2ray
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
#include "CommandArgs.hpp"
|
#include "CommandArgs.hpp"
|
||||||
|
|
||||||
#include "base/Qv2rayBase.hpp"
|
#include "base/Qv2rayBase.hpp"
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
QvCommandArgParser::QvCommandArgParser() : QObject(),
|
QvCommandArgParser::QvCommandArgParser()
|
||||||
noAPIOption("noAPI", QObject::tr("Disable gRPC API subsystems.")),
|
: QObject(), noAPIOption("noAPI", QObject::tr("Disable gRPC API subsystems.")),
|
||||||
runAsRootOption("I-just-wanna-run-with-root", QObject::tr("Explicitly run Qv2ray as root.")),
|
runAsRootOption("I-just-wanna-run-with-root", QObject::tr("Explicitly run Qv2ray as root.")),
|
||||||
debugOption("debug", QObject::tr("Enable Debug Output")),
|
debugOption("debug", QObject::tr("Enable Debug Output")),
|
||||||
withToolbarOption("withToolbarPlugin", QObject::tr("Enable Qv2ray network toolbar plugin")),
|
withToolbarOption("withToolbarPlugin", QObject::tr("Enable Qv2ray network toolbar plugin")),
|
||||||
//
|
//
|
||||||
helpOption("FAKE"), versionOption("FAKE")
|
helpOption("FAKE"), versionOption("FAKE")
|
||||||
{
|
{
|
||||||
parser.setApplicationDescription(QObject::tr("Qv2ray - A cross-platform Qt frontend for V2ray."));
|
parser.setApplicationDescription(QObject::tr("Qv2ray - A cross-platform Qt frontend for V2ray."));
|
||||||
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
|
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
|
||||||
@ -24,7 +25,8 @@ namespace Qv2ray::common
|
|||||||
|
|
||||||
CommandLineParseResult QvCommandArgParser::ParseCommandLine(QString *errorMessage)
|
CommandLineParseResult QvCommandArgParser::ParseCommandLine(QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (!parser.parse(QCoreApplication::arguments())) {
|
if (!parser.parse(QCoreApplication::arguments()))
|
||||||
|
{
|
||||||
*errorMessage = parser.errorText();
|
*errorMessage = parser.errorText();
|
||||||
return CommandLineError;
|
return CommandLineError;
|
||||||
}
|
}
|
||||||
@ -35,27 +37,31 @@ namespace Qv2ray::common
|
|||||||
if (parser.isSet(helpOption))
|
if (parser.isSet(helpOption))
|
||||||
return CommandLineHelpRequested;
|
return CommandLineHelpRequested;
|
||||||
|
|
||||||
if (parser.isSet(noAPIOption)) {
|
if (parser.isSet(noAPIOption))
|
||||||
DEBUG(INIT, "noAPIOption is set.")
|
{
|
||||||
|
DEBUG(MODULE_INIT, "noAPIOption is set.")
|
||||||
StartupOption.noAPI = true;
|
StartupOption.noAPI = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser.isSet(runAsRootOption)) {
|
if (parser.isSet(runAsRootOption))
|
||||||
DEBUG(INIT, "runAsRootOption is set.")
|
{
|
||||||
|
DEBUG(MODULE_INIT, "runAsRootOption is set.")
|
||||||
StartupOption.forceRunAsRootUser = true;
|
StartupOption.forceRunAsRootUser = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser.isSet(debugOption)) {
|
if (parser.isSet(debugOption))
|
||||||
DEBUG(INIT, "debugOption is set.")
|
{
|
||||||
|
DEBUG(MODULE_INIT, "debugOption is set.")
|
||||||
StartupOption.debugLog = true;
|
StartupOption.debugLog = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser.isSet(withToolbarOption)) {
|
if (parser.isSet(withToolbarOption))
|
||||||
DEBUG(INIT, "withToolbarOption is set.")
|
{
|
||||||
|
DEBUG(MODULE_INIT, "withToolbarOption is set.")
|
||||||
StartupOption.enableToolbarPlguin = true;
|
StartupOption.enableToolbarPlguin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommandLineOk;
|
return CommandLineOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
enum CommandLineParseResult {
|
enum CommandLineParseResult
|
||||||
|
{
|
||||||
CommandLineOk,
|
CommandLineOk,
|
||||||
CommandLineError,
|
CommandLineError,
|
||||||
CommandLineVersionRequested,
|
CommandLineVersionRequested,
|
||||||
@ -12,24 +13,24 @@ namespace Qv2ray::common
|
|||||||
};
|
};
|
||||||
class QvCommandArgParser : public QObject
|
class QvCommandArgParser : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QvCommandArgParser();
|
QvCommandArgParser();
|
||||||
CommandLineParseResult ParseCommandLine(QString *errorMessage);
|
CommandLineParseResult ParseCommandLine(QString *errorMessage);
|
||||||
const QCommandLineParser *Parser()
|
const QCommandLineParser *Parser()
|
||||||
{
|
{
|
||||||
return &parser;
|
return &parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
QCommandLineOption noAPIOption;
|
QCommandLineOption noAPIOption;
|
||||||
QCommandLineOption runAsRootOption;
|
QCommandLineOption runAsRootOption;
|
||||||
QCommandLineOption debugOption;
|
QCommandLineOption debugOption;
|
||||||
QCommandLineOption withToolbarOption;
|
QCommandLineOption withToolbarOption;
|
||||||
QCommandLineOption helpOption;
|
QCommandLineOption helpOption;
|
||||||
QCommandLineOption versionOption;
|
QCommandLineOption versionOption;
|
||||||
};
|
};
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
|
||||||
using namespace Qv2ray::common;
|
using namespace Qv2ray::common;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#include "HTTPRequestHelper.hpp"
|
#include "HTTPRequestHelper.hpp"
|
||||||
|
|
||||||
|
#include "base/Qv2rayBase.hpp"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
#include "base/Qv2rayBase.hpp"
|
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
QvHttpRequestHelper::QvHttpRequestHelper() : reply()
|
QvHttpRequestHelper::QvHttpRequestHelper(QObject *parent) : QObject(parent), reply()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,8 +20,9 @@ namespace Qv2ray::common
|
|||||||
{
|
{
|
||||||
QUrl qUrl = QUrl(url);
|
QUrl qUrl = QUrl(url);
|
||||||
|
|
||||||
if (!qUrl.isValid()) {
|
if (!qUrl.isValid())
|
||||||
LOG(NETWORK, "Provided URL is invalid: " + url)
|
{
|
||||||
|
LOG(MODULE_NETWORK, "Provided URL is invalid: " + url)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +32,7 @@ namespace Qv2ray::common
|
|||||||
|
|
||||||
void QvHttpRequestHelper::setHeader(const QByteArray &key, const QByteArray &value)
|
void QvHttpRequestHelper::setHeader(const QByteArray &key, const QByteArray &value)
|
||||||
{
|
{
|
||||||
DEBUG(NETWORK, "Adding HTTP request header: " + key + ":" + value)
|
DEBUG(MODULE_NETWORK, "Adding HTTP request header: " + key + ":" + value)
|
||||||
request.setRawHeader(key, value);
|
request.setRawHeader(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,17 +40,22 @@ namespace Qv2ray::common
|
|||||||
{
|
{
|
||||||
this->setUrl(url);
|
this->setUrl(url);
|
||||||
|
|
||||||
if (useProxy) {
|
if (useProxy)
|
||||||
|
{
|
||||||
auto proxy = QNetworkProxyFactory::systemProxyForQuery();
|
auto proxy = QNetworkProxyFactory::systemProxyForQuery();
|
||||||
accessManager.setProxy(proxy.first());
|
accessManager.setProxy(proxy.first());
|
||||||
} else {
|
LOG(MODULE_NETWORK, "Sync get is using system proxy settings")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
accessManager.setProxy(QNetworkProxy(QNetworkProxy::ProxyType::NoProxy));
|
accessManager.setProxy(QNetworkProxy(QNetworkProxy::ProxyType::NoProxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(NETWORK, "Sync get is using system proxy settings")
|
|
||||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||||
|
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, "Mozilla/5.0 (rv:71.0) Gecko/20100101 Firefox/71.0");
|
||||||
reply = accessManager.get(request);
|
reply = accessManager.get(request);
|
||||||
connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished);
|
connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished_p);
|
||||||
//
|
//
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||||
@ -60,28 +68,34 @@ namespace Qv2ray::common
|
|||||||
void QvHttpRequestHelper::get(const QString &url)
|
void QvHttpRequestHelper::get(const QString &url)
|
||||||
{
|
{
|
||||||
this->setUrl(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);
|
reply = accessManager.get(request);
|
||||||
connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished);
|
connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished_p);
|
||||||
connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead);
|
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);
|
// this->setUrl(url);
|
||||||
// request.setRawHeader("Content-Type", "application/json");
|
// request.setRawHeader("Content-Type", "application/json");
|
||||||
// reply = accessManager.post(request, data);
|
// reply = accessManager.post(request, data);
|
||||||
// connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished);
|
// connect(reply, &QNetworkReply::finished, this,
|
||||||
// connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead);
|
// &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);
|
// this->setUrl(url);
|
||||||
// request.setRawHeader("Content-Type", "application/json");
|
// request.setRawHeader("Content-Type", "application/json");
|
||||||
// reply = accessManager.put(request, data);
|
// reply = accessManager.put(request, data);
|
||||||
// connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished);
|
// connect(reply, &QNetworkReply::finished, this,
|
||||||
// connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead);
|
// &QvHttpRequestHelper::onRequestFinished); connect(reply,
|
||||||
|
// &QNetworkReply::readyRead, this,
|
||||||
|
// &QvHttpRequestHelper::onReadyRead);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void QvHttpRequestHelper::del(const QString &url)
|
// void QvHttpRequestHelper::del(const QString &url)
|
||||||
@ -89,28 +103,46 @@ namespace Qv2ray::common
|
|||||||
// this->setUrl(url);
|
// this->setUrl(url);
|
||||||
// request.setRawHeader("Content-Type", "application/json");
|
// request.setRawHeader("Content-Type", "application/json");
|
||||||
// reply = accessManager.deleteResource(request);
|
// reply = accessManager.deleteResource(request);
|
||||||
// connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished);
|
// connect(reply, &QNetworkReply::finished, this,
|
||||||
// connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead);
|
// &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);
|
// this->setUrl(url);
|
||||||
// request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
// request.setRawHeader("Content-Type",
|
||||||
// reply = accessManager.post(request, data);
|
// "application/x-www-form-urlencoded"); reply =
|
||||||
// connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished);
|
// accessManager.post(request, data); connect(reply,
|
||||||
// connect(reply, &QNetworkReply::readyRead, this, &QvHttpRequestHelper::onReadyRead);
|
// &QNetworkReply::finished, this,
|
||||||
|
// &QvHttpRequestHelper::onRequestFinished); connect(reply,
|
||||||
|
// &QNetworkReply::readyRead, this,
|
||||||
|
// &QvHttpRequestHelper::onReadyRead);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void QvHttpRequestHelper::onRequestFinished()
|
void QvHttpRequestHelper::onRequestFinished_p()
|
||||||
{
|
{
|
||||||
LOG(NETWORK, "Network request errcode: " + QSTRN(reply->error()))
|
if (reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute).toBool())
|
||||||
|
{
|
||||||
|
DEBUG(MODULE_NETWORK, "HTTP/2 was used.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply->error() != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
QString error = QMetaEnum::fromType<QNetworkReply::NetworkError>().key(reply->error());
|
||||||
|
LOG(MODULE_NETWORK, "Network request error string: " + error)
|
||||||
|
QByteArray empty;
|
||||||
|
emit httpRequestFinished(empty);
|
||||||
|
}
|
||||||
|
|
||||||
emit httpRequestFinished(this->data);
|
emit httpRequestFinished(this->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QvHttpRequestHelper::onReadyRead()
|
void QvHttpRequestHelper::onReadyRead()
|
||||||
{
|
{
|
||||||
DEBUG(NETWORK, "A request is now ready read")
|
DEBUG(MODULE_NETWORK, "A request is now ready read")
|
||||||
this->data += reply->readAll();
|
this->data += reply->readAll();
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
@ -18,45 +18,46 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
class QvHttpRequestHelper : public QObject
|
class QvHttpRequestHelper : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit QvHttpRequestHelper();
|
explicit QvHttpRequestHelper(QObject *parent = nullptr);
|
||||||
~QvHttpRequestHelper();
|
~QvHttpRequestHelper();
|
||||||
bool setUrl(const QString &url);
|
bool setUrl(const QString &url);
|
||||||
void setHeader(const QByteArray &key, const QByteArray &value);
|
void setHeader(const QByteArray &key, const QByteArray &value);
|
||||||
// get
|
// get
|
||||||
QByteArray syncget(const QString &url, bool useProxy);
|
QByteArray syncget(const QString &url, bool useProxy);
|
||||||
void get(const QString &url);
|
void get(const QString &url);
|
||||||
//// insert
|
//// insert
|
||||||
//void post(const QString &url, const QByteArray &data);
|
// void post(const QString &url, const QByteArray &data);
|
||||||
//// update
|
//// update
|
||||||
//void put(const QString &url, const QByteArray &data);
|
// void put(const QString &url, const QByteArray &data);
|
||||||
//// delete
|
//// delete
|
||||||
//void del(const QString &url);
|
// void del(const QString &url);
|
||||||
//void login(const QString &url, const QByteArray &data);
|
// void login(const QString &url, const QByteArray &data);
|
||||||
signals:
|
signals:
|
||||||
void httpRequestFinished(QByteArray &data);
|
void httpRequestFinished(QByteArray &data);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onRequestFinished();
|
void onRequestFinished_p();
|
||||||
private slots:
|
private slots:
|
||||||
void onReadyRead();
|
void onReadyRead();
|
||||||
private:
|
|
||||||
QByteArray data;
|
private:
|
||||||
QUrl url;
|
QByteArray data;
|
||||||
QNetworkReply *reply;
|
QUrl url;
|
||||||
QNetworkRequest request;
|
QNetworkReply *reply;
|
||||||
QNetworkAccessManager accessManager;
|
QNetworkRequest request;
|
||||||
|
QNetworkAccessManager accessManager;
|
||||||
};
|
};
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
|
||||||
using namespace Qv2ray::common;
|
using namespace Qv2ray::common;
|
||||||
|
111
src/common/JsonHighlighter.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include "JsonHighlighter.hpp"
|
||||||
|
|
||||||
|
#include "core/settings/SettingsBackend.hpp"
|
||||||
|
|
||||||
|
namespace Qv2ray::common
|
||||||
|
{
|
||||||
|
vCoreConfigJsonHighlighter::vCoreConfigJsonHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||||
|
{
|
||||||
|
QTextCharFormat keywordFormat;
|
||||||
|
keywordFormat.setForeground(GlobalConfig.uiConfig.useDarkTheme ? Qt::GlobalColor::magenta : Qt::darkMagenta);
|
||||||
|
keywordFormat.setFontWeight(QFont::Bold);
|
||||||
|
// It's holy a dirty hack here, we'll fully ultilize the vCoreConfig models.
|
||||||
|
auto keywordPatterns = { "inbounds",
|
||||||
|
"outbounds",
|
||||||
|
"routing",
|
||||||
|
"settings",
|
||||||
|
"transport",
|
||||||
|
"request",
|
||||||
|
"headers",
|
||||||
|
"ip",
|
||||||
|
"tag",
|
||||||
|
"protocol",
|
||||||
|
"listen",
|
||||||
|
"rules",
|
||||||
|
"port",
|
||||||
|
"reverse",
|
||||||
|
"dsSettings",
|
||||||
|
"httpSettings",
|
||||||
|
"kcpSettings",
|
||||||
|
"network",
|
||||||
|
"quicSettings",
|
||||||
|
"security",
|
||||||
|
"sockopt",
|
||||||
|
"tcpSettings",
|
||||||
|
"tlsSettings",
|
||||||
|
"wsSettings",
|
||||||
|
"streamSettings",
|
||||||
|
"mux",
|
||||||
|
"sendThrough",
|
||||||
|
"vnext",
|
||||||
|
"address",
|
||||||
|
"users",
|
||||||
|
"alterId",
|
||||||
|
"id",
|
||||||
|
"level",
|
||||||
|
"path",
|
||||||
|
"host",
|
||||||
|
"congestion",
|
||||||
|
"downlinkCapacity",
|
||||||
|
"header",
|
||||||
|
"type",
|
||||||
|
"mtu",
|
||||||
|
"readBufferSize",
|
||||||
|
"tti",
|
||||||
|
"uplinkCapacity",
|
||||||
|
"writeBufferSize",
|
||||||
|
"key",
|
||||||
|
"mark",
|
||||||
|
"tcpFastOpen",
|
||||||
|
"tproxy",
|
||||||
|
"allowInsecure",
|
||||||
|
"alpn",
|
||||||
|
"disableSystemRoot",
|
||||||
|
"certificates",
|
||||||
|
"serverName",
|
||||||
|
"QV2RAY_RULE_ENABLED",
|
||||||
|
"QV2RAY_RULE_TAG",
|
||||||
|
"QV2RAY_RULE_USE_BALANCER" };
|
||||||
|
int i = 0;
|
||||||
|
for (const QString &pattern : keywordPatterns)
|
||||||
|
{
|
||||||
|
SetRule(QString("00_KeyWord_%1").arg(i), "\"" + pattern + "\"", keywordFormat);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Values
|
||||||
|
QTextCharFormat valueFormat, classFormat;
|
||||||
|
valueFormat.setForeground(Qt::blue);
|
||||||
|
SetRule("03_Values", "\\btrue\\b|\\bfalse\\b|\\b[0-9]+\\b", valueFormat);
|
||||||
|
//
|
||||||
|
// Single Line Comments
|
||||||
|
QTextCharFormat singleLineCommentFormat;
|
||||||
|
singleLineCommentFormat.setForeground(Qt::darkGreen);
|
||||||
|
SetRule("z2_SingleLineComments", "//[^\n]*", singleLineCommentFormat);
|
||||||
|
}
|
||||||
|
void vCoreConfigJsonHighlighter::SetRule(const QString &kind, const QString &pattern, QTextCharFormat format)
|
||||||
|
{
|
||||||
|
JsonHighlightingRule rule;
|
||||||
|
rule.name = kind;
|
||||||
|
rule.pattern = QRegularExpression(pattern);
|
||||||
|
rule.format = format;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vCoreConfigJsonHighlighter::highlightBlock(const QString &text)
|
||||||
|
{
|
||||||
|
for (const auto &rule : std::as_const(highlightingRules))
|
||||||
|
{
|
||||||
|
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||||
|
|
||||||
|
while (matchIterator.hasNext())
|
||||||
|
{
|
||||||
|
QRegularExpressionMatch match = matchIterator.next();
|
||||||
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentBlockState(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Qv2ray::common
|
29
src/common/JsonHighlighter.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
namespace Qv2ray::common
|
||||||
|
{
|
||||||
|
struct JsonHighlightingRule
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
QRegularExpression pattern;
|
||||||
|
QTextCharFormat format;
|
||||||
|
};
|
||||||
|
class vCoreConfigJsonHighlighter : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
vCoreConfigJsonHighlighter(QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<JsonHighlightingRule> highlightingRules;
|
||||||
|
void SetRule(const QString &kind, const QString &pattern, QTextCharFormat format);
|
||||||
|
void highlightBlock(const QString &text) override;
|
||||||
|
};
|
||||||
|
} // namespace Qv2ray::common
|
||||||
|
using namespace Qv2ray::common;
|
@ -1,30 +1,32 @@
|
|||||||
#include "LogHighlighter.hpp"
|
#include "LogHighlighter.hpp"
|
||||||
|
|
||||||
#include "common/QvHelpers.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
|
|
||||||
#define TO_EOL "(([\\s\\S]*)|([\\d\\D]*)|([\\w\\W]*))$"
|
#define TO_EOL "(([\\s\\S]*)|([\\d\\D]*)|([\\w\\W]*))$"
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
SyntaxHighlighter::SyntaxHighlighter(bool darkMode, QTextDocument *parent)
|
SyntaxHighlighter::SyntaxHighlighter(bool darkMode, QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||||
: QSyntaxHighlighter(parent)
|
|
||||||
{
|
{
|
||||||
HighlightingRule rule;
|
HighlightingRule rule;
|
||||||
keywordFormat.setForeground(darkMode ? Qt::darkMagenta : Qt::magenta);
|
keywordFormat.setForeground(darkMode ? Qt::darkMagenta : Qt::magenta);
|
||||||
keywordFormat.setFontWeight(QFont::Bold);
|
keywordFormat.setFontWeight(QFont::Bold);
|
||||||
const QString keywordPatterns[] = {
|
const QString keywordPatterns[] = { "tcp", "udp" };
|
||||||
"tcp", "udp"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const QString &pattern : keywordPatterns) {
|
for (const QString &pattern : keywordPatterns)
|
||||||
|
{
|
||||||
rule.pattern = QRegularExpression(pattern);
|
rule.pattern = QRegularExpression(pattern);
|
||||||
rule.format = keywordFormat;
|
rule.format = keywordFormat;
|
||||||
highlightingRules.append(rule);
|
highlightingRules.append(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (darkMode) {
|
if (darkMode)
|
||||||
|
{
|
||||||
ipHostFormat.setForeground(Qt::yellow);
|
ipHostFormat.setForeground(Qt::yellow);
|
||||||
warningFormat.setForeground(QColor(230, 180, 0));
|
warningFormat.setForeground(QColor(230, 180, 0));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ipHostFormat.setForeground(Qt::black);
|
ipHostFormat.setForeground(Qt::black);
|
||||||
ipHostFormat.setFontWeight(QFont::Bold);
|
ipHostFormat.setFontWeight(QFont::Bold);
|
||||||
warningFormat.setForeground(Qt::white);
|
warningFormat.setForeground(Qt::white);
|
||||||
@ -49,7 +51,7 @@ namespace Qv2ray::common
|
|||||||
rule.format = debugFormat;
|
rule.format = debugFormat;
|
||||||
highlightingRules.append(rule);
|
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.pattern = QRegularExpression("\\[[Ii]nfo\\]" TO_EOL);
|
||||||
rule.format = infoFormat;
|
rule.format = infoFormat;
|
||||||
highlightingRules.append(rule);
|
highlightingRules.append(rule);
|
||||||
@ -119,10 +121,12 @@ namespace Qv2ray::common
|
|||||||
|
|
||||||
void SyntaxHighlighter::highlightBlock(const QString &text)
|
void SyntaxHighlighter::highlightBlock(const QString &text)
|
||||||
{
|
{
|
||||||
for (const HighlightingRule &rule : qAsConst(highlightingRules)) {
|
for (const HighlightingRule &rule : qAsConst(highlightingRules))
|
||||||
|
{
|
||||||
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||||
|
|
||||||
while (matchIterator.hasNext()) {
|
while (matchIterator.hasNext())
|
||||||
|
{
|
||||||
QRegularExpressionMatch match = matchIterator.next();
|
QRegularExpressionMatch match = matchIterator.next();
|
||||||
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||||
}
|
}
|
||||||
@ -130,4 +134,4 @@ namespace Qv2ray::common
|
|||||||
|
|
||||||
setCurrentBlockState(0);
|
setCurrentBlockState(0);
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
@ -49,45 +49,46 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
#include <QTextCharFormat>
|
#include <QTextCharFormat>
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
class SyntaxHighlighter : public QSyntaxHighlighter
|
class SyntaxHighlighter : public QSyntaxHighlighter
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SyntaxHighlighter(bool darkMode, QTextDocument *parent = nullptr);
|
explicit SyntaxHighlighter(bool darkMode, QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void highlightBlock(const QString &text) override;
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct HighlightingRule {
|
struct HighlightingRule
|
||||||
QRegularExpression pattern;
|
{
|
||||||
QTextCharFormat format;
|
QRegularExpression pattern;
|
||||||
};
|
QTextCharFormat format;
|
||||||
QVector<HighlightingRule> highlightingRules;
|
};
|
||||||
|
QVector<HighlightingRule> highlightingRules;
|
||||||
|
|
||||||
QTextCharFormat keywordFormat;
|
QTextCharFormat keywordFormat;
|
||||||
QTextCharFormat dateFormat;
|
QTextCharFormat dateFormat;
|
||||||
QTextCharFormat acceptedFormat;
|
QTextCharFormat acceptedFormat;
|
||||||
QTextCharFormat rejectedFormat;
|
QTextCharFormat rejectedFormat;
|
||||||
QTextCharFormat failedFormat;
|
QTextCharFormat failedFormat;
|
||||||
QTextCharFormat warningFormat;
|
QTextCharFormat warningFormat;
|
||||||
QTextCharFormat infoFormat;
|
QTextCharFormat infoFormat;
|
||||||
QTextCharFormat debugFormat;
|
QTextCharFormat debugFormat;
|
||||||
QTextCharFormat timeFormat;
|
QTextCharFormat timeFormat;
|
||||||
QTextCharFormat ipHostFormat;
|
QTextCharFormat ipHostFormat;
|
||||||
QTextCharFormat v2rayComponentFormat;
|
QTextCharFormat v2rayComponentFormat;
|
||||||
//
|
//
|
||||||
QTextCharFormat qvAppLogFormat;
|
QTextCharFormat qvAppLogFormat;
|
||||||
QTextCharFormat qvAppDebugLogFormat;
|
QTextCharFormat qvAppDebugLogFormat;
|
||||||
};
|
};
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
|
||||||
using namespace Qv2ray::common;
|
using namespace Qv2ray::common;
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
@ -23,10 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "QJsonModel.hpp"
|
#include "QJsonModel.hpp"
|
||||||
#include <QFile>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFont>
|
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFont>
|
||||||
|
|
||||||
QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent)
|
QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent)
|
||||||
{
|
{
|
||||||
@ -101,27 +101,34 @@ QJsonTreeItem *QJsonTreeItem::load(const QJsonValue &value, QJsonTreeItem *paren
|
|||||||
QJsonTreeItem *rootItem = new QJsonTreeItem(parent);
|
QJsonTreeItem *rootItem = new QJsonTreeItem(parent);
|
||||||
rootItem->setKey("root");
|
rootItem->setKey("root");
|
||||||
|
|
||||||
if (value.isObject()) {
|
if (value.isObject())
|
||||||
//Get all QJsonValue childs
|
{
|
||||||
for (QString key : value.toObject().keys()) {
|
// Get all QJsonValue childs
|
||||||
|
for (QString key : value.toObject().keys())
|
||||||
|
{
|
||||||
QJsonValue v = value.toObject().value(key);
|
QJsonValue v = value.toObject().value(key);
|
||||||
QJsonTreeItem *child = load(v, rootItem);
|
QJsonTreeItem *child = load(v, rootItem);
|
||||||
child->setKey(key);
|
child->setKey(key);
|
||||||
child->setType(v.type());
|
child->setType(v.type());
|
||||||
rootItem->appendChild(child);
|
rootItem->appendChild(child);
|
||||||
}
|
}
|
||||||
} else if (value.isArray()) {
|
}
|
||||||
//Get all QJsonValue childs
|
else if (value.isArray())
|
||||||
|
{
|
||||||
|
// Get all QJsonValue childs
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (QJsonValue v : value.toArray()) {
|
for (QJsonValue v : value.toArray())
|
||||||
|
{
|
||||||
QJsonTreeItem *child = load(v, rootItem);
|
QJsonTreeItem *child = load(v, rootItem);
|
||||||
child->setKey(QString::number(index));
|
child->setKey(QString::number(index));
|
||||||
child->setType(v.type());
|
child->setType(v.type());
|
||||||
rootItem->appendChild(child);
|
rootItem->appendChild(child);
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
rootItem->setValue(value.toVariant().toString());
|
rootItem->setValue(value.toVariant().toString());
|
||||||
rootItem->setType(value.type());
|
rootItem->setType(value.type());
|
||||||
}
|
}
|
||||||
@ -131,35 +138,27 @@ QJsonTreeItem *QJsonTreeItem::load(const QJsonValue &value, QJsonTreeItem *paren
|
|||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
QJsonModel::QJsonModel(QObject *parent)
|
QJsonModel::QJsonModel(QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem }
|
||||||
: QAbstractItemModel(parent)
|
|
||||||
, mRootItem{new QJsonTreeItem}
|
|
||||||
{
|
{
|
||||||
mHeaders.append("key");
|
mHeaders.append("key");
|
||||||
mHeaders.append("value");
|
mHeaders.append("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonModel::QJsonModel(const QString &fileName, QObject *parent)
|
QJsonModel::QJsonModel(const QString &fileName, QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem }
|
||||||
: QAbstractItemModel(parent)
|
|
||||||
, mRootItem{new QJsonTreeItem}
|
|
||||||
{
|
{
|
||||||
mHeaders.append("key");
|
mHeaders.append("key");
|
||||||
mHeaders.append("value");
|
mHeaders.append("value");
|
||||||
load(fileName);
|
load(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonModel::QJsonModel(QIODevice *device, QObject *parent)
|
QJsonModel::QJsonModel(QIODevice *device, QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem }
|
||||||
: QAbstractItemModel(parent)
|
|
||||||
, mRootItem{new QJsonTreeItem}
|
|
||||||
{
|
{
|
||||||
mHeaders.append("key");
|
mHeaders.append("key");
|
||||||
mHeaders.append("value");
|
mHeaders.append("value");
|
||||||
load(device);
|
load(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonModel::QJsonModel(const QByteArray &json, QObject *parent)
|
QJsonModel::QJsonModel(const QByteArray &json, QObject *parent) : QAbstractItemModel(parent), mRootItem{ new QJsonTreeItem }
|
||||||
: QAbstractItemModel(parent)
|
|
||||||
, mRootItem{new QJsonTreeItem}
|
|
||||||
{
|
{
|
||||||
mHeaders.append("key");
|
mHeaders.append("key");
|
||||||
mHeaders.append("value");
|
mHeaders.append("value");
|
||||||
@ -176,10 +175,13 @@ bool QJsonModel::load(const QString &fileName)
|
|||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
success = load(&file);
|
success = load(&file);
|
||||||
file.close();
|
file.close();
|
||||||
} else success = false;
|
}
|
||||||
|
else
|
||||||
|
success = false;
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -193,14 +195,18 @@ bool QJsonModel::loadJson(const QByteArray &json)
|
|||||||
{
|
{
|
||||||
auto const &jdoc = QJsonDocument::fromJson(json);
|
auto const &jdoc = QJsonDocument::fromJson(json);
|
||||||
|
|
||||||
if (!jdoc.isNull()) {
|
if (!jdoc.isNull())
|
||||||
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
delete mRootItem;
|
delete mRootItem;
|
||||||
|
|
||||||
if (jdoc.isArray()) {
|
if (jdoc.isArray())
|
||||||
|
{
|
||||||
mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.array()));
|
mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.array()));
|
||||||
mRootItem->setType(QJsonValue::Array);
|
mRootItem->setType(QJsonValue::Array);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.object()));
|
mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.object()));
|
||||||
mRootItem->setType(QJsonValue::Object);
|
mRootItem->setType(QJsonValue::Object);
|
||||||
}
|
}
|
||||||
@ -213,7 +219,6 @@ bool QJsonModel::loadJson(const QByteArray &json)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant QJsonModel::data(const QModelIndex &index, int role) const
|
QVariant QJsonModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
@ -221,14 +226,18 @@ QVariant QJsonModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
QJsonTreeItem *item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
QJsonTreeItem *item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
if (index.column() == 0)
|
if (index.column() == 0)
|
||||||
return QString("%1").arg(item->key());
|
return QString("%1").arg(item->key());
|
||||||
|
|
||||||
if (index.column() == 1)
|
if (index.column() == 1)
|
||||||
return QString("%1").arg(item->value());
|
return QString("%1").arg(item->value());
|
||||||
} else if (Qt::EditRole == role) {
|
}
|
||||||
if (index.column() == 1) {
|
else if (Qt::EditRole == role)
|
||||||
|
{
|
||||||
|
if (index.column() == 1)
|
||||||
|
{
|
||||||
return QString("%1").arg(item->value());
|
return QString("%1").arg(item->value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,11 +249,13 @@ bool QJsonModel::setData(const QModelIndex &index, const QVariant &value, int ro
|
|||||||
{
|
{
|
||||||
int col = index.column();
|
int col = index.column();
|
||||||
|
|
||||||
if (Qt::EditRole == role) {
|
if (Qt::EditRole == role)
|
||||||
if (col == 1) {
|
{
|
||||||
|
if (col == 1)
|
||||||
|
{
|
||||||
QJsonTreeItem *item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
QJsonTreeItem *item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||||
item->setValue(value.toString());
|
item->setValue(value.toString());
|
||||||
emit dataChanged(index, index, {Qt::EditRole});
|
emit dataChanged(index, index, { Qt::EditRole });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,16 +263,16 @@ bool QJsonModel::setData(const QModelIndex &index, const QVariant &value, int ro
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QVariant QJsonModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant QJsonModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
if (role != Qt::DisplayRole)
|
if (role != Qt::DisplayRole)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (orientation == Qt::Horizontal) {
|
if (orientation == Qt::Horizontal)
|
||||||
|
{
|
||||||
return mHeaders.value(section);
|
return mHeaders.value(section);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,14 +333,17 @@ int QJsonModel::columnCount(const QModelIndex &parent) const
|
|||||||
|
|
||||||
Qt::ItemFlags QJsonModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags QJsonModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
int col = index.column();
|
int col = index.column();
|
||||||
auto item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
auto item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||||
auto isArray = QJsonValue::Array == item->type();
|
auto isArray = QJsonValue::Array == item->type();
|
||||||
auto isObject = QJsonValue::Object == item->type();
|
auto isObject = QJsonValue::Object == item->type();
|
||||||
|
|
||||||
if ((col == 1) && !(isArray || isObject)) {
|
if ((col == 1) && !(isArray || isObject))
|
||||||
|
{
|
||||||
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
|
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return QAbstractItemModel::flags(index);
|
return QAbstractItemModel::flags(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,40 +353,50 @@ QJsonDocument QJsonModel::json() const
|
|||||||
auto v = genJson(mRootItem);
|
auto v = genJson(mRootItem);
|
||||||
QJsonDocument doc;
|
QJsonDocument doc;
|
||||||
|
|
||||||
if (v.isObject()) {
|
if (v.isObject())
|
||||||
|
{
|
||||||
doc = QJsonDocument(v.toObject());
|
doc = QJsonDocument(v.toObject());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
doc = QJsonDocument(v.toArray());
|
doc = QJsonDocument(v.toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const
|
QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const
|
||||||
{
|
{
|
||||||
auto type = item->type();
|
auto type = item->type();
|
||||||
int nchild = item->childCount();
|
int nchild = item->childCount();
|
||||||
|
|
||||||
if (QJsonValue::Object == type) {
|
if (QJsonValue::Object == type)
|
||||||
|
{
|
||||||
QJsonObject jo;
|
QJsonObject jo;
|
||||||
|
|
||||||
for (int i = 0; i < nchild; ++i) {
|
for (int i = 0; i < nchild; ++i)
|
||||||
|
{
|
||||||
auto ch = item->child(i);
|
auto ch = item->child(i);
|
||||||
auto key = ch->key();
|
auto key = ch->key();
|
||||||
jo.insert(key, genJson(ch));
|
jo.insert(key, genJson(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
return jo;
|
return jo;
|
||||||
} else if (QJsonValue::Array == type) {
|
}
|
||||||
|
else if (QJsonValue::Array == type)
|
||||||
|
{
|
||||||
QJsonArray arr;
|
QJsonArray arr;
|
||||||
|
|
||||||
for (int i = 0; i < nchild; ++i) {
|
for (int i = 0; i < nchild; ++i)
|
||||||
|
{
|
||||||
auto ch = item->child(i);
|
auto ch = item->child(i);
|
||||||
arr.append(genJson(ch));
|
arr.append(genJson(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QJsonValue va(item->value());
|
QJsonValue va(item->value());
|
||||||
return va;
|
return va;
|
||||||
}
|
}
|
||||||
|
@ -1,101 +1,94 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011 SCHUTZ Sacha
|
* Copyright (c) 2011 SCHUTZ Sacha
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonValue>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
|
|
||||||
class QJsonModel;
|
class QJsonModel;
|
||||||
class QJsonItem;
|
class QJsonItem;
|
||||||
|
|
||||||
class QJsonTreeItem
|
class QJsonTreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QJsonTreeItem(QJsonTreeItem *parent = nullptr);
|
QJsonTreeItem(QJsonTreeItem *parent = nullptr);
|
||||||
~QJsonTreeItem();
|
~QJsonTreeItem();
|
||||||
void appendChild(QJsonTreeItem *item);
|
void appendChild(QJsonTreeItem *item);
|
||||||
QJsonTreeItem *child(int row);
|
QJsonTreeItem *child(int row);
|
||||||
QJsonTreeItem *parent();
|
QJsonTreeItem *parent();
|
||||||
int childCount() const;
|
int childCount() const;
|
||||||
int row() const;
|
int row() const;
|
||||||
void setKey(const QString &key);
|
void setKey(const QString &key);
|
||||||
void setValue(const QString &value);
|
void setValue(const QString &value);
|
||||||
void setType(const QJsonValue::Type &type);
|
void setType(const QJsonValue::Type &type);
|
||||||
QString key() const;
|
QString key() const;
|
||||||
QString value() const;
|
QString value() const;
|
||||||
QJsonValue::Type type() const;
|
QJsonValue::Type type() const;
|
||||||
|
|
||||||
|
|
||||||
static QJsonTreeItem *load(const QJsonValue &value, QJsonTreeItem *parent = 0);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString mKey;
|
|
||||||
QString mValue;
|
|
||||||
QJsonValue::Type mType;
|
|
||||||
QList<QJsonTreeItem *> mChilds;
|
|
||||||
QJsonTreeItem *mParent;
|
|
||||||
|
|
||||||
|
static QJsonTreeItem *load(const QJsonValue &value, QJsonTreeItem *parent = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
QString mKey;
|
||||||
|
QString mValue;
|
||||||
|
QJsonValue::Type mType;
|
||||||
|
QList<QJsonTreeItem *> mChilds;
|
||||||
|
QJsonTreeItem *mParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
class QJsonModel : public QAbstractItemModel
|
class QJsonModel : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit QJsonModel(QObject *parent = nullptr);
|
explicit QJsonModel(QObject *parent = nullptr);
|
||||||
QJsonModel(const QString &fileName, QObject *parent = nullptr);
|
QJsonModel(const QString &fileName, QObject *parent = nullptr);
|
||||||
QJsonModel(QIODevice *device, QObject *parent = nullptr);
|
QJsonModel(QIODevice *device, QObject *parent = nullptr);
|
||||||
QJsonModel(const QByteArray &json, QObject *parent = nullptr);
|
QJsonModel(const QByteArray &json, QObject *parent = nullptr);
|
||||||
~QJsonModel();
|
~QJsonModel();
|
||||||
bool load(const QString &fileName);
|
bool load(const QString &fileName);
|
||||||
bool load(QIODevice *device);
|
bool load(QIODevice *device);
|
||||||
bool loadJson(const QByteArray &json);
|
bool loadJson(const QByteArray &json);
|
||||||
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
|
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;
|
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;
|
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 index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
int columnCount(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;
|
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||||
QJsonDocument json() const;
|
QJsonDocument json() const;
|
||||||
|
|
||||||
private:
|
|
||||||
QJsonValue genJson(QJsonTreeItem *) const;
|
|
||||||
|
|
||||||
QJsonTreeItem *mRootItem;
|
|
||||||
QStringList mHeaders;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJsonValue genJson(QJsonTreeItem *) const;
|
||||||
|
|
||||||
|
QJsonTreeItem *mRootItem;
|
||||||
|
QStringList mHeaders;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
#include "common/QvHelpers.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
|
|
||||||
|
#include "libs/puresource/src/PureJson.hpp"
|
||||||
|
|
||||||
|
#include <QGraphicsEffect>
|
||||||
|
#include <QGraphicsProxyWidget>
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
#include <QGraphicsView>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
@ -8,7 +15,8 @@ namespace Qv2ray::common
|
|||||||
const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
|
const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
|
||||||
QString randomString;
|
QString randomString;
|
||||||
|
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
uint rand = QRandomGenerator::system()->generate();
|
uint rand = QRandomGenerator::system()->generate();
|
||||||
uint max = static_cast<uint>(possibleCharacters.length());
|
uint max = static_cast<uint>(possibleCharacters.length());
|
||||||
QChar nextChar = possibleCharacters[rand % max];
|
QChar nextChar = possibleCharacters[rand % max];
|
||||||
@ -26,21 +34,43 @@ namespace Qv2ray::common
|
|||||||
|
|
||||||
QString StringFromFile(QFile *source)
|
QString StringFromFile(QFile *source)
|
||||||
{
|
{
|
||||||
source->open(QFile::ReadOnly);
|
bool wasOpened = source->isOpen();
|
||||||
QTextStream stream(source);
|
if (!wasOpened)
|
||||||
QString str = stream.readAll();
|
source->open(QFile::ReadOnly);
|
||||||
source->close();
|
auto byteArray = source->readAll();
|
||||||
return str;
|
if (!wasOpened)
|
||||||
|
source->close();
|
||||||
|
//
|
||||||
|
QTextCodec::ConverterState state;
|
||||||
|
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
|
||||||
|
const QString text = codec->toUnicode(byteArray.constData(), byteArray.size(), &state);
|
||||||
|
if (state.invalidChars > 0)
|
||||||
|
{
|
||||||
|
LOG(MODULE_FILEIO, "Not a valid UTF-8 sequence: " + source->fileName())
|
||||||
|
return source->readAll();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StringToFile(const QString *text, QFile *targetFile)
|
bool StringToFile(const QString &text, const QString &targetpath)
|
||||||
{
|
{
|
||||||
bool override = targetFile->exists();
|
auto file = QFile(targetpath);
|
||||||
targetFile->open(QFile::WriteOnly);
|
return StringToFile(text, file);
|
||||||
QTextStream stream(targetFile);
|
}
|
||||||
stream << *text << endl;
|
bool StringToFile(const QString &text, QFile &targetFile)
|
||||||
stream.flush();
|
{
|
||||||
targetFile->close();
|
QFileInfo info(targetFile);
|
||||||
|
if (!info.dir().exists())
|
||||||
|
{
|
||||||
|
info.dir().mkpath(info.dir().path());
|
||||||
|
}
|
||||||
|
bool override = targetFile.exists();
|
||||||
|
targetFile.open(QFile::WriteOnly);
|
||||||
|
targetFile.write(text.toUtf8());
|
||||||
|
targetFile.close();
|
||||||
return override;
|
return override;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,14 +80,14 @@ namespace Qv2ray::common
|
|||||||
return JsonFromString(json);
|
return JsonFromString(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString JsonToString(QJsonObject json, QJsonDocument::JsonFormat format)
|
QString JsonToString(const QJsonObject &json, QJsonDocument::JsonFormat format)
|
||||||
{
|
{
|
||||||
QJsonDocument doc;
|
QJsonDocument doc;
|
||||||
doc.setObject(json);
|
doc.setObject(json);
|
||||||
return doc.toJson(format);
|
return doc.toJson(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString JsonToString(QJsonArray array, QJsonDocument::JsonFormat format)
|
QString JsonToString(const QJsonArray &array, QJsonDocument::JsonFormat format)
|
||||||
{
|
{
|
||||||
QJsonDocument doc;
|
QJsonDocument doc;
|
||||||
doc.setArray(array);
|
doc.setArray(array);
|
||||||
@ -70,27 +100,35 @@ namespace Qv2ray::common
|
|||||||
QJsonDocument doc = QJsonDocument::fromJson(source.toUtf8(), &error);
|
QJsonDocument doc = QJsonDocument::fromJson(source.toUtf8(), &error);
|
||||||
Q_UNUSED(doc)
|
Q_UNUSED(doc)
|
||||||
|
|
||||||
if (error.error == QJsonParseError::NoError) {
|
if (error.error == QJsonParseError::NoError)
|
||||||
|
{
|
||||||
return "";
|
return "";
|
||||||
} else {
|
}
|
||||||
LOG(UI, "WARNING: Json parse returns: " + error.errorString())
|
else
|
||||||
|
{
|
||||||
|
LOG(MODULE_UI, "WARNING: Json parse returns: " + error.errorString())
|
||||||
return error.errorString();
|
return error.errorString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject JsonFromString(QString string)
|
QJsonObject JsonFromString(const QString &string)
|
||||||
{
|
{
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(string.toUtf8());
|
auto removeComment = RemoveComment(string.trimmed()).trimmed();
|
||||||
|
if (removeComment != string.trimmed())
|
||||||
|
{
|
||||||
|
LOG(MODULE_FILEIO, "Some comments have been removed from the json.")
|
||||||
|
}
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(removeComment.toUtf8());
|
||||||
return doc.object();
|
return doc.object();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Base64Encode(QString string)
|
QString Base64Encode(const QString &string)
|
||||||
{
|
{
|
||||||
QByteArray ba = string.toUtf8();
|
QByteArray ba = string.toUtf8();
|
||||||
return ba.toBase64();
|
return ba.toBase64();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Base64Decode(QString string)
|
QString Base64Decode(const QString &string)
|
||||||
{
|
{
|
||||||
QByteArray ba = string.toUtf8();
|
QByteArray ba = string.toUtf8();
|
||||||
return QString(QByteArray::fromBase64(ba));
|
return QString(QByteArray::fromBase64(ba));
|
||||||
@ -105,50 +143,52 @@ namespace Qv2ray::common
|
|||||||
{
|
{
|
||||||
list<string> list;
|
list<string> list;
|
||||||
|
|
||||||
for (auto line : _string.split(QRegExp("[\r\n]"), QString::SkipEmptyParts)) {
|
for (auto line : _string.split(QRegExp("[\r\n]"), QString::SkipEmptyParts))
|
||||||
|
{
|
||||||
list.push_back(line.toStdString());
|
list.push_back(line.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GetFileList(QDir dir)
|
QStringList GetFileList(const QDir &dir)
|
||||||
{
|
{
|
||||||
return dir.entryList(QStringList() << "*" << "*.*", QDir::Hidden | QDir::Files);
|
return dir.entryList(QStringList{ "*", "*.*" }, QDir::Hidden | QDir::Files);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileExistsIn(QDir dir, QString fileName)
|
bool FileExistsIn(const QDir &dir, const QString &fileName)
|
||||||
{
|
{
|
||||||
return GetFileList(dir).contains(fileName);
|
return GetFileList(dir).contains(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QvMessageBoxWarn(QWidget *parent, QString title, QString text)
|
void QvMessageBoxWarn(QWidget *parent, const QString &title, const QString &text)
|
||||||
{
|
{
|
||||||
QMessageBox::warning(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0);
|
QMessageBox::warning(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QvMessageBoxInfo(QWidget *parent, QString title, QString text)
|
void QvMessageBoxInfo(QWidget *parent, const QString &title, const QString &text)
|
||||||
{
|
{
|
||||||
QMessageBox::information(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0);
|
QMessageBox::information(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox::StandardButton QvMessageBoxAsk(QWidget *parent, QString title, QString text, QMessageBox::StandardButton extraButtons)
|
QMessageBox::StandardButton QvMessageBoxAsk(QWidget *parent, const QString &title, const QString &text,
|
||||||
|
QMessageBox::StandardButton extraButtons)
|
||||||
{
|
{
|
||||||
return QMessageBox::question(parent, title, text, QMessageBox::Yes | QMessageBox::No | extraButtons);
|
return QMessageBox::question(parent, title, text, QMessageBox::Yes | QMessageBox::No | extraButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FormatBytes(long long bytes)
|
QString FormatBytes(const int64_t b)
|
||||||
{
|
{
|
||||||
|
auto _bytes = b;
|
||||||
char str[64];
|
char str[64];
|
||||||
const char *sizes[5] = { "B", "KB", "MB", "GB", "TB" };
|
const char *sizes[5] = { "B", "KB", "MB", "GB", "TB" };
|
||||||
int i;
|
int i;
|
||||||
double dblByte = bytes;
|
double dblByte = _bytes;
|
||||||
|
|
||||||
for (i = 0; i < 5 && bytes >= 1024; i++, bytes /= 1024)
|
for (i = 0; i < 5 && _bytes >= 1024; i++, _bytes /= 1024) dblByte = _bytes / 1024.0;
|
||||||
dblByte = bytes / 1024.0;
|
|
||||||
|
|
||||||
sprintf(str, "%.2f", dblByte);
|
sprintf(str, "%.2f", dblByte);
|
||||||
return strcat(strcat(str, " "), sizes[i]);
|
return QString(str) + " " + QString(sizes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidFileName(const QString &fileName)
|
bool IsValidFileName(const QString &fileName)
|
||||||
@ -160,9 +200,8 @@ namespace Qv2ray::common
|
|||||||
QString RemoveInvalidFileName(const QString &fileName)
|
QString RemoveInvalidFileName(const QString &fileName)
|
||||||
{
|
{
|
||||||
std::string _name = fileName.toStdString();
|
std::string _name = fileName.toStdString();
|
||||||
std::replace_if(_name.begin(), _name.end(), [](char c) {
|
std::replace_if(
|
||||||
return std::string::npos != string(R"("/\?%&^*;:|><)").find(c);
|
_name.begin(), _name.end(), [](char c) { return std::string::npos != string(R"("/\?%&^*;:|><)").find(c); }, '_');
|
||||||
}, '_');
|
|
||||||
return QString::fromStdString(_name);
|
return QString::fromStdString(_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,42 +210,54 @@ namespace Qv2ray::common
|
|||||||
{
|
{
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
if (!QDir(baseDir).exists()) {
|
if (!QDir(baseDir).exists())
|
||||||
|
{
|
||||||
QDir(baseDir).mkpath(baseDir);
|
QDir(baseDir).mkpath(baseDir);
|
||||||
LOG(FILEIO, "Making path: " + baseDir)
|
LOG(MODULE_FILEIO, "Making path: " + baseDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true)
|
||||||
if (!QFile(baseDir + "/" + fileName + "_" + QSTRN(i) + extension).exists()) {
|
{
|
||||||
|
if (!QFile(baseDir + "/" + fileName + "_" + QSTRN(i) + extension).exists())
|
||||||
|
{
|
||||||
*fileName = *fileName + "_" + QSTRN(i);
|
*fileName = *fileName + "_" + QSTRN(i);
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
DEBUG(FILEIO, "File with name: " + *fileName + "_" + QSTRN(i) + extension + " already exists")
|
else
|
||||||
|
{
|
||||||
|
DEBUG(MODULE_FILEIO, "File with name: " + *fileName + "_" + QSTRN(i) + extension + " already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ConvertQStringList(const QList<string> &stdListString)
|
QPixmap BlurImage(const QPixmap &pixmap, const double rad)
|
||||||
{
|
{
|
||||||
QStringList listQt;
|
QGraphicsView view;
|
||||||
listQt.reserve(stdListString.size());
|
QGraphicsScene scene;
|
||||||
|
QGraphicsBlurEffect pBlur;
|
||||||
for (const std::string &s : stdListString) {
|
//
|
||||||
listQt.append(QString::fromStdString(s));
|
view.setScene(&scene);
|
||||||
}
|
scene.setSceneRect(pixmap.rect());
|
||||||
|
pBlur.setBlurRadius(rad);
|
||||||
return listQt;
|
QGraphicsPixmapItem *p = view.scene()->addPixmap(pixmap);
|
||||||
|
p->setGraphicsEffect(&pBlur);
|
||||||
|
return view.grab();
|
||||||
}
|
}
|
||||||
std::list<string> ConvertStdStringList(const QStringList &qStringList)
|
|
||||||
|
QPixmap ColorizeImage(const QPixmap &pixmap, const QColor &color, const qreal factor)
|
||||||
{
|
{
|
||||||
std::list<string> stdList;
|
QGraphicsView view;
|
||||||
|
QGraphicsScene scene;
|
||||||
for (auto &s : qStringList) {
|
QGraphicsColorizeEffect pColor;
|
||||||
stdList.push_back(s.toStdString());
|
pColor.setColor(color);
|
||||||
}
|
pColor.setStrength(factor);
|
||||||
|
//
|
||||||
return stdList;
|
view.setScene(&scene);
|
||||||
|
scene.setSceneRect(pixmap.rect());
|
||||||
|
QGraphicsPixmapItem *p = view.scene()->addPixmap(pixmap);
|
||||||
|
p->setGraphicsEffect(&pColor);
|
||||||
|
return view.grab();
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::common
|
||||||
|
@ -1,50 +1,61 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/Qv2rayBase.hpp"
|
#include "base/Qv2rayBase.hpp"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#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_IPV6_ADDR \
|
||||||
#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]))"
|
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])*)"
|
#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
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
QStringList GetFileList(QDir dir);
|
QStringList GetFileList(const QDir &dir);
|
||||||
QString Base64Encode(QString string);
|
QString Base64Encode(const QString &string);
|
||||||
QString Base64Decode(QString string);
|
QString Base64Decode(const QString &string);
|
||||||
QStringList SplitLines(const QString &str);
|
QStringList SplitLines(const QString &str);
|
||||||
list<string> SplitLines_std(const QString &_string);
|
list<string> SplitLines_std(const QString &_string);
|
||||||
bool FileExistsIn(QDir dir, QString fileName);
|
bool FileExistsIn(const QDir &dir, const QString &fileName);
|
||||||
const QString GenerateRandomString(int len = 12);
|
const QString GenerateRandomString(int len = 12);
|
||||||
//
|
//
|
||||||
void QvMessageBoxWarn(QWidget *parent, QString title, QString text);
|
void QvMessageBoxWarn(QWidget *parent, const QString &title, const QString &text);
|
||||||
void QvMessageBoxInfo(QWidget *parent, QString title, QString text);
|
void QvMessageBoxInfo(QWidget *parent, const QString &title, const QString &text);
|
||||||
QMessageBox::StandardButton QvMessageBoxAsk(QWidget *parent, QString title, QString text, QMessageBox::StandardButton extraButtons = QMessageBox::NoButton);
|
QMessageBox::StandardButton QvMessageBoxAsk(QWidget *parent, const QString &title, const QString &text,
|
||||||
|
QMessageBox::StandardButton extraButtons = QMessageBox::NoButton);
|
||||||
//
|
//
|
||||||
QString StringFromFile(const QString &filePath);
|
QString StringFromFile(const QString &filePath);
|
||||||
QString StringFromFile(QFile *source);
|
QString StringFromFile(QFile *source);
|
||||||
bool StringToFile(const QString *text, QFile *target);
|
bool StringToFile(const QString &text, QFile &target);
|
||||||
|
bool StringToFile(const QString &text, const QString &targetpath);
|
||||||
//
|
//
|
||||||
QJsonObject JsonFromString(QString string);
|
QJsonObject JsonFromString(const QString &string);
|
||||||
QString JsonToString(QJsonObject json, QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented);
|
QString JsonToString(const QJsonObject &json, QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented);
|
||||||
QString JsonToString(QJsonArray array, QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented);
|
QString JsonToString(const QJsonArray &array, QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented);
|
||||||
QString VerifyJsonString(const QString &source);
|
QString VerifyJsonString(const QString &source);
|
||||||
//
|
//
|
||||||
QString FormatBytes(long long bytes);
|
QString FormatBytes(const int64_t bytes);
|
||||||
void DeducePossibleFileName(const QString &baseDir, QString *fileName, const QString &extension);
|
void DeducePossibleFileName(const QString &baseDir, QString *fileName, const QString &extension);
|
||||||
QStringList ConvertQStringList(const QList<string> &stdListString);
|
//
|
||||||
std::list<string> ConvertStdStringList(const QStringList &qStringList);
|
QPixmap BlurImage(const QPixmap &pixmap, const double rad = 50);
|
||||||
|
QPixmap ColorizeImage(const QPixmap &pixmap, const QColor &color, const qreal factor);
|
||||||
// This function cannot be marked as inline.
|
// This function cannot be marked as inline.
|
||||||
QString RemoveInvalidFileName(const QString &fileName);
|
QString RemoveInvalidFileName(const QString &fileName);
|
||||||
bool IsValidFileName(const QString &fileName);
|
bool IsValidFileName(const QString &fileName);
|
||||||
|
inline QString GenerateUuid()
|
||||||
|
{
|
||||||
|
return GenerateRandomString().toLower();
|
||||||
|
// return QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
template <typename TYPE>
|
template<typename TYPE>
|
||||||
QString StructToJsonString(const TYPE t)
|
QString StructToJsonString(const TYPE t)
|
||||||
{
|
{
|
||||||
return QString::fromStdString(x2struct::X::tojson(t, "", 4, ' '));
|
return QString::fromStdString(x2struct::X::tojson(t, "", 4, ' '));
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
template <typename TYPE>
|
template<typename TYPE>
|
||||||
TYPE StructFromJsonString(const QString &str)
|
TYPE StructFromJsonString(const QString &str)
|
||||||
{
|
{
|
||||||
TYPE v;
|
TYPE v;
|
||||||
@ -59,68 +70,43 @@ namespace Qv2ray::common
|
|||||||
return JsonFromString(json);
|
return JsonFromString(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsIPv4Address(const QString &addr)
|
inline QString TruncateString(const QString &str, int limit = -1, const QString &suffix = "...")
|
||||||
{
|
{
|
||||||
return QRegularExpression(REGEX_IPV4_ADDR "$").match(addr).hasMatch();
|
QString t = str;
|
||||||
|
t.truncate(limit);
|
||||||
|
return (limit == -1 || str.length() < limit) ? str : (t + suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsIPv6Address(const QString &addr)
|
namespace validation
|
||||||
{
|
{
|
||||||
return QRegularExpression(REGEX_IPV6_ADDR "$").match(addr).hasMatch();
|
const inline QRegularExpression __regex_ipv4_full(REGEX_IPV4_ADDR "$");
|
||||||
}
|
const inline QRegularExpression __regex_ipv6_full(REGEX_IPV6_ADDR "$");
|
||||||
|
|
||||||
inline bool IsValidIPAddress(const QString &addr)
|
inline bool IsIPv4Address(const QString &addr)
|
||||||
{
|
{
|
||||||
return IsIPv4Address(addr) || IsIPv6Address(addr);
|
return __regex_ipv4_full.match(addr).hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
inline bool IsIPv6Address(const QString &addr)
|
||||||
* Generic function to find if an element of any type exists in list
|
{
|
||||||
*/
|
return __regex_ipv6_full.match(addr).hasMatch();
|
||||||
template<typename T>
|
}
|
||||||
bool contains(std::list<T> &listOfElements, const T &element)
|
|
||||||
{
|
inline bool IsValidIPAddress(const QString &addr)
|
||||||
// Find the iterator if element in list
|
{
|
||||||
auto it = std::find(listOfElements.begin(), listOfElements.end(), element);
|
return IsIPv4Address(addr) || IsIPv6Address(addr);
|
||||||
//return if iterator points to end or not. It points to end then it means element
|
}
|
||||||
// does not exists in list
|
} // namespace validation
|
||||||
return it != listOfElements.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString timeToString(const time_t &t)
|
inline QString timeToString(const time_t &t)
|
||||||
{
|
{
|
||||||
auto _tm = std::localtime(&t);
|
auto _tm = std::localtime(&t);
|
||||||
char MY_TIME[128];
|
char MY_TIME[128];
|
||||||
|
setlocale(1, "3");
|
||||||
// using strftime to display time
|
// using strftime to display time
|
||||||
strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", _tm);
|
strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", _tm);
|
||||||
return QString(MY_TIME);
|
return QString(MY_TIME);
|
||||||
}
|
}
|
||||||
|
} // namespace Qv2ray::common
|
||||||
template<typename myMap>
|
|
||||||
std::vector<typename myMap::key_type> Keys(const myMap &m)
|
|
||||||
{
|
|
||||||
std::vector<typename myMap::key_type> r;
|
|
||||||
r.reserve(m.size());
|
|
||||||
|
|
||||||
for (const auto &kvp : m) {
|
|
||||||
r.push_back(kvp.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename myMap>
|
|
||||||
std::vector<typename myMap::mapped_type> Values(const myMap &m)
|
|
||||||
{
|
|
||||||
std::vector<typename myMap::mapped_type> r;
|
|
||||||
r.reserve(m.size());
|
|
||||||
|
|
||||||
for (const auto &kvp : m) {
|
|
||||||
r.push_back(kvp.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace Qv2ray::common;
|
using namespace Qv2ray::common;
|
||||||
|
93
src/common/QvTranslator.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "QvTranslator.hpp"
|
||||||
|
|
||||||
|
#include "base/Qv2rayLog.hpp"
|
||||||
|
#include "common/QvHelpers.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace Qv2ray::base;
|
||||||
|
|
||||||
|
// path searching list.
|
||||||
|
QStringList getLanguageSearchPaths()
|
||||||
|
{
|
||||||
|
// Configuration Path
|
||||||
|
QStringList list;
|
||||||
|
list << QV2RAY_CONFIG_DIR + "lang";
|
||||||
|
//
|
||||||
|
#ifdef EMBED_TRANSLATIONS
|
||||||
|
// If the translations have been embedded.
|
||||||
|
list << QString(":/translations/");
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
//
|
||||||
|
#ifdef QV2RAY_TRANSLATION_PATH
|
||||||
|
// Platform-specific dir, if specified.
|
||||||
|
list << QString(QV2RAY_TRANSLATION_PATH);
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
//
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
// Linux platform directories.
|
||||||
|
list << QString("/usr/share/qv2ray/lang/");
|
||||||
|
list << QString("/usr/local/share/qv2ray/lang/");
|
||||||
|
list << QStandardPaths::locateAll(QStandardPaths::AppDataLocation, "lang", QStandardPaths::LocateDirectory);
|
||||||
|
list << QStandardPaths::locateAll(QStandardPaths::AppConfigLocation, "lang", QStandardPaths::LocateDirectory);
|
||||||
|
#elif defined(Q_OS_MAC)
|
||||||
|
// macOS platform directories.
|
||||||
|
list << QDir(QApplication::applicationDirPath() + "/../Resources/lang").absolutePath();
|
||||||
|
#else
|
||||||
|
// This is the default behavior on Windows
|
||||||
|
list << QApplication::applicationDirPath() + "/lang";
|
||||||
|
#endif
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Qv2ray::common
|
||||||
|
{
|
||||||
|
QvTranslator::QvTranslator()
|
||||||
|
{
|
||||||
|
DEBUG(MODULE_UI, "QvTranslator constructor.")
|
||||||
|
GetAvailableLanguages();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QvTranslator::GetAvailableLanguages()
|
||||||
|
{
|
||||||
|
languages.clear();
|
||||||
|
for (auto path : getLanguageSearchPaths())
|
||||||
|
{
|
||||||
|
languages << QDir(path).entryList(QStringList{ "*.qm" }, QDir::Hidden | QDir::Files);
|
||||||
|
}
|
||||||
|
std::transform(languages.begin(), languages.end(), languages.begin(), [](QString &fileName) { return fileName.replace(".qm", ""); });
|
||||||
|
languages.removeDuplicates();
|
||||||
|
DEBUG(MODULE_UI, "Found translations: " + languages.join(" "))
|
||||||
|
return languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QvTranslator::InstallTranslation(const QString &code)
|
||||||
|
{
|
||||||
|
for (auto path : getLanguageSearchPaths())
|
||||||
|
{
|
||||||
|
if (FileExistsIn(QDir(path), code + ".qm"))
|
||||||
|
{
|
||||||
|
LOG(MODULE_UI, "Found " + code + " in folder: " + path)
|
||||||
|
QTranslator *translatorNew = new QTranslator();
|
||||||
|
translatorNew->load(code + ".qm", path);
|
||||||
|
if (pTranslator)
|
||||||
|
{
|
||||||
|
LOG(MODULE_INIT, "Removed translations")
|
||||||
|
qApp->removeTranslator(pTranslator.get());
|
||||||
|
}
|
||||||
|
this->pTranslator.reset(translatorNew);
|
||||||
|
qApp->installTranslator(pTranslator.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace Qv2ray::common
|
@ -2,20 +2,30 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace Qv2ray::common
|
namespace Qv2ray::common
|
||||||
{
|
{
|
||||||
class QvTranslator
|
class QvTranslator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QvTranslator(const QString &lang)
|
explicit QvTranslator();
|
||||||
{
|
|
||||||
QTranslator *translator = new QTranslator();
|
|
||||||
translator->load(lang + ".qm", ":/translations/");
|
|
||||||
this->pTranslator.reset(translator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<QTranslator> pTranslator;
|
/**
|
||||||
|
* @brief get the available languages.
|
||||||
|
* @return (if available) languages (zh_CN, en_US, ...)
|
||||||
|
*/
|
||||||
|
QStringList GetAvailableLanguages();
|
||||||
|
/**
|
||||||
|
* @brief reload the translation from file
|
||||||
|
* @param code eg: en_US, zh_CN, ...
|
||||||
|
*/
|
||||||
|
bool InstallTranslation(const QString &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList languages;
|
||||||
|
std::unique_ptr<QTranslator> pTranslator;
|
||||||
};
|
};
|
||||||
|
inline std::unique_ptr<common::QvTranslator> Qv2rayTranslator;
|
||||||
} // namespace Qv2ray::common
|
} // namespace Qv2ray::common
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#include "QvAutoLaunch.hpp"
|
#include "QvAutoLaunch.hpp"
|
||||||
#include <QSettings>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QSettings>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
// macOS headers (possibly OBJ-c)
|
// macOS headers (possibly OBJ-c)
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
#include <CoreServices/CoreServices.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreServices/CoreServices.h>
|
||||||
#endif
|
#endif
|
||||||
namespace Qv2ray::components::autolaunch
|
namespace Qv2ray::components::autolaunch
|
||||||
{
|
{
|
||||||
@ -34,8 +35,10 @@ namespace Qv2ray::components::autolaunch
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined Q_OS_MAC
|
#elif defined Q_OS_MAC
|
||||||
// From https://github.com/nextcloud/desktop/blob/master/src/common/utility_mac.cpp
|
// From
|
||||||
// this is quite some duplicate code with setLaunchOnStartup, at some point we should fix this FIXME.
|
// 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;
|
bool returnValue = false;
|
||||||
QString filePath = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).absolutePath();
|
QString filePath = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).absolutePath();
|
||||||
CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8);
|
CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8);
|
||||||
@ -49,14 +52,17 @@ namespace Qv2ray::components::autolaunch
|
|||||||
CFArrayRef itemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue);
|
CFArrayRef itemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue);
|
||||||
CFStringRef appUrlRefString = CFURLGetString(urlRef); // no need for release
|
CFStringRef appUrlRefString = CFURLGetString(urlRef); // no need for release
|
||||||
|
|
||||||
for (int i = 0; i < CFArrayGetCount(itemsArray); i++) {
|
for (int i = 0; i < CFArrayGetCount(itemsArray); i++)
|
||||||
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(itemsArray, i);
|
{
|
||||||
|
LSSharedFileListItemRef item = (LSSharedFileListItemRef) CFArrayGetValueAtIndex(itemsArray, i);
|
||||||
CFURLRef itemUrlRef = NULL;
|
CFURLRef itemUrlRef = NULL;
|
||||||
|
|
||||||
if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef) {
|
if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef)
|
||||||
|
{
|
||||||
CFStringRef itemUrlString = CFURLGetString(itemUrlRef);
|
CFStringRef itemUrlString = CFURLGetString(itemUrlRef);
|
||||||
|
|
||||||
if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo) {
|
if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo)
|
||||||
|
{
|
||||||
returnValue = true;
|
returnValue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,16 +92,20 @@ namespace Qv2ray::components::autolaunch
|
|||||||
QString appName = QApplication::applicationName();
|
QString appName = QApplication::applicationName();
|
||||||
QSettings reg("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
|
QSettings reg("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
|
||||||
|
|
||||||
if (enable) {
|
if (enable)
|
||||||
|
{
|
||||||
QString strAppPath = QDir::toNativeSeparators(QCoreApplication::applicationFilePath());
|
QString strAppPath = QDir::toNativeSeparators(QCoreApplication::applicationFilePath());
|
||||||
reg.setValue(appName, strAppPath);
|
reg.setValue(appName, strAppPath);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
reg.remove(appName);
|
reg.remove(appName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined Q_OS_MAC
|
#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();
|
QString filePath = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).absolutePath();
|
||||||
CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8);
|
CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8);
|
||||||
CFURLRef urlRef = CFURLCreateWithFileSystemPath(0, folderCFStr, kCFURLPOSIXPathStyle, true);
|
CFURLRef urlRef = CFURLCreateWithFileSystemPath(0, folderCFStr, kCFURLPOSIXPathStyle, true);
|
||||||
@ -103,30 +113,32 @@ namespace Qv2ray::components::autolaunch
|
|||||||
|
|
||||||
if (loginItems && enable)
|
if (loginItems && enable)
|
||||||
{
|
{
|
||||||
//Insert an item to the list.
|
// Insert an item to the list.
|
||||||
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems,
|
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemLast, 0, 0, urlRef, 0, 0);
|
||||||
kLSSharedFileListItemLast, 0, 0,
|
|
||||||
urlRef, 0, 0);
|
|
||||||
|
|
||||||
if (item)
|
if (item)
|
||||||
CFRelease(item);
|
CFRelease(item);
|
||||||
|
|
||||||
CFRelease(loginItems);
|
CFRelease(loginItems);
|
||||||
} else if (loginItems && !enable)
|
}
|
||||||
|
else if (loginItems && !enable)
|
||||||
{
|
{
|
||||||
// We need to iterate over the items and check which one is "ours".
|
// We need to iterate over the items and check which one is "ours".
|
||||||
UInt32 seedValue;
|
UInt32 seedValue;
|
||||||
CFArrayRef itemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue);
|
CFArrayRef itemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue);
|
||||||
CFStringRef appUrlRefString = CFURLGetString(urlRef);
|
CFStringRef appUrlRefString = CFURLGetString(urlRef);
|
||||||
|
|
||||||
for (int i = 0; i < CFArrayGetCount(itemsArray); i++) {
|
for (int i = 0; i < CFArrayGetCount(itemsArray); i++)
|
||||||
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(itemsArray, i);
|
{
|
||||||
|
LSSharedFileListItemRef item = (LSSharedFileListItemRef) CFArrayGetValueAtIndex(itemsArray, i);
|
||||||
CFURLRef itemUrlRef = NULL;
|
CFURLRef itemUrlRef = NULL;
|
||||||
|
|
||||||
if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef) {
|
if (LSSharedFileListItemResolve(item, 0, &itemUrlRef, NULL) == noErr && itemUrlRef)
|
||||||
|
{
|
||||||
CFStringRef itemUrlString = CFURLGetString(itemUrlRef);
|
CFStringRef itemUrlString = CFURLGetString(itemUrlRef);
|
||||||
|
|
||||||
if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo) {
|
if (CFStringCompare(itemUrlString, appUrlRefString, 0) == kCFCompareEqualTo)
|
||||||
|
{
|
||||||
LSSharedFileListItemRemove(loginItems, item); // remove it!
|
LSSharedFileListItemRemove(loginItems, item); // remove it!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +155,10 @@ namespace Qv2ray::components::autolaunch
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined Q_OS_LINUX
|
#elif defined Q_OS_LINUX
|
||||||
|
//
|
||||||
|
// For AppImage packaging.
|
||||||
|
auto binPath = qEnvironmentVariableIsSet("APPIMAGE") ? qEnvironmentVariable("APPIMAGE") : QCoreApplication::applicationFilePath();
|
||||||
|
//
|
||||||
// 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 appName = QApplication::applicationName();
|
||||||
QString userAutoStartPath = getUserAutostartDir_private();
|
QString userAutoStartPath = getUserAutostartDir_private();
|
||||||
@ -150,15 +166,19 @@ namespace Qv2ray::components::autolaunch
|
|||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath)) {
|
if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath))
|
||||||
// qCWarning(lcUtility) << "Could not create autostart folder" << userAutoStartPath;
|
{
|
||||||
|
// qCWarning(lcUtility) << "Could not create autostart folder"
|
||||||
|
// << userAutoStartPath;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile iniFile(desktopFileLocation);
|
QFile iniFile(desktopFileLocation);
|
||||||
|
|
||||||
if (!iniFile.open(QIODevice::WriteOnly)) {
|
if (!iniFile.open(QIODevice::WriteOnly))
|
||||||
// qCWarning(lcUtility) << "Could not write auto start entry" << desktopFileLocation;
|
{
|
||||||
|
// qCWarning(lcUtility) << "Could not write auto start entry" <<
|
||||||
|
// desktopFileLocation;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,20 +187,22 @@ namespace Qv2ray::components::autolaunch
|
|||||||
ts << QLatin1String("[Desktop Entry]") << endl
|
ts << QLatin1String("[Desktop Entry]") << endl
|
||||||
<< QLatin1String("Name=") << QApplication::applicationName() << endl
|
<< QLatin1String("Name=") << QApplication::applicationName() << endl
|
||||||
<< QLatin1String("GenericName=") << QLatin1String("V2ray Frontend") << endl
|
<< QLatin1String("GenericName=") << QLatin1String("V2ray Frontend") << endl
|
||||||
<< QLatin1String("Exec=") << QCoreApplication::applicationFilePath() << endl
|
<< QLatin1String("Exec=") << binPath << endl
|
||||||
<< QLatin1String("Terminal=") << "false" << endl
|
<< QLatin1String("Terminal=") << "false" << endl
|
||||||
<< QLatin1String("Icon=") << "qv2ray" << endl // always use lowercase for icons
|
<< QLatin1String("Icon=") << "qv2ray" << endl // always use lowercase for icons
|
||||||
<< QLatin1String("Categories=") << "Network" << endl
|
<< QLatin1String("Categories=") << "Network" << endl
|
||||||
<< QLatin1String("Type=") << "Application" << endl
|
<< QLatin1String("Type=") << "Application" << endl
|
||||||
<< QLatin1String("StartupNotify=") << "false" << endl
|
<< QLatin1String("StartupNotify=") << "false" << endl
|
||||||
<< QLatin1String("X-GNOME-Autostart-enabled=") << "true" << endl;
|
<< QLatin1String("X-GNOME-Autostart-enabled=") << "true" << endl;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!QFile::remove(desktopFileLocation)) {
|
if (!QFile::remove(desktopFileLocation))
|
||||||
// qCWarning(lcUtility) << "Could not remove autostart desktop file";
|
{
|
||||||
|
// qCWarning(lcUtility) << "Could not remove autostart desktop
|
||||||
|
// file";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
} // namespace Qv2ray::components::autolaunch
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ namespace Qv2ray::components::autolaunch
|
|||||||
{
|
{
|
||||||
bool GetLaunchAtLoginStatus();
|
bool GetLaunchAtLoginStatus();
|
||||||
void SetLaunchAtLoginStatus(bool enable);
|
void SetLaunchAtLoginStatus(bool enable);
|
||||||
}
|
} // namespace Qv2ray::components::autolaunch
|
||||||
|
|
||||||
using namespace Qv2ray::components;
|
using namespace Qv2ray::components;
|
||||||
using namespace Qv2ray::components::autolaunch;
|
using namespace Qv2ray::components::autolaunch;
|
||||||
|
34
src/components/darkmode/DarkmodeDetector.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "DarkmodeDetector.hpp"
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QStyle>
|
||||||
|
#elif defined(Q_OS_WIN32)
|
||||||
|
#include <QSettings>
|
||||||
|
#else
|
||||||
|
// TODO: macOS headers.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Qv2ray::components::darkmode
|
||||||
|
{
|
||||||
|
// Referenced from github.com/keepassxreboot/keepassxc. Licensed under GPL2/3.
|
||||||
|
// Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||||
|
bool isDarkMode()
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
if (!qApp || !qApp->style())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return qApp->style()->standardPalette().color(QPalette::Window).toHsl().lightness() < 110;
|
||||||
|
#elif defined(Q_OS_WIN32)
|
||||||
|
QSettings settings(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)", QSettings::NativeFormat);
|
||||||
|
return settings.value("AppsUseLightTheme", 1).toInt() == 0;
|
||||||
|
#elif defined(Q_OS_DARWIN)
|
||||||
|
// TODO: expand this stub
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Qv2ray::components::darkmode
|
6
src/components/darkmode/DarkmodeDetector.hpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Qv2ray::components::darkmode
|
||||||
|
{
|
||||||
|
bool isDarkMode();
|
||||||
|
}
|
@ -1,20 +1,22 @@
|
|||||||
#include "QvGeositeReader.hpp"
|
#include "QvGeositeReader.hpp"
|
||||||
#include "libs/gen/v2ray_geosite.pb.h"
|
|
||||||
|
#include "v2ray_geosite.pb.h"
|
||||||
|
|
||||||
namespace Qv2ray::components::geosite
|
namespace Qv2ray::components::geosite
|
||||||
{
|
{
|
||||||
QStringList ReadGeoSiteFromFile(QString filepath)
|
QStringList ReadGeoSiteFromFile(QString filepath)
|
||||||
{
|
{
|
||||||
QStringList list;
|
QStringList list;
|
||||||
LOG(FILEIO, "Reading geosites from: " + filepath)
|
LOG(MODULE_FILEIO, "Reading geosites from: " + filepath)
|
||||||
//
|
//
|
||||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
//
|
//
|
||||||
QFile f(filepath);
|
QFile f(filepath);
|
||||||
bool opened = f.open(QFile::OpenModeFlag::ReadOnly);
|
bool opened = f.open(QFile::OpenModeFlag::ReadOnly);
|
||||||
|
|
||||||
if (!opened) {
|
if (!opened)
|
||||||
LOG(FILEIO, "File cannot be opened: " + filepath)
|
{
|
||||||
|
LOG(MODULE_FILEIO, "File cannot be opened: " + filepath)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,14 +26,15 @@ namespace Qv2ray::components::geosite
|
|||||||
GeoSiteList sites;
|
GeoSiteList sites;
|
||||||
sites.ParseFromArray(content.data(), content.size());
|
sites.ParseFromArray(content.data(), content.size());
|
||||||
|
|
||||||
for (auto e : sites.entry()) {
|
for (auto e : sites.entry())
|
||||||
|
{
|
||||||
// We want to use lower string.
|
// We want to use lower string.
|
||||||
list << QString::fromStdString(e.country_code()).toLower();
|
list << QString::fromStdString(e.country_code()).toLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(FILEIO, "Loaded " + QSTRN(list.count()) + " geosite entries from data file.")
|
LOG(MODULE_FILEIO, "Loaded " + QSTRN(list.count()) + " geosite entries from data file.")
|
||||||
// Optional: Delete all global objects allocated by libprotobuf.
|
// Optional: Delete all global objects allocated by libprotobuf.
|
||||||
google::protobuf::ShutdownProtobufLibrary();
|
google::protobuf::ShutdownProtobufLibrary();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::components::geosite
|
||||||
|
52
src/components/icmping/win/ICMPPinger.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include "ICMPPinger.hpp"
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
ICMPPinger::ICMPPinger(UINT64 timeout = DEFAULT_TIMEOUT)
|
||||||
|
{
|
||||||
|
// create icmp handle
|
||||||
|
if ((this->hIcmpFile = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
throw "IcmpCreateFile failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember the timeout
|
||||||
|
this->timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ICMPPinger::~ICMPPinger()
|
||||||
|
{
|
||||||
|
// release the handle on destruction
|
||||||
|
IcmpCloseHandle(this->hIcmpFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::optional<UINT64>, std::optional<std::string>> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// request buffer
|
||||||
|
const static char bufRequest[] = "echo test";
|
||||||
|
|
||||||
|
// response buffer
|
||||||
|
const auto responseSize = sizeof(ICMP_ECHO_REPLY) + sizeof(bufRequest);
|
||||||
|
const std::unique_ptr<char> bufRecv(new (char[responseSize]));
|
||||||
|
|
||||||
|
// send echo
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read round-trip time
|
||||||
|
PICMP_ECHO_REPLY pReply = (PICMP_ECHO_REPLY) bufRecv.get();
|
||||||
|
return std::pair(pReply->RoundTripTime, std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
34
src/components/icmping/win/ICMPPinger.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <optional>
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* ICMPPinger - An Implementation of ICMPPing on Windows Platform
|
||||||
|
* Required Windows Version: 2000 / XP / 7 / Vista+
|
||||||
|
* License: WTFPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <icmpapi.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <utility>
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
class ICMPPinger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ICMPPinger(UINT64 timeout = DEFAULT_TIMEOUT);
|
||||||
|
~ICMPPinger();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const UINT64 DEFAULT_TIMEOUT = 10000U;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::pair<std::optional<UINT64>, std::optional<std::string>> ping(const std::string &ipAddr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE hIcmpFile;
|
||||||
|
UINT64 timeout = DEFAULT_TIMEOUT;
|
||||||
|
};
|
||||||
|
#endif
|
@ -21,27 +21,37 @@ namespace Qv2ray::components::pac
|
|||||||
bool passRule1 = originLine.find("|") != string::npos; // Proxy Lines
|
bool passRule1 = originLine.find("|") != string::npos; // Proxy Lines
|
||||||
bool passRule2 = originLine.find(".") != string::npos; // Link-Contained Lines
|
bool passRule2 = originLine.find(".") != string::npos; // Link-Contained Lines
|
||||||
|
|
||||||
if (originLine[endPosition] == '\n') {
|
if (originLine[endPosition] == '\n')
|
||||||
|
{
|
||||||
endPosition -= 1;
|
endPosition -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originLine.find("http://") != string::npos) {
|
if (originLine.find("http://") != string::npos)
|
||||||
|
{
|
||||||
startPosition += 8;
|
startPosition += 8;
|
||||||
} else if (originLine.find("https://") != string::npos) {
|
}
|
||||||
|
else if (originLine.find("https://") != string::npos)
|
||||||
|
{
|
||||||
startPosition += 9;
|
startPosition += 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip unrelated lines
|
// Skip unrelated lines
|
||||||
if (skipRule1 || skipRule2 || skipRule3 || skipRule4) {
|
if (skipRule1 || skipRule2 || skipRule3 || skipRule4)
|
||||||
|
{
|
||||||
return "";
|
return "";
|
||||||
} else if (passRule2) {
|
}
|
||||||
if (passRule1) {
|
else if (passRule2)
|
||||||
|
{
|
||||||
|
if (passRule1)
|
||||||
|
{
|
||||||
startPosition += originLine.find_last_of("|") + 1;
|
startPosition += originLine.find_last_of("|") + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originLine[startPosition] == '\n') startPosition += 1;
|
if (originLine[startPosition] == '\n')
|
||||||
|
startPosition += 1;
|
||||||
|
|
||||||
for (size_t i = startPosition; i < endPosition; ++i) {
|
for (size_t i = startPosition; i < endPosition; ++i)
|
||||||
|
{
|
||||||
returnBuffer += originLine[i];
|
returnBuffer += originLine[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,17 +62,20 @@ namespace Qv2ray::components::pac
|
|||||||
QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString)
|
QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString)
|
||||||
{
|
{
|
||||||
auto rawFileContent = Base64Decode(rawContent).toStdString();
|
auto rawFileContent = Base64Decode(rawContent).toStdString();
|
||||||
string readBuffer = ""; //cleanup
|
string readBuffer = ""; // cleanup
|
||||||
string writeBuffer;
|
string writeBuffer;
|
||||||
string domainListCache = "";
|
string domainListCache = "";
|
||||||
|
|
||||||
for (size_t i = 0; i < rawFileContent.size(); ++i) {
|
for (size_t i = 0; i < rawFileContent.size(); ++i)
|
||||||
|
{
|
||||||
readBuffer += rawFileContent[i];
|
readBuffer += rawFileContent[i];
|
||||||
|
|
||||||
if (rawFileContent[i + 1] == '\n') {
|
if (rawFileContent[i + 1] == '\n')
|
||||||
|
{
|
||||||
writeBuffer = getRawDomain(readBuffer);
|
writeBuffer = getRawDomain(readBuffer);
|
||||||
|
|
||||||
if (writeBuffer != "") {
|
if (writeBuffer != "")
|
||||||
|
{
|
||||||
domainListCache += writeBuffer + "\n";
|
domainListCache += writeBuffer + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,19 +85,22 @@ namespace Qv2ray::components::pac
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t rotatorTwo = 0;
|
size_t rotatorTwo = 0;
|
||||||
string readDomainBuffer = "";
|
string readDomainBuffer = "";
|
||||||
bool isFirstLine = true;
|
bool isFirstLine = true;
|
||||||
string outputContent = "";
|
string outputContent = "";
|
||||||
//Header
|
// Header
|
||||||
outputContent += "var domains = {\n";
|
outputContent += "var domains = {\n";
|
||||||
|
|
||||||
//Read and process output content line by line
|
// Read and process output content line by line
|
||||||
while (rotatorTwo < domainListCache.size()) {
|
while (rotatorTwo < domainListCache.size())
|
||||||
while (true) {
|
{
|
||||||
//Get Domain
|
while (true)
|
||||||
|
{
|
||||||
|
// Get Domain
|
||||||
readDomainBuffer += domainListCache[rotatorTwo];
|
readDomainBuffer += domainListCache[rotatorTwo];
|
||||||
|
|
||||||
if (domainListCache[rotatorTwo + 1] == '\n') {
|
if (domainListCache[rotatorTwo + 1] == '\n')
|
||||||
|
{
|
||||||
rotatorTwo += 2;
|
rotatorTwo += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -92,9 +108,11 @@ namespace Qv2ray::components::pac
|
|||||||
rotatorTwo++;
|
rotatorTwo++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Format
|
// Format
|
||||||
if (!isFirstLine) outputContent += ",\n";
|
if (!isFirstLine)
|
||||||
else isFirstLine = false;
|
outputContent += ",\n";
|
||||||
|
else
|
||||||
|
isFirstLine = false;
|
||||||
|
|
||||||
outputContent += "\t\"";
|
outputContent += "\t\"";
|
||||||
outputContent += readDomainBuffer;
|
outputContent += readDomainBuffer;
|
||||||
@ -102,32 +120,18 @@ namespace Qv2ray::components::pac
|
|||||||
readDomainBuffer = "";
|
readDomainBuffer = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
//End Message
|
// End Message
|
||||||
outputContent +=
|
outputContent += NEWLINE "};" NEWLINE "" NEWLINE " var proxy = \"" + customProxyString.toStdString() + ";\";" +
|
||||||
NEWLINE "};"
|
NEWLINE " var direct = 'DIRECT;';" NEWLINE " function FindProxyForURL(url, host) {" NEWLINE
|
||||||
NEWLINE ""
|
" var suffix;" NEWLINE " var pos = host.lastIndexOf('.');" NEWLINE
|
||||||
NEWLINE " var proxy = \"" + customProxyString.toStdString() + ";\";" +
|
" pos = host.lastIndexOf('.', pos - 1);" NEWLINE " //" NEWLINE " while (1) {" NEWLINE
|
||||||
NEWLINE " var direct = 'DIRECT;';"
|
" if (domains[host] != undefined) {" NEWLINE " return proxy;" NEWLINE
|
||||||
NEWLINE " function FindProxyForURL(url, host) {"
|
" }" NEWLINE " else if (pos <= 0) {" NEWLINE
|
||||||
NEWLINE " var suffix;"
|
" return domains['.' + host] != undefined ? proxy : direct;" NEWLINE " }" NEWLINE
|
||||||
NEWLINE " var pos = host.lastIndexOf('.');"
|
" suffix = host.substring(pos);" NEWLINE " if (domains[suffix] != undefined) {" NEWLINE
|
||||||
NEWLINE " pos = host.lastIndexOf('.', pos - 1);"
|
" return proxy;" NEWLINE " }" NEWLINE
|
||||||
NEWLINE " //"
|
" pos = host.lastIndexOf('.', pos - 1);" NEWLINE " }" 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);
|
return QString::fromStdString(outputContent);
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::components::pac
|
||||||
|
@ -1,79 +1,82 @@
|
|||||||
#include "QvPACHandler.hpp"
|
#include "QvPACHandler.hpp"
|
||||||
#include "qhttprequest.h"
|
|
||||||
#include "qhttpresponse.h"
|
#include "3rdparty/cpp-httplib/httplib.h"
|
||||||
#include "core/CoreUtils.hpp"
|
|
||||||
#include "common/QvHelpers.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
|
#include "core/CoreUtils.hpp"
|
||||||
|
|
||||||
namespace Qv2ray::components::pac
|
namespace Qv2ray::components::pac
|
||||||
{
|
{
|
||||||
|
|
||||||
PACServer::PACServer() : QObject(), pacServer(this)
|
PACServer::PACServer() : QThread()
|
||||||
{
|
{
|
||||||
connect(&pacServer, &QHttpServer::newRequest, this, &PACServer::onNewRequest);
|
pacServer = new httplib::Server();
|
||||||
}
|
}
|
||||||
PACServer::~PACServer()
|
PACServer::~PACServer()
|
||||||
{
|
{
|
||||||
if (isStarted) {
|
StopServer();
|
||||||
pacServer.close();
|
delete pacServer;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void PACServer::SetProxyString(const QString &proxyString)
|
void PACServer::SetProxyString(const QString &proxyString)
|
||||||
{
|
{
|
||||||
DEBUG(PROXY, "Setting new PAC proxy string: " + proxyString)
|
DEBUG(MODULE_PROXY, "Setting new PAC proxy string: " + proxyString)
|
||||||
this->proxyString = proxyString;
|
this->proxyString = proxyString;
|
||||||
}
|
}
|
||||||
void PACServer::StartListen()
|
void PACServer::run()
|
||||||
{
|
{
|
||||||
LOG(PROXY, "Starting PAC listener")
|
LOG(MODULE_PROXY, "Starting PAC listener")
|
||||||
//
|
//
|
||||||
auto address = GlobalConfig.inboundConfig.listenip;
|
auto address = GlobalConfig.inboundConfig.listenip;
|
||||||
auto port = GlobalConfig.inboundConfig.pacConfig.port;
|
auto port = GlobalConfig.inboundConfig.pacConfig.port;
|
||||||
//
|
//
|
||||||
DEBUG(PROXY, "PAC Listening local endpoint: " + address + ":" + QSTRN(port))
|
DEBUG(MODULE_PROXY, "PAC Listening local endpoint: " + address + ":" + QSTRN(port))
|
||||||
//
|
//
|
||||||
QString gfwContent = StringFromFile(QV2RAY_RULES_GFWLIST_PATH);
|
QString gfwContent = StringFromFile(QV2RAY_RULES_GFWLIST_PATH);
|
||||||
pacContent = ConvertGFWToPAC(gfwContent, proxyString);
|
pacContent = ConvertGFWToPAC(gfwContent, proxyString);
|
||||||
//
|
//
|
||||||
auto result = pacServer.listen(QHostAddress(address), static_cast<ushort>(port));
|
pacServer->Get("/pac", onNewRequest);
|
||||||
|
auto result = pacServer->listen(address.toStdString().c_str(), static_cast<ushort>(port));
|
||||||
if (result) {
|
if (result)
|
||||||
isStarted = true;
|
{
|
||||||
DEBUG(PROXY, "Started PAC handler")
|
DEBUG(MODULE_PROXY, "PAC handler stopped.")
|
||||||
} else {
|
}
|
||||||
LOG(PROXY, "Failed to listen on port " + QSTRN(port) + ", possible permission denied.")
|
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"));
|
QvMessageBoxWarn(nullptr, tr("PAC Handler"), tr("Failed to listen PAC request on this port, please verify the permissions"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PACServer::StopServer()
|
void PACServer::StopServer()
|
||||||
{
|
{
|
||||||
if (isStarted) {
|
if (pacServer->is_running())
|
||||||
pacServer.close();
|
{
|
||||||
DEBUG(PROXY, "PAC Handler stopped.")
|
pacServer->stop();
|
||||||
isStarted = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PACServer::onNewRequest(QHttpRequest *req, QHttpResponse *rsp)
|
void PACServer::onNewRequest(const httplib::Request &req, httplib::Response &rsp)
|
||||||
{
|
{
|
||||||
rsp->setHeader("Server", "Qv2ray/" QV2RAY_VERSION_STRING " PAC_Handler");
|
rsp.set_header("Server", "Qv2ray/" QV2RAY_VERSION_STRING " PAC_Handler");
|
||||||
|
if (req.method == "GET")
|
||||||
if (req->method() == QHttpRequest::HTTP_GET) {
|
{
|
||||||
//
|
if (req.path == "/pac")
|
||||||
if (req->path() == "/pac") {
|
{
|
||||||
DEBUG(PROXY, "Serving PAC file request.")
|
DEBUG(MODULE_PROXY, "Serving PAC file request.")
|
||||||
//
|
//
|
||||||
rsp->setHeader("Content-Type", "application/javascript; charset=utf-8");
|
rsp.status = 200;
|
||||||
rsp->writeHead(QHttpResponse::StatusCode::STATUS_OK);
|
rsp.set_content(pacContent.toStdString(), "application/javascript; charset=utf-8");
|
||||||
rsp->end(pacContent.toUtf8());
|
DEBUG(MODULE_PROXY, "Serving a pac file...")
|
||||||
DEBUG(PROXY, "Serving a pac file...")
|
|
||||||
} 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");
|
rsp.status = 404;
|
||||||
|
rsp.set_content("NOT FOUND", "text/plain; charset=utf-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rsp.status = 405;
|
||||||
|
rsp.set_content("PAC ONLY SUPPORT GET", "text/plain; charset=utf-8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::components::pac
|
||||||
|
@ -1,33 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "qhttpserver.h"
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QThread>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
namespace httplib
|
||||||
|
{
|
||||||
|
class Server;
|
||||||
|
struct Request;
|
||||||
|
struct Response;
|
||||||
|
} // namespace httplib
|
||||||
|
|
||||||
namespace Qv2ray::components::pac
|
namespace Qv2ray::components::pac
|
||||||
{
|
{
|
||||||
QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString);
|
QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString);
|
||||||
class PACServer : public QObject
|
class PACServer : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PACServer();
|
explicit PACServer();
|
||||||
~PACServer();
|
~PACServer();
|
||||||
void SetProxyString(const QString &proxyString);
|
void SetProxyString(const QString &proxyString);
|
||||||
void StartListen();
|
void StartListen()
|
||||||
void StopServer();
|
{
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
void StopServer();
|
||||||
|
|
||||||
QString gfwFilePath;
|
QString gfwFilePath;
|
||||||
|
|
||||||
public slots:
|
private:
|
||||||
void onNewRequest(QHttpRequest *request, QHttpResponse *response);
|
void run() override;
|
||||||
|
httplib::Server *pacServer;
|
||||||
|
QString proxyString;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isStarted;
|
static void onNewRequest(const httplib::Request &req, httplib::Response &rsp);
|
||||||
QHttpServer pacServer;
|
static inline QString pacContent;
|
||||||
QString pacContent;
|
|
||||||
QString proxyString;
|
|
||||||
};
|
};
|
||||||
}
|
} // namespace Qv2ray::components::pac
|
||||||
|
|
||||||
using namespace Qv2ray::components;
|
using namespace Qv2ray::components;
|
||||||
using namespace Qv2ray::components::pac;
|
using namespace Qv2ray::components::pac;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include <QThread>
|
#include "components/plugins/toolbar/QvToolbar.hpp"
|
||||||
#include "ui/w_MainWindow.hpp"
|
|
||||||
#include "components/plugins/toolbar/QvToolbar.hpp"
|
|
||||||
#include "common/QvHelpers.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
|
#include "core/handler/ConfigHandler.hpp"
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
namespace Qv2ray::components::plugins
|
namespace Qv2ray::components::plugins
|
||||||
{
|
{
|
||||||
@ -30,129 +32,148 @@ namespace Qv2ray::components::plugins
|
|||||||
}
|
}
|
||||||
QString GetAnswerToRequest(const QString &pchRequest)
|
QString GetAnswerToRequest(const QString &pchRequest)
|
||||||
{
|
{
|
||||||
auto instance = MainWindow::mwInstance;
|
|
||||||
|
|
||||||
if (instance == nullptr || instance->vinstance == nullptr) {
|
|
||||||
LOG(PLUGIN, "MainWindow != nullptr Assertion failed!")
|
|
||||||
return "{}";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto vinstance = instance->vinstance;
|
|
||||||
//
|
|
||||||
auto req = pchRequest.trimmed();
|
auto req = pchRequest.trimmed();
|
||||||
QString reply = "{}";
|
QString reply = "{}";
|
||||||
|
|
||||||
if (req == "START") {
|
if (req == "START")
|
||||||
emit instance->Connect();
|
{
|
||||||
} else if (req == "STOP") {
|
emit ConnectionManager->RestartConnection();
|
||||||
emit instance->DisConnect();
|
}
|
||||||
} else if (req == "RESTART") {
|
else if (req == "STOP")
|
||||||
emit instance->ReConnect();
|
{
|
||||||
|
emit ConnectionManager->StopConnection();
|
||||||
|
}
|
||||||
|
else if (req == "RESTART")
|
||||||
|
{
|
||||||
|
emit ConnectionManager->RestartConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BarConfig = GlobalConfig.toolBarConfig;
|
auto BarConfig = GlobalConfig.toolBarConfig;
|
||||||
|
|
||||||
for (auto i = 0; i < BarConfig.Pages.size(); i++) {
|
for (auto i = 0; i < BarConfig.Pages.size(); i++)
|
||||||
for (auto j = 0; j < BarConfig.Pages[i].Lines.size(); j++) {
|
{
|
||||||
|
for (auto j = 0; j < BarConfig.Pages[i].Lines.size(); j++)
|
||||||
|
{
|
||||||
#define CL BarConfig.Pages[i].Lines[j]
|
#define CL BarConfig.Pages[i].Lines[j]
|
||||||
|
|
||||||
switch (CL.ContentType) {
|
switch (CL.ContentType)
|
||||||
case 0: {
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
// Custom Text
|
// Custom Text
|
||||||
// We do nothing...
|
// We do nothing...
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 101: {
|
case 101:
|
||||||
|
{
|
||||||
// Current Time
|
// Current Time
|
||||||
CL.Message = QTime().currentTime().toString("hh:mm:ss");
|
CL.Message = QTime().currentTime().toString("hh:mm:ss");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 102: {
|
case 102:
|
||||||
|
{
|
||||||
// Current Date
|
// Current Date
|
||||||
CL.Message = QDate().currentDate().toString("yyyy-MM-dd");
|
CL.Message = QDate().currentDate().toString("yyyy-MM-dd");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 103: {
|
case 103:
|
||||||
|
{
|
||||||
// Current Qv2ray Version
|
// Current Qv2ray Version
|
||||||
CL.Message = QV2RAY_VERSION_STRING;
|
CL.Message = QV2RAY_VERSION_STRING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 104: {
|
case 104:
|
||||||
|
{
|
||||||
// Current Connection Name
|
// Current Connection Name
|
||||||
CL.Message = instance->GetCurrentConnectedConfigName();
|
CL.Message = GetDisplayName(ConnectionManager->CurrentConnection());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 105: {
|
case 105:
|
||||||
|
{
|
||||||
// Current Connection Status
|
// Current Connection Status
|
||||||
CL.Message = instance->vinstance->KernelStarted
|
CL.Message = ConnectionManager->CurrentConnection() == NullConnectionId ? QObject::tr("Not connected") :
|
||||||
? QObject::tr("Connected")
|
QObject::tr("Connected");
|
||||||
: QObject::tr("Disconnected");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 201: {
|
// case 201:
|
||||||
// Total upload speed;
|
//{
|
||||||
CL.Message = FormatBytes(vinstance->getAllSpeedUp()) + "/s";
|
// // Total upload speed;
|
||||||
break;
|
// CL.Message = FormatBytes(get<0>(GetConnectionUsageAmount())) + "/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 202: {
|
case 301:
|
||||||
// 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
|
// Total Upload
|
||||||
CL.Message = FormatBytes(vinstance->getAllDataUp());
|
CL.Message = FormatBytes(get<0>(GetConnectionUsageAmount(ConnectionManager->CurrentConnection())));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 302: {
|
case 302:
|
||||||
|
{
|
||||||
// Total download
|
// Total download
|
||||||
CL.Message = FormatBytes(vinstance->getAllDataDown());
|
CL.Message = FormatBytes(get<1>(GetConnectionUsageAmount(ConnectionManager->CurrentConnection())));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 303: {
|
// case 303:
|
||||||
// Upload for tag
|
//{
|
||||||
CL.Message = FormatBytes(vinstance->getTagDataUp(CL.Message));
|
// // 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 305:
|
||||||
|
{
|
||||||
|
// Connection latency
|
||||||
|
CL.Message = QSTRN(GetConnectionLatency(ConnectionManager->CurrentConnection())) + " ms";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
case 304: {
|
{
|
||||||
// Download for tag
|
CL.Message = "Not Implemented";
|
||||||
CL.Message = FormatBytes(vinstance->getTagDataDown(CL.Message));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
CL.Message = "Not Supported?";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#undef CL
|
||||||
reply = StructToJsonString(BarConfig);
|
reply = StructToJsonString(BarConfig);
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Toolbar
|
||||||
}
|
} // namespace Qv2ray::components::plugins
|
||||||
|
@ -9,8 +9,8 @@ namespace Qv2ray::components::plugins
|
|||||||
namespace Toolbar
|
namespace Toolbar
|
||||||
{
|
{
|
||||||
/// NO NOT CHANGE THE ORDER
|
/// NO NOT CHANGE THE ORDER
|
||||||
static const QMap<int, QString> NetSpeedPluginMessages {
|
static const QMap<int, QString> NetSpeedPluginMessages{
|
||||||
{ 0, QObject::tr("Custom Text")},
|
{ 0, QObject::tr("Custom Text") },
|
||||||
// Current Status
|
// Current Status
|
||||||
{ 101, QObject::tr("Current Time") },
|
{ 101, QObject::tr("Current Time") },
|
||||||
{ 102, QObject::tr("Current Date") },
|
{ 102, QObject::tr("Current Date") },
|
||||||
@ -20,13 +20,14 @@ namespace Qv2ray::components::plugins
|
|||||||
// Speeds
|
// Speeds
|
||||||
{ 201, QObject::tr("Total Upload Speed") },
|
{ 201, QObject::tr("Total Upload Speed") },
|
||||||
{ 202, QObject::tr("Total Download Speed") },
|
{ 202, QObject::tr("Total Download Speed") },
|
||||||
{ 203, QObject::tr("Upload Speed for Specific Tag") },
|
//{ 203, QObject::tr("Upload Speed for Specific Tag") },
|
||||||
{ 204, QObject::tr("Download Speed for Specific Tag") },
|
//{ 204, QObject::tr("Download Speed for Specific Tag") },
|
||||||
// Datas
|
// Datas
|
||||||
{ 301, QObject::tr("Total Uploaded Data") },
|
{ 301, QObject::tr("Total Uploaded Data") },
|
||||||
{ 302, QObject::tr("Total Downloaded Data") },
|
{ 302, QObject::tr("Total Downloaded Data") },
|
||||||
{ 303, QObject::tr("Uploaded Data for Specific Tag") },
|
//{ 303, QObject::tr("Uploaded Data for Specific Tag") },
|
||||||
{ 304, QObject::tr("Downloaded Data for Specific Tag") }
|
//{ 304, QObject::tr("Downloaded Data for Specific Tag") }
|
||||||
|
{ 305, QObject::tr("Current Connection Latency") } //
|
||||||
};
|
};
|
||||||
void StartProcessingPlugins();
|
void StartProcessingPlugins();
|
||||||
void StopProcessingPlugins();
|
void StopProcessingPlugins();
|
||||||
@ -35,7 +36,7 @@ namespace Qv2ray::components::plugins
|
|||||||
{
|
{
|
||||||
void StartNamedPipeThread();
|
void StartNamedPipeThread();
|
||||||
void KillNamedPipeThread();
|
void KillNamedPipeThread();
|
||||||
}
|
} // namespace _win
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
namespace _linux
|
namespace _linux
|
||||||
@ -45,13 +46,12 @@ namespace Qv2ray::components::plugins
|
|||||||
void StartMessageQThread();
|
void StartMessageQThread();
|
||||||
void StopMessageQThread();
|
void StopMessageQThread();
|
||||||
|
|
||||||
}
|
} // namespace _linux
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString GetAnswerToRequest(const QString &pchRequest);
|
QString GetAnswerToRequest(const QString &pchRequest);
|
||||||
}
|
} // namespace Toolbar
|
||||||
}
|
} // namespace Qv2ray::components::plugins
|
||||||
|
|
||||||
using namespace Qv2ray::components;
|
using namespace Qv2ray::components;
|
||||||
using namespace Qv2ray::components::plugins::Toolbar;
|
using namespace Qv2ray::components::plugins::Toolbar;
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
#include "components/plugins/toolbar/QvToolbar.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
#include "common/QvHelpers.hpp"
|
#include "components/plugins/toolbar/QvToolbar.hpp"
|
||||||
#include <QLocalSocket>
|
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
namespace Qv2ray::components::plugins::Toolbar
|
namespace Qv2ray::components::plugins::Toolbar
|
||||||
{
|
{
|
||||||
namespace _linux
|
namespace _linux
|
||||||
@ -19,32 +20,41 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
if (!socket->waitForConnected() || !socket->waitForReadyRead())
|
if (!socket->waitForConnected() || !socket->waitForReadyRead())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try
|
||||||
while (!isExiting && socket->isOpen() && socket->isValid() && socket->waitForReadyRead()) {
|
{
|
||||||
|
while (!isExiting && socket->isOpen() && socket->isValid() && socket->waitForReadyRead())
|
||||||
|
{
|
||||||
// CANNOT PROPERLY READ...
|
// CANNOT PROPERLY READ...
|
||||||
// Temp-ly fixed (but why and how?)
|
// Temp-ly fixed (but why and how?)
|
||||||
auto in = QString(socket->readAll());
|
auto in = QString(socket->readAll());
|
||||||
|
|
||||||
if (!isExiting && !in.isEmpty()) {
|
if (!isExiting && !in.isEmpty())
|
||||||
|
{
|
||||||
auto out = GetAnswerToRequest(in);
|
auto out = GetAnswerToRequest(in);
|
||||||
//
|
//
|
||||||
socket->write(out.toUtf8());
|
socket->write(out.toUtf8());
|
||||||
socket->flush();
|
socket->flush();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QThread::msleep(200);
|
QThread::msleep(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
}
|
||||||
LOG(PLUGIN, "Closing a broken socket.")
|
catch (...)
|
||||||
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "Closing a broken socket.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void DataMessageQThread()
|
void DataMessageQThread()
|
||||||
{
|
{
|
||||||
server = new QLocalServer();
|
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);
|
bool listening = server->listen(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_LINUX);
|
||||||
|
|
||||||
while (!isExiting && !listening) {
|
while (!isExiting && !listening)
|
||||||
|
{
|
||||||
QThread::msleep(500);
|
QThread::msleep(500);
|
||||||
listening = server->listen(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_LINUX);
|
listening = server->listen(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_LINUX);
|
||||||
}
|
}
|
||||||
@ -53,10 +63,11 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
server->setSocketOptions(QLocalServer::WorldAccessOption);
|
server->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||||
QObject::connect(server, &QLocalServer::newConnection, &qobject_proxy);
|
QObject::connect(server, &QLocalServer::newConnection, &qobject_proxy);
|
||||||
|
|
||||||
while (!isExiting) {
|
while (!isExiting)
|
||||||
|
{
|
||||||
bool result = server->waitForNewConnection(5000, &timeOut);
|
bool result = server->waitForNewConnection(5000, &timeOut);
|
||||||
DEBUG(PLUGIN, "Plugin thread listening failed: " + server->errorString())
|
DEBUG(MODULE_PLUGIN, "Plugin thread listening failed: " + server->errorString())
|
||||||
DEBUG(PLUGIN, "waitForNewConnection: " + QString(result ? "true" : "false") + ", " + QString(timeOut ? "true" : "false"))
|
DEBUG(MODULE_PLUGIN, "waitForNewConnection: " + QString(result ? "true" : "false") + ", " + QString(timeOut ? "true" : "false"))
|
||||||
}
|
}
|
||||||
|
|
||||||
server->close();
|
server->close();
|
||||||
@ -72,13 +83,14 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
{
|
{
|
||||||
isExiting = true;
|
isExiting = true;
|
||||||
|
|
||||||
if (linuxWorkerThread->isRunning()) {
|
if (linuxWorkerThread->isRunning())
|
||||||
LOG(PLUGIN, "Waiting for linuxWorkerThread to stop.")
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "Waiting for linuxWorkerThread to stop.")
|
||||||
linuxWorkerThread->wait();
|
linuxWorkerThread->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete _linux::linuxWorkerThread;
|
delete _linux::linuxWorkerThread;
|
||||||
}
|
}
|
||||||
}
|
} // namespace _linux
|
||||||
}
|
} // namespace Qv2ray::components::plugins::Toolbar
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include "components/plugins/toolbar/QvToolbar.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
#include "common/QvHelpers.hpp"
|
#include "components/plugins/toolbar/QvToolbar.hpp"
|
||||||
#include <windows.h>
|
|
||||||
|
#include <windows.h>
|
||||||
namespace Qv2ray::components::plugins::Toolbar
|
namespace Qv2ray::components::plugins::Toolbar
|
||||||
{
|
{
|
||||||
namespace _win
|
namespace _win
|
||||||
@ -25,40 +26,53 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
{
|
{
|
||||||
auto hThread = CreateThread(nullptr, 0, NamedPipeMasterThread, nullptr, 0, nullptr);
|
auto hThread = CreateThread(nullptr, 0, NamedPipeMasterThread, nullptr, 0, nullptr);
|
||||||
|
|
||||||
if (hThread == nullptr) {
|
if (hThread == nullptr)
|
||||||
LOG(PLUGIN, "CreateThread failed, GLE=" + QSTRN(GetLastError()))
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" + QSTRN(GetLastError()))
|
||||||
return;
|
return;
|
||||||
} else CloseHandle(hThread);
|
}
|
||||||
|
else
|
||||||
|
CloseHandle(hThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI NamedPipeMasterThread(LPVOID lpvParam)
|
DWORD WINAPI NamedPipeMasterThread(LPVOID lpvParam)
|
||||||
{
|
{
|
||||||
Q_UNUSED(lpvParam)
|
Q_UNUSED(lpvParam)
|
||||||
BOOL fConnected = FALSE;
|
BOOL fConnected = FALSE;
|
||||||
DWORD dwThreadId = 0;
|
DWORD dwThreadId = 0;
|
||||||
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
||||||
auto lpszPipename = QString(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_WIN).toStdWString();
|
auto lpszPipename = QString(QV2RAY_NETSPEED_PLUGIN_PIPE_NAME_WIN).toStdWString();
|
||||||
|
|
||||||
while (!isExiting) {
|
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);
|
// 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(PLUGIN, "CreateNamedPipe failed, GLE=" + QSTRN(GetLastError()))
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "CreateNamedPipe failed, GLE=" + QSTRN(GetLastError()))
|
||||||
return static_cast<DWORD>(-1);
|
return static_cast<DWORD>(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fConnected = ConnectNamedPipe(hPipe, nullptr) ? true : (GetLastError() == ERROR_PIPE_CONNECTED);
|
fConnected = ConnectNamedPipe(hPipe, nullptr) ? true : (GetLastError() == ERROR_PIPE_CONNECTED);
|
||||||
|
|
||||||
if (fConnected) {
|
if (fConnected)
|
||||||
LOG(PLUGIN, "Client connected, creating a processing thread")
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "Client connected, creating a processing thread")
|
||||||
ThreadHandle = CreateThread(nullptr, 0, InstanceThread, hPipe, 0, &dwThreadId);
|
ThreadHandle = CreateThread(nullptr, 0, InstanceThread, hPipe, 0, &dwThreadId);
|
||||||
|
|
||||||
if (ThreadHandle == nullptr) {
|
if (ThreadHandle == nullptr)
|
||||||
LOG(PLUGIN, "CreateThread failed, GLE=" + QSTRN(GetLastError()))
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" + QSTRN(GetLastError()))
|
||||||
return static_cast<DWORD>(-1);
|
return static_cast<DWORD>(-1);
|
||||||
} else CloseHandle(ThreadHandle);
|
}
|
||||||
} else CloseHandle(hPipe);
|
else
|
||||||
|
CloseHandle(ThreadHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CloseHandle(hPipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -71,14 +85,19 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
HANDLE hPipe = static_cast<HANDLE>(lpvParam);
|
HANDLE hPipe = static_cast<HANDLE>(lpvParam);
|
||||||
TCHAR pchRequest[BUFSIZE] = { 0 };
|
TCHAR pchRequest[BUFSIZE] = { 0 };
|
||||||
|
|
||||||
while (!isExiting) {
|
while (!isExiting)
|
||||||
|
{
|
||||||
fSuccess = ReadFile(hPipe, pchRequest, BUFSIZE * sizeof(TCHAR), &cbBytesRead, nullptr);
|
fSuccess = ReadFile(hPipe, pchRequest, BUFSIZE * sizeof(TCHAR), &cbBytesRead, nullptr);
|
||||||
|
|
||||||
if (!fSuccess || cbBytesRead == 0) {
|
if (!fSuccess || cbBytesRead == 0)
|
||||||
if (GetLastError() == ERROR_BROKEN_PIPE) {
|
{
|
||||||
LOG(PLUGIN, "InstanceThread: client disconnected, GLE=" + QSTRN(GetLastError()))
|
if (GetLastError() == ERROR_BROKEN_PIPE)
|
||||||
} else {
|
{
|
||||||
LOG(PLUGIN, "InstanceThread ReadFile failed, GLE=" + QSTRN(GetLastError()))
|
LOG(MODULE_PLUGIN, "InstanceThread: client disconnected, GLE=" + QSTRN(GetLastError()))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "InstanceThread ReadFile failed, GLE=" + QSTRN(GetLastError()))
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -87,18 +106,21 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
auto req = QString::fromStdWString(pchRequest);
|
auto req = QString::fromStdWString(pchRequest);
|
||||||
QString replyQString = "{}";
|
QString replyQString = "{}";
|
||||||
|
|
||||||
if (!isExiting) {
|
if (!isExiting)
|
||||||
|
{
|
||||||
replyQString = GetAnswerToRequest(req);
|
replyQString = GetAnswerToRequest(req);
|
||||||
//
|
//
|
||||||
// REPLY as std::string
|
// REPLY as std::string
|
||||||
std::string pchReply = replyQString.toUtf8().constData();
|
std::string pchReply = replyQString.toUtf8().constData();
|
||||||
cbReplyBytes = static_cast<DWORD>(pchReply.length() + 1) * sizeof(CHAR);
|
cbReplyBytes = static_cast<DWORD>(pchReply.length() + 1) * sizeof(CHAR);
|
||||||
//cbReplyBytes = static_cast<DWORD>(replyQString.length() + 1) * sizeof(TCHAR);
|
// cbReplyBytes = static_cast<DWORD>(replyQString.length() +
|
||||||
|
// 1) * sizeof(TCHAR);
|
||||||
//
|
//
|
||||||
fSuccess = WriteFile(hPipe, pchReply.c_str(), cbReplyBytes, &cbWritten, nullptr);
|
fSuccess = WriteFile(hPipe, pchReply.c_str(), cbReplyBytes, &cbWritten, nullptr);
|
||||||
|
|
||||||
if (!fSuccess || cbReplyBytes != cbWritten) {
|
if (!fSuccess || cbReplyBytes != cbWritten)
|
||||||
LOG(PLUGIN, "InstanceThread WriteFile failed, GLE=" + QSTRN(GetLastError()))
|
{
|
||||||
|
LOG(MODULE_PLUGIN, "InstanceThread WriteFile failed, GLE=" + QSTRN(GetLastError()))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +131,6 @@ namespace Qv2ray::components::plugins::Toolbar
|
|||||||
CloseHandle(hPipe);
|
CloseHandle(hPipe);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
} // namespace _win
|
||||||
}
|
} // namespace Qv2ray::components::plugins::Toolbar
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include "QvProxyConfigurator.hpp"
|
#include "QvProxyConfigurator.hpp"
|
||||||
|
|
||||||
#include "common/QvHelpers.hpp"
|
#include "common/QvHelpers.hpp"
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include "wininet.h"
|
#include <WinInet.h>
|
||||||
#include <windows.h>
|
|
||||||
|
#include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Qv2ray::components::proxy
|
namespace Qv2ray::components::proxy
|
||||||
@ -13,30 +15,33 @@ namespace Qv2ray::components::proxy
|
|||||||
{
|
{
|
||||||
QProcess p;
|
QProcess p;
|
||||||
p.setProgram("/usr/sbin/networksetup");
|
p.setProgram("/usr/sbin/networksetup");
|
||||||
p.setArguments(QStringList() << "-listallnetworkservices");
|
p.setArguments(QStringList{ "-listallnetworkservices" });
|
||||||
p.start();
|
p.start();
|
||||||
p.waitForStarted();
|
p.waitForStarted();
|
||||||
p.waitForFinished();
|
p.waitForFinished();
|
||||||
LOG(PROXY, p.errorString())
|
LOG(MODULE_PROXY, p.errorString())
|
||||||
auto str = p.readAllStandardOutput();
|
auto str = p.readAllStandardOutput();
|
||||||
auto lines = SplitLines(str);
|
auto lines = SplitLines(str);
|
||||||
QStringList result;
|
QStringList result;
|
||||||
|
|
||||||
// Start from 1 since first line is unneeded.
|
// 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.
|
// * means disabled.
|
||||||
if (!lines[i].contains("*")) {
|
if (!lines[i].contains("*"))
|
||||||
result << (lines[i].contains(" ") ? "\"" + lines[i] + "\"" : lines[i]);
|
{
|
||||||
|
result << (lines[i].contains(" ") ? "\"" + lines[i] + "\"" : lines[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(PROXY, "Found " + QSTRN(result.size()) + " network services: " + result.join(";"))
|
LOG(MODULE_PROXY, "Found " + QSTRN(result.size()) + " network services: " + result.join(";"))
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#define NO_CONST(expr) const_cast<wchar_t *>(expr)
|
#define NO_CONST(expr) const_cast<wchar_t *>(expr)
|
||||||
//static auto DEFAULT_CONNECTION_NAME = NO_CONST(L"DefaultConnectionSettings");
|
// static auto DEFAULT_CONNECTION_NAME =
|
||||||
|
// NO_CONST(L"DefaultConnectionSettings");
|
||||||
///
|
///
|
||||||
/// INTERNAL FUNCTION
|
/// INTERNAL FUNCTION
|
||||||
bool __QueryProxyOptions()
|
bool __QueryProxyOptions()
|
||||||
@ -52,58 +57,69 @@ namespace Qv2ray::components::proxy
|
|||||||
Option[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
|
Option[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
|
||||||
//
|
//
|
||||||
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
|
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.dwOptionCount = 5;
|
||||||
List.dwOptionError = 0;
|
List.dwOptionError = 0;
|
||||||
List.pOptions = Option;
|
List.pOptions = Option;
|
||||||
|
|
||||||
if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
|
if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize))
|
||||||
LOG(PROXY, "InternetQueryOption failed, GLE=" + QSTRN(GetLastError()))
|
{
|
||||||
|
LOG(MODULE_PROXY, "InternetQueryOption failed, GLE=" + QSTRN(GetLastError()))
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(PROXY, "System default proxy info:")
|
LOG(MODULE_PROXY, "System default proxy info:")
|
||||||
|
|
||||||
if (Option[0].Value.pszValue != nullptr) {
|
if (Option[0].Value.pszValue != nullptr)
|
||||||
LOG(PROXY, QString::fromWCharArray(Option[0].Value.pszValue))
|
{
|
||||||
|
LOG(MODULE_PROXY, QString::fromWCharArray(Option[0].Value.pszValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL) {
|
if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL)
|
||||||
LOG(PROXY, "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) {
|
if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT)
|
||||||
LOG(PROXY, "PROXY_TYPE_AUTO_DETECT")
|
{
|
||||||
|
LOG(MODULE_PROXY, "PROXY_TYPE_AUTO_DETECT")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Option[2].Value.dwValue & PROXY_TYPE_DIRECT) == PROXY_TYPE_DIRECT) {
|
if ((Option[2].Value.dwValue & PROXY_TYPE_DIRECT) == PROXY_TYPE_DIRECT)
|
||||||
LOG(PROXY, "PROXY_TYPE_DIRECT")
|
{
|
||||||
|
LOG(MODULE_PROXY, "PROXY_TYPE_DIRECT")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Option[2].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY) {
|
if ((Option[2].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY)
|
||||||
LOG(PROXY, "PROXY_TYPE_PROXY")
|
{
|
||||||
|
LOG(MODULE_PROXY, "PROXY_TYPE_PROXY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
|
if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize))
|
||||||
LOG(PROXY, "InternetQueryOption failed,GLE=" + QSTRN(GetLastError()))
|
{
|
||||||
|
LOG(MODULE_PROXY, "InternetQueryOption failed,GLE=" + QSTRN(GetLastError()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Option[4].Value.pszValue != nullptr) {
|
if (Option[4].Value.pszValue != nullptr)
|
||||||
LOG(PROXY, QString::fromStdWString(Option[4].Value.pszValue))
|
{
|
||||||
|
LOG(MODULE_PROXY, QString::fromStdWString(Option[4].Value.pszValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNET_VERSION_INFO Version;
|
INTERNET_VERSION_INFO Version;
|
||||||
nSize = sizeof(INTERNET_VERSION_INFO);
|
nSize = sizeof(INTERNET_VERSION_INFO);
|
||||||
InternetQueryOption(nullptr, INTERNET_OPTION_VERSION, &Version, &nSize);
|
InternetQueryOption(nullptr, INTERNET_OPTION_VERSION, &Version, &nSize);
|
||||||
|
|
||||||
if (Option[0].Value.pszValue != nullptr) {
|
if (Option[0].Value.pszValue != nullptr)
|
||||||
|
{
|
||||||
GlobalFree(Option[0].Value.pszValue);
|
GlobalFree(Option[0].Value.pszValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Option[3].Value.pszValue != nullptr) {
|
if (Option[3].Value.pszValue != nullptr)
|
||||||
|
{
|
||||||
GlobalFree(Option[3].Value.pszValue);
|
GlobalFree(Option[3].Value.pszValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Option[4].Value.pszValue != nullptr) {
|
if (Option[4].Value.pszValue != nullptr)
|
||||||
|
{
|
||||||
GlobalFree(Option[4].Value.pszValue);
|
GlobalFree(Option[4].Value.pszValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,21 +128,23 @@ namespace Qv2ray::components::proxy
|
|||||||
bool __SetProxyOptions(LPWSTR proxy_full_addr, bool isPAC)
|
bool __SetProxyOptions(LPWSTR proxy_full_addr, bool isPAC)
|
||||||
{
|
{
|
||||||
INTERNET_PER_CONN_OPTION_LIST list;
|
INTERNET_PER_CONN_OPTION_LIST list;
|
||||||
BOOL bReturn;
|
BOOL bReturn;
|
||||||
DWORD dwBufSize = sizeof(list);
|
DWORD dwBufSize = sizeof(list);
|
||||||
// Fill the list structure.
|
// Fill the list structure.
|
||||||
list.dwSize = sizeof(list);
|
list.dwSize = sizeof(list);
|
||||||
// NULL == LAN, otherwise connectoid name.
|
// NULL == LAN, otherwise connectoid name.
|
||||||
list.pszConnection = nullptr;
|
list.pszConnection = nullptr;
|
||||||
|
|
||||||
if (isPAC) {
|
if (isPAC)
|
||||||
LOG(PROXY, "Setting system proxy for PAC")
|
{
|
||||||
|
LOG(MODULE_PROXY, "Setting system proxy for PAC")
|
||||||
//
|
//
|
||||||
list.dwOptionCount = 2;
|
list.dwOptionCount = 2;
|
||||||
list.pOptions = new INTERNET_PER_CONN_OPTION[2];
|
list.pOptions = new INTERNET_PER_CONN_OPTION[2];
|
||||||
|
|
||||||
// Ensure that the memory was allocated.
|
// Ensure that the memory was allocated.
|
||||||
if (nullptr == list.pOptions) {
|
if (nullptr == list.pOptions)
|
||||||
|
{
|
||||||
// Return FALSE if the memory wasn't allocated.
|
// Return FALSE if the memory wasn't allocated.
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -137,13 +155,16 @@ namespace Qv2ray::components::proxy
|
|||||||
// Set proxy name.
|
// Set proxy name.
|
||||||
list.pOptions[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
|
list.pOptions[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
|
||||||
list.pOptions[1].Value.pszValue = proxy_full_addr;
|
list.pOptions[1].Value.pszValue = proxy_full_addr;
|
||||||
} else {
|
}
|
||||||
LOG(PROXY, "Setting system proxy for Global Proxy")
|
else
|
||||||
|
{
|
||||||
|
LOG(MODULE_PROXY, "Setting system proxy for Global Proxy")
|
||||||
//
|
//
|
||||||
list.dwOptionCount = 3;
|
list.dwOptionCount = 3;
|
||||||
list.pOptions = new INTERNET_PER_CONN_OPTION[3];
|
list.pOptions = new INTERNET_PER_CONN_OPTION[3];
|
||||||
|
|
||||||
if (nullptr == list.pOptions) {
|
if (nullptr == list.pOptions)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +182,7 @@ namespace Qv2ray::components::proxy
|
|||||||
|
|
||||||
// Set the options on the connection.
|
// Set the options on the connection.
|
||||||
bReturn = InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
|
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_SETTINGS_CHANGED, nullptr, 0);
|
||||||
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
||||||
return bReturn;
|
return bReturn;
|
||||||
@ -170,43 +191,54 @@ namespace Qv2ray::components::proxy
|
|||||||
|
|
||||||
void SetSystemProxy(const QString &address, int httpPort, int socksPort, bool usePAC)
|
void SetSystemProxy(const QString &address, int httpPort, int socksPort, bool usePAC)
|
||||||
{
|
{
|
||||||
|
LOG(MODULE_PROXY, "Setting up System Proxy")
|
||||||
bool hasHTTP = (httpPort != 0);
|
bool hasHTTP = (httpPort != 0);
|
||||||
bool hasSOCKS = (socksPort != 0);
|
bool hasSOCKS = (socksPort != 0);
|
||||||
|
|
||||||
if (!(hasHTTP || hasSOCKS || usePAC)) {
|
if (!(hasHTTP || hasSOCKS || usePAC))
|
||||||
LOG(PROXY, "Nothing?")
|
{
|
||||||
|
LOG(MODULE_PROXY, "Nothing?")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usePAC) {
|
if (usePAC)
|
||||||
LOG(PROXY, "Qv2ray will set system proxy to use PAC file")
|
{
|
||||||
} else {
|
LOG(MODULE_PROXY, "Qv2ray will set system proxy to use PAC file")
|
||||||
if (hasHTTP) {
|
}
|
||||||
LOG(PROXY, "Qv2ray will set system proxy to use HTTP")
|
else
|
||||||
|
{
|
||||||
|
if (hasHTTP)
|
||||||
|
{
|
||||||
|
LOG(MODULE_PROXY, "Qv2ray will set system proxy to use HTTP")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasSOCKS) {
|
if (hasSOCKS)
|
||||||
LOG(PROXY, "Qv2ray will set system proxy to use SOCKS")
|
{
|
||||||
|
LOG(MODULE_PROXY, "Qv2ray will set system proxy to use SOCKS")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString __a;
|
QString __a;
|
||||||
|
|
||||||
if (usePAC) {
|
if (usePAC)
|
||||||
|
{
|
||||||
__a = address;
|
__a = address;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
__a = (hasHTTP ? "http://" : "socks5://") + address + ":" + QSTRN(httpPort);
|
__a = (hasHTTP ? "http://" : "socks5://") + address + ":" + QSTRN(httpPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(PROXY, "Windows proxy string: " + __a)
|
LOG(MODULE_PROXY, "Windows proxy string: " + __a)
|
||||||
auto proxyStrW = new WCHAR[__a.length() + 1];
|
auto proxyStrW = new WCHAR[__a.length() + 1];
|
||||||
wcscpy(proxyStrW, __a.toStdWString().c_str());
|
wcscpy(proxyStrW, __a.toStdWString().c_str());
|
||||||
//
|
//
|
||||||
__QueryProxyOptions();
|
__QueryProxyOptions();
|
||||||
|
|
||||||
if (!__SetProxyOptions(proxyStrW, usePAC)) {
|
if (!__SetProxyOptions(proxyStrW, usePAC))
|
||||||
LOG(PROXY, "Failed to set proxy.")
|
{
|
||||||
|
LOG(MODULE_PROXY, "Failed to set proxy.")
|
||||||
}
|
}
|
||||||
|
|
||||||
__QueryProxyOptions();
|
__QueryProxyOptions();
|
||||||
@ -214,54 +246,104 @@ namespace Qv2ray::components::proxy
|
|||||||
QStringList actions;
|
QStringList actions;
|
||||||
auto proxyMode = usePAC ? "auto" : "manual";
|
auto proxyMode = usePAC ? "auto" : "manual";
|
||||||
actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg(proxyMode);
|
actions << QString("gsettings set org.gnome.system.proxy mode '%1'").arg(proxyMode);
|
||||||
|
bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE";
|
||||||
if (usePAC) {
|
if (isKDE)
|
||||||
|
{
|
||||||
|
LOG(MODULE_PROXY, "KDE detected")
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (usePAC)
|
||||||
|
{
|
||||||
actions << QString("gsettings set org.gnome.system.proxy autoconfig-url '%1'").arg(address);
|
actions << QString("gsettings set org.gnome.system.proxy autoconfig-url '%1'").arg(address);
|
||||||
} else {
|
if (isKDE)
|
||||||
if (hasHTTP) {
|
{
|
||||||
|
actions << QString("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
|
||||||
|
"/kioslaverc --group \"Proxy Settings\" --key ProxyType 2");
|
||||||
|
|
||||||
|
actions << QString("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
|
||||||
|
"/kioslaverc --group \"Proxy Settings\" --key \"Proxy Config Script\" " + address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isKDE)
|
||||||
|
{
|
||||||
|
actions << QString("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
|
||||||
|
"/kioslaverc --group \"Proxy Settings\" --key ProxyType 1");
|
||||||
|
}
|
||||||
|
if (hasHTTP)
|
||||||
|
{
|
||||||
actions << QString("gsettings set org.gnome.system.proxy.http host '%1'").arg(address);
|
actions << QString("gsettings set org.gnome.system.proxy.http 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.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 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 (isKDE)
|
||||||
|
{
|
||||||
|
// FTP here should be scheme: ftp://
|
||||||
|
for (auto protocol : { "http", "ftp", "https" })
|
||||||
|
{
|
||||||
|
auto str = QString("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
|
||||||
|
"/kioslaverc --group \"Proxy Settings\" --key %1Proxy \"http://%2 %3\"")
|
||||||
|
.arg(protocol)
|
||||||
|
.arg(address)
|
||||||
|
.arg(QSTRN(httpPort));
|
||||||
|
actions << str;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 host '%1'").arg(address);
|
||||||
actions << QString("gsettings set org.gnome.system.proxy.socks port %1").arg(socksPort);
|
actions << QString("gsettings set org.gnome.system.proxy.socks port %1").arg(socksPort);
|
||||||
|
if (isKDE)
|
||||||
|
{
|
||||||
|
actions << QString("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
|
||||||
|
"/kioslaverc --group \"Proxy Settings\" --key socksProxy \"socks://%1 %2\"")
|
||||||
|
.arg(address)
|
||||||
|
.arg(QSTRN(socksPort));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: do not use std::all_of / any_of / none_of,
|
// note: do not use std::all_of / any_of / none_of,
|
||||||
// because those are short-circuit and cannot guarantee atomicity.
|
// because those are short-circuit and cannot guarantee atomicity.
|
||||||
auto result = std::count_if(actions.cbegin(), actions.cend(), [](const QString & action) {
|
auto result = std::count_if(actions.cbegin(), actions.cend(), [](const QString &action) {
|
||||||
DEBUG(PROXY, action)
|
DEBUG(MODULE_PROXY, action)
|
||||||
return QProcess::execute(action) == QProcess::NormalExit;
|
return QProcess::execute(action) == QProcess::NormalExit;
|
||||||
}) == actions.size();
|
}) == actions.size();
|
||||||
|
|
||||||
if (!result) {
|
if (!result)
|
||||||
LOG(PROXY, "Something wrong happens when setting system proxy -> Gnome ONLY.")
|
{
|
||||||
LOG(PROXY, "If you are using KDE Plasma and receiving this message, just simply ignore this.")
|
LOG(MODULE_PROXY, "There was something wrong when setting proxies.")
|
||||||
|
LOG(MODULE_PROXY, "It may happen if you are using KDE with no gsettings support.")
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_UNUSED(result);
|
Q_UNUSED(result);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
for (auto service : macOSgetNetworkServices()) {
|
for (auto service : macOSgetNetworkServices())
|
||||||
LOG(PROXY, "Setting proxy for interface: " + service)
|
{
|
||||||
|
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 -setautoproxystate " + service + " on");
|
||||||
QProcess::execute("/usr/sbin/networksetup -setautoproxyurl " + service + " " + address);
|
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 -setwebproxystate " + service + " on");
|
||||||
QProcess::execute("/usr/sbin/networksetup -setsecurewebproxystate " + 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 -setwebproxy " + service + " " + address + " " + QSTRN(httpPort));
|
||||||
QProcess::execute("/usr/sbin/networksetup -setsecurewebproxy " + 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 -setsocksfirewallproxystate " + service + " on");
|
||||||
QProcess::execute("/usr/sbin/networksetup -setsocksfirewallproxy " + service + " " + address + " " + QSTRN(socksPort));
|
QProcess::execute("/usr/sbin/networksetup -setsocksfirewallproxy " + service + " " + address + " " + QSTRN(socksPort));
|
||||||
}
|
}
|
||||||
@ -273,8 +355,9 @@ namespace Qv2ray::components::proxy
|
|||||||
|
|
||||||
void ClearSystemProxy()
|
void ClearSystemProxy()
|
||||||
{
|
{
|
||||||
|
LOG(MODULE_PROXY, "Clearing System Proxy")
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
LOG(PROXY, "Cleaning system proxy settings.")
|
LOG(MODULE_PROXY, "Cleaning system proxy settings.")
|
||||||
INTERNET_PER_CONN_OPTION_LIST list;
|
INTERNET_PER_CONN_OPTION_LIST list;
|
||||||
BOOL bReturn;
|
BOOL bReturn;
|
||||||
DWORD dwBufSize = sizeof(list);
|
DWORD dwBufSize = sizeof(list);
|
||||||
@ -287,9 +370,10 @@ namespace Qv2ray::components::proxy
|
|||||||
list.pOptions = new INTERNET_PER_CONN_OPTION[list.dwOptionCount];
|
list.pOptions = new INTERNET_PER_CONN_OPTION[list.dwOptionCount];
|
||||||
|
|
||||||
// Make sure the memory was allocated.
|
// Make sure the memory was allocated.
|
||||||
if (nullptr == list.pOptions) {
|
if (nullptr == list.pOptions)
|
||||||
|
{
|
||||||
// Return FALSE if the memory wasn't allocated.
|
// Return FALSE if the memory wasn't allocated.
|
||||||
LOG(PROXY, "Failed to allocat memory in DisableConnectionProxy()")
|
LOG(MODULE_PROXY, "Failed to allocat memory in DisableConnectionProxy()")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set flags.
|
// Set flags.
|
||||||
@ -298,15 +382,21 @@ namespace Qv2ray::components::proxy
|
|||||||
//
|
//
|
||||||
// Set the options on the connection.
|
// Set the options on the connection.
|
||||||
bReturn = InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
|
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_SETTINGS_CHANGED, nullptr, 0);
|
||||||
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_LINUX)
|
||||||
|
if (qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE")
|
||||||
|
{
|
||||||
|
QProcess::execute("kwriteconfig5 --file " + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
|
||||||
|
"/kioslaverc --group \"Proxy Settings\" --key ProxyType 0");
|
||||||
|
}
|
||||||
QProcess::execute("gsettings set org.gnome.system.proxy mode 'none'");
|
QProcess::execute("gsettings set org.gnome.system.proxy mode 'none'");
|
||||||
#else
|
#else
|
||||||
|
|
||||||
for (auto service : macOSgetNetworkServices()) {
|
for (auto service : macOSgetNetworkServices())
|
||||||
LOG(PROXY, "Clearing proxy for interface: " + service)
|
{
|
||||||
|
LOG(MODULE_PROXY, "Clearing proxy for interface: " + service)
|
||||||
QProcess::execute("/usr/sbin/networksetup -setautoproxystate " + service + " off");
|
QProcess::execute("/usr/sbin/networksetup -setautoproxystate " + service + " off");
|
||||||
QProcess::execute("/usr/sbin/networksetup -setwebproxystate " + service + " off");
|
QProcess::execute("/usr/sbin/networksetup -setwebproxystate " + service + " off");
|
||||||
QProcess::execute("/usr/sbin/networksetup -setsecurewebproxystate " + service + " off");
|
QProcess::execute("/usr/sbin/networksetup -setsecurewebproxystate " + service + " off");
|
||||||
@ -315,4 +405,4 @@ namespace Qv2ray::components::proxy
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
} // namespace Qv2ray::components::proxy
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <QString>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
//
|
//
|
||||||
namespace Qv2ray::components::proxy
|
namespace Qv2ray::components::proxy
|
||||||
{
|
{
|
||||||
void ClearSystemProxy();
|
void ClearSystemProxy();
|
||||||
void SetSystemProxy(const QString &address, int http_port, int socks_port, bool usePAC);
|
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;
|
||||||
using namespace Qv2ray::components::proxy;
|
using namespace Qv2ray::components::proxy;
|
||||||
|
@ -14,39 +14,40 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
* 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),
|
* 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
|
* 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
|
* License in all respects for all of the code used other than "OpenSSL". If
|
||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* you modify file(s), you may extend this exception to your version of the
|
||||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||||
* exception statement from your version.
|
* delete this exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "speedplotview.hpp"
|
#include "speedplotview.hpp"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#define VIEWABLE 120
|
||||||
|
|
||||||
#define VIEWABLE 60
|
|
||||||
|
|
||||||
// use binary prefix standards from IEC 60027-2
|
// use binary prefix standards from IEC 60027-2
|
||||||
// see http://en.wikipedia.org/wiki/Kilobyte
|
// see http://en.wikipedia.org/wiki/Kilobyte
|
||||||
enum class SizeUnit {
|
enum class SizeUnit
|
||||||
Byte, // 1024^0,
|
{
|
||||||
KibiByte, // 1024^1,
|
Byte, // 1024^0,
|
||||||
MebiByte, // 1024^2,
|
KibiByte, // 1024^1,
|
||||||
GibiByte, // 1024^3,
|
MebiByte, // 1024^2,
|
||||||
TebiByte, // 1024^4,
|
GibiByte, // 1024^3,
|
||||||
PebiByte, // 1024^5,
|
TebiByte, // 1024^4,
|
||||||
ExbiByte // 1024^6,
|
PebiByte, // 1024^5,
|
||||||
|
ExbiByte // 1024^6,
|
||||||
// int64 is used for sizes and thus the next units can not be handled
|
// int64 is used for sizes and thus the next units can not be handled
|
||||||
// ZebiByte, // 1024^7,
|
// ZebiByte, // 1024^7,
|
||||||
// YobiByte, // 1024^8
|
// YobiByte, // 1024^8
|
||||||
@ -54,19 +55,18 @@ enum class SizeUnit {
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const struct {
|
const struct
|
||||||
|
{
|
||||||
const char *source;
|
const char *source;
|
||||||
const char *comment;
|
const char *comment;
|
||||||
} units[] = {
|
} units[] = { QT_TRANSLATE_NOOP3("misc", "B", "bytes"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "B", "bytes"),
|
QT_TRANSLATE_NOOP3("misc", "KiB", "kibibytes (1024 bytes)"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "KiB", "kibibytes (1024 bytes)"),
|
QT_TRANSLATE_NOOP3("misc", "MiB", "mebibytes (1024 kibibytes)"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "MiB", "mebibytes (1024 kibibytes)"),
|
QT_TRANSLATE_NOOP3("misc", "GiB", "gibibytes (1024 mibibytes)"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "GiB", "gibibytes (1024 mibibytes)"),
|
QT_TRANSLATE_NOOP3("misc", "TiB", "tebibytes (1024 gibibytes)"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "TiB", "tebibytes (1024 gibibytes)"),
|
QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"),
|
QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)") };
|
||||||
QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)")
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString unitString(const SizeUnit unit, const bool isSpeed)
|
QString unitString(const SizeUnit unit, const bool isSpeed)
|
||||||
{
|
{
|
||||||
@ -82,53 +82,34 @@ QString unitString(const SizeUnit unit, const bool isSpeed)
|
|||||||
int friendlyUnitPrecision(const SizeUnit unit)
|
int friendlyUnitPrecision(const SizeUnit unit)
|
||||||
{
|
{
|
||||||
// friendlyUnit's number of digits after the decimal point
|
// friendlyUnit's number of digits after the decimal point
|
||||||
switch (unit) {
|
switch (unit)
|
||||||
case SizeUnit::Byte:
|
{
|
||||||
return 0;
|
case SizeUnit::Byte: return 0;
|
||||||
|
|
||||||
case SizeUnit::KibiByte:
|
case SizeUnit::KibiByte:
|
||||||
case SizeUnit::MebiByte:
|
case SizeUnit::MebiByte: return 1;
|
||||||
return 1;
|
|
||||||
|
|
||||||
case SizeUnit::GibiByte:
|
case SizeUnit::GibiByte: return 2;
|
||||||
return 2;
|
|
||||||
|
|
||||||
default:
|
default: return 3;
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong sizeInBytes(qreal size, const SizeUnit unit)
|
qlonglong sizeInBytes(qreal size, const SizeUnit unit)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < static_cast<int>(unit); ++i)
|
for (int i = 0; i < static_cast<int>(unit); ++i) size *= 1024;
|
||||||
size *= 1024;
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
constexpr typename std::add_const<T>::type &asConst(T &t) noexcept
|
|
||||||
{
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward rvalue as const
|
|
||||||
template <typename T>
|
|
||||||
constexpr typename std::add_const<T>::type asConst(T &&t) noexcept
|
|
||||||
{
|
|
||||||
return std::move(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent const rvalue arguments
|
|
||||||
template <typename T>
|
|
||||||
void asConst(const T &&) = delete;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// table of supposed nice steps for grid marks to get nice looking quarters of scale
|
// table of supposed nice steps for grid marks to get nice looking quarters
|
||||||
const double roundingTable[] = {1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8};
|
// 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;
|
double arg;
|
||||||
SizeUnit unit;
|
SizeUnit unit;
|
||||||
qint64 sizeInBytes() const
|
qint64 sizeInBytes() const
|
||||||
@ -139,56 +120,56 @@ namespace
|
|||||||
|
|
||||||
SplittedValue getRoundedYScale(double value)
|
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;
|
SizeUnit calculatedUnit = SizeUnit::Byte;
|
||||||
|
|
||||||
while (value > 1024) {
|
while (value > 1024)
|
||||||
|
{
|
||||||
value /= 1024;
|
value /= 1024;
|
||||||
calculatedUnit = static_cast<SizeUnit>(static_cast<int>(calculatedUnit) + 1);
|
calculatedUnit = static_cast<SizeUnit>(static_cast<int>(calculatedUnit) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > 100.0) {
|
if (value > 100.0)
|
||||||
|
{
|
||||||
int roundedValue = static_cast<int>(value / 40) * 40;
|
int roundedValue = static_cast<int>(value / 40) * 40;
|
||||||
|
|
||||||
while (roundedValue < value)
|
while (roundedValue < value) roundedValue += 40;
|
||||||
roundedValue += 40;
|
|
||||||
|
|
||||||
return {static_cast<double>(roundedValue), calculatedUnit};
|
return { static_cast<double>(roundedValue), calculatedUnit };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > 10.0) {
|
if (value > 10.0)
|
||||||
|
{
|
||||||
int roundedValue = static_cast<int>(value / 4) * 4;
|
int roundedValue = static_cast<int>(value / 4) * 4;
|
||||||
|
|
||||||
while (roundedValue < value)
|
while (roundedValue < value) roundedValue += 4;
|
||||||
roundedValue += 4;
|
|
||||||
|
|
||||||
return {static_cast<double>(roundedValue), calculatedUnit};
|
return { static_cast<double>(roundedValue), calculatedUnit };
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &roundedValue : roundingTable) {
|
for (const auto &roundedValue : roundingTable)
|
||||||
|
{
|
||||||
if (value <= roundedValue)
|
if (value <= roundedValue)
|
||||||
return {roundedValue, calculatedUnit};
|
return { roundedValue, calculatedUnit };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {10.0, calculatedUnit};
|
return { 10.0, calculatedUnit };
|
||||||
}
|
}
|
||||||
|
|
||||||
QString formatLabel(const double argValue, const SizeUnit unit)
|
QString formatLabel(const double argValue, const SizeUnit unit)
|
||||||
{
|
{
|
||||||
// check is there need for digits after decimal separator
|
// check is there need for digits after decimal separator
|
||||||
const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0;
|
const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0;
|
||||||
return QLocale::system().toString(argValue, 'f', precision)
|
return QLocale::system().toString(argValue, 'f', precision) + QString::fromUtf8(" ") + unitString(unit, true);
|
||||||
+ QString::fromUtf8(" ")
|
|
||||||
+ unitString(unit, true);
|
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
SpeedPlotView::SpeedPlotView(QWidget *parent)
|
SpeedPlotView::SpeedPlotView(QWidget *parent) : QGraphicsView(parent), m_currentData(&m_datahalfMin)
|
||||||
: QGraphicsView(parent)
|
|
||||||
, m_currentData(&m_datahalfMin)
|
|
||||||
{
|
{
|
||||||
QPen greenPen;
|
QPen greenPen;
|
||||||
greenPen.setWidthF(1.5);
|
greenPen.setWidthF(1.5);
|
||||||
@ -210,7 +191,8 @@ void SpeedPlotView::pushPoint(const SpeedPlotView::PointData &point)
|
|||||||
{
|
{
|
||||||
m_datahalfMin.push_back(point);
|
m_datahalfMin.push_back(point);
|
||||||
|
|
||||||
while (m_datahalfMin.length() > VIEWABLE) {
|
while (m_datahalfMin.length() > VIEWABLE)
|
||||||
|
{
|
||||||
m_datahalfMin.removeFirst();
|
m_datahalfMin.removeFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,9 +212,11 @@ quint64 SpeedPlotView::maxYValue()
|
|||||||
auto &queue = getCurrentData();
|
auto &queue = getCurrentData();
|
||||||
quint64 maxYValue = 0;
|
quint64 maxYValue = 0;
|
||||||
|
|
||||||
for (int id = UP; id < NB_GRAPHS; ++id) {
|
for (int id = UP; id < NB_GRAPHS; ++id)
|
||||||
|
{
|
||||||
// 30 is half min
|
// 30 is half min
|
||||||
for (int i = queue.size() - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j) {
|
for (int i = queue.size() - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j)
|
||||||
|
{
|
||||||
if (queue[i].y[id] > maxYValue)
|
if (queue[i].y[id] > maxYValue)
|
||||||
maxYValue = queue[i].y[id];
|
maxYValue = queue[i].y[id];
|
||||||
}
|
}
|
||||||
@ -266,7 +250,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
|
|
||||||
int i = 0;
|
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()),
|
QRectF labelRect(rect.topLeft() + QPointF(-yAxisWidth, (i++) * 0.25 * rect.height() - fontMetrics.height()),
|
||||||
QSizeF(2 * yAxisWidth, fontMetrics.height()));
|
QSizeF(2 * yAxisWidth, fontMetrics.height()));
|
||||||
painter.drawText(labelRect, label, Qt::AlignRight | Qt::AlignTop);
|
painter.drawText(labelRect, label, Qt::AlignRight | Qt::AlignTop);
|
||||||
@ -286,7 +271,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
painter.drawLine(fullRect.left(), rect.bottom(), rect.right(), rect.bottom());
|
painter.drawLine(fullRect.left(), rect.bottom(), rect.right(), rect.bottom());
|
||||||
const int TIME_AXIS_DIVISIONS = 6;
|
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;
|
const int x = rect.left() + (i * rect.width()) / TIME_AXIS_DIVISIONS;
|
||||||
painter.drawLine(x, fullRect.top(), x, fullRect.bottom());
|
painter.drawLine(x, fullRect.top(), x, fullRect.bottom());
|
||||||
}
|
}
|
||||||
@ -299,10 +285,12 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
const double xTickSize = static_cast<double>(rect.width()) / VIEWABLE;
|
const double xTickSize = static_cast<double>(rect.width()) / VIEWABLE;
|
||||||
auto &queue = getCurrentData();
|
auto &queue = getCurrentData();
|
||||||
|
|
||||||
for (int id = UP; id < NB_GRAPHS; ++id) {
|
for (int id = UP; id < NB_GRAPHS; ++id)
|
||||||
|
{
|
||||||
QVector<QPoint> points;
|
QVector<QPoint> points;
|
||||||
|
|
||||||
for (int i = static_cast<int>(queue.size()) - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j) {
|
for (int i = static_cast<int>(queue.size()) - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j)
|
||||||
|
{
|
||||||
int newX = rect.right() - j * xTickSize;
|
int newX = rect.right() - j * xTickSize;
|
||||||
int newY = rect.bottom() - queue[i].y[id] * yMultiplier;
|
int newY = rect.bottom() - queue[i].y[id] * yMultiplier;
|
||||||
points.push_back(QPoint(newX, newY));
|
points.push_back(QPoint(newX, newY));
|
||||||
@ -317,7 +305,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
double legendHeight = 0;
|
double legendHeight = 0;
|
||||||
int legendWidth = 0;
|
int legendWidth = 0;
|
||||||
|
|
||||||
for (const auto &property : asConst(m_properties)) {
|
for (const auto &property : m_properties)
|
||||||
|
{
|
||||||
if (fontMetrics.horizontalAdvance(property.name) > legendWidth)
|
if (fontMetrics.horizontalAdvance(property.name) > legendWidth)
|
||||||
legendWidth = fontMetrics.horizontalAdvance(property.name);
|
legendWidth = fontMetrics.horizontalAdvance(property.name);
|
||||||
|
|
||||||
@ -326,18 +315,19 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
|
|
||||||
QRectF legendBackgroundRect(QPoint(legendTopLeft.x() - 4, legendTopLeft.y() - 4), QSizeF(legendWidth + 8, legendHeight + 8));
|
QRectF legendBackgroundRect(QPoint(legendTopLeft.x() - 4, legendTopLeft.y() - 4), QSizeF(legendWidth + 8, legendHeight + 8));
|
||||||
QColor legendBackgroundColor = QWidget::palette().color(QWidget::backgroundRole());
|
QColor legendBackgroundColor = QWidget::palette().color(QWidget::backgroundRole());
|
||||||
legendBackgroundColor.setAlpha(128); // 50% transparent
|
legendBackgroundColor.setAlpha(128); // 50% transparent
|
||||||
painter.fillRect(legendBackgroundRect, legendBackgroundColor);
|
painter.fillRect(legendBackgroundRect, legendBackgroundColor);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
for (const auto &property : asConst(m_properties)) {
|
for (const auto &property : m_properties)
|
||||||
|
{
|
||||||
int nameSize = fontMetrics.horizontalAdvance(property.name);
|
int nameSize = fontMetrics.horizontalAdvance(property.name);
|
||||||
double indent = 1.5 * (i++) * fontMetrics.height();
|
double indent = 1.5 * (i++) * fontMetrics.height();
|
||||||
painter.setPen(property.pen);
|
painter.setPen(property.pen);
|
||||||
painter.drawLine(legendTopLeft + QPointF(0, indent + fontMetrics.height()),
|
painter.drawLine(legendTopLeft + QPointF(0, indent + fontMetrics.height()),
|
||||||
legendTopLeft + QPointF(nameSize, indent + fontMetrics.height()));
|
legendTopLeft + QPointF(nameSize, indent + fontMetrics.height()));
|
||||||
painter.drawText(QRectF(legendTopLeft + QPointF(0, indent), QSizeF(2 * nameSize, fontMetrics.height())),
|
painter.drawText(QRectF(legendTopLeft + QPointF(0, indent), QSizeF(2 * nameSize, fontMetrics.height())), property.name,
|
||||||
property.name, QTextOption(Qt::AlignVCenter));
|
QTextOption(Qt::AlignVCenter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,8 +335,6 @@ SpeedPlotView::GraphProperties::GraphProperties()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeedPlotView::GraphProperties::GraphProperties(const QString &name, const QPen &pen)
|
SpeedPlotView::GraphProperties::GraphProperties(const QString &name, const QPen &pen) : name(name), pen(pen)
|
||||||
: name(name)
|
|
||||||
, pen(pen)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -36,43 +36,46 @@ class QPen;
|
|||||||
|
|
||||||
class SpeedPlotView : public QGraphicsView
|
class SpeedPlotView : public QGraphicsView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum GraphID {
|
enum GraphID
|
||||||
UP = 0,
|
{
|
||||||
DOWN,
|
UP = 0,
|
||||||
NB_GRAPHS
|
DOWN,
|
||||||
};
|
NB_GRAPHS
|
||||||
|
};
|
||||||
|
|
||||||
struct PointData {
|
struct PointData
|
||||||
qint64 x;
|
{
|
||||||
quint64 y[NB_GRAPHS];
|
qint64 x;
|
||||||
};
|
quint64 y[NB_GRAPHS];
|
||||||
|
};
|
||||||
|
|
||||||
explicit SpeedPlotView(QWidget *parent = nullptr);
|
explicit SpeedPlotView(QWidget *parent = nullptr);
|
||||||
void pushPoint(const PointData &point);
|
void pushPoint(const PointData &point);
|
||||||
void Clear();
|
void Clear();
|
||||||
void replot();
|
void replot();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct GraphProperties {
|
struct GraphProperties
|
||||||
GraphProperties();
|
{
|
||||||
GraphProperties(const QString &name, const QPen &pen);
|
GraphProperties();
|
||||||
|
GraphProperties(const QString &name, const QPen &pen);
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
QPen pen;
|
QPen pen;
|
||||||
};
|
};
|
||||||
|
|
||||||
quint64 maxYValue();
|
quint64 maxYValue();
|
||||||
QList<PointData> &getCurrentData();
|
QList<PointData> &getCurrentData();
|
||||||
QList<PointData> m_datahalfMin;
|
QList<PointData> m_datahalfMin;
|
||||||
QList<PointData> *m_currentData;
|
QList<PointData> *m_currentData;
|
||||||
|
|
||||||
QMap<GraphID, GraphProperties> m_properties;
|
QMap<GraphID, GraphProperties> m_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SPEEDPLOTVIEW_H
|
#endif // SPEEDPLOTVIEW_H
|
||||||
|