Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27c53be209 | ||
|
|
d93c12b354 | ||
|
|
98d4a47efb | ||
|
|
8ab04c65b5 | ||
|
|
1b2dab1388 | ||
|
|
4f8dae7fa0 | ||
|
|
cdc23e32c4 | ||
|
|
20457e9e63 | ||
|
|
e63042af84 | ||
|
|
c35b4d3c1b | ||
|
|
64a83a5d64 | ||
|
|
01039d0b47 | ||
|
|
7c1e5a3cba | ||
|
|
038161527f | ||
|
|
b12b7a17e6 | ||
|
|
37cf23d5fe | ||
|
|
ed7fb4f6e3 | ||
|
|
5d4bd2fee6 | ||
|
|
aae5906311 | ||
|
|
4a7bafd011 | ||
|
|
626ebfe65d | ||
|
|
3cc75cd46d | ||
|
|
f809ee7b20 | ||
|
|
1295d8191c | ||
|
|
bc2adbfa77 | ||
|
|
9583dff176 | ||
|
|
5732b84a7b | ||
|
|
c0d27504ac | ||
|
|
3db1dd7bbb | ||
|
|
5392766c5e | ||
|
|
730b7dea37 | ||
|
|
02a13ce028 | ||
|
|
7884853098 | ||
|
|
e122ea8146 | ||
|
|
f500d2b9f4 | ||
|
|
79e53bf1f5 | ||
|
|
31de7ec094 | ||
|
|
2e4501187c | ||
|
|
4430c9bd74 | ||
|
|
cf8be85ff7 | ||
|
|
0759be1223 | ||
|
|
21f8ddcf9f | ||
|
|
37cba5ee34 | ||
|
|
ff642fd1ac | ||
|
|
647f1d9c8b | ||
|
|
d886195ee3 | ||
|
|
e2b8f4f89a | ||
|
|
1dcfe661e9 | ||
|
|
d6dd110781 | ||
|
|
a0f956c885 | ||
|
|
88bcafed97 | ||
|
|
6e4f15ab52 | ||
|
|
20cae1ff4d | ||
|
|
dcf621b822 | ||
|
|
eafa20032b | ||
|
|
7375e1a490 | ||
|
|
199d87ba84 | ||
|
|
b43975ebfc |
57
.github/workflows/build-linux.yml
vendored
57
.github/workflows/build-linux.yml
vendored
@@ -1,10 +1,20 @@
|
|||||||
name: release Linux
|
name: release Linux
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
push:
|
push:
|
||||||
branches: [ "master" ]
|
branches:
|
||||||
pull_request:
|
- master
|
||||||
branches: [ "master" ]
|
|
||||||
|
env:
|
||||||
|
OutputArch: "linux-64"
|
||||||
|
OutputArchArm: "linux-arm64"
|
||||||
|
OutputPath64: "${{ github.workspace }}/v2rayN/Release/linux-64"
|
||||||
|
OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/linux-arm64"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -21,14 +31,47 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cd v2rayN
|
cd v2rayN
|
||||||
chmod 755 build-linux.sh
|
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
|
||||||
./build-linux.sh
|
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPath64
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: v2rayN-linux
|
name: v2rayN-linux
|
||||||
path: |
|
path: |
|
||||||
./v2rayN/v2rayN-linux.zip
|
${{ github.workspace }}/v2rayN/Release/linux*
|
||||||
|
|
||||||
|
# release debian package
|
||||||
|
- name: Package debian
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
run: |
|
||||||
|
chmod 755 package-debian.sh
|
||||||
|
./package-debian.sh $OutputArch $OutputPath64 ${{ github.event.inputs.release_tag }}
|
||||||
|
./package-debian.sh $OutputArchArm $OutputPathArm64 ${{ github.event.inputs.release_tag }}
|
||||||
|
|
||||||
|
- name: Upload deb to release
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
with:
|
||||||
|
file: ${{ github.workspace }}/v2rayN*.deb
|
||||||
|
tag: ${{ github.event.inputs.release_tag }}
|
||||||
|
file_glob: true
|
||||||
|
|
||||||
|
# release zip archive
|
||||||
|
- name: Package release zip archive
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
run: |
|
||||||
|
chmod 755 package-release-zip.sh
|
||||||
|
./package-release-zip.sh $OutputArch $OutputPath64
|
||||||
|
./package-release-zip.sh $OutputArchArm $OutputPathArm64
|
||||||
|
|
||||||
|
- name: Upload zip archive to release
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
with:
|
||||||
|
file: ${{ github.workspace }}/v2rayN*.zip
|
||||||
|
tag: ${{ github.event.inputs.release_tag }}
|
||||||
|
file_glob: true
|
||||||
|
prerelease: true
|
||||||
60
.github/workflows/build-osx.yml
vendored
60
.github/workflows/build-osx.yml
vendored
@@ -1,10 +1,20 @@
|
|||||||
name: release macOS
|
name: release macOS
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
push:
|
push:
|
||||||
branches: [ "master" ]
|
branches:
|
||||||
pull_request:
|
- master
|
||||||
branches: [ "master" ]
|
|
||||||
|
env:
|
||||||
|
OutputArch: "macos-64"
|
||||||
|
OutputArchArm: "macos-arm64"
|
||||||
|
OutputPath64: "${{ github.workspace }}/v2rayN/Release/macos-64"
|
||||||
|
OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/macos-arm64"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -21,14 +31,48 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cd v2rayN
|
cd v2rayN
|
||||||
chmod 755 build-osx.sh
|
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
|
||||||
./build-osx.sh
|
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPath64
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: v2rayN-osx
|
name: v2rayN-macos
|
||||||
path: |
|
path: |
|
||||||
./v2rayN/v2rayN-osx.zip
|
${{ github.workspace }}/v2rayN/Release/macos*
|
||||||
|
|
||||||
|
# release osx package
|
||||||
|
- name: Package osx
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
run: |
|
||||||
|
brew install create-dmg
|
||||||
|
chmod 755 package-osx.sh
|
||||||
|
./package-osx.sh $OutputArch $OutputPath64 ${{ github.event.inputs.release_tag }}
|
||||||
|
./package-osx.sh $OutputArchArm $OutputPathArm64 ${{ github.event.inputs.release_tag }}
|
||||||
|
|
||||||
|
- name: Upload dmg to release
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
with:
|
||||||
|
file: ${{ github.workspace }}/v2rayN*.dmg
|
||||||
|
tag: ${{ github.event.inputs.release_tag }}
|
||||||
|
file_glob: true
|
||||||
|
|
||||||
|
# release zip archive
|
||||||
|
- name: Package release zip archive
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
run: |
|
||||||
|
chmod 755 package-release-zip.sh
|
||||||
|
./package-release-zip.sh $OutputArch $OutputPath64
|
||||||
|
./package-release-zip.sh $OutputArchArm $OutputPathArm64
|
||||||
|
|
||||||
|
- name: Upload zip archive to release
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
with:
|
||||||
|
file: ${{ github.workspace }}/v2rayN*.zip
|
||||||
|
tag: ${{ github.event.inputs.release_tag }}
|
||||||
|
file_glob: true
|
||||||
|
prerelease: true
|
||||||
68
.github/workflows/build-windows.yml
vendored
Normal file
68
.github/workflows/build-windows.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
name: release Windows
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
env:
|
||||||
|
OutputArch: "windows-64"
|
||||||
|
OutputArchArm: "windows-arm64"
|
||||||
|
OutputPath64: "${{ github.workspace }}/v2rayN/Release/windows-64"
|
||||||
|
OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/windows-arm64"
|
||||||
|
OutputPath64Sc: "${{ github.workspace }}/v2rayN/Release/windows-64-SelfContained"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
configuration: [Release]
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cd v2rayN
|
||||||
|
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
|
||||||
|
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-arm64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
|
||||||
|
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
|
||||||
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
|
||||||
|
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: v2rayN-windows
|
||||||
|
path: |
|
||||||
|
${{ github.workspace }}/v2rayN/Release/windows*
|
||||||
|
|
||||||
|
# release zip archive
|
||||||
|
- name: Package release zip archive
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
run: |
|
||||||
|
chmod 755 package-release-zip.sh
|
||||||
|
./package-release-zip.sh $OutputArch $OutputPath64
|
||||||
|
./package-release-zip.sh "windows-64-With-Core" $OutputPath64
|
||||||
|
./package-release-zip.sh $OutputArchArm $OutputPathArm64
|
||||||
|
./package-release-zip.sh "windows-64-SelfContained" $OutputPath64Sc
|
||||||
|
./package-release-zip.sh "windows-64-SelfContained-With-Core" $OutputPath64Sc
|
||||||
|
|
||||||
|
- name: Upload zip archive to release
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
if: github.event.inputs.release_tag != ''
|
||||||
|
with:
|
||||||
|
file: ${{ github.workspace }}/v2rayN*.zip
|
||||||
|
tag: ${{ github.event.inputs.release_tag }}
|
||||||
|
file_glob: true
|
||||||
|
prerelease: true
|
||||||
41
.github/workflows/build.yml
vendored
41
.github/workflows/build.yml
vendored
@@ -1,41 +0,0 @@
|
|||||||
name: release Windows
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
configuration: [Release]
|
|
||||||
|
|
||||||
runs-on: windows-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cd v2rayN &&
|
|
||||||
./build.ps1
|
|
||||||
|
|
||||||
- name: Upload build artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: v2rayN-windows-64
|
|
||||||
path: |
|
|
||||||
./v2rayN/v2rayN-windows-64.zip
|
|
||||||
|
|
||||||
- name: Upload build artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: v2rayN-windows-arm64
|
|
||||||
path: |
|
|
||||||
./v2rayN/v2rayN-windows-arm64.zip
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# v2rayN
|
# v2rayN
|
||||||
A GUI client for Windows and Linux, support [Xray core](https://github.com/XTLS/Xray-core) and [sing-box-core](https://github.com/SagerNet/sing-box/releases) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
|
A GUI client for Windows, Linux and macOS, support [Xray core](https://github.com/XTLS/Xray-core) and [sing-box-core](https://github.com/SagerNet/sing-box/releases) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
|
||||||
|
|
||||||
|
|
||||||
[](https://github.com/2dust/v2rayN/commits/master)
|
[](https://github.com/2dust/v2rayN/commits/master)
|
||||||
@@ -19,6 +19,11 @@ Debian 9+
|
|||||||
Ubuntu 16.04+
|
Ubuntu 16.04+
|
||||||
Fedora 30+
|
Fedora 30+
|
||||||
```
|
```
|
||||||
|
### macOS
|
||||||
|
- `chmod +x v2rayN` Run `./v2rayN` under user permissions
|
||||||
|
```
|
||||||
|
macOS 11+
|
||||||
|
```
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- [Microsoft .NET 8.0 Desktop Runtime ](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
|
- [Microsoft .NET 8.0 Desktop Runtime ](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
|
||||||
|
|||||||
53
package-debian.sh
Normal file
53
package-debian.sh
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
Arch="$1"
|
||||||
|
OutputPath="$2"
|
||||||
|
Version="$3"
|
||||||
|
|
||||||
|
PackagePath="v2rayN-Package-${Arch}"
|
||||||
|
mkdir -p "${PackagePath}/DEBIAN"
|
||||||
|
mkdir -p "${PackagePath}/opt"
|
||||||
|
cp -rf $OutputPath "${PackagePath}/opt/v2rayN"
|
||||||
|
echo "When this file exists, app will not store configs under this folder" > "${PackagePath}/opt/v2rayN/NotStoreConfigHere.txt"
|
||||||
|
|
||||||
|
if [ $Arch = "linux-64" ]; then
|
||||||
|
Arch2="amd64"
|
||||||
|
else
|
||||||
|
Arch2="arm64"
|
||||||
|
fi
|
||||||
|
echo $Arch2
|
||||||
|
|
||||||
|
# basic
|
||||||
|
cat >"${PackagePath}/DEBIAN/control" <<-EOF
|
||||||
|
Package: v2rayN
|
||||||
|
Version: $Version
|
||||||
|
Architecture: $Arch2
|
||||||
|
Maintainer: https://github.com/2dust/v2rayN
|
||||||
|
Description: A GUI client for Windows and Linux, support Xray core and sing-box-core and others
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >"${PackagePath}/DEBIAN/postinst" <<-EOF
|
||||||
|
if [ ! -s /usr/share/applications/v2rayN.desktop ]; then
|
||||||
|
cat >/usr/share/applications/v2rayN.desktop<<-END
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=v2rayN
|
||||||
|
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
|
||||||
|
Exec=/opt/v2rayN/v2rayN
|
||||||
|
Icon=/opt/v2rayN/v2rayN.png
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Network;Application;
|
||||||
|
END
|
||||||
|
fi
|
||||||
|
|
||||||
|
update-desktop-database
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo chmod 0755 "${PackagePath}/DEBIAN/postinst"
|
||||||
|
sudo chmod 0755 "${PackagePath}/opt/v2rayN/v2rayN"
|
||||||
|
sudo chmod 0755 "${PackagePath}/opt/v2rayN/AmazTool"
|
||||||
|
|
||||||
|
# desktop && PATH
|
||||||
|
|
||||||
|
sudo dpkg-deb -Zxz --build $PackagePath
|
||||||
|
sudo mv "${PackagePath}.deb" "v2rayN-${Arch}.deb"
|
||||||
65
package-osx.sh
Executable file
65
package-osx.sh
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
Arch="$1"
|
||||||
|
OutputPath="$2"
|
||||||
|
Version="$3"
|
||||||
|
|
||||||
|
PackagePath="v2rayN-Package-${Arch}"
|
||||||
|
mkdir -p "$PackagePath/v2rayN.app/Contents/Resources"
|
||||||
|
cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS"
|
||||||
|
echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt"
|
||||||
|
chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN"
|
||||||
|
|
||||||
|
mkdir -p "$PackagePath/icons.iconset"
|
||||||
|
sips -z 16 16 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_16x16.png"
|
||||||
|
sips -z 32 32 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_16x16@2x.png"
|
||||||
|
sips -z 32 32 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_32x32.png"
|
||||||
|
sips -z 64 64 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_32x32@2x.png"
|
||||||
|
sips -z 128 128 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_128x128.png"
|
||||||
|
sips -z 256 256 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_128x128@2x.png"
|
||||||
|
sips -z 256 256 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_256x256.png"
|
||||||
|
sips -z 512 512 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_256x256@2x.png"
|
||||||
|
sips -z 512 512 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_512x512.png"
|
||||||
|
sips -z 1024 1024 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_512x512@2x.png"
|
||||||
|
iconutil -c icns "$PackagePath/icons.iconset" -o "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
|
||||||
|
|
||||||
|
cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF
|
||||||
|
<?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>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>v2rayN</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>v2rayN</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>AppIcon</string>
|
||||||
|
<key>CFBundleIconName</key>
|
||||||
|
<string>AppIcon</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>2dust.v2rayN</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>v2rayN</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${Version}</string>
|
||||||
|
<key>CSResourcesFileMapped</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
create-dmg \
|
||||||
|
--volname "v2rayN Installer" \
|
||||||
|
--window-size 700 420 \
|
||||||
|
--icon-size 100 \
|
||||||
|
--icon "v2rayN.app" 160 185 \
|
||||||
|
--hide-extension "v2rayN.app" \
|
||||||
|
--app-drop-link 500 185 \
|
||||||
|
"v2rayN-${Arch}.dmg" \
|
||||||
|
"$PackagePath/v2rayN.app"
|
||||||
15
package-release-zip.sh
Normal file
15
package-release-zip.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
Arch="$1"
|
||||||
|
OutputPath="$2"
|
||||||
|
|
||||||
|
OutputArch="v2rayN-${Arch}"
|
||||||
|
FileName="v2rayN-${Arch}.zip"
|
||||||
|
|
||||||
|
wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
|
||||||
|
|
||||||
|
ZipPath64="./$OutputArch"
|
||||||
|
mkdir $ZipPath64
|
||||||
|
|
||||||
|
cp -rf $OutputPath "$ZipPath64/$OutputArch"
|
||||||
|
7z a -tZip $FileName "$ZipPath64/$OutputArch" -mx1
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
|
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
|
||||||
<FileVersion>1.3.0</FileVersion>
|
<FileVersion>1.3.1</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -15,8 +15,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileName = Uri.UnescapeDataString(string.Join(" ", args));
|
var argData = Uri.UnescapeDataString(string.Join(" ", args));
|
||||||
UpgradeApp.Upgrade(fileName);
|
if (argData.Equals("rebootas"))
|
||||||
|
{
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
Utils.StartV2RayN();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpgradeApp.Upgrade(argData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ namespace AmazTool
|
|||||||
{
|
{
|
||||||
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
|
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
|
||||||
|
|
||||||
Waiting(9);
|
Waiting(3);
|
||||||
|
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
{
|
{
|
||||||
@@ -21,11 +21,11 @@ namespace AmazTool
|
|||||||
Console.WriteLine(Resx.Resource.TryTerminateProcess);
|
Console.WriteLine(Resx.Resource.TryTerminateProcess);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var existing = Process.GetProcessesByName(V2rayN);
|
var existing = Process.GetProcessesByName(Utils.V2rayN);
|
||||||
foreach (var pp in existing)
|
foreach (var pp in existing)
|
||||||
{
|
{
|
||||||
var path = pp.MainModule?.FileName ?? "";
|
var path = pp.MainModule?.FileName ?? "";
|
||||||
if (path.StartsWith(GetPath(V2rayN)))
|
if (path.StartsWith(Utils.GetPath(Utils.V2rayN)))
|
||||||
{
|
{
|
||||||
pp?.Kill();
|
pp?.Kill();
|
||||||
pp?.WaitForExit(1000);
|
pp?.WaitForExit(1000);
|
||||||
@@ -42,7 +42,7 @@ namespace AmazTool
|
|||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string thisAppOldFile = $"{GetExePath()}.tmp";
|
string thisAppOldFile = $"{Utils.GetExePath()}.tmp";
|
||||||
File.Delete(thisAppOldFile);
|
File.Delete(thisAppOldFile);
|
||||||
string splitKey = "/";
|
string splitKey = "/";
|
||||||
|
|
||||||
@@ -62,12 +62,12 @@ namespace AmazTool
|
|||||||
if (lst.Length == 1) continue;
|
if (lst.Length == 1) continue;
|
||||||
string fullName = string.Join(splitKey, lst[1..lst.Length]);
|
string fullName = string.Join(splitKey, lst[1..lst.Length]);
|
||||||
|
|
||||||
if (string.Equals(GetExePath(), GetPath(fullName), StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
File.Move(GetExePath(), thisAppOldFile);
|
File.Move(Utils.GetExePath(), thisAppOldFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
string entryOutputPath = GetPath(fullName);
|
string entryOutputPath = Utils.GetPath(fullName);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!);
|
Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!);
|
||||||
entry.ExtractToFile(entryOutputPath, true);
|
entry.ExtractToFile(entryOutputPath, true);
|
||||||
|
|
||||||
@@ -91,40 +91,12 @@ namespace AmazTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(Resx.Resource.Restartv2rayN);
|
Console.WriteLine(Resx.Resource.Restartv2rayN);
|
||||||
Waiting(9);
|
Waiting(2);
|
||||||
Process process = new()
|
|
||||||
{
|
Utils.StartV2RayN();
|
||||||
StartInfo = new()
|
|
||||||
{
|
|
||||||
UseShellExecute = true,
|
|
||||||
FileName = V2rayN,
|
|
||||||
WorkingDirectory = StartupPath()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
process.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetExePath()
|
public static void Waiting(int second)
|
||||||
{
|
|
||||||
return Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string StartupPath()
|
|
||||||
{
|
|
||||||
return AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetPath(string fileName)
|
|
||||||
{
|
|
||||||
string startupPath = StartupPath();
|
|
||||||
if (string.IsNullOrEmpty(fileName))
|
|
||||||
{
|
|
||||||
return startupPath;
|
|
||||||
}
|
|
||||||
return Path.Combine(startupPath, fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Waiting(int second)
|
|
||||||
{
|
{
|
||||||
for (var i = second; i > 0; i--)
|
for (var i = second; i > 0; i--)
|
||||||
{
|
{
|
||||||
@@ -132,7 +104,5 @@ namespace AmazTool
|
|||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string V2rayN => "v2rayN";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
43
v2rayN/AmazTool/Utils.cs
Normal file
43
v2rayN/AmazTool/Utils.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace AmazTool
|
||||||
|
{
|
||||||
|
internal class Utils
|
||||||
|
{
|
||||||
|
public static string GetExePath()
|
||||||
|
{
|
||||||
|
return Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StartupPath()
|
||||||
|
{
|
||||||
|
return AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetPath(string fileName)
|
||||||
|
{
|
||||||
|
string startupPath = StartupPath();
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
return startupPath;
|
||||||
|
}
|
||||||
|
return Path.Combine(startupPath, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string V2rayN => "v2rayN";
|
||||||
|
|
||||||
|
public static void StartV2RayN()
|
||||||
|
{
|
||||||
|
Process process = new()
|
||||||
|
{
|
||||||
|
StartInfo = new()
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
FileName = V2rayN,
|
||||||
|
WorkingDirectory = StartupPath()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
process.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
public static class FileManager
|
public static class FileManager
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "FileManager";
|
||||||
|
|
||||||
public static bool ByteArrayToFile(string fileName, byte[] content)
|
public static bool ByteArrayToFile(string fileName, byte[] content)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -15,7 +17,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +62,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +81,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,13 +107,13 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -130,7 +132,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +150,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
public class JsonUtils
|
public class JsonUtils
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "JsonUtils";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DeepCopy
|
/// DeepCopy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -90,7 +92,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
118
v2rayN/ServiceLib/Common/ProcUtils.cs
Normal file
118
v2rayN/ServiceLib/Common/ProcUtils.cs
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ServiceLib.Common;
|
||||||
|
|
||||||
|
public static class ProcUtils
|
||||||
|
{
|
||||||
|
private static readonly string _tag = "ProcUtils";
|
||||||
|
|
||||||
|
public static void ProcessStart(string? fileName, string arguments = "")
|
||||||
|
{
|
||||||
|
ProcessStart(fileName, arguments, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int? ProcessStart(string? fileName, string arguments, string? dir)
|
||||||
|
{
|
||||||
|
if (fileName.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes();
|
||||||
|
if (arguments.Contains(' ')) arguments = arguments.AppendQuotes();
|
||||||
|
|
||||||
|
Process process = new()
|
||||||
|
{
|
||||||
|
StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
FileName = fileName,
|
||||||
|
Arguments = arguments,
|
||||||
|
WorkingDirectory = dir
|
||||||
|
}
|
||||||
|
};
|
||||||
|
process.Start();
|
||||||
|
return process.Id;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RebootAsAdmin(bool blAdmin = true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProcessStartInfo startInfo = new()
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
Arguments = Global.RebootAs,
|
||||||
|
WorkingDirectory = Utils.StartupPath(),
|
||||||
|
FileName = Utils.GetExePath().AppendQuotes(),
|
||||||
|
Verb = blAdmin ? "runas" : null,
|
||||||
|
};
|
||||||
|
Process.Start(startInfo);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task ProcessKill(int pid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ProcessKill(Process.GetProcessById(pid), false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task ProcessKill(Process? proc, bool review)
|
||||||
|
{
|
||||||
|
if (proc is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var procId = review ? proc?.Id : null;
|
||||||
|
var fileName = review ? proc?.MainModule?.FileName : null;
|
||||||
|
var processName = review ? proc?.ProcessName : null;
|
||||||
|
|
||||||
|
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
|
||||||
|
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
|
||||||
|
try { proc?.Close(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
|
||||||
|
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
|
||||||
|
|
||||||
|
await Task.Delay(300);
|
||||||
|
if (review && procId != null && fileName != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var lstProc = Process.GetProcessesByName(processName);
|
||||||
|
foreach (var proc2 in lstProc)
|
||||||
|
{
|
||||||
|
if (proc2.Id == procId)
|
||||||
|
{
|
||||||
|
Logging.SaveLog($"{_tag}, KillProcess not completing the job, procId");
|
||||||
|
await ProcessKill(proc2, false);
|
||||||
|
}
|
||||||
|
if (proc2.MainModule != null && proc2.MainModule?.FileName == fileName)
|
||||||
|
{
|
||||||
|
Logging.SaveLog($"{_tag}, KillProcess not completing the job, fileName");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,5 +73,19 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
return _dbAsync.Table<T>();
|
return _dbAsync.Table<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task DisposeDbConnectionAsync()
|
||||||
|
{
|
||||||
|
await Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
_db?.Close();
|
||||||
|
_db?.Dispose();
|
||||||
|
_db = null;
|
||||||
|
|
||||||
|
_dbAsync?.GetConnection()?.Close();
|
||||||
|
_dbAsync?.GetConnection()?.Dispose();
|
||||||
|
_dbAsync = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,8 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
public class Utils
|
public class Utils
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "Utils";
|
||||||
|
|
||||||
#region 资源操作
|
#region 资源操作
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -36,7 +38,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -57,7 +59,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -92,7 +94,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@@ -117,7 +119,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -139,7 +141,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -159,7 +161,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("Base64Encode", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@@ -193,7 +195,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("Base64Decode", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@@ -483,7 +485,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -515,10 +517,10 @@ namespace ServiceLib.Common
|
|||||||
|
|
||||||
#region 杂项
|
#region 杂项
|
||||||
|
|
||||||
public static bool UpgradeAppExists(out string fileName)
|
public static bool UpgradeAppExists(out string upgradeFileName)
|
||||||
{
|
{
|
||||||
fileName = Path.Combine(Utils.StartupPath(), GetExeName("AmazTool"));
|
upgradeFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GetExeName("AmazTool"));
|
||||||
return File.Exists(fileName);
|
return File.Exists(upgradeFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -530,12 +532,12 @@ namespace ServiceLib.Common
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
return blFull
|
return blFull
|
||||||
? $"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture} - {StartupPath()}"
|
? $"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture}"
|
||||||
: $"{Global.AppName}/{GetVersionInfo()}";
|
: $"{Global.AppName}/{GetVersionInfo()}";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Global.AppName;
|
return Global.AppName;
|
||||||
@@ -549,11 +551,16 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return "0.0";
|
return "0.0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetRuntimeInfo()
|
||||||
|
{
|
||||||
|
return $"{Utils.GetVersion()} | {Utils.StartupPath()} | {Utils.GetExePath()} | {Environment.OSVersion} | {(Environment.Is64BitOperatingSystem ? 64 : 32)}";
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取得GUID
|
/// 取得GUID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -573,7 +580,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@@ -584,23 +591,6 @@ namespace ServiceLib.Common
|
|||||||
return Guid.TryParse(strSrc, out _);
|
return Guid.TryParse(strSrc, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ProcessStart(string? fileName, string arguments = "")
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (fileName.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Process.Start(new ProcessStartInfo(fileName, arguments) { UseShellExecute = true });
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, string> GetSystemHosts()
|
public static Dictionary<string, string> GetSystemHosts()
|
||||||
{
|
{
|
||||||
var systemHosts = new Dictionary<string, string>();
|
var systemHosts = new Dictionary<string, string>();
|
||||||
@@ -623,7 +613,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return systemHosts;
|
return systemHosts;
|
||||||
@@ -675,6 +665,12 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//When this file exists, it is equivalent to having no permission to read and write
|
||||||
|
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NotStoreConfigHere.txt")))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var tempPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "guiTemps");
|
var tempPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "guiTemps");
|
||||||
if (!Directory.Exists(tempPath))
|
if (!Directory.Exists(tempPath))
|
||||||
{
|
{
|
||||||
@@ -851,18 +847,19 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
|
return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
{
|
//else
|
||||||
var id = GetLinuxUserId().Result ?? "1000";
|
//{
|
||||||
if (int.TryParse(id, out var userId))
|
// var id = GetLinuxUserId().Result ?? "1000";
|
||||||
{
|
// if (int.TryParse(id, out var userId))
|
||||||
return userId == 0;
|
// {
|
||||||
}
|
// return userId == 0;
|
||||||
else
|
// }
|
||||||
{
|
// else
|
||||||
return false;
|
// {
|
||||||
}
|
// return false;
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string?> GetLinuxUserId()
|
private static async Task<string?> GetLinuxUserId()
|
||||||
@@ -874,6 +871,7 @@ namespace ServiceLib.Common
|
|||||||
public static async Task<string?> SetLinuxChmod(string? fileName)
|
public static async Task<string?> SetLinuxChmod(string? fileName)
|
||||||
{
|
{
|
||||||
if (fileName.IsNullOrEmpty()) return null;
|
if (fileName.IsNullOrEmpty()) return null;
|
||||||
|
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes();
|
||||||
//File.SetUnixFileMode(fileName, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
|
//File.SetUnixFileMode(fileName, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
|
||||||
var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
|
var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
|
||||||
return await GetCliWrapOutput("/bin/bash", arg);
|
return await GetCliWrapOutput("/bin/bash", arg);
|
||||||
@@ -893,6 +891,12 @@ namespace ServiceLib.Common
|
|||||||
: Environment.GetEnvironmentVariable("HOME");
|
: Environment.GetEnvironmentVariable("HOME");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<string?> GetListNetworkServices()
|
||||||
|
{
|
||||||
|
var arg = new List<string>() { "-c", $"networksetup -listallnetworkservices" };
|
||||||
|
return await GetCliWrapOutput("/bin/bash", arg);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Platform
|
#endregion Platform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,8 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
internal static class WindowsUtils
|
internal static class WindowsUtils
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "WindowsUtils";
|
||||||
|
|
||||||
public static string? RegReadValue(string path, string name, string def)
|
public static string? RegReadValue(string path, string name, string def)
|
||||||
{
|
{
|
||||||
RegistryKey? regKey = null;
|
RegistryKey? regKey = null;
|
||||||
@@ -15,7 +17,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -41,7 +43,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
public class YamlUtils
|
public class YamlUtils
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "YamlUtils";
|
||||||
|
|
||||||
#region YAML
|
#region YAML
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -26,7 +28,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("FromYaml", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return deserializer.Deserialize<T>("");
|
return deserializer.Deserialize<T>("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +55,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -71,7 +73,7 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("PreprocessYaml", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
{
|
{
|
||||||
Default = 0,
|
Default = 0,
|
||||||
Russia = 1,
|
Russia = 1,
|
||||||
|
Iran = 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,21 +124,25 @@
|
|||||||
public static readonly List<string> GeoFilesSources = new() {
|
public static readonly List<string> GeoFilesSources = new() {
|
||||||
"",
|
"",
|
||||||
@"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/{0}.dat",
|
@"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/{0}.dat",
|
||||||
|
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/{0}.dat",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> SingboxRulesetSources = new() {
|
public static readonly List<string> SingboxRulesetSources = new() {
|
||||||
"",
|
"",
|
||||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-rules-dat@release/sing-box/rule-set-{0}/{1}.srs",
|
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-rules-dat@release/sing-box/rule-set-{0}/{1}.srs",
|
||||||
|
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-sing-box-rules@rule-set/{1}.srs",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> RoutingRulesSources = new() {
|
public static readonly List<string> RoutingRulesSources = new() {
|
||||||
"",
|
"",
|
||||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/template.json",
|
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/template.json",
|
||||||
|
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/template.json",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> DNSTemplateSources = new() {
|
public static readonly List<string> DNSTemplateSources = new() {
|
||||||
"",
|
"",
|
||||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/",
|
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/",
|
||||||
|
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly Dictionary<string, string> UserAgentTexts = new()
|
public static readonly Dictionary<string, string> UserAgentTexts = new()
|
||||||
@@ -205,7 +209,7 @@
|
|||||||
public static readonly List<string> RuleNetworks = new() { "", "tcp", "udp", "tcp,udp" };
|
public static readonly List<string> RuleNetworks = new() { "", "tcp", "udp", "tcp,udp" };
|
||||||
public static readonly List<string> destOverrideProtocols = ["http", "tls", "quic", "fakedns", "fakedns+others"];
|
public static readonly List<string> destOverrideProtocols = ["http", "tls", "quic", "fakedns", "fakedns+others"];
|
||||||
public static readonly List<string> TunMtus = new() { "1280", "1408", "1500", "9000" };
|
public static readonly List<string> TunMtus = new() { "1280", "1408", "1500", "9000" };
|
||||||
public static readonly List<string> TunStacks = new() { "gvisor", "system" };
|
public static readonly List<string> TunStacks = new() { "gvisor", "system", "mixed" };
|
||||||
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
|
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
|
||||||
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
||||||
public static readonly List<string> TuicCongestionControls = new() { "cubic", "new_reno", "bbr" };
|
public static readonly List<string> TuicCongestionControls = new() { "cubic", "new_reno", "bbr" };
|
||||||
|
|||||||
@@ -77,8 +77,7 @@
|
|||||||
|
|
||||||
public bool InitComponents()
|
public bool InitComponents()
|
||||||
{
|
{
|
||||||
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
Logging.SaveLog($"v2rayN start up | {Utils.GetRuntimeInfo()}");
|
||||||
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
|
||||||
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
|
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
|
||||||
Logging.ClearLogs();
|
Logging.ClearLogs();
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
public static class AutoStartupHandler
|
public static class AutoStartupHandler
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "AutoStartupHandler";
|
||||||
|
|
||||||
public static async Task<bool> UpdateTask(Config config)
|
public static async Task<bool> UpdateTask(Config config)
|
||||||
{
|
{
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
@@ -62,7 +64,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +125,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +145,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace ServiceLib.Handler
|
|||||||
|
|
||||||
private Dictionary<string, ProxiesItem>? _proxies;
|
private Dictionary<string, ProxiesItem>? _proxies;
|
||||||
public Dictionary<string, object> ProfileContent { get; set; }
|
public Dictionary<string, object> ProfileContent { get; set; }
|
||||||
|
private static readonly string _tag = "ClashApiHandler";
|
||||||
|
|
||||||
public async Task<Tuple<ClashProxies, ClashProviders>?> GetClashProxiesAsync(Config config)
|
public async Task<Tuple<ClashProxies, ClashProviders>?> GetClashProxiesAsync(Config config)
|
||||||
{
|
{
|
||||||
@@ -109,7 +110,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GetClashProxyGroups", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +126,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +154,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +170,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -184,7 +185,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace ServiceLib.Handler
|
|||||||
public class ConfigHandler
|
public class ConfigHandler
|
||||||
{
|
{
|
||||||
private static readonly string _configRes = Global.ConfigFileName;
|
private static readonly string _configRes = Global.ConfigFileName;
|
||||||
|
private static readonly string _tag = "ConfigHandler";
|
||||||
|
|
||||||
#region ConfigHandler
|
#region ConfigHandler
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ namespace ServiceLib.Handler
|
|||||||
config.RoutingBasicItem ??= new();
|
config.RoutingBasicItem ??= new();
|
||||||
if (Utils.IsNullOrEmpty(config.RoutingBasicItem.DomainStrategy))
|
if (Utils.IsNullOrEmpty(config.RoutingBasicItem.DomainStrategy))
|
||||||
{
|
{
|
||||||
config.RoutingBasicItem.DomainStrategy = Global.DomainStrategies.First();//"IPIfNonMatch";
|
config.RoutingBasicItem.DomainStrategy = Global.DomainStrategies.First();
|
||||||
}
|
}
|
||||||
|
|
||||||
config.KcpItem ??= new KcpItem
|
config.KcpItem ??= new KcpItem
|
||||||
@@ -155,6 +156,12 @@ namespace ServiceLib.Handler
|
|||||||
config.SystemProxyItem ??= new();
|
config.SystemProxyItem ??= new();
|
||||||
config.WebDavItem ??= new();
|
config.WebDavItem ??= new();
|
||||||
config.CheckUpdateItem ??= new();
|
config.CheckUpdateItem ??= new();
|
||||||
|
config.Fragment4RayItem ??= new()
|
||||||
|
{
|
||||||
|
Packets = "tlshello",
|
||||||
|
Length = "100-200",
|
||||||
|
Interval = "10-20"
|
||||||
|
};
|
||||||
|
|
||||||
if (Utils.IsNotEmpty(config.ConstItem.DefIEProxyExceptions))
|
if (Utils.IsNotEmpty(config.ConstItem.DefIEProxyExceptions))
|
||||||
{
|
{
|
||||||
@@ -194,7 +201,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("ToJsonFile", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +507,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +994,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("Remove Item", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1868,6 +1875,16 @@ namespace ServiceLib.Handler
|
|||||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json"));
|
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json"));
|
||||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
|
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case EPresetType.Iran:
|
||||||
|
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[2];
|
||||||
|
config.ConstItem.SrsSourceUrl = Global.SingboxRulesetSources[2];
|
||||||
|
config.ConstItem.RouteRulesTemplateSourceUrl = Global.RoutingRulesSources[2];
|
||||||
|
|
||||||
|
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[2] + "v2ray.json"));
|
||||||
|
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[2] + "sing_box.json"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CoreConfigHandler
|
public class CoreConfigHandler
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "CoreConfigHandler";
|
||||||
|
|
||||||
public static async Task<RetResult> GenerateClientConfig(ProfileItem node, string? fileName)
|
public static async Task<RetResult> GenerateClientConfig(ProfileItem node, string? fileName)
|
||||||
{
|
{
|
||||||
var config = AppHandler.Instance.Config;
|
var config = AppHandler.Instance.Config;
|
||||||
@@ -82,7 +84,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GenerateClientCustomConfig", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace ServiceLib.Handler
|
|||||||
private Process? _processPre;
|
private Process? _processPre;
|
||||||
private int _linuxSudoPid = -1;
|
private int _linuxSudoPid = -1;
|
||||||
private Action<bool, string>? _updateFunc;
|
private Action<bool, string>? _updateFunc;
|
||||||
|
private const string _tag = "CoreHandler";
|
||||||
|
|
||||||
public async Task Init(Config config, Action<bool, string> updateFunc)
|
public async Task Init(Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
@@ -31,9 +32,9 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
if (it.CoreType == ECoreType.v2rayN)
|
if (it.CoreType == ECoreType.v2rayN)
|
||||||
{
|
{
|
||||||
if (Utils.UpgradeAppExists(out var fileName))
|
if (Utils.UpgradeAppExists(out var upgradeFileName))
|
||||||
{
|
{
|
||||||
await Utils.SetLinuxChmod(fileName);
|
await Utils.SetLinuxChmod(upgradeFileName);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -54,7 +55,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
if (node == null)
|
if (node == null)
|
||||||
{
|
{
|
||||||
ShowMsg(false, ResUI.CheckServerSettings);
|
UpdateFunc(false, ResUI.CheckServerSettings);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,13 +63,13 @@ namespace ServiceLib.Handler
|
|||||||
var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
|
var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
|
||||||
if (result.Success != true)
|
if (result.Success != true)
|
||||||
{
|
{
|
||||||
ShowMsg(true, result.Msg);
|
UpdateFunc(true, result.Msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowMsg(true, $"{node.GetSummary()}");
|
UpdateFunc(true, $"{node.GetSummary()}");
|
||||||
ShowMsg(false, $"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
UpdateFunc(false, $"{Utils.GetRuntimeInfo()}");
|
||||||
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
||||||
await CoreStop();
|
await CoreStop();
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
await CoreStart(node);
|
await CoreStart(node);
|
||||||
@@ -80,15 +81,23 @@ namespace ServiceLib.Handler
|
|||||||
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray;
|
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray;
|
||||||
var configPath = Utils.GetConfigPath(Global.CoreSpeedtestConfigFileName);
|
var configPath = Utils.GetConfigPath(Global.CoreSpeedtestConfigFileName);
|
||||||
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
|
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
|
||||||
ShowMsg(false, result.Msg);
|
UpdateFunc(false, result.Msg);
|
||||||
if (result.Success != true)
|
if (result.Success != true)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
||||||
ShowMsg(false, configPath);
|
UpdateFunc(false, configPath);
|
||||||
return await CoreStartSpeedtest(configPath, coreType);
|
|
||||||
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||||
|
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
|
||||||
|
if (proc is null)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return proc.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CoreStop()
|
public async Task CoreStop()
|
||||||
@@ -97,12 +106,14 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
if (_process != null)
|
if (_process != null)
|
||||||
{
|
{
|
||||||
_process = await KillProcess(_process);
|
await ProcUtils.ProcessKill(_process, true);
|
||||||
|
_process = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_processPre != null)
|
if (_processPre != null)
|
||||||
{
|
{
|
||||||
_processPre = await KillProcess(_processPre);
|
await ProcUtils.ProcessKill(_processPre, true);
|
||||||
|
_processPre = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_linuxSudoPid > 0)
|
if (_linuxSudoPid > 0)
|
||||||
@@ -113,45 +124,12 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CoreStopPid(int pid)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await KillProcess(Process.GetProcessById(pid));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Private
|
#region Private
|
||||||
|
|
||||||
private string CoreFindExe(CoreInfo coreInfo)
|
|
||||||
{
|
|
||||||
var fileName = string.Empty;
|
|
||||||
foreach (var name in coreInfo.CoreExes)
|
|
||||||
{
|
|
||||||
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
|
|
||||||
if (File.Exists(vName))
|
|
||||||
{
|
|
||||||
fileName = vName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
|
||||||
{
|
|
||||||
var msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
|
|
||||||
Logging.SaveLog(msg);
|
|
||||||
ShowMsg(false, msg);
|
|
||||||
}
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CoreStart(ProfileItem node)
|
private async Task CoreStart(ProfileItem node)
|
||||||
{
|
{
|
||||||
var coreType = _config.RunningCoreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
var coreType = _config.RunningCoreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
||||||
@@ -191,28 +169,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> CoreStartSpeedtest(string configPath, ECoreType coreType)
|
private void UpdateFunc(bool notify, string msg)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
|
||||||
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
|
|
||||||
if (proc is null)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return proc.Id;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
ShowMsg(false, ex.Message);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowMsg(bool notify, string msg)
|
|
||||||
{
|
{
|
||||||
_updateFunc?.Invoke(notify, msg);
|
_updateFunc?.Invoke(notify, msg);
|
||||||
}
|
}
|
||||||
@@ -230,11 +187,12 @@ namespace ServiceLib.Handler
|
|||||||
|
|
||||||
#region Process
|
#region Process
|
||||||
|
|
||||||
private async Task<Process?> RunProcess(CoreInfo coreInfo, string configPath, bool displayLog, bool mayNeedSudo)
|
private async Task<Process?> RunProcess(CoreInfo? coreInfo, string configPath, bool displayLog, bool mayNeedSudo)
|
||||||
{
|
{
|
||||||
var fileName = CoreFindExe(coreInfo);
|
var fileName = CoreInfoHandler.Instance.GetCoreExecFile(coreInfo, out var msg);
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
if (Utils.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
|
UpdateFunc(false, msg);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,12 +227,12 @@ namespace ServiceLib.Handler
|
|||||||
proc.OutputDataReceived += (sender, e) =>
|
proc.OutputDataReceived += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(e.Data)) return;
|
if (Utils.IsNullOrEmpty(e.Data)) return;
|
||||||
ShowMsg(false, e.Data + Environment.NewLine);
|
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||||
};
|
};
|
||||||
proc.ErrorDataReceived += (sender, e) =>
|
proc.ErrorDataReceived += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(e.Data)) return;
|
if (Utils.IsNullOrEmpty(e.Data)) return;
|
||||||
ShowMsg(false, e.Data + Environment.NewLine);
|
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||||
|
|
||||||
if (!startUpSuccessful)
|
if (!startUpSuccessful)
|
||||||
{
|
{
|
||||||
@@ -315,26 +273,12 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ShowMsg(true, ex.Message);
|
UpdateFunc(true, ex.Message);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Process?> KillProcess(Process? proc)
|
|
||||||
{
|
|
||||||
if (proc is null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try { proc?.Kill(true); } catch { }
|
|
||||||
try { proc?.Close(); } catch { }
|
|
||||||
try { proc?.Dispose(); } catch { }
|
|
||||||
|
|
||||||
await Task.Delay(100);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Process
|
#endregion Process
|
||||||
|
|
||||||
#region Linux
|
#region Linux
|
||||||
|
|||||||
@@ -29,6 +29,27 @@
|
|||||||
return _coreInfo ?? [];
|
return _coreInfo ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetCoreExecFile(CoreInfo? coreInfo, out string msg)
|
||||||
|
{
|
||||||
|
var fileName = string.Empty;
|
||||||
|
msg = string.Empty;
|
||||||
|
foreach (var name in coreInfo?.CoreExes)
|
||||||
|
{
|
||||||
|
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
|
||||||
|
if (File.Exists(vName))
|
||||||
|
{
|
||||||
|
fileName = vName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fileName.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
|
||||||
|
Logging.SaveLog(msg);
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
private void InitCoreInfo()
|
private void InitCoreInfo()
|
||||||
{
|
{
|
||||||
_coreInfo = [];
|
_coreInfo = [];
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
{
|
{
|
||||||
public class FmtHandler
|
public class FmtHandler
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "FmtHandler";
|
||||||
|
|
||||||
public static string? GetShareUri(ProfileItem item)
|
public static string? GetShareUri(ProfileItem item)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -23,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,7 +83,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
msg = ResUI.Incorrectconfiguration;
|
msg = ResUI.Incorrectconfiguration;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace ServiceLib.Handler
|
|||||||
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
||||||
private Queue<string> _queIndexIds = new();
|
private Queue<string> _queIndexIds = new();
|
||||||
public static ProfileExHandler Instance => _instance.Value;
|
public static ProfileExHandler Instance => _instance.Value;
|
||||||
|
private static readonly string _tag = "ProfileExHandler";
|
||||||
|
|
||||||
public ProfileExHandler()
|
public ProfileExHandler()
|
||||||
{
|
{
|
||||||
@@ -87,7 +88,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("ProfileExHandler", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +120,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
private StatisticsXrayService? _statisticsXray;
|
private StatisticsXrayService? _statisticsXray;
|
||||||
private StatisticsSingboxService? _statisticsSingbox;
|
private StatisticsSingboxService? _statisticsSingbox;
|
||||||
|
private static readonly string _tag = "StatisticsHandler";
|
||||||
public List<ServerStatItem> ServerStat => _lstServerStat;
|
public List<ServerStatItem> ServerStat => _lstServerStat;
|
||||||
|
|
||||||
public async Task Init(Config config, Action<ServerSpeedItem> updateFunc)
|
public async Task Init(Config config, Action<ServerSpeedItem> updateFunc)
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,10 @@
|
|||||||
{
|
{
|
||||||
public class ProxySettingOSX
|
public class ProxySettingOSX
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* 仅测试了,MacOS 13.7.1 x86 版本,其他版本有待确认
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用接口类型
|
/// 应用接口类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly List<string> LstInterface = ["Ethernet", "Wi-Fi", "Thunderbolt Bridge"];
|
private static readonly List<string> LstInterface = ["Ethernet", "Wi-Fi", "Thunderbolt Bridge", "USB 10/100/1000 LAN"];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 代理类型,对应 http,https,socks
|
/// 代理类型,对应 http,https,socks
|
||||||
@@ -18,13 +14,15 @@
|
|||||||
|
|
||||||
public static async Task SetProxy(string host, int port, string exceptions)
|
public static async Task SetProxy(string host, int port, string exceptions)
|
||||||
{
|
{
|
||||||
var lstCmd = GetSetCmds(host, port, exceptions);
|
var lstInterface = await GetListNetworkServices();
|
||||||
|
var lstCmd = GetSetCmds(lstInterface, host, port, exceptions);
|
||||||
await ExecCmd(lstCmd);
|
await ExecCmd(lstCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task UnsetProxy()
|
public static async Task UnsetProxy()
|
||||||
{
|
{
|
||||||
var lstCmd = GetUnsetCmds();
|
var lstInterface = await GetListNetworkServices();
|
||||||
|
var lstCmd = GetUnsetCmds(lstInterface);
|
||||||
await ExecCmd(lstCmd);
|
await ExecCmd(lstCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +40,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CmdItem> GetSetCmds(string host, int port, string exceptions)
|
private static List<CmdItem> GetSetCmds(List<string> lstInterface, string host, int port, string exceptions)
|
||||||
{
|
{
|
||||||
List<CmdItem> lstCmd = [];
|
List<CmdItem> lstCmd = [];
|
||||||
foreach (var interf in LstInterface)
|
foreach (var interf in lstInterface)
|
||||||
{
|
{
|
||||||
foreach (var type in LstTypes)
|
foreach (var type in LstTypes)
|
||||||
{
|
{
|
||||||
@@ -70,10 +68,10 @@
|
|||||||
return lstCmd;
|
return lstCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CmdItem> GetUnsetCmds()
|
private static List<CmdItem> GetUnsetCmds(List<string> lstInterface)
|
||||||
{
|
{
|
||||||
List<CmdItem> lstCmd = [];
|
List<CmdItem> lstCmd = [];
|
||||||
foreach (var interf in LstInterface)
|
foreach (var interf in lstInterface)
|
||||||
{
|
{
|
||||||
foreach (var type in LstTypes)
|
foreach (var type in LstTypes)
|
||||||
{
|
{
|
||||||
@@ -87,5 +85,17 @@
|
|||||||
|
|
||||||
return lstCmd;
|
return lstCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<List<string>> GetListNetworkServices()
|
||||||
|
{
|
||||||
|
var services = await Utils.GetListNetworkServices();
|
||||||
|
if (services.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return LstInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lst = services.Split(Environment.NewLine).Where(t => t.Length > 0 && t.Contains('*') == false);
|
||||||
|
return lst.ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,6 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
SetProxyFallback(strProxy, exceptions, type);
|
SetProxyFallback(strProxy, exceptions, type);
|
||||||
//Logging.SaveLog(ex.Message, ex);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
{
|
{
|
||||||
public static class SysProxyHandler
|
public static class SysProxyHandler
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "SysProxyHandler";
|
||||||
|
|
||||||
public static async Task<bool> UpdateSysProxy(Config config, bool forceDisable)
|
public static async Task<bool> UpdateSysProxy(Config config, bool forceDisable)
|
||||||
{
|
{
|
||||||
var type = config.SystemProxyItem.SysProxyType;
|
var type = config.SystemProxyItem.SysProxyType;
|
||||||
@@ -59,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace ServiceLib.Handler
|
|||||||
private string? _lastDescription;
|
private string? _lastDescription;
|
||||||
private string _webDir = Global.AppName + "_backup";
|
private string _webDir = Global.AppName + "_backup";
|
||||||
private readonly string _webFileName = "backup.zip";
|
private readonly string _webFileName = "backup.zip";
|
||||||
private string _logTitle = "WebDav--";
|
private readonly string _tag = "WebDav--";
|
||||||
|
|
||||||
public WebDavHandler()
|
public WebDavHandler()
|
||||||
{
|
{
|
||||||
@@ -81,13 +81,13 @@ namespace ServiceLib.Handler
|
|||||||
private void SaveLog(string desc)
|
private void SaveLog(string desc)
|
||||||
{
|
{
|
||||||
_lastDescription = desc;
|
_lastDescription = desc;
|
||||||
Logging.SaveLog(_logTitle + desc);
|
Logging.SaveLog(_tag + desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveLog(Exception ex)
|
private void SaveLog(Exception ex)
|
||||||
{
|
{
|
||||||
_lastDescription = ex.Message;
|
_lastDescription = ex.Message;
|
||||||
Logging.SaveLog(_logTitle, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> CheckConnection()
|
public async Task<bool> CheckConnection()
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
public SystemProxyItem SystemProxyItem { get; set; }
|
public SystemProxyItem SystemProxyItem { get; set; }
|
||||||
public WebDavItem WebDavItem { get; set; }
|
public WebDavItem WebDavItem { get; set; }
|
||||||
public CheckUpdateItem CheckUpdateItem { get; set; }
|
public CheckUpdateItem CheckUpdateItem { get; set; }
|
||||||
|
public Fragment4RayItem? Fragment4RayItem { get; set; }
|
||||||
public List<InItem> Inbound { get; set; }
|
public List<InItem> Inbound { get; set; }
|
||||||
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
||||||
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
||||||
|
|||||||
@@ -246,4 +246,12 @@
|
|||||||
public bool CheckPreReleaseUpdate { get; set; }
|
public bool CheckPreReleaseUpdate { get; set; }
|
||||||
public List<string>? SelectedCoreTypes { get; set; }
|
public List<string>? SelectedCoreTypes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class Fragment4RayItem
|
||||||
|
{
|
||||||
|
public string? Packets { get; set; }
|
||||||
|
public string? Length { get; set; }
|
||||||
|
public string? Interval { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -1248,6 +1248,15 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Iran 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuRegionalPresetsIran {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuRegionalPresetsIran", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Russia 的本地化字符串。
|
/// 查找类似 Russia 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1129,6 +1129,9 @@
|
|||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>روسیه</value>
|
<value>روسیه</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRegionalPresetsIran" xml:space="preserve">
|
||||||
|
<value>ایران</value>
|
||||||
|
</data>
|
||||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
<value>کاربران در منطقه چین می توانند این مورد را نادیده بگیرند</value>
|
<value>کاربران در منطقه چین می توانند این مورد را نادیده بگیرند</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -1342,6 +1342,9 @@
|
|||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>Oroszország</value>
|
<value>Oroszország</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRegionalPresetsIran" xml:space="preserve">
|
||||||
|
<value>Irán</value>
|
||||||
|
</data>
|
||||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
<value>A Kínában élő felhasználók figyelmen kívül hagyhatják ezt a tételt</value>
|
<value>A Kínában élő felhasználók figyelmen kívül hagyhatják ezt a tételt</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -1342,6 +1342,9 @@
|
|||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>Russia</value>
|
<value>Russia</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRegionalPresetsIran" xml:space="preserve">
|
||||||
|
<value>Iran</value>
|
||||||
|
</data>
|
||||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
<value>Users in China region can ignore this item</value>
|
<value>Users in China region can ignore this item</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -1039,6 +1039,9 @@
|
|||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>Россия</value>
|
<value>Россия</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRegionalPresetsIran" xml:space="preserve">
|
||||||
|
<value>Иран</value>
|
||||||
|
</data>
|
||||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
<value>Используйте Настройки -> Региональные пресеты вместо изменения этого поля</value>
|
<value>Используйте Настройки -> Региональные пресеты вместо изменения этого поля</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
<value>配置格式不正确</value>
|
<value>配置格式不正确</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="CustomServerTips" xml:space="preserve">
|
<data name="CustomServerTips" xml:space="preserve">
|
||||||
<value>注意,自定义配置完全依赖您自己的配置,不能使用所有设置功能。如需使用系统代理请手动修改监听端口。</value>
|
<value>注意,自定义配置完全依赖您自己的配置,不能使用所有设置功能。如需使用系统代理请手动修改监听端口。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Downloading" xml:space="preserve">
|
<data name="Downloading" xml:space="preserve">
|
||||||
<value>下载开始...</value>
|
<value>下载开始...</value>
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
<value>下载</value>
|
<value>下载</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DownloadYesNo" xml:space="preserve">
|
<data name="DownloadYesNo" xml:space="preserve">
|
||||||
<value>是否下载? {0}</value>
|
<value>是否下载?{0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FailedConversionConfiguration" xml:space="preserve">
|
<data name="FailedConversionConfiguration" xml:space="preserve">
|
||||||
<value>转换配置文件失败</value>
|
<value>转换配置文件失败</value>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<value>读取配置文件失败</value>
|
<value>读取配置文件失败</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FillCorrectServerPort" xml:space="preserve">
|
<data name="FillCorrectServerPort" xml:space="preserve">
|
||||||
<value>请填写正确格式服务器端口</value>
|
<value>请填写正确格式的服务器端口</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FillLocalListeningPort" xml:space="preserve">
|
<data name="FillLocalListeningPort" xml:space="preserve">
|
||||||
<value>请填写本地监听端口</value>
|
<value>请填写本地监听端口</value>
|
||||||
@@ -169,16 +169,16 @@
|
|||||||
<value>请填写用户ID</value>
|
<value>请填写用户ID</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Incorrectconfiguration" xml:space="preserve">
|
<data name="Incorrectconfiguration" xml:space="preserve">
|
||||||
<value>不是正确的配置,请检查</value>
|
<value>配置不正确,请检查</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InitialConfiguration" xml:space="preserve">
|
<data name="InitialConfiguration" xml:space="preserve">
|
||||||
<value>初始化配置</value>
|
<value>初始化配置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsLatestCore" xml:space="preserve">
|
<data name="IsLatestCore" xml:space="preserve">
|
||||||
<value>{0} {1} 已是最新版本。</value>
|
<value>{0} {1} 已是最新版本</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsLatestN" xml:space="preserve">
|
<data name="IsLatestN" xml:space="preserve">
|
||||||
<value>{0} {1} 已是最新版本。</value>
|
<value>{0} {1} 已是最新版本</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvAddress" xml:space="preserve">
|
<data name="LvAddress" xml:space="preserve">
|
||||||
<value>地址</value>
|
<value>地址</value>
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
<value>未设置有效的订阅</value>
|
<value>未设置有效的订阅</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgParsingSuccessfully" xml:space="preserve">
|
<data name="MsgParsingSuccessfully" xml:space="preserve">
|
||||||
<value>解析{0}成功</value>
|
<value>解析 {0} 成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgStartGettingSubscriptions" xml:space="preserve">
|
<data name="MsgStartGettingSubscriptions" xml:space="preserve">
|
||||||
<value>开始获取订阅内容</value>
|
<value>开始获取订阅内容</value>
|
||||||
@@ -259,10 +259,10 @@
|
|||||||
<value>在文件夹 ({0}) 下未找到Core文件 (文件名:{1}),请下载后放入文件夹,下载地址: {2}</value>
|
<value>在文件夹 ({0}) 下未找到Core文件 (文件名:{1}),请下载后放入文件夹,下载地址: {2}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NoValidQRcodeFound" xml:space="preserve">
|
<data name="NoValidQRcodeFound" xml:space="preserve">
|
||||||
<value>扫描完成,未发现有效二维码</value>
|
<value>扫描完成,未发现有效二维码</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OperationFailed" xml:space="preserve">
|
<data name="OperationFailed" xml:space="preserve">
|
||||||
<value>操作失败,请检查重试</value>
|
<value>操作失败,请检查并重试</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PleaseFillRemarks" xml:space="preserve">
|
<data name="PleaseFillRemarks" xml:space="preserve">
|
||||||
<value>请填写别名</value>
|
<value>请填写别名</value>
|
||||||
@@ -280,10 +280,10 @@
|
|||||||
<value>服务器去重完成。原数量: {0},现数量: {1}</value>
|
<value>服务器去重完成。原数量: {0},现数量: {1}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RemoveServer" xml:space="preserve">
|
<data name="RemoveServer" xml:space="preserve">
|
||||||
<value>是否确定移除服务器?</value>
|
<value>是否确定移除服务器?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SaveClientConfigurationIn" xml:space="preserve">
|
<data name="SaveClientConfigurationIn" xml:space="preserve">
|
||||||
<value>客户端配置文件保存在:{0}</value>
|
<value>客户端配置文件保存在:{0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="StartService" xml:space="preserve">
|
<data name="StartService" xml:space="preserve">
|
||||||
<value>启动服务({0})...</value>
|
<value>启动服务({0})...</value>
|
||||||
@@ -311,10 +311,10 @@
|
|||||||
<value>请先选择规则</value>
|
<value>请先选择规则</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RemoveRules" xml:space="preserve">
|
<data name="RemoveRules" xml:space="preserve">
|
||||||
<value>是否确定移除规则?</value>
|
<value>是否确定移除规则?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
|
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
|
||||||
<value>{0},必填其中一项.</value>
|
<value>{0},必填其中一项.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvRemarks" xml:space="preserve">
|
<data name="LvRemarks" xml:space="preserve">
|
||||||
<value>别名</value>
|
<value>别名</value>
|
||||||
@@ -329,10 +329,10 @@
|
|||||||
<value>请填写Url</value>
|
<value>请填写Url</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AddBatchRoutingRulesYesNo" xml:space="preserve">
|
<data name="AddBatchRoutingRulesYesNo" xml:space="preserve">
|
||||||
<value>是否追加规则?选择是则追加,选择否则替换</value>
|
<value>是否追加规则?选择“是”则追加,选择“否”则全部替换。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
|
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
|
||||||
<value>下载 GeoFile: {0} 成功</value>
|
<value>下载 GeoFile:{0} 成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgInformationTitle" xml:space="preserve">
|
<data name="MsgInformationTitle" xml:space="preserve">
|
||||||
<value>信息</value>
|
<value>信息</value>
|
||||||
@@ -386,7 +386,7 @@
|
|||||||
<value>*Kcp seed</value>
|
<value>*Kcp seed</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RegisterGlobalHotkeyFailed" xml:space="preserve">
|
<data name="RegisterGlobalHotkeyFailed" xml:space="preserve">
|
||||||
<value>注册全局热键 {0} 失败,原因 {1}</value>
|
<value>注册全局热键 {0} 失败,原因:{1}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RegisterGlobalHotkeySuccessfully" xml:space="preserve">
|
<data name="RegisterGlobalHotkeySuccessfully" xml:space="preserve">
|
||||||
<value>注册全局热键 {0} 成功</value>
|
<value>注册全局热键 {0} 成功</value>
|
||||||
@@ -485,10 +485,10 @@
|
|||||||
<value>暗黑模式</value>
|
<value>暗黑模式</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
|
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
|
||||||
<value>是否跟随系统主题</value>
|
<value>跟随系统主题</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsLanguage" xml:space="preserve">
|
<data name="TbSettingsLanguage" xml:space="preserve">
|
||||||
<value>语言(重启)</value>
|
<value>语言(需重启)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
||||||
<value>从剪贴板导入分享链接 (Ctrl+V)</value>
|
<value>从剪贴板导入分享链接 (Ctrl+V)</value>
|
||||||
@@ -638,7 +638,7 @@
|
|||||||
<value>传输层安全(TLS)</value>
|
<value>传输层安全(TLS)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipNetwork" xml:space="preserve">
|
<data name="TipNetwork" xml:space="preserve">
|
||||||
<value>*默认tcp,选错会无法连接</value>
|
<value>*默认tcp,选错会无法连接</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCoreType" xml:space="preserve">
|
<data name="TbCoreType" xml:space="preserve">
|
||||||
<value>Core类型</value>
|
<value>Core类型</value>
|
||||||
@@ -671,7 +671,7 @@
|
|||||||
<value>Socks端口</value>
|
<value>Socks端口</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipPreSocksPort" xml:space="preserve">
|
<data name="TipPreSocksPort" xml:space="preserve">
|
||||||
<value>* 自定义配置的Socks端口值,可不设置;当设置此值后,将使用Xray/sing-box(Tun)额外启动一个前置Socks服务,提供分流和速度显示等功能</value>
|
<value>*自定义配置的Socks端口值,可不设置;当设置此值后,将使用Xray/sing-box(Tun)额外启动一个前置Socks服务,提供分流和速度显示等功能</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbBrowse" xml:space="preserve">
|
<data name="TbBrowse" xml:space="preserve">
|
||||||
<value>浏览</value>
|
<value>浏览</value>
|
||||||
@@ -680,7 +680,7 @@
|
|||||||
<value>编辑</value>
|
<value>编辑</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAdvancedProtocol" xml:space="preserve">
|
<data name="TbSettingsAdvancedProtocol" xml:space="preserve">
|
||||||
<value>高级代理设置, 协议选择(可选)</value>
|
<value>高级代理设置,协议选择(可选)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
||||||
<value>允许来自局域网的连接</value>
|
<value>允许来自局域网的连接</value>
|
||||||
@@ -689,19 +689,19 @@
|
|||||||
<value>启动后隐藏窗口</value>
|
<value>启动后隐藏窗口</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
|
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
|
||||||
<value>自动更新Geo文件的间隔(单位小时)</value>
|
<value>自动更新Geo文件的间隔(小时)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCore" xml:space="preserve">
|
<data name="TbSettingsCore" xml:space="preserve">
|
||||||
<value>Core: 基础设置</value>
|
<value>Core: 基础设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCoreDns" xml:space="preserve">
|
<data name="TbSettingsCoreDns" xml:space="preserve">
|
||||||
<value>V2ray DNS设置</value>
|
<value>v2ray DNS设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCoreKcp" xml:space="preserve">
|
<data name="TbSettingsCoreKcp" xml:space="preserve">
|
||||||
<value>Core: KCP设置</value>
|
<value>Core: KCP设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCoreType" xml:space="preserve">
|
<data name="TbSettingsCoreType" xml:space="preserve">
|
||||||
<value>Core类型设置</value>
|
<value>Core 类型设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsDefAllowInsecure" xml:space="preserve">
|
<data name="TbSettingsDefAllowInsecure" xml:space="preserve">
|
||||||
<value>默认跳过证书验证(allowInsecure)</value>
|
<value>默认跳过证书验证(allowInsecure)</value>
|
||||||
@@ -719,7 +719,7 @@
|
|||||||
<value>例外</value>
|
<value>例外</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip" xml:space="preserve">
|
<data name="TbSettingsExceptionTip" xml:space="preserve">
|
||||||
<value>例外. 对于下列字符开头的地址不使用代理配置文件:使用分号(;)分隔</value>
|
<value>例外:对于下列字符开头的地址,不使用代理配置文件。使用分号(;)分隔。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsHttpPort" xml:space="preserve">
|
<data name="TbSettingsHttpPort" xml:space="preserve">
|
||||||
<value>本地http监听端口</value>
|
<value>本地http监听端口</value>
|
||||||
@@ -746,7 +746,7 @@
|
|||||||
<value>认证密码</value>
|
<value>认证密码</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsRemoteDNS" xml:space="preserve">
|
<data name="TbSettingsRemoteDNS" xml:space="preserve">
|
||||||
<value>自定义DNS(可多个,用逗号(,)分隔)</value>
|
<value>自定义DNS(可多个,用逗号(,)分隔)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsSetUWP" xml:space="preserve">
|
<data name="TbSettingsSetUWP" xml:space="preserve">
|
||||||
<value>解除Win10 UWP应用回环代理限制</value>
|
<value>解除Win10 UWP应用回环代理限制</value>
|
||||||
@@ -791,7 +791,7 @@
|
|||||||
<value>全局热键设置</value>
|
<value>全局热键设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
|
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
|
||||||
<value>直接按键盘进行设置, 重启后生效</value>
|
<value>直接按键盘进行设置,重启后生效</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbNotChangeSystemProxy" xml:space="preserve">
|
<data name="TbNotChangeSystemProxy" xml:space="preserve">
|
||||||
<value>不改变系统代理</value>
|
<value>不改变系统代理</value>
|
||||||
@@ -830,7 +830,7 @@
|
|||||||
<value>上移 (U)</value>
|
<value>上移 (U)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgFilterTitle" xml:space="preserve">
|
<data name="MsgFilterTitle" xml:space="preserve">
|
||||||
<value>过滤器, 支持正则</value>
|
<value>过滤器(支持正则)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuWebsiteItem" xml:space="preserve">
|
<data name="menuWebsiteItem" xml:space="preserve">
|
||||||
<value>{0} 官网</value>
|
<value>{0} 官网</value>
|
||||||
@@ -872,7 +872,7 @@
|
|||||||
<value>预定义规则集列表</value>
|
<value>预定义规则集列表</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoutingTips" xml:space="preserve">
|
<data name="TbRoutingTips" xml:space="preserve">
|
||||||
<value>*设置的路由规则,用逗号(,)分隔;正则中的逗号用<COMMA>替代</value>
|
<value>*设置的路由规则,用逗号(,)分隔;正则中的逗号用<COMMA>替代</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuImportRulesFromClipboard" xml:space="preserve">
|
<data name="menuImportRulesFromClipboard" xml:space="preserve">
|
||||||
<value>从剪贴板中导入规则</value>
|
<value>从剪贴板中导入规则</value>
|
||||||
@@ -902,13 +902,13 @@
|
|||||||
<value>路由规则详情设置</value>
|
<value>路由规则详情设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAutoSort" xml:space="preserve">
|
<data name="TbAutoSort" xml:space="preserve">
|
||||||
<value>保存时Domain, IP, 进程名 自动排序</value>
|
<value>保存时 Domain, IP, 进程名 自动排序</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRuleobjectDoc" xml:space="preserve">
|
<data name="TbRuleobjectDoc" xml:space="preserve">
|
||||||
<value>规则详细说明文档</value>
|
<value>规则详细说明文档</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDnsObjectDoc" xml:space="preserve">
|
<data name="TbDnsObjectDoc" xml:space="preserve">
|
||||||
<value>支持填写DnsObject,JSON格式,点击查看文档</value>
|
<value>支持填写DnsObject,JSON格式,点击查看文档</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SubUrlTips" xml:space="preserve">
|
<data name="SubUrlTips" xml:space="preserve">
|
||||||
<value>普通分组此处请留空</value>
|
<value>普通分组此处请留空</value>
|
||||||
@@ -920,7 +920,7 @@
|
|||||||
<value>系统代理设置改变</value>
|
<value>系统代理设置改变</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsRouteOnly" xml:space="preserve">
|
<data name="TbSettingsRouteOnly" xml:space="preserve">
|
||||||
<value>RouteOnly</value>
|
<value>仅限路由(routeOnly)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
|
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
|
||||||
<value>请勿将代理服务器用于本地(Intranet)地址</value>
|
<value>请勿将代理服务器用于本地(Intranet)地址</value>
|
||||||
@@ -935,7 +935,7 @@
|
|||||||
<value>速度(M/s)</value>
|
<value>速度(M/s)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FailedToRunCore" xml:space="preserve">
|
<data name="FailedToRunCore" xml:space="preserve">
|
||||||
<value>运行Core失败,请看日志</value>
|
<value>运行Core失败,请查看日志</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvFilter" xml:space="preserve">
|
<data name="LvFilter" xml:space="preserve">
|
||||||
<value>别名正则过滤</value>
|
<value>别名正则过滤</value>
|
||||||
@@ -953,7 +953,7 @@
|
|||||||
<value>为局域网开启新的端口</value>
|
<value>为局域网开启新的端口</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsTunMode" xml:space="preserve">
|
<data name="TbSettingsTunMode" xml:space="preserve">
|
||||||
<value>Tun模式设置</value>
|
<value>Tun 模式设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuMoveToGroup" xml:space="preserve">
|
<data name="menuMoveToGroup" xml:space="preserve">
|
||||||
<value>移至订阅分组</value>
|
<value>移至订阅分组</value>
|
||||||
@@ -1342,6 +1342,9 @@
|
|||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>俄罗斯</value>
|
<value>俄罗斯</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRegionalPresetsIran" xml:space="preserve">
|
||||||
|
<value>伊朗</value>
|
||||||
|
</data>
|
||||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
<value>扫描图片中的二维码</value>
|
<value>扫描图片中的二维码</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -1370,7 +1373,7 @@
|
|||||||
<value>请先在Tun模式设置中设置sudo密码</value>
|
<value>请先在Tun模式设置中设置sudo密码</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
<value>请不要用sudo运行本app</value>
|
<value>请不要用sudo运行本程序</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
<value>*xhttp 模式</value>
|
<value>*xhttp 模式</value>
|
||||||
@@ -1385,7 +1388,7 @@
|
|||||||
<value>测试时自动分批的每批数量(最大1000)</value>
|
<value>测试时自动分批的每批数量(最大1000)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
||||||
<value>例外. 对于下列地址不使用代理配置文件:使用逗号(,)分隔</value>
|
<value>例外:对于下列地址不使用代理配置文件。使用逗号(,)分隔。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsDestOverride" xml:space="preserve">
|
<data name="TbSettingsDestOverride" xml:space="preserve">
|
||||||
<value>流量探测类型</value>
|
<value>流量探测类型</value>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@
|
|||||||
<value>下載</value>
|
<value>下載</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DownloadYesNo" xml:space="preserve">
|
<data name="DownloadYesNo" xml:space="preserve">
|
||||||
<value>是否下載? {0}</value>
|
<value>是否下載?{0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FailedConversionConfiguration" xml:space="preserve">
|
<data name="FailedConversionConfiguration" xml:space="preserve">
|
||||||
<value>轉換設定檔失敗</value>
|
<value>轉換設定檔失敗</value>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<value>讀取設定檔失敗</value>
|
<value>讀取設定檔失敗</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FillCorrectServerPort" xml:space="preserve">
|
<data name="FillCorrectServerPort" xml:space="preserve">
|
||||||
<value>請填寫正確格式伺服器埠</value>
|
<value>請填寫正確格式的伺服器埠</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FillLocalListeningPort" xml:space="preserve">
|
<data name="FillLocalListeningPort" xml:space="preserve">
|
||||||
<value>請填寫本機偵聽埠</value>
|
<value>請填寫本機偵聽埠</value>
|
||||||
@@ -169,16 +169,16 @@
|
|||||||
<value>請填寫使用者ID</value>
|
<value>請填寫使用者ID</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Incorrectconfiguration" xml:space="preserve">
|
<data name="Incorrectconfiguration" xml:space="preserve">
|
||||||
<value>不是正確的設定,請檢查</value>
|
<value>設定不正確,請檢查</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InitialConfiguration" xml:space="preserve">
|
<data name="InitialConfiguration" xml:space="preserve">
|
||||||
<value>初始化設定</value>
|
<value>初始化設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsLatestCore" xml:space="preserve">
|
<data name="IsLatestCore" xml:space="preserve">
|
||||||
<value>{0} {1} 已是最新版本。</value>
|
<value>{0} {1} 已是最新版本</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsLatestN" xml:space="preserve">
|
<data name="IsLatestN" xml:space="preserve">
|
||||||
<value>{0} {1} 已是最新版本。</value>
|
<value>{0} {1} 已是最新版本</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvAddress" xml:space="preserve">
|
<data name="LvAddress" xml:space="preserve">
|
||||||
<value>位址</value>
|
<value>位址</value>
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
<value>未設定有效的訂閱</value>
|
<value>未設定有效的訂閱</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgParsingSuccessfully" xml:space="preserve">
|
<data name="MsgParsingSuccessfully" xml:space="preserve">
|
||||||
<value>解析{0}成功</value>
|
<value>解析 {0} 成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgStartGettingSubscriptions" xml:space="preserve">
|
<data name="MsgStartGettingSubscriptions" xml:space="preserve">
|
||||||
<value>開始獲取訂閱內容</value>
|
<value>開始獲取訂閱內容</value>
|
||||||
@@ -259,10 +259,10 @@
|
|||||||
<value>在資料夾 ({0}) 下未找到Core檔案 (檔案名:{1}),請下載後放入資料夾,下載網址: {2}</value>
|
<value>在資料夾 ({0}) 下未找到Core檔案 (檔案名:{1}),請下載後放入資料夾,下載網址: {2}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NoValidQRcodeFound" xml:space="preserve">
|
<data name="NoValidQRcodeFound" xml:space="preserve">
|
||||||
<value>掃描完成,未發現有效二維碼</value>
|
<value>掃描完成,未發現有效二維碼</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OperationFailed" xml:space="preserve">
|
<data name="OperationFailed" xml:space="preserve">
|
||||||
<value>操作失敗,請檢查重試</value>
|
<value>操作失敗,請檢查後重試</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PleaseFillRemarks" xml:space="preserve">
|
<data name="PleaseFillRemarks" xml:space="preserve">
|
||||||
<value>請填寫別名</value>
|
<value>請填寫別名</value>
|
||||||
@@ -280,16 +280,17 @@
|
|||||||
<value>伺服器去重完成。原數量: {0},現數量: {1}</value>
|
<value>伺服器去重完成。原數量: {0},現數量: {1}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RemoveServer" xml:space="preserve">
|
<data name="RemoveServer" xml:space="preserve">
|
||||||
<value>是否確定移除伺服器?</value>
|
<value>是否確定移除伺服器?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SaveClientConfigurationIn" xml:space="preserve">
|
<data name="SaveClientConfigurationIn" xml:space="preserve">
|
||||||
<value>用戶端設定檔儲存在:{0}</value>
|
<value>用戶端設定檔儲存在:{0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="StartService" xml:space="preserve">
|
<data name="StartService" xml:space="preserve">
|
||||||
<value>啟動服務({0})...</value>
|
<value>啟動服務({0})...</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfulConfiguration" xml:space="preserve">
|
<data name="SuccessfulConfiguration" xml:space="preserve">
|
||||||
<value>設定成功{0}</value>
|
<value>設定成功
|
||||||
|
{0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedCustomServer" xml:space="preserve">
|
<data name="SuccessfullyImportedCustomServer" xml:space="preserve">
|
||||||
<value>成功匯入自訂設定伺服器</value>
|
<value>成功匯入自訂設定伺服器</value>
|
||||||
@@ -310,10 +311,10 @@
|
|||||||
<value>請先選擇規則</value>
|
<value>請先選擇規則</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RemoveRules" xml:space="preserve">
|
<data name="RemoveRules" xml:space="preserve">
|
||||||
<value>是否確定移除規則?</value>
|
<value>是否確定移除規則?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
|
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
|
||||||
<value>{0},必填其中一項.</value>
|
<value>{0},必填其中一項.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvRemarks" xml:space="preserve">
|
<data name="LvRemarks" xml:space="preserve">
|
||||||
<value>別名</value>
|
<value>別名</value>
|
||||||
@@ -328,10 +329,10 @@
|
|||||||
<value>請填寫URL</value>
|
<value>請填寫URL</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AddBatchRoutingRulesYesNo" xml:space="preserve">
|
<data name="AddBatchRoutingRulesYesNo" xml:space="preserve">
|
||||||
<value>是否追加規則?選擇是則追加,選擇否則取代</value>
|
<value>是否追加規則?選擇“是”則追加,選擇“否”則完全取代。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
|
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
|
||||||
<value>下載 GeoFile: {0} 成功</value>
|
<value>下載 GeoFile:{0} 成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgInformationTitle" xml:space="preserve">
|
<data name="MsgInformationTitle" xml:space="preserve">
|
||||||
<value>資訊</value>
|
<value>資訊</value>
|
||||||
@@ -385,7 +386,7 @@
|
|||||||
<value>*KCP seed</value>
|
<value>*KCP seed</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RegisterGlobalHotkeyFailed" xml:space="preserve">
|
<data name="RegisterGlobalHotkeyFailed" xml:space="preserve">
|
||||||
<value>註冊全域快速鍵 {0} 失敗,原因 {1}</value>
|
<value>註冊全域快速鍵 {0} 失敗,原因:{1}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RegisterGlobalHotkeySuccessfully" xml:space="preserve">
|
<data name="RegisterGlobalHotkeySuccessfully" xml:space="preserve">
|
||||||
<value>註冊全域快速鍵 {0} 成功</value>
|
<value>註冊全域快速鍵 {0} 成功</value>
|
||||||
@@ -484,10 +485,10 @@
|
|||||||
<value>暗黑模式</value>
|
<value>暗黑模式</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
|
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
|
||||||
<value>是否跟隨系統主題</value>
|
<value>跟隨系統主題</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsLanguage" xml:space="preserve">
|
<data name="TbSettingsLanguage" xml:space="preserve">
|
||||||
<value>語言(重啟)</value>
|
<value>語言(需重啟)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
||||||
<value>從剪貼簿導入分享鏈接 (Ctrl+V)</value>
|
<value>從剪貼簿導入分享鏈接 (Ctrl+V)</value>
|
||||||
@@ -637,7 +638,7 @@
|
|||||||
<value>傳輸層安全(TLS)</value>
|
<value>傳輸層安全(TLS)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipNetwork" xml:space="preserve">
|
<data name="TipNetwork" xml:space="preserve">
|
||||||
<value>*預設TCP,選錯會無法連接</value>
|
<value>*預設TCP,選錯會無法連接</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCoreType" xml:space="preserve">
|
<data name="TbCoreType" xml:space="preserve">
|
||||||
<value>Core類型</value>
|
<value>Core類型</value>
|
||||||
@@ -670,7 +671,7 @@
|
|||||||
<value>SOCKS埠</value>
|
<value>SOCKS埠</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipPreSocksPort" xml:space="preserve">
|
<data name="TipPreSocksPort" xml:space="preserve">
|
||||||
<value>* 自訂設定的Socks埠值,可不設定;當設定此值後,將使用Xray/sing-box(Tun)額外啟動一個前置Socks服務,提供分流和速度顯示等功能</value>
|
<value>*自訂設定的Socks埠值,可不設定;當設定此值後,將使用Xray/sing-box(Tun)額外啟動一個前置Socks服務,提供分流和速度顯示等功能</value>
|
||||||
</data>
|
</data>
|
||||||
<!--********************************************-->
|
<!--********************************************-->
|
||||||
<data name="TbBrowse" xml:space="preserve">
|
<data name="TbBrowse" xml:space="preserve">
|
||||||
@@ -680,7 +681,7 @@
|
|||||||
<value>編輯</value>
|
<value>編輯</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAdvancedProtocol" xml:space="preserve">
|
<data name="TbSettingsAdvancedProtocol" xml:space="preserve">
|
||||||
<value>進階代理設定, 協定選擇(可選)</value>
|
<value>進階代理設定,協定選擇(可選)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
||||||
<value>允許來自區域網路的連線</value>
|
<value>允許來自區域網路的連線</value>
|
||||||
@@ -689,7 +690,7 @@
|
|||||||
<value>啟動後隱藏視窗</value>
|
<value>啟動後隱藏視窗</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
|
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
|
||||||
<value>自動更新Geo檔案的間隔(單位小時)</value>
|
<value>自動更新Geo檔案的間隔(小時)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCore" xml:space="preserve">
|
<data name="TbSettingsCore" xml:space="preserve">
|
||||||
<value>Core: 基礎設定</value>
|
<value>Core: 基礎設定</value>
|
||||||
@@ -701,7 +702,7 @@
|
|||||||
<value>Core: KCP設定</value>
|
<value>Core: KCP設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCoreType" xml:space="preserve">
|
<data name="TbSettingsCoreType" xml:space="preserve">
|
||||||
<value>Core類型設定</value>
|
<value>Core 類型設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsDefAllowInsecure" xml:space="preserve">
|
<data name="TbSettingsDefAllowInsecure" xml:space="preserve">
|
||||||
<value>預設跳過憑證驗證(allowinsecure)</value>
|
<value>預設跳過憑證驗證(allowinsecure)</value>
|
||||||
@@ -719,7 +720,7 @@
|
|||||||
<value>例外</value>
|
<value>例外</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip" xml:space="preserve">
|
<data name="TbSettingsExceptionTip" xml:space="preserve">
|
||||||
<value>例外. 對於下列字元開頭的位址不使用代理設定檔:使用分號(;)分隔</value>
|
<value>例外:對於下列字元開頭的位址,不使用代理設定檔。使用分號(;)分隔。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsHttpPort" xml:space="preserve">
|
<data name="TbSettingsHttpPort" xml:space="preserve">
|
||||||
<value>本機HTTP偵聽埠</value>
|
<value>本機HTTP偵聽埠</value>
|
||||||
@@ -746,7 +747,7 @@
|
|||||||
<value>認證密碼</value>
|
<value>認證密碼</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsRemoteDNS" xml:space="preserve">
|
<data name="TbSettingsRemoteDNS" xml:space="preserve">
|
||||||
<value>自訂DNS(可多個,用逗號(,)分隔)</value>
|
<value>自訂DNS(可多個,用逗號(,)分隔)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsSetUWP" xml:space="preserve">
|
<data name="TbSettingsSetUWP" xml:space="preserve">
|
||||||
<value>解除Win10 UWP應用回環代理限制</value>
|
<value>解除Win10 UWP應用回環代理限制</value>
|
||||||
@@ -791,7 +792,7 @@
|
|||||||
<value>全域快速鍵設定</value>
|
<value>全域快速鍵設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
|
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
|
||||||
<value>直接按鍵盤進行設定, 重啟後生效</value>
|
<value>直接按鍵盤進行設定,重啟後生效</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbNotChangeSystemProxy" xml:space="preserve">
|
<data name="TbNotChangeSystemProxy" xml:space="preserve">
|
||||||
<value>不改變系統代理</value>
|
<value>不改變系統代理</value>
|
||||||
@@ -830,7 +831,7 @@
|
|||||||
<value>上移 (U)</value>
|
<value>上移 (U)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgFilterTitle" xml:space="preserve">
|
<data name="MsgFilterTitle" xml:space="preserve">
|
||||||
<value>過濾, 支援正則</value>
|
<value>過濾(允許正則)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuWebsiteItem" xml:space="preserve">
|
<data name="menuWebsiteItem" xml:space="preserve">
|
||||||
<value>{0} 官網</value>
|
<value>{0} 官網</value>
|
||||||
@@ -872,7 +873,7 @@
|
|||||||
<value>預定義規則集列表</value>
|
<value>預定義規則集列表</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoutingTips" xml:space="preserve">
|
<data name="TbRoutingTips" xml:space="preserve">
|
||||||
<value>*設定的路由規則,用逗號(,)分隔;正則中的逗號用<COMMA>替代</value>
|
<value>*設定的路由規則,用逗號(,)分隔;正則中的逗號用<COMMA>替代</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuImportRulesFromClipboard" xml:space="preserve">
|
<data name="menuImportRulesFromClipboard" xml:space="preserve">
|
||||||
<value>從剪貼簿中匯入規則</value>
|
<value>從剪貼簿中匯入規則</value>
|
||||||
@@ -902,13 +903,13 @@
|
|||||||
<value>路由規則詳情設定</value>
|
<value>路由規則詳情設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAutoSort" xml:space="preserve">
|
<data name="TbAutoSort" xml:space="preserve">
|
||||||
<value>儲存時Domain, IP, 行程名 自動排序</value>
|
<value>儲存時 Domain, IP, 行程名 自動排序</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRuleobjectDoc" xml:space="preserve">
|
<data name="TbRuleobjectDoc" xml:space="preserve">
|
||||||
<value>規則詳細說明檔案</value>
|
<value>規則詳細說明檔案</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDnsObjectDoc" xml:space="preserve">
|
<data name="TbDnsObjectDoc" xml:space="preserve">
|
||||||
<value>支援填寫DnsObject,JSON格式,點擊查看檔案</value>
|
<value>支援填寫DnsObject,JSON格式,點擊查看説明</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SubUrlTips" xml:space="preserve">
|
<data name="SubUrlTips" xml:space="preserve">
|
||||||
<value>普通分組此處請留空</value>
|
<value>普通分組此處請留空</value>
|
||||||
@@ -920,7 +921,7 @@
|
|||||||
<value>系統代理設定已改變</value>
|
<value>系統代理設定已改變</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsRouteOnly" xml:space="preserve">
|
<data name="TbSettingsRouteOnly" xml:space="preserve">
|
||||||
<value>RouteOnly</value>
|
<value>僅限路由(routeOnly)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
|
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
|
||||||
<value>請勿將代理伺服器用於本機(Intranet)位址</value>
|
<value>請勿將代理伺服器用於本機(Intranet)位址</value>
|
||||||
@@ -935,7 +936,7 @@
|
|||||||
<value>速度(M/s)</value>
|
<value>速度(M/s)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FailedToRunCore" xml:space="preserve">
|
<data name="FailedToRunCore" xml:space="preserve">
|
||||||
<value>執行Core失敗,請看日誌</value>
|
<value>執行Core失敗,請查閲日誌</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvFilter" xml:space="preserve">
|
<data name="LvFilter" xml:space="preserve">
|
||||||
<value>別名正則過濾</value>
|
<value>別名正則過濾</value>
|
||||||
@@ -947,13 +948,13 @@
|
|||||||
<value>匯入舊的設定檔guiNConfig</value>
|
<value>匯入舊的設定檔guiNConfig</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbEnableTunAs" xml:space="preserve">
|
<data name="TbEnableTunAs" xml:space="preserve">
|
||||||
<value>啟用TUN</value>
|
<value>啟用Tun</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsNewPort4LAN" xml:space="preserve">
|
<data name="TbSettingsNewPort4LAN" xml:space="preserve">
|
||||||
<value>為區域網路開啟新的埠</value>
|
<value>為區域網路開啟新的埠</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsTunMode" xml:space="preserve">
|
<data name="TbSettingsTunMode" xml:space="preserve">
|
||||||
<value>TUN模式設定</value>
|
<value>Tun 模式設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuMoveToGroup" xml:space="preserve">
|
<data name="menuMoveToGroup" xml:space="preserve">
|
||||||
<value>移至訂閱分組</value>
|
<value>移至訂閱分組</value>
|
||||||
@@ -1067,7 +1068,7 @@
|
|||||||
<value>sing-box Mux 多路復用協定</value>
|
<value>sing-box Mux 多路復用協定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
||||||
<value>行程名全稱 (TUN模式)</value>
|
<value>行程名全稱 (Tun模式)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoutingRuleDomain" xml:space="preserve">
|
<data name="TbRoutingRuleDomain" xml:space="preserve">
|
||||||
<value>Domain</value>
|
<value>Domain</value>
|
||||||
@@ -1222,6 +1223,9 @@
|
|||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>俄羅斯</value>
|
<value>俄羅斯</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRegionalPresetsIran" xml:space="preserve">
|
||||||
|
<value>伊朗</value>
|
||||||
|
</data>
|
||||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
<value>掃描圖片中的二維碼</value>
|
<value>掃描圖片中的二維碼</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -1370,7 +1374,7 @@
|
|||||||
<value>請先在Tun模式設定中設定sudo密碼</value>
|
<value>請先在Tun模式設定中設定sudo密碼</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
<value>請不要用sudo來運行本app</value>
|
<value>請不要用sudo來運行此App</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
<value>*xhttp 模式</value>
|
<value>*xhttp 模式</value>
|
||||||
@@ -1385,7 +1389,7 @@
|
|||||||
<value>測試時自動分批的每批數量(最大1000)</value>
|
<value>測試時自動分批的每批數量(最大1000)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
||||||
<value>例外. 對於下列位址不使用代理設定檔:使用逗號(,)分隔</value>
|
<value>例外:對於下列位址不使用代理設定檔,使用逗號(,)分隔。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsDestOverride" xml:space="preserve">
|
<data name="TbSettingsDestOverride" xml:space="preserve">
|
||||||
<value>流量探測類型</value>
|
<value>流量探測類型</value>
|
||||||
|
|||||||
@@ -5,24 +5,25 @@
|
|||||||
"loglevel": "warning"
|
"loglevel": "warning"
|
||||||
},
|
},
|
||||||
"inbounds": [],
|
"inbounds": [],
|
||||||
"outbounds": [{
|
"outbounds": [
|
||||||
|
{
|
||||||
"tag": "proxy",
|
"tag": "proxy",
|
||||||
"protocol": "vmess",
|
"protocol": "vmess",
|
||||||
"settings": {
|
"settings": {
|
||||||
"vnext": [{
|
"vnext": [{
|
||||||
"address": "v2ray.cool",
|
"address": "",
|
||||||
"port": 10086,
|
"port": 0,
|
||||||
"users": [{
|
"users": [{
|
||||||
"id": "a3482e88-686a-4a58-8126-99c9df64b7bf",
|
"id": "",
|
||||||
"security": "auto"
|
"security": "auto"
|
||||||
}]
|
}]
|
||||||
}],
|
}],
|
||||||
"servers": [{
|
"servers": [{
|
||||||
"address": "v2ray.cool",
|
"address": "",
|
||||||
"method": "chacha20",
|
"method": "",
|
||||||
"ota": false,
|
"ota": false,
|
||||||
"password": "123456",
|
"password": "",
|
||||||
"port": 10086,
|
"port": 0,
|
||||||
"level": 1
|
"level": 1
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
@@ -35,27 +36,23 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"protocol": "freedom",
|
"protocol": "freedom",
|
||||||
"settings": {},
|
|
||||||
"tag": "direct"
|
"tag": "direct"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"protocol": "blackhole",
|
"protocol": "blackhole",
|
||||||
"tag": "block",
|
"tag": "block"
|
||||||
"settings": {
|
|
||||||
"response": {
|
|
||||||
"type": "http"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"routing": {
|
"routing": {
|
||||||
"domainStrategy": "IPIfNonMatch",
|
"domainStrategy": "IPIfNonMatch",
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
{
|
||||||
"inboundTag": ["api"],
|
"inboundTag": [
|
||||||
"outboundTag": "api",
|
"api"
|
||||||
"type": "field"
|
],
|
||||||
}
|
"outboundTag": "api",
|
||||||
|
"type": "field"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,10 +99,5 @@
|
|||||||
"domain": [
|
"domain": [
|
||||||
"geosite:cn"
|
"geosite:cn"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"remarks": "最终代理",
|
|
||||||
"port": "0-65535",
|
|
||||||
"outboundTag": "proxy"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -4,6 +4,15 @@
|
|||||||
"proxy.example.com": "127.0.0.1"
|
"proxy.example.com": "127.0.0.1"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
|
{
|
||||||
|
"address": "1.1.1.1",
|
||||||
|
"domains": [
|
||||||
|
"geosite:geolocation-!cn"
|
||||||
|
],
|
||||||
|
"expectIPs": [
|
||||||
|
"geoip:!cn"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"address": "223.5.5.5",
|
"address": "223.5.5.5",
|
||||||
"domains": [
|
"domains": [
|
||||||
@@ -13,7 +22,6 @@
|
|||||||
"geoip:cn"
|
"geoip:cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"1.1.1.1",
|
|
||||||
"8.8.8.8",
|
"8.8.8.8",
|
||||||
"https://dns.google/dns-query"
|
"https://dns.google/dns-query"
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>7.4.2</Version>
|
<Version>7.5.6</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageReference Include="Splat.NLog" Version="15.2.22" />
|
<PackageReference Include="Splat.NLog" Version="15.2.22" />
|
||||||
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="16.2.1" />
|
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageReference Include="CliWrap" Version="3.7.0" />
|
<PackageReference Include="CliWrap" Version="3.7.0" />
|
||||||
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
public class CoreConfigClashService
|
public class CoreConfigClashService
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
private static readonly string _tag = "CoreConfigClashService";
|
||||||
|
|
||||||
public CoreConfigClashService(Config config)
|
public CoreConfigClashService(Config config)
|
||||||
{
|
{
|
||||||
@@ -131,7 +132,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GenerateClientConfigClash-Mixin", ex);
|
Logging.SaveLog($"{_tag}-Mixin", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var txtFileNew = YamlUtils.ToYaml(fileContent).Replace(tagYamlStr2, tagYamlStr3);
|
var txtFileNew = YamlUtils.ToYaml(fileContent).Replace(tagYamlStr2, tagYamlStr3);
|
||||||
@@ -151,7 +152,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GenerateClientConfigClash", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
public class CoreConfigSingboxService
|
public class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
private static readonly string _tag = "CoreConfigSingboxService";
|
||||||
|
|
||||||
public CoreConfigSingboxService(Config config)
|
public CoreConfigSingboxService(Config config)
|
||||||
{
|
{
|
||||||
@@ -71,7 +72,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GenerateClientConfig4Singbox", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -114,7 +115,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenLog(singboxConfig);
|
await GenLog(singboxConfig);
|
||||||
@@ -235,7 +236,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -312,7 +313,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
await GenOutbound(item, outbound);
|
await GenOutbound(item, outbound);
|
||||||
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
|
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
|
||||||
singboxConfig.outbounds.Add(outbound);
|
singboxConfig.outbounds.Insert(0, outbound);
|
||||||
tagProxy.Add(outbound.tag);
|
tagProxy.Add(outbound.tag);
|
||||||
}
|
}
|
||||||
if (tagProxy.Count <= 0)
|
if (tagProxy.Count <= 0)
|
||||||
@@ -332,7 +333,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
outbounds = tagProxy,
|
outbounds = tagProxy,
|
||||||
interrupt_exist_connections = false,
|
interrupt_exist_connections = false,
|
||||||
};
|
};
|
||||||
singboxConfig.outbounds.Add(outUrltest);
|
singboxConfig.outbounds.Insert(0, outUrltest);
|
||||||
|
|
||||||
//add selector outbound
|
//add selector outbound
|
||||||
var outSelector = new Outbound4Sbox
|
var outSelector = new Outbound4Sbox
|
||||||
@@ -343,7 +344,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
interrupt_exist_connections = false,
|
interrupt_exist_connections = false,
|
||||||
};
|
};
|
||||||
outSelector.outbounds.Insert(0, outUrltest.tag);
|
outSelector.outbounds.Insert(0, outUrltest.tag);
|
||||||
singboxConfig.outbounds.Add(outSelector);
|
singboxConfig.outbounds.Insert(0, outSelector);
|
||||||
|
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
ret.Data = JsonUtils.Serialize(singboxConfig);
|
ret.Data = JsonUtils.Serialize(singboxConfig);
|
||||||
@@ -351,7 +352,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -432,7 +433,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -473,7 +474,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -562,7 +563,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -695,7 +696,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -718,7 +719,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -768,7 +769,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -845,7 +846,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -897,7 +898,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -969,7 +970,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1085,7 +1086,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1185,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
public class CoreConfigV2rayService
|
public class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
private static readonly string _tag = "CoreConfigV2rayService";
|
||||||
|
|
||||||
public CoreConfigV2rayService(Config config)
|
public CoreConfigV2rayService(Config config)
|
||||||
{
|
{
|
||||||
@@ -70,7 +71,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GenerateClientConfig4V2ray", ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -153,7 +154,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
||||||
await GenOutbound(item, outbound);
|
await GenOutbound(item, outbound);
|
||||||
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
|
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
|
||||||
v2rayConfig.outbounds.Add(outbound);
|
v2rayConfig.outbounds.Insert(0, outbound);
|
||||||
tagProxy.Add(outbound.tag);
|
tagProxy.Add(outbound.tag);
|
||||||
}
|
}
|
||||||
if (tagProxy.Count <= 0)
|
if (tagProxy.Count <= 0)
|
||||||
@@ -181,15 +182,12 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
rule.balancerTag = balancer.tag;
|
rule.balancerTag = balancer.tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
v2rayConfig.routing.rules.Add(new()
|
||||||
{
|
{
|
||||||
v2rayConfig.routing.rules.Add(new()
|
network = "tcp,udp",
|
||||||
{
|
balancerTag = balancer.tag,
|
||||||
network = "tcp,udp",
|
type = "field"
|
||||||
balancerTag = balancer.tag,
|
});
|
||||||
type = "field"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
ret.Data = JsonUtils.Serialize(v2rayConfig);
|
ret.Data = JsonUtils.Serialize(v2rayConfig);
|
||||||
@@ -197,7 +195,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -240,7 +238,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenLog(v2rayConfig);
|
await GenLog(v2rayConfig);
|
||||||
@@ -349,7 +347,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -379,7 +377,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -423,7 +421,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -482,7 +480,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -560,7 +558,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -569,6 +567,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var muxEnabled = _config.CoreBasicItem.MuxEnabled;
|
||||||
switch (node.ConfigType)
|
switch (node.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.VMess:
|
case EConfigType.VMess:
|
||||||
@@ -609,7 +608,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
usersItem.security = Global.DefaultSecurity;
|
usersItem.security = Global.DefaultSecurity;
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
|
await GenOutboundMux(node, outbound, muxEnabled, muxEnabled);
|
||||||
|
|
||||||
outbound.settings.servers = null;
|
outbound.settings.servers = null;
|
||||||
break;
|
break;
|
||||||
@@ -634,7 +633,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
serversItem.ota = false;
|
serversItem.ota = false;
|
||||||
serversItem.level = 1;
|
serversItem.level = 1;
|
||||||
|
|
||||||
await GenOutboundMux(node, outbound, false);
|
await GenOutboundMux(node, outbound);
|
||||||
|
|
||||||
outbound.settings.vnext = null;
|
outbound.settings.vnext = null;
|
||||||
break;
|
break;
|
||||||
@@ -670,7 +669,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
|
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenOutboundMux(node, outbound, false);
|
await GenOutboundMux(node, outbound);
|
||||||
|
|
||||||
outbound.settings.vnext = null;
|
outbound.settings.vnext = null;
|
||||||
break;
|
break;
|
||||||
@@ -704,22 +703,15 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
usersItem.email = Global.UserEMail;
|
usersItem.email = Global.UserEMail;
|
||||||
usersItem.encryption = node.Security;
|
usersItem.encryption = node.Security;
|
||||||
|
|
||||||
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
|
if (node.Flow.IsNullOrEmpty())
|
||||||
|
|
||||||
if (node.StreamSecurity == Global.StreamSecurityReality || node.StreamSecurity == Global.StreamSecurity)
|
|
||||||
{
|
{
|
||||||
if (Utils.IsNotEmpty(node.Flow))
|
await GenOutboundMux(node, outbound, muxEnabled, muxEnabled);
|
||||||
{
|
|
||||||
usersItem.flow = node.Flow;
|
|
||||||
|
|
||||||
await GenOutboundMux(node, outbound, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (node.StreamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.Flow))
|
else
|
||||||
{
|
{
|
||||||
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
|
usersItem.flow = node.Flow;
|
||||||
|
await GenOutboundMux(node, outbound, false, muxEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
outbound.settings.servers = null;
|
outbound.settings.servers = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -742,7 +734,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
serversItem.ota = false;
|
serversItem.ota = false;
|
||||||
serversItem.level = 1;
|
serversItem.level = 1;
|
||||||
|
|
||||||
await GenOutboundMux(node, outbound, false);
|
await GenOutboundMux(node, outbound);
|
||||||
|
|
||||||
outbound.settings.vnext = null;
|
outbound.settings.vnext = null;
|
||||||
break;
|
break;
|
||||||
@@ -754,31 +746,33 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled)
|
private async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabledTCP = false, bool enabledUDP = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (enabled)
|
outbound.mux.enabled = false;
|
||||||
|
outbound.mux.concurrency = -1;
|
||||||
|
|
||||||
|
if (enabledTCP)
|
||||||
{
|
{
|
||||||
outbound.mux.enabled = true;
|
outbound.mux.enabled = true;
|
||||||
outbound.mux.concurrency = _config.Mux4RayItem.Concurrency;
|
outbound.mux.concurrency = _config.Mux4RayItem.Concurrency;
|
||||||
|
}
|
||||||
|
else if (enabledUDP)
|
||||||
|
{
|
||||||
|
outbound.mux.enabled = true;
|
||||||
outbound.mux.xudpConcurrency = _config.Mux4RayItem.XudpConcurrency;
|
outbound.mux.xudpConcurrency = _config.Mux4RayItem.XudpConcurrency;
|
||||||
outbound.mux.xudpProxyUDP443 = _config.Mux4RayItem.XudpProxyUDP443;
|
outbound.mux.xudpProxyUDP443 = _config.Mux4RayItem.XudpProxyUDP443;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
outbound.mux.enabled = false;
|
|
||||||
outbound.mux.concurrency = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -930,7 +924,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
streamSettings.xhttpSettings = xhttpSettings;
|
streamSettings.xhttpSettings = xhttpSettings;
|
||||||
await GenOutboundMux(node, outbound, false);
|
await GenOutboundMux(node, outbound);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//h2
|
//h2
|
||||||
@@ -1020,7 +1014,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1040,9 +1034,13 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
//Outbound Freedom domainStrategy
|
//Outbound Freedom domainStrategy
|
||||||
if (Utils.IsNotEmpty(domainStrategy4Freedom))
|
if (Utils.IsNotEmpty(domainStrategy4Freedom))
|
||||||
{
|
{
|
||||||
var outbound = v2rayConfig.outbounds[1];
|
var outbound = v2rayConfig.outbounds.FirstOrDefault(t => t is { protocol: "freedom", tag: Global.DirectTag });
|
||||||
outbound.settings.domainStrategy = domainStrategy4Freedom;
|
if (outbound != null)
|
||||||
outbound.settings.userLevel = 0;
|
{
|
||||||
|
outbound.settings = new();
|
||||||
|
outbound.settings.domainStrategy = domainStrategy4Freedom;
|
||||||
|
outbound.settings.userLevel = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var obj = JsonUtils.ParseJson(normalDNS);
|
var obj = JsonUtils.ParseJson(normalDNS);
|
||||||
@@ -1083,7 +1081,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1169,9 +1167,9 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
{
|
{
|
||||||
fragment = new()
|
fragment = new()
|
||||||
{
|
{
|
||||||
packets = "tlshello",
|
packets = _config.Fragment4RayItem?.Packets,
|
||||||
length = "100-200",
|
length = _config.Fragment4RayItem?.Length,
|
||||||
interval = "10-20"
|
interval = _config.Fragment4RayItem?.Interval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1241,7 +1239,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
public event ErrorEventHandler? Error;
|
public event ErrorEventHandler? Error;
|
||||||
|
|
||||||
|
private static readonly string _tag = "DownloadService";
|
||||||
|
|
||||||
public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> updateFunc)
|
public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -68,7 +70,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
|
|
||||||
Error?.Invoke(this, new ErrorEventArgs(ex));
|
Error?.Invoke(this, new ErrorEventArgs(ex));
|
||||||
if (ex.InnerException != null)
|
if (ex.InnerException != null)
|
||||||
@@ -113,7 +115,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
Error?.Invoke(this, new ErrorEventArgs(ex));
|
Error?.Invoke(this, new ErrorEventArgs(ex));
|
||||||
if (ex.InnerException != null)
|
if (ex.InnerException != null)
|
||||||
{
|
{
|
||||||
@@ -131,7 +133,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
Error?.Invoke(this, new ErrorEventArgs(ex));
|
Error?.Invoke(this, new ErrorEventArgs(ex));
|
||||||
if (ex.InnerException != null)
|
if (ex.InnerException != null)
|
||||||
{
|
{
|
||||||
@@ -177,7 +179,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
Error?.Invoke(this, new ErrorEventArgs(ex));
|
Error?.Invoke(this, new ErrorEventArgs(ex));
|
||||||
if (ex.InnerException != null)
|
if (ex.InnerException != null)
|
||||||
{
|
{
|
||||||
@@ -208,7 +210,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
Error?.Invoke(this, new ErrorEventArgs(ex));
|
Error?.Invoke(this, new ErrorEventArgs(ex));
|
||||||
if (ex.InnerException != null)
|
if (ex.InnerException != null)
|
||||||
{
|
{
|
||||||
@@ -232,13 +234,13 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace ServiceLib.Services
|
|||||||
private Action<SpeedTestResult>? _updateFunc;
|
private Action<SpeedTestResult>? _updateFunc;
|
||||||
|
|
||||||
private bool _exitLoop = false;
|
private bool _exitLoop = false;
|
||||||
|
private static readonly string _tag = "SpeedtestService";
|
||||||
|
|
||||||
public SpeedtestService(Config config, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> updateFunc)
|
public SpeedtestService(Config config, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> updateFunc)
|
||||||
{
|
{
|
||||||
@@ -146,7 +147,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -154,7 +155,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -201,7 +202,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -209,13 +210,13 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (pid > 0)
|
if (pid > 0)
|
||||||
{
|
{
|
||||||
await CoreHandler.Instance.CoreStopPid(pid);
|
await ProcUtils.ProcessKill(pid);
|
||||||
}
|
}
|
||||||
await ProfileExHandler.Instance.SaveTo();
|
await ProfileExHandler.Instance.SaveTo();
|
||||||
}
|
}
|
||||||
@@ -277,7 +278,7 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
if (pid > 0)
|
if (pid > 0)
|
||||||
{
|
{
|
||||||
await CoreHandler.Instance.CoreStopPid(pid);
|
await ProcUtils.ProcessKill(pid);
|
||||||
}
|
}
|
||||||
await ProfileExHandler.Instance.SaveTo();
|
await ProfileExHandler.Instance.SaveTo();
|
||||||
}
|
}
|
||||||
@@ -341,7 +342,7 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
if (pid > 0)
|
if (pid > 0)
|
||||||
{
|
{
|
||||||
await CoreHandler.Instance.CoreStopPid(pid);
|
await ProcUtils.ProcessKill(pid);
|
||||||
}
|
}
|
||||||
await ProfileExHandler.Instance.SaveTo();
|
await ProfileExHandler.Instance.SaveTo();
|
||||||
}
|
}
|
||||||
@@ -389,7 +390,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return responseTime;
|
return responseTime;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace ServiceLib.Services.Statistics
|
|||||||
private ClientWebSocket? webSocket;
|
private ClientWebSocket? webSocket;
|
||||||
private Action<ServerSpeedItem>? _updateFunc;
|
private Action<ServerSpeedItem>? _updateFunc;
|
||||||
private string Url => $"ws://{Global.Loopback}:{AppHandler.Instance.StatePort2}/traffic";
|
private string Url => $"ws://{Global.Loopback}:{AppHandler.Instance.StatePort2}/traffic";
|
||||||
|
private static readonly string _tag = "StatisticsSingboxService";
|
||||||
|
|
||||||
public StatisticsSingboxService(Config config, Action<ServerSpeedItem> updateFunc)
|
public StatisticsSingboxService(Config config, Action<ServerSpeedItem> updateFunc)
|
||||||
{
|
{
|
||||||
@@ -48,7 +49,7 @@ namespace ServiceLib.Services.Statistics
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace ServiceLib.Services
|
|||||||
{
|
{
|
||||||
private Action<bool, string>? _updateFunc;
|
private Action<bool, string>? _updateFunc;
|
||||||
private int _timeout = 30;
|
private int _timeout = 30;
|
||||||
|
private static readonly string _tag = "UpdateService";
|
||||||
|
|
||||||
public async Task CheckUpdateGuiN(Config config, Action<bool, string> updateFunc, bool preRelease)
|
public async Task CheckUpdateGuiN(Config config, Action<bool, string> updateFunc, bool preRelease)
|
||||||
{
|
{
|
||||||
@@ -272,7 +273,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
_updateFunc?.Invoke(false, ex.Message);
|
_updateFunc?.Invoke(false, ex.Message);
|
||||||
return new RetResult(false, ex.Message);
|
return new RetResult(false, ex.Message);
|
||||||
}
|
}
|
||||||
@@ -356,7 +357,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
_updateFunc?.Invoke(false, ex.Message);
|
_updateFunc?.Invoke(false, ex.Message);
|
||||||
return new SemanticVersion("");
|
return new SemanticVersion("");
|
||||||
}
|
}
|
||||||
@@ -415,7 +416,7 @@ namespace ServiceLib.Services
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
_updateFunc?.Invoke(false, ex.Message);
|
_updateFunc?.Invoke(false, ex.Message);
|
||||||
return new RetResult(false, ex.Message);
|
return new RetResult(false, ex.Message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ namespace ServiceLib.ViewModels
|
|||||||
address = Utils.GetConfigPath(address);
|
address = Utils.GetConfigPath(address);
|
||||||
if (File.Exists(address))
|
if (File.Exists(address))
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(address);
|
ProcUtils.ProcessStart(address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -130,18 +130,31 @@ namespace ServiceLib.ViewModels
|
|||||||
DisplayOperationMsg(ResUI.LocalRestoreInvalidZipTips);
|
DisplayOperationMsg(ResUI.LocalRestoreInvalidZipTips);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Utils.UpgradeAppExists(out _))
|
|
||||||
{
|
|
||||||
DisplayOperationMsg(ResUI.UpgradeAppNotExistTip);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//backup first
|
//backup first
|
||||||
var fileBackup = Utils.GetBackupPath(BackupFileName);
|
var fileBackup = Utils.GetBackupPath(BackupFileName);
|
||||||
var result = await CreateZipFileFromDirectory(fileBackup);
|
var result = await CreateZipFileFromDirectory(fileBackup);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.UpgradeApp(fileName);
|
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||||
|
await service?.MyAppExitAsync(true);
|
||||||
|
await SQLiteHelper.Instance.DisposeDbConnectionAsync();
|
||||||
|
|
||||||
|
var toPath = Utils.GetConfigPath();
|
||||||
|
FileManager.ZipExtractToFile(fileName, toPath, "");
|
||||||
|
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
|
ProcUtils.RebootAsAdmin(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Utils.UpgradeAppExists(out var upgradeFileName))
|
||||||
|
{
|
||||||
|
ProcUtils.ProcessStart(upgradeFileName, Global.RebootAs, Utils.StartupPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service?.Shutdown(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Linq;
|
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels
|
namespace ServiceLib.ViewModels
|
||||||
{
|
{
|
||||||
@@ -50,6 +48,8 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> RegionalPresetRussiaCmd { get; }
|
public ReactiveCommand<Unit, Unit> RegionalPresetRussiaCmd { get; }
|
||||||
|
|
||||||
|
public ReactiveCommand<Unit, Unit> RegionalPresetIranCmd { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> ReloadCmd { get; }
|
public ReactiveCommand<Unit, Unit> ReloadCmd { get; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
@@ -197,6 +197,11 @@ namespace ServiceLib.ViewModels
|
|||||||
await ApplyRegionalPreset(EPresetType.Russia);
|
await ApplyRegionalPreset(EPresetType.Russia);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RegionalPresetIranCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
|
{
|
||||||
|
await ApplyRegionalPreset(EPresetType.Iran);
|
||||||
|
});
|
||||||
|
|
||||||
#endregion WhenAnyValue && ReactiveCommand
|
#endregion WhenAnyValue && ReactiveCommand
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
@@ -272,9 +277,8 @@ namespace ServiceLib.ViewModels
|
|||||||
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,34 +303,23 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
if (!blWindowsShutDown)
|
if (!blWindowsShutDown)
|
||||||
{
|
{
|
||||||
_updateView?.Invoke(EViewAction.Shutdown, null);
|
_updateView?.Invoke(EViewAction.Shutdown, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpgradeApp(string arg)
|
public async Task UpgradeApp(string arg)
|
||||||
{
|
{
|
||||||
if (!Utils.UpgradeAppExists(out var fileName))
|
if (!Utils.UpgradeAppExists(out var upgradeFileName))
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.UpgradeAppNotExistTip);
|
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.UpgradeAppNotExistTip);
|
||||||
Logging.SaveLog("UpgradeApp does not exist");
|
Logging.SaveLog("UpgradeApp does not exist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process process = new()
|
var id = ProcUtils.ProcessStart(upgradeFileName, arg, Utils.StartupPath());
|
||||||
|
if (id > 0)
|
||||||
{
|
{
|
||||||
StartInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
UseShellExecute = true,
|
|
||||||
FileName = fileName,
|
|
||||||
Arguments = arg.AppendQuotes(),
|
|
||||||
WorkingDirectory = Utils.StartupPath()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
process.Start();
|
|
||||||
if (process.Id > 0)
|
|
||||||
{
|
|
||||||
await MyAppExitAsync(false);
|
|
||||||
await MyAppExitAsync(false);
|
await MyAppExitAsync(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,6 +329,11 @@ namespace ServiceLib.ViewModels
|
|||||||
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
|
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Shutdown(bool byUser)
|
||||||
|
{
|
||||||
|
_updateView?.Invoke(EViewAction.Shutdown, byUser);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Actions
|
#endregion Actions
|
||||||
|
|
||||||
#region Servers && Groups
|
#region Servers && Groups
|
||||||
@@ -504,20 +502,8 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
public async Task RebootAsAdmin()
|
public async Task RebootAsAdmin()
|
||||||
{
|
{
|
||||||
try
|
ProcUtils.RebootAsAdmin();
|
||||||
{
|
await MyAppExitAsync(false);
|
||||||
ProcessStartInfo startInfo = new()
|
|
||||||
{
|
|
||||||
UseShellExecute = true,
|
|
||||||
Arguments = Global.RebootAs,
|
|
||||||
WorkingDirectory = Utils.StartupPath(),
|
|
||||||
FileName = Utils.GetExePath().AppendQuotes(),
|
|
||||||
Verb = "runas",
|
|
||||||
};
|
|
||||||
Process.Start(startInfo);
|
|
||||||
await MyAppExitAsync(false);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ClearServerStatistics()
|
private async Task ClearServerStatistics()
|
||||||
@@ -528,17 +514,18 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task OpenTheFileLocation()
|
private async Task OpenTheFileLocation()
|
||||||
{
|
{
|
||||||
|
var path = Utils.StartupPath();
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("Explorer", $"/select,{Utils.GetConfigPath()}");
|
ProcUtils.ProcessStart(path);
|
||||||
}
|
}
|
||||||
else if (Utils.IsLinux())
|
else if (Utils.IsLinux())
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("nautilus", Utils.GetConfigPath());
|
ProcUtils.ProcessStart("nautilus", path);
|
||||||
}
|
}
|
||||||
else if (Utils.IsOSX())
|
else if (Utils.IsOSX())
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("open", Utils.GetConfigPath());
|
ProcUtils.ProcessStart("open", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,15 +74,16 @@ namespace ServiceLib.ViewModels
|
|||||||
SelectedSource.Protocol = ProtocolItems?.ToList();
|
SelectedSource.Protocol = ProtocolItems?.ToList();
|
||||||
SelectedSource.InboundTag = InboundTagItems?.ToList();
|
SelectedSource.InboundTag = InboundTagItems?.ToList();
|
||||||
|
|
||||||
bool hasRule = SelectedSource.Domain?.Count > 0
|
var hasRule = SelectedSource.Domain?.Count > 0
|
||||||
|| SelectedSource.Ip?.Count > 0
|
|| SelectedSource.Ip?.Count > 0
|
||||||
|| SelectedSource.Protocol?.Count > 0
|
|| SelectedSource.Protocol?.Count > 0
|
||||||
|| SelectedSource.Process?.Count > 0
|
|| SelectedSource.Process?.Count > 0
|
||||||
|| Utils.IsNotEmpty(SelectedSource.Port);
|
|| Utils.IsNotEmpty(SelectedSource.Port)
|
||||||
|
|| Utils.IsNotEmpty(SelectedSource.Network);
|
||||||
|
|
||||||
if (!hasRule)
|
if (!hasRule)
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(string.Format(ResUI.RoutingRuleDetailRequiredTips, "Port/Protocol/Domain/IP/Process"));
|
NoticeHandler.Instance.Enqueue(string.Format(ResUI.RoutingRuleDetailRequiredTips, "Network/Port/Protocol/Domain/IP/Process"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
//NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
|
|||||||
@@ -177,12 +177,12 @@ namespace ServiceLib.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lst = new List<RulesItem>();
|
var lst = new List<RulesItem>();
|
||||||
foreach (var it in SelectedSources ?? [SelectedSource])
|
var sources = SelectedSources ?? [SelectedSource];
|
||||||
|
foreach (var it in _rules)
|
||||||
{
|
{
|
||||||
var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
|
if (sources.Any(t => t.Id == it?.Id))
|
||||||
if (item != null)
|
|
||||||
{
|
{
|
||||||
var item2 = JsonUtils.DeepCopy(item); //JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
var item2 = JsonUtils.DeepCopy(it);
|
||||||
item2.Id = null;
|
item2.Id = null;
|
||||||
lst.Add(item2 ?? new());
|
lst.Add(item2 ?? new());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo 'Building Linux'
|
|
||||||
|
|
||||||
OutputPath='./bin/v2rayN'
|
|
||||||
OutputPath64="${OutputPath}/linux-x64"
|
|
||||||
OutputPathArm64="${OutputPath}/linux-arm64"
|
|
||||||
|
|
||||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
|
|
||||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
|
|
||||||
|
|
||||||
rm -rf "$OutputPath64/*.pdb"
|
|
||||||
rm -rf "$OutputPathArm64/*.pdb"
|
|
||||||
|
|
||||||
echo 'Build done'
|
|
||||||
|
|
||||||
7z a v2rayN-linux.zip $OutputPath
|
|
||||||
exit 0
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo 'Building macOS'
|
|
||||||
|
|
||||||
OutputPath='./bin/v2rayN'
|
|
||||||
OutputPath64="${OutputPath}/osx-x64"
|
|
||||||
OutputPathArm64="${OutputPath}/osx-arm64"
|
|
||||||
|
|
||||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
|
|
||||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
|
|
||||||
|
|
||||||
rm -rf "$OutputPath64/*.pdb"
|
|
||||||
rm -rf "$OutputPathArm64/*.pdb"
|
|
||||||
|
|
||||||
echo 'Build done'
|
|
||||||
|
|
||||||
7z a v2rayN-osx.zip $OutputPath
|
|
||||||
exit 0
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
param (
|
|
||||||
[Parameter()]
|
|
||||||
[ValidateNotNullOrEmpty()]
|
|
||||||
[string]
|
|
||||||
$OutputPathWin64 = './bin/v2rayN/win-x64',
|
|
||||||
$OutputPathWinArm64 = './bin/v2rayN/win-arm64'
|
|
||||||
)
|
|
||||||
|
|
||||||
Write-Host 'Building Windows'
|
|
||||||
|
|
||||||
dotnet publish `
|
|
||||||
./v2rayN/v2rayN.csproj `
|
|
||||||
-c Release `
|
|
||||||
-r win-x64 `
|
|
||||||
--self-contained false `
|
|
||||||
-p:PublishReadyToRun=false `
|
|
||||||
-p:PublishSingleFile=true `
|
|
||||||
-o $OutputPathWin64
|
|
||||||
|
|
||||||
dotnet publish `
|
|
||||||
./v2rayN/v2rayN.csproj `
|
|
||||||
-c Release `
|
|
||||||
-r win-arm64 `
|
|
||||||
--self-contained false `
|
|
||||||
-p:PublishReadyToRun=false `
|
|
||||||
-p:PublishSingleFile=true `
|
|
||||||
-o $OutputPathWinArm64
|
|
||||||
|
|
||||||
if ( -Not $? ) {
|
|
||||||
exit $lastExitCode
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( Test-Path -Path ./bin/v2rayN ) {
|
|
||||||
rm -Force "$OutputPathWin64/*.pdb"
|
|
||||||
rm -Force "$OutputPathWinArm64/*.pdb"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host 'Build done'
|
|
||||||
|
|
||||||
7z a v2rayN-windows-64.zip $OutputPathWin64
|
|
||||||
7z a v2rayN-windows-arm64.zip $OutputPathWinArm64
|
|
||||||
exit 0
|
|
||||||
@@ -3,12 +3,13 @@
|
|||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
|
xmlns:semi="https://irihi.tech/semi"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
x:DataType="vms:StatusBarViewModel"
|
x:DataType="vms:StatusBarViewModel"
|
||||||
RequestedThemeVariant="Default">
|
RequestedThemeVariant="Default">
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
|
<semi:SemiTheme />
|
||||||
<StyleInclude Source="Assets/GlobalStyles.axaml" />
|
<StyleInclude Source="Assets/GlobalStyles.axaml" />
|
||||||
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
|
|
||||||
<StyleInclude Source="avares://Semi.Avalonia.DataGrid/Index.axaml" />
|
<StyleInclude Source="avares://Semi.Avalonia.DataGrid/Index.axaml" />
|
||||||
<StyleInclude Source="avares://DialogHost.Avalonia/Styles.xaml" />
|
<StyleInclude Source="avares://DialogHost.Avalonia/Styles.xaml" />
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
|
|||||||
@@ -71,12 +71,8 @@ public partial class App : Application
|
|||||||
|
|
||||||
private async void MenuExit_Click(object? sender, EventArgs e)
|
private async void MenuExit_Click(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||||
{
|
if (service != null) await service.MyAppExitAsync(true);
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
service?.Shutdown(true);
|
||||||
if (service != null) await service.MyAppExitAsync(false);
|
|
||||||
|
|
||||||
desktop.Shutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,7 @@ namespace v2rayN.Desktop.ViewModels
|
|||||||
{
|
{
|
||||||
ModifyTheme();
|
ModifyTheme();
|
||||||
ModifyFontFamily();
|
ModifyFontFamily();
|
||||||
|
ModifyFontSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BindingUI()
|
private void BindingUI()
|
||||||
@@ -67,11 +68,10 @@ namespace v2rayN.Desktop.ViewModels
|
|||||||
y => y > 0)
|
y => y > 0)
|
||||||
.Subscribe(c =>
|
.Subscribe(c =>
|
||||||
{
|
{
|
||||||
if (CurrentFontSize >= Global.MinFontSize)
|
if (_config.UiItem.CurrentFontSize != CurrentFontSize && CurrentFontSize >= Global.MinFontSize)
|
||||||
{
|
{
|
||||||
_config.UiItem.CurrentFontSize = CurrentFontSize;
|
_config.UiItem.CurrentFontSize = CurrentFontSize;
|
||||||
double size = CurrentFontSize;
|
ModifyFontSize();
|
||||||
ModifyFontSize(size);
|
|
||||||
ConfigHandler.SaveConfig(_config);
|
ConfigHandler.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -100,8 +100,11 @@ namespace v2rayN.Desktop.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ModifyFontSize(double size)
|
private void ModifyFontSize()
|
||||||
{
|
{
|
||||||
|
double size = CurrentFontSize;
|
||||||
|
if (size < Global.MinFontSize) return;
|
||||||
|
|
||||||
Style style = new(x => Selectors.Or(
|
Style style = new(x => Selectors.Or(
|
||||||
x.OfType<Button>(),
|
x.OfType<Button>(),
|
||||||
x.OfType<TextBox>(),
|
x.OfType<TextBox>(),
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="8"
|
Margin="8"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
IsChecked="{Binding IsSelected}" />
|
IsChecked="{Binding IsSelected}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void linkDnsObjectDoc_Click(object? sender, RoutedEventArgs e)
|
private void linkDnsObjectDoc_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
|
ProcUtils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void linkDnsSingboxObjectDoc_Click(object? sender, RoutedEventArgs e)
|
private void linkDnsSingboxObjectDoc_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,6 +80,7 @@
|
|||||||
<MenuItem Header="{x:Static resx:ResUI.menuRegionalPresets}">
|
<MenuItem Header="{x:Static resx:ResUI.menuRegionalPresets}">
|
||||||
<MenuItem x:Name="menuRegionalPresetsDefault" Header="{x:Static resx:ResUI.menuRegionalPresetsDefault}" />
|
<MenuItem x:Name="menuRegionalPresetsDefault" Header="{x:Static resx:ResUI.menuRegionalPresetsDefault}" />
|
||||||
<MenuItem x:Name="menuRegionalPresetsRussia" Header="{x:Static resx:ResUI.menuRegionalPresetsRussia}" />
|
<MenuItem x:Name="menuRegionalPresetsRussia" Header="{x:Static resx:ResUI.menuRegionalPresetsRussia}" />
|
||||||
|
<MenuItem x:Name="menuRegionalPresetsIran" Header="{x:Static resx:ResUI.menuRegionalPresetsIran}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="menuBackupAndRestore" Header="{x:Static resx:ResUI.menuBackupAndRestore}" />
|
<MenuItem x:Name="menuBackupAndRestore" Header="{x:Static resx:ResUI.menuBackupAndRestore}" />
|
||||||
<MenuItem x:Name="menuOpenTheFileLocation" Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
<MenuItem x:Name="menuOpenTheFileLocation" Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.BindCommand(ViewModel, vm => vm.OpenTheFileLocationCmd, v => v.menuOpenTheFileLocation).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.OpenTheFileLocationCmd, v => v.menuOpenTheFileLocation).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RegionalPresetDefaultCmd, v => v.menuRegionalPresetsDefault).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RegionalPresetDefaultCmd, v => v.menuRegionalPresetsDefault).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RegionalPresetRussiaCmd, v => v.menuRegionalPresetsRussia).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RegionalPresetRussiaCmd, v => v.menuRegionalPresetsRussia).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.RegionalPresetIranCmd, v => v.menuRegionalPresetsIran).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
||||||
@@ -133,7 +134,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
this.Title = $"{Utils.GetVersion()}";
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
|
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||||
@@ -222,6 +223,10 @@ namespace v2rayN.Desktop.Views
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.Shutdown:
|
case EViewAction.Shutdown:
|
||||||
|
if (obj != null && _blCloseByUser == false)
|
||||||
|
{
|
||||||
|
_blCloseByUser = (bool)obj;
|
||||||
|
}
|
||||||
StorageUI();
|
StorageUI();
|
||||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
@@ -304,7 +309,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private async void MainWindow_KeyDown(object? sender, KeyEventArgs e)
|
private async void MainWindow_KeyDown(object? sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyModifiers == KeyModifiers.Control)
|
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
|
||||||
{
|
{
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
@@ -329,12 +334,12 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void menuPromotion_Click(object? sender, RoutedEventArgs e)
|
private void menuPromotion_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuSettingsSetUWP_Click(object? sender, RoutedEventArgs e)
|
private void menuSettingsSetUWP_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ScanScreenTaskAsync()
|
public async Task ScanScreenTaskAsync()
|
||||||
@@ -480,7 +485,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
{
|
{
|
||||||
if (sender is MenuItem item)
|
if (sender is MenuItem item)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(item.Tag?.ToString());
|
ProcUtils.ProcessStart(item.Tag?.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("fill fonts error", ex);
|
Logging.SaveLog("GetFonts", ex);
|
||||||
}
|
}
|
||||||
return lstFonts;
|
return lstFonts;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,12 +187,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void lstProfiles_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
private void lstProfiles_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
List<ProfileItemModel> lst = [];
|
ViewModel.SelectedProfiles = lstProfiles.SelectedItems.Cast<ProfileItemModel>().ToList();
|
||||||
foreach (var item in lstProfiles.SelectedItems)
|
|
||||||
{
|
|
||||||
lst.Add((ProfileItemModel)item);
|
|
||||||
}
|
|
||||||
ViewModel.SelectedProfiles = lst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
||||||
@@ -233,7 +228,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void LstProfiles_KeyDown(object? sender, KeyEventArgs e)
|
private void LstProfiles_KeyDown(object? sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyModifiers == KeyModifiers.Control)
|
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
|
||||||
{
|
{
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void linkRuleobjectDoc_Click(object? sender, RoutedEventArgs e)
|
private void linkRuleobjectDoc_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
|
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void RoutingRuleSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
private void RoutingRuleSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyModifiers == KeyModifiers.Control)
|
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.A)
|
if (e.Key == Key.A)
|
||||||
{
|
{
|
||||||
@@ -166,12 +166,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void lstRules_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
private void lstRules_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
List<RulesItemModel> lst = [];
|
ViewModel.SelectedSources = lstRules.SelectedItems.Cast<RulesItemModel>().ToList();
|
||||||
foreach (var item in lstRules.SelectedItems)
|
|
||||||
{
|
|
||||||
lst.Add((RulesItemModel)item);
|
|
||||||
}
|
|
||||||
ViewModel.SelectedSources = lst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LstRules_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
private void LstRules_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
||||||
@@ -208,7 +203,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void linkCustomRulesetPath4Singbox(object? sender, RoutedEventArgs e)
|
private void linkCustomRulesetPath4Singbox(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
|
ProcUtils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void RoutingSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
private void RoutingSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyModifiers == KeyModifiers.Control)
|
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.A)
|
if (e.Key == Key.A)
|
||||||
{
|
{
|
||||||
@@ -107,12 +107,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void lstRoutings_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
private void lstRoutings_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
List<RoutingItemModel> lst = [];
|
ViewModel.SelectedSources = lstRoutings.SelectedItems.Cast<RoutingItemModel>().ToList();
|
||||||
foreach (var item in lstRoutings.SelectedItems)
|
|
||||||
{
|
|
||||||
lst.Add((RoutingItemModel)item);
|
|
||||||
}
|
|
||||||
ViewModel.SelectedSources = lst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LstRoutings_DoubleTapped(object? sender, TappedEventArgs e)
|
private void LstRoutings_DoubleTapped(object? sender, TappedEventArgs e)
|
||||||
@@ -122,12 +117,12 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void linkdomainStrategy_Click(object? sender, RoutedEventArgs e)
|
private void linkdomainStrategy_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/routing.html");
|
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e)
|
private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
||||||
|
|||||||
@@ -82,12 +82,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void LstSubscription_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
private void LstSubscription_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
List<SubItem> lst = [];
|
ViewModel.SelectedSources = lstSubscription.SelectedItems.Cast<SubItem>().ToList();
|
||||||
foreach (var item in lstSubscription.SelectedItems)
|
|
||||||
{
|
|
||||||
lst.Add((SubItem)item);
|
|
||||||
}
|
|
||||||
ViewModel.SelectedSources = lst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuClose_Click(object? sender, RoutedEventArgs e)
|
private void menuClose_Click(object? sender, RoutedEventArgs e)
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.3" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.3" />
|
||||||
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
||||||
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
|
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||||
<PackageReference Include="Semi.Avalonia" Version="11.2.1.2" />
|
<PackageReference Include="Semi.Avalonia" Version="11.2.1.3" />
|
||||||
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.1.2" />
|
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.1.3" />
|
||||||
<PackageReference Include="ReactiveUI" Version="20.1.63" />
|
<PackageReference Include="ReactiveUI" Version="20.1.63" />
|
||||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -42,6 +42,15 @@
|
|||||||
<EmbeddedResource Include="Assets\v2rayN.ico">
|
<EmbeddedResource Include="Assets\v2rayN.ico">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="v2rayN.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="v2rayN2.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
BIN
v2rayN/v2rayN.Desktop/v2rayN.png
Normal file
BIN
v2rayN/v2rayN.Desktop/v2rayN.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
v2rayN/v2rayN.Desktop/v2rayN2.png
Normal file
BIN
v2rayN/v2rayN.Desktop/v2rayN2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -13,6 +13,8 @@ namespace v2rayN
|
|||||||
{
|
{
|
||||||
internal static class WindowsUtils
|
internal static class WindowsUtils
|
||||||
{
|
{
|
||||||
|
private static readonly string _tag = "WindowsUtils";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取剪贴板数
|
/// 获取剪贴板数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -31,7 +33,7 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
}
|
}
|
||||||
return strData;
|
return strData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
private static readonly Lazy<WindowsHandler> instance = new(() => new());
|
private static readonly Lazy<WindowsHandler> instance = new(() => new());
|
||||||
public static WindowsHandler Instance => instance.Value;
|
public static WindowsHandler Instance => instance.Value;
|
||||||
|
private static readonly string _tag = "WindowsHandler";
|
||||||
|
|
||||||
public async Task<Icon> GetNotifyIcon(Config config)
|
public async Task<Icon> GetNotifyIcon(Config config)
|
||||||
{
|
{
|
||||||
@@ -39,7 +40,7 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return Properties.Resources.NotifyIcon1;
|
return Properties.Resources.NotifyIcon1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +90,7 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace v2rayN.ViewModels
|
|||||||
private void RestoreUI()
|
private void RestoreUI()
|
||||||
{
|
{
|
||||||
ModifyTheme();
|
ModifyTheme();
|
||||||
|
ModifyFontSize();
|
||||||
if (!_config.UiItem.ColorPrimaryName.IsNullOrEmpty())
|
if (!_config.UiItem.ColorPrimaryName.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.UiItem.ColorPrimaryName);
|
var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.UiItem.ColorPrimaryName);
|
||||||
@@ -121,14 +122,10 @@ namespace v2rayN.ViewModels
|
|||||||
y => y > 0)
|
y => y > 0)
|
||||||
.Subscribe(c =>
|
.Subscribe(c =>
|
||||||
{
|
{
|
||||||
if (CurrentFontSize >= Global.MinFontSize)
|
if (_config.UiItem.CurrentFontSize != CurrentFontSize)
|
||||||
{
|
{
|
||||||
_config.UiItem.CurrentFontSize = CurrentFontSize;
|
_config.UiItem.CurrentFontSize = CurrentFontSize;
|
||||||
double size = (long)CurrentFontSize;
|
ModifyFontSize();
|
||||||
Application.Current.Resources["StdFontSize"] = size;
|
|
||||||
Application.Current.Resources["StdFontSize1"] = size + 1;
|
|
||||||
Application.Current.Resources["StdFontSize-1"] = size - 1;
|
|
||||||
|
|
||||||
ConfigHandler.SaveConfig(_config);
|
ConfigHandler.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -158,6 +155,16 @@ namespace v2rayN.ViewModels
|
|||||||
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);
|
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ModifyFontSize()
|
||||||
|
{
|
||||||
|
double size = (long)CurrentFontSize;
|
||||||
|
if (size < Global.MinFontSize) return;
|
||||||
|
|
||||||
|
Application.Current.Resources["StdFontSize"] = size;
|
||||||
|
Application.Current.Resources["StdFontSize1"] = size + 1;
|
||||||
|
Application.Current.Resources["StdFontSize-1"] = size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
public void ChangePrimaryColor(System.Windows.Media.Color color)
|
public void ChangePrimaryColor(System.Windows.Media.Color color)
|
||||||
{
|
{
|
||||||
var theme = _paletteHelper.GetTheme();
|
var theme = _paletteHelper.GetTheme();
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
|
|||||||
@@ -705,7 +705,7 @@
|
|||||||
x:Name="txtExtra"
|
x:Name="txtExtra"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
MinLines="6"
|
MinLines="6"
|
||||||
Style="{StaticResource MyOutlinedTextBox}"
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
IsChecked="{Binding IsSelected}" />
|
IsChecked="{Binding IsSelected}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)
|
private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
|
ProcUtils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void linkDnsSingboxObjectDoc_Click(object sender, RoutedEventArgs e)
|
private void linkDnsSingboxObjectDoc_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
||||||
@@ -159,7 +159,7 @@
|
|||||||
Grid.Row="5"
|
Grid.Row="5"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
|
||||||
|
|||||||
@@ -194,6 +194,10 @@
|
|||||||
x:Name="menuRegionalPresetsRussia"
|
x:Name="menuRegionalPresetsRussia"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuRegionalPresetsRussia}" />
|
Header="{x:Static resx:ResUI.menuRegionalPresetsRussia}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuRegionalPresetsIran"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuRegionalPresetsIran}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuBackupAndRestore"
|
x:Name="menuBackupAndRestore"
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ namespace v2rayN.Views
|
|||||||
this.BindCommand(ViewModel, vm => vm.OpenTheFileLocationCmd, v => v.menuOpenTheFileLocation).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.OpenTheFileLocationCmd, v => v.menuOpenTheFileLocation).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RegionalPresetDefaultCmd, v => v.menuRegionalPresetsDefault).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RegionalPresetDefaultCmd, v => v.menuRegionalPresetsDefault).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RegionalPresetRussiaCmd, v => v.menuRegionalPresetsRussia).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RegionalPresetRussiaCmd, v => v.menuRegionalPresetsRussia).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.RegionalPresetIranCmd, v => v.menuRegionalPresetsIran).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
||||||
@@ -307,12 +308,12 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
private void menuPromotion_Click(object sender, RoutedEventArgs e)
|
private void menuPromotion_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
|
private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ScanScreenTaskAsync()
|
private async Task ScanScreenTaskAsync()
|
||||||
@@ -442,7 +443,7 @@ namespace v2rayN.Views
|
|||||||
{
|
{
|
||||||
if (sender is MenuItem item)
|
if (sender is MenuItem item)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(item.Tag.ToString());
|
ProcUtils.ProcessStart(item.Tag.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ namespace v2rayN.Views
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("fill fonts error", ex);
|
Logging.SaveLog("GetFonts", ex);
|
||||||
}
|
}
|
||||||
return lstFonts.OrderBy(t => t).ToList();
|
return lstFonts.OrderBy(t => t).ToList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
private void linkRuleobjectDoc_Click(object sender, RoutedEventArgs e)
|
private void linkRuleobjectDoc_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
|
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
Width="300"
|
Width="300"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource DefTextBox}"
|
Style="{StaticResource DefTextBox}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="600"
|
Width="600"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource DefTextBox}"
|
Style="{StaticResource DefTextBox}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="600"
|
Width="600"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource DefTextBox}"
|
Style="{StaticResource DefTextBox}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="600"
|
Width="600"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource DefTextBox}"
|
Style="{StaticResource DefTextBox}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
private void linkCustomRulesetPath4Singbox(object sender, RoutedEventArgs e)
|
private void linkCustomRulesetPath4Singbox(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
|
ProcUtils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,12 +122,12 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
private void linkdomainStrategy_Click(object sender, System.Windows.RoutedEventArgs e)
|
private void linkdomainStrategy_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/routing.html");
|
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)
|
private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
|
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}"
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}"
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
x:Name="txtMoreUrl"
|
x:Name="txtMoreUrl"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
MinLines="4"
|
MinLines="4"
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
x:Name="txtAutoUpdateInterval"
|
x:Name="txtAutoUpdateInterval"
|
||||||
Width="100"
|
Width="100"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
DockPanel.Dock="Right"
|
DockPanel.Dock="Right"
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
Grid.Row="5"
|
Grid.Row="5"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
Grid.Row="7"
|
Grid.Row="7"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}"
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
@@ -240,7 +240,7 @@
|
|||||||
Width="100"
|
Width="100"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@
|
|||||||
Grid.Row="9"
|
Grid.Row="9"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.LvPrevProfileTip}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.LvPrevProfileTip}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
Grid.Row="10"
|
Grid.Row="10"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.LvPrevProfileTip}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.LvPrevProfileTip}"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
@@ -308,7 +308,7 @@
|
|||||||
Grid.Row="12"
|
Grid.Row="12"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Center"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}"
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
|
<PackageReference Include="MaterialDesignThemes" Version="5.2.0" />
|
||||||
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.2.0" />
|
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.2.0" />
|
||||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />
|
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />
|
||||||
|
|||||||
Reference in New Issue
Block a user