Compare commits

...

12 Commits

Author SHA1 Message Date
62a2558174 Change build scripts 2025-10-25 08:39:53 +03:00
45b6fe4d5a Format build scripts with shfmt 2025-10-25 03:24:28 +03:00
6b8b2d0b1b Make all build scripts executable 2025-10-24 13:36:52 +03:00
2dust
f39bc6d3b0 up 7.15.4 2025-10-17 20:59:27 +08:00
2dust
0c0ecc359b Fix
https://github.com/2dust/v2rayN/issues/8129
2025-10-16 12:18:14 +08:00
2dust
68713e7b77 MB/s 2025-10-15 19:46:10 +08:00
2dust
899b3fc97b up 7.15.3 2025-10-14 19:52:42 +08:00
DHR60
a1490d0ac1 Update singbox_fakeip_filter (#8117) 2025-10-12 09:59:30 +08:00
DHR60
b23f49ffce Remove unnecessary settings (#8107) 2025-10-11 19:22:26 +08:00
2dust
9a9e28e494 Update GlobalHotKeys 2025-10-10 19:25:54 +08:00
2dust
65ee5eb510 Fix,remove NaiveproxyFmt HysteriaFmt ,adjust ClashFmt
https://github.com/2dust/v2rayN/issues/8102
2025-10-10 17:12:45 +08:00
DHR60
1f42d32e1a Fix Freedom Resolver (#8100) 2025-10-10 16:58:18 +08:00
34 changed files with 502 additions and 963 deletions

View File

@@ -9,6 +9,10 @@ end_of_line = crlf
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[*.sh]
end_of_line = lf
indent_size = 2
[*.{yml,yaml}] [*.{yml,yaml}]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
@@ -157,14 +161,14 @@ dotnet_naming_rule.non_field_members_should_be_pascal.symbols = non_field_member
dotnet_naming_rule.non_field_members_should_be_pascal.style = pascal dotnet_naming_rule.non_field_members_should_be_pascal.style = pascal
dotnet_naming_symbols.interface.applicable_kinds = interface dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = * dotnet_naming_symbols.interface.applicable_accessibilities = *
dotnet_naming_symbols.interface.required_modifiers = dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = * dotnet_naming_symbols.types.applicable_accessibilities = *
dotnet_naming_symbols.types.required_modifiers = dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = * dotnet_naming_symbols.non_field_members.applicable_accessibilities = *
dotnet_naming_symbols.non_field_members.required_modifiers = dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_style.pascal.required_prefix = dotnet_naming_style.pascal.required_prefix =
dotnet_naming_style.pascal.required_suffix = dotnet_naming_style.pascal.required_suffix =
dotnet_naming_style.pascal.word_separator = dotnet_naming_style.pascal.word_separator =
dotnet_naming_style.pascal.capitalization = pascal_case dotnet_naming_style.pascal.capitalization = pascal_case

10
package-appimage.sh Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Install deps # Install deps
@@ -17,10 +17,10 @@ cp -rf "$OutputPath64"/* "$APPDIR_X64/usr/lib/v2rayN" || true
[ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/usr/share/pixmaps/v2rayN.png" || true [ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/usr/share/pixmaps/v2rayN.png" || true
[ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/v2rayN.png" || true [ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/v2rayN.png" || true
printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' > "$APPDIR_X64/AppRun" printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' >"$APPDIR_X64/AppRun"
chmod +x "$APPDIR_X64/AppRun" chmod +x "$APPDIR_X64/AppRun"
ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_X64/usr/bin/v2rayN" ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_X64/usr/bin/v2rayN"
cat > "$APPDIR_X64/v2rayN.desktop" <<EOF cat >"$APPDIR_X64/v2rayN.desktop" <<EOF
[Desktop Entry] [Desktop Entry]
Name=v2rayN Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
@@ -43,10 +43,10 @@ cp -rf "$OutputPathArm64"/* "$APPDIR_ARM64/usr/lib/v2rayN" || true
[ -f "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_ARM64/usr/share/pixmaps/v2rayN.png" || true [ -f "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_ARM64/usr/share/pixmaps/v2rayN.png" || true
[ -f "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_ARM64/v2rayN.png" || true [ -f "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_ARM64/v2rayN.png" || true
printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' > "$APPDIR_ARM64/AppRun" printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' >"$APPDIR_ARM64/AppRun"
chmod +x "$APPDIR_ARM64/AppRun" chmod +x "$APPDIR_ARM64/AppRun"
ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_ARM64/usr/bin/v2rayN" ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_ARM64/usr/bin/v2rayN"
cat > "$APPDIR_ARM64/v2rayN.desktop" <<EOF cat >"$APPDIR_ARM64/v2rayN.desktop" <<EOF
[Desktop Entry] [Desktop Entry]
Name=v2rayN Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others

51
package-debian.sh Normal file → Executable file
View File

@@ -1,34 +1,52 @@
#!/bin/bash #!/usr/bin/env bash
set -euo pipefail
Arch="$1" # Root directory = the script's location
OutputPath="$2" SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
Version="$3" cd "$SCRIPT_DIR"
source ./utils.sh
FileName="v2rayN-${Arch}.zip" Arch="linux-64"
wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName" OutputPath="$(mktemp -d)"
7z x $FileName Version="$1"
cp -rf v2rayN-${Arch}/* $OutputPath
PROJ="./v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj"
dotnet clean "${PROJ}" -c Release
sudo rm -rf "$(dirname "$PROJ")/bin/Release/net8.0"
dotnet publish "${PROJ}" -c Release -r "linux-x64" --self-contained -o "$OutputPath"
PROJ="./v2rayN/AmazTool/AmazTool.csproj"
dotnet clean "${PROJ}" -c Release
sudo rm -rf "$(dirname "$PROJ")/bin/Release/net8.0"
dotnet publish "${PROJ}" -c Release -r "linux-x64" --self-contained -p:PublishTrimmed=true -o "$OutputPath"
export RID_DIR="linux-x64"
download_xray "$OutputPath/bin/xray"
download_singbox "$OutputPath/bin/sing_box"
download_geo_assets "$OutputPath"
PackagePath="v2rayN-Package-${Arch}" PackagePath="v2rayN-Package-${Arch}"
mkdir -p "${PackagePath}/DEBIAN" mkdir -p "${PackagePath}/DEBIAN"
mkdir -p "${PackagePath}/opt" mkdir -p "${PackagePath}/opt"
cp -rf $OutputPath "${PackagePath}/opt/v2rayN" cp -rf "$OutputPath" "${PackagePath}/opt/v2rayN"
echo "When this file exists, app will not store configs under this folder" > "${PackagePath}/opt/v2rayN/NotStoreConfigHere.txt" echo "When this file exists, app will not store configs under this folder" >"${PackagePath}/opt/v2rayN/NotStoreConfigHere.txt"
if [ $Arch = "linux-64" ]; then if [ "$Arch" = "linux-64" ]; then
Arch2="amd64" Arch2="amd64"
else else
Arch2="arm64" Arch2="arm64"
fi fi
echo $Arch2 echo $Arch2
# basic # basic
cat >"${PackagePath}/DEBIAN/control" <<-EOF cat >"${PackagePath}/DEBIAN/control" <<-EOF
Package: v2rayN Package: v2rayn-unofficial
Version: $Version Version: $Version
Maintainer: Vlyaii <voronin9032n3@gmail.com>
Architecture: $Arch2 Architecture: $Arch2
Maintainer: https://github.com/2dust/v2rayN Replaces: v2rayN, v2rayn
Depends: desktop-file-utils, xdg-utils Depends: desktop-file-utils, xdg-utils
Breaks: v2rayN, v2rayn
Conflicts: v2rayN, v2rayn
Description: A GUI client for Windows and Linux, support Xray core and sing-box-core and others Description: A GUI client for Windows and Linux, support Xray core and sing-box-core and others
EOF EOF
@@ -65,5 +83,6 @@ sudo chmod 755 "${PackagePath}/opt/v2rayN/v2rayN" 2>/dev/null || true
sudo chmod 755 "${PackagePath}/opt/v2rayN/AmazTool" 2>/dev/null || true sudo chmod 755 "${PackagePath}/opt/v2rayN/AmazTool" 2>/dev/null || true
# build deb package # build deb package
sudo dpkg-deb -Zxz --build $PackagePath sudo dpkg-deb -Zzstd --build "$PackagePath"
sudo mv "${PackagePath}.deb" "v2rayN-${Arch}.deb" sudo mv "${PackagePath}.deb" "v2rayN-${Arch}.deb"
sudo rm -rf "$OutputPath"

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
Arch="$1" Arch="$1"
OutputPath="$2" OutputPath="$2"
@@ -13,7 +13,7 @@ PackagePath="v2rayN-Package-${Arch}"
mkdir -p "$PackagePath/v2rayN.app/Contents/Resources" mkdir -p "$PackagePath/v2rayN.app/Contents/Resources"
cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS" cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS"
cp -f "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN.icns" "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns" cp -f "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN.icns" "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt" 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" chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN"
cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF
@@ -48,11 +48,11 @@ cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF
EOF EOF
create-dmg \ create-dmg \
--volname "v2rayN Installer" \ --volname "v2rayN Installer" \
--window-size 700 420 \ --window-size 700 420 \
--icon-size 100 \ --icon-size 100 \
--icon "v2rayN.app" 160 185 \ --icon "v2rayN.app" 160 185 \
--hide-extension "v2rayN.app" \ --hide-extension "v2rayN.app" \
--app-drop-link 500 185 \ --app-drop-link 500 185 \
"v2rayN-${Arch}.dmg" \ "v2rayN-${Arch}.dmg" \
"$PackagePath/v2rayN.app" "$PackagePath/v2rayN.app"

4
package-release-zip.sh Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
Arch="$1" Arch="$1"
OutputPath="$2" OutputPath="$2"
@@ -12,4 +12,4 @@ ZipPath64="./$OutputArch"
mkdir $ZipPath64 mkdir $ZipPath64
cp -rf $OutputPath "$ZipPath64/$OutputArch" cp -rf $OutputPath "$ZipPath64/$OutputArch"
7z a -tZip $FileName "$ZipPath64/$OutputArch" -mx1 7z a -tZip $FileName "$ZipPath64/$OutputArch" -mx1

657
package-rhel.sh Normal file → Executable file
View File

@@ -1,18 +1,18 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# == Require Red Hat Enterprise Linux/FedoraLinux/RockyLinux/AlmaLinux/CentOS OR Ubuntu/Debian == # == Require Red Hat Enterprise Linux/FedoraLinux/RockyLinux/AlmaLinux/CentOS OR Ubuntu ==
if [[ -r /etc/os-release ]]; then if [[ -r /etc/os-release ]]; then
. /etc/os-release source /etc/os-release
case "$ID" in case "$ID" in
rhel|rocky|almalinux|fedora|centos|ubuntu|debian) rhel | rocky | almalinux | fedora | centos | ubuntu)
echo "[OK] Detected supported system: $NAME $VERSION_ID" echo "[OK] Detected supported system: $NAME $VERSION_ID"
;; ;;
*) *)
echo "[ERROR] Unsupported system: $NAME ($ID)." echo "[ERROR] Unsupported system: $NAME ($ID)."
echo "This script only supports Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS or Ubuntu/Debian." echo "This script only supports Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS or Ubuntu."
exit 1 exit 1
;; ;;
esac esac
else else
echo "[ERROR] Cannot detect system (missing /etc/os-release)." echo "[ERROR] Cannot detect system (missing /etc/os-release)."
@@ -20,12 +20,9 @@ else
fi fi
# ===== Config & Parse arguments ========================================================= # ===== Config & Parse arguments =========================================================
VERSION_ARG="${1:-}" # Pass version number like 7.13.8, or leave empty VERSION_ARG="${1:-}" # Pass version number like 7.13.8, or leave empty
WITH_CORE="both" # Default: bundle both xray+sing-box WITH_CORE="both" # Default: bundle both xray+sing-box
AUTOSTART=0 # 1 = enable system-wide autostart (/etc/xdg/autostart) ARCH_OVERRIDE="" # --arch x64|arm64|all (optional compile target)
FORCE_NETCORE=0 # --netcore => skip archive bundle, use separate downloads
ARCH_OVERRIDE="" # --arch x64|arm64|all (optional compile target)
BUILD_FROM="" # --buildfrom 1|2|3 to select channel non-interactively
# If the first argument starts with --, do not treat it as a version number # If the first argument starts with --, do not treat it as a version number
if [[ "${VERSION_ARG:-}" == --* ]]; then if [[ "${VERSION_ARG:-}" == --* ]]; then
@@ -37,97 +34,86 @@ if [[ -n "${VERSION_ARG:-}" ]]; then shift || true; fi
# Parse remaining optional arguments # Parse remaining optional arguments
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
--with-core) WITH_CORE="${2:-both}"; shift 2;; --with-core)
--autostart) AUTOSTART=1; shift;; WITH_CORE="${2:-both}"
--xray-ver) XRAY_VER="${2:-}"; shift 2;; shift 2
--singbox-ver) SING_VER="${2:-}"; shift 2;; ;;
--netcore) FORCE_NETCORE=1; shift;; --xray-ver)
--arch) ARCH_OVERRIDE="${2:-}"; shift 2;; XRAY_VER="${2:-}"
--buildfrom) BUILD_FROM="${2:-}"; shift 2;; shift 2
*) ;;
if [[ -z "${VERSION_ARG:-}" ]]; then VERSION_ARG="$1"; fi --singbox-ver)
shift;; SING_VER="${2:-}"
shift 2
;;
--arch)
ARCH_OVERRIDE="${2:-}"
shift 2
;;
--release)
RPM_RELEASE="${2:-}"
shift 2
;;
*)
if [[ -z "${VERSION_ARG:-}" ]]; then VERSION_ARG="$1"; fi
shift
;;
esac esac
done done
# Conflict: version number AND --buildfrom cannot be used together if [[ -z "${RPM_RELEASE:-}" ]]; then
if [[ -n "${VERSION_ARG:-}" && -n "${BUILD_FROM:-}" ]]; then echo "--release is required"
echo "[ERROR] You cannot specify both an explicit version and --buildfrom at the same time."
echo " Provide either a version (e.g. 7.14.0) OR --buildfrom 1|2|3."
exit 1 exit 1
fi fi
# ===== Environment check + Dependencies ======================================== # ===== Environment check + Dependencies ========================================
host_arch="$(uname -m)" host_arch="$(uname -m)"
[[ "$host_arch" == "aarch64" || "$host_arch" == "x86_64" ]] || { echo "Only supports aarch64 / x86_64"; exit 1; } if ! [[ "$host_arch" == "aarch64" || "$host_arch" == "x86_64" ]]; then
echo "Only supports aarch64 / x86_64"
exit 1
fi
install_ok=0 install_ok=0
case "$ID" in case "$ID" in
# ------------------------------ RHEL family (UNCHANGED) ------------------------------ # ------------------------------ RHEL family (UNCHANGED) ------------------------------
rhel|rocky|almalinux|centos) rhel | rocky | almalinux | centos)
if command -v dnf >/dev/null 2>&1; then if command -v dnf >/dev/null 2>&1; then
sudo dnf -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync || \ sudo dnf -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync ||
sudo dnf -y install dotnet-sdk rpm-build rpmdevtools curl unzip tar rsync sudo dnf -y install dotnet-sdk rpm-build rpmdevtools curl unzip tar rsync
install_ok=1 install_ok=1
elif command -v yum >/dev/null 2>&1; then elif command -v yum >/dev/null 2>&1; then
sudo yum -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync || \ sudo yum -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync ||
sudo yum -y install dotnet-sdk rpm-build rpmdevtools curl unzip tar rsync sudo yum -y install dotnet-sdk rpm-build rpmdevtools curl unzip tar rsync
install_ok=1
fi
;;
# ------------------------------ Ubuntu ----------------------------------------------
ubuntu)
sudo apt-get update
# Ensure 'universe' (Ubuntu) to get 'rpm'
if ! apt-cache policy | grep -q '^500 .*ubuntu.com/ubuntu.* universe'; then
sudo apt-get -y install software-properties-common || true
sudo add-apt-repository -y universe || true
sudo apt-get update
fi
# Base tools + rpm (provides rpmbuild)
sudo apt-get -y install curl unzip tar rsync rpm || true
# Cross-arch binutils so strip matches target arch + objdump for brp scripts
sudo apt-get -y install binutils binutils-x86-64-linux-gnu binutils-aarch64-linux-gnu || true
# rpmbuild presence check
if ! command -v rpmbuild >/dev/null 2>&1; then
echo "[ERROR] 'rpmbuild' not found after installing 'rpm'."
echo " Please ensure the 'rpm' package is available from your repos (universe on Ubuntu)."
exit 1
fi
# .NET SDK 8 (best effort via apt)
if ! command -v dotnet >/dev/null 2>&1; then
sudo apt-get -y install dotnet-sdk-8.0 || true
sudo apt-get -y install dotnet-sdk-8 || true
sudo apt-get -y install dotnet-sdk || true
fi
install_ok=1 install_ok=1
;; fi
# ------------------------------ Debian (KEEP, with local dotnet install) ------------ ;;
debian) # ------------------------------ Ubuntu ----------------------------------------------
ubuntu)
sudo apt-get update
# Ensure 'universe' (Ubuntu) to get 'rpm'
if ! apt-cache policy | grep -q '^500 .*ubuntu.com/ubuntu.* universe'; then
sudo apt-get -y install software-properties-common || true
sudo add-apt-repository -y universe || true
sudo apt-get update sudo apt-get update
# Base tools + rpm (provides rpmbuild on Debian) + objdump/strip fi
sudo apt-get -y install curl unzip tar rsync rpm binutils || true # Base tools + rpm (provides rpmbuild)
# rpmbuild presence check sudo apt-get -y install curl unzip tar rsync rpm || true
if ! command -v rpmbuild >/dev/null 2>&1; then # Cross-arch binutils so strip matches target arch + objdump for brp scripts
echo "[ERROR] 'rpmbuild' not found after installing 'rpm'." sudo apt-get -y install binutils binutils-x86-64-linux-gnu binutils-aarch64-linux-gnu || true
echo " Please ensure 'rpm' is available from Debian repos." # rpmbuild presence check
exit 1 if ! command -v rpmbuild >/dev/null 2>&1; then
fi echo "[ERROR] 'rpmbuild' not found after installing 'rpm'."
# Try apt for dotnet; fallback to official installer into $HOME/.dotnet echo " Please ensure the 'rpm' package is available from your repos (universe on Ubuntu)."
if ! command -v dotnet >/dev/null 2>&1; then exit 1
echo "[INFO] 'dotnet' not found. Installing .NET 8 SDK locally to \$HOME/.dotnet ..." fi
tmp="$(mktemp -d)"; trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN # .NET SDK 8 (best effort via apt)
curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$tmp/dotnet-install.sh" if ! command -v dotnet >/dev/null 2>&1; then
bash "$tmp/dotnet-install.sh" --channel 8.0 --install-dir "$HOME/.dotnet" sudo apt-get -y install dotnet-sdk-8.0 || true
export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH" sudo apt-get -y install dotnet-sdk-8 || true
export DOTNET_ROOT="$HOME/.dotnet" sudo apt-get -y install dotnet-sdk || true
if ! command -v dotnet >/dev/null 2>&1; then fi
echo "[ERROR] dotnet installation failed." install_ok=1
exit 1 ;;
fi
fi
install_ok=1
;;
esac esac
if [[ "$install_ok" -ne 1 ]]; then if [[ "$install_ok" -ne 1 ]]; then
@@ -141,6 +127,8 @@ command -v curl >/dev/null
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR" cd "$SCRIPT_DIR"
source ./utils.sh
# Git submodules (best effort) # Git submodules (best effort)
if [[ -f .gitmodules ]]; then if [[ -f .gitmodules ]]; then
git submodule sync --recursive || true git submodule sync --recursive || true
@@ -152,348 +140,16 @@ PROJECT="v2rayN.Desktop/v2rayN.Desktop.csproj"
if [[ ! -f "$PROJECT" ]]; then if [[ ! -f "$PROJECT" ]]; then
PROJECT="$(find . -maxdepth 3 -name 'v2rayN.Desktop.csproj' | head -n1 || true)" PROJECT="$(find . -maxdepth 3 -name 'v2rayN.Desktop.csproj' | head -n1 || true)"
fi fi
[[ -f "$PROJECT" ]] || { echo "v2rayN.Desktop.csproj not found"; exit 1; } [[ -f "$PROJECT" ]] || {
echo "v2rayN.Desktop.csproj not found"
# ===== Resolve GUI version & auto checkout ============================================ exit 1
VERSION=""
choose_channel() {
# If --buildfrom provided, map it directly and skip interaction.
if [[ -n "${BUILD_FROM:-}" ]]; then
case "$BUILD_FROM" in
1) echo "latest"; return 0;;
2) echo "prerelease"; return 0;;
3) echo "keep"; return 0;;
*) echo "[ERROR] Invalid --buildfrom value: ${BUILD_FROM}. Use 1|2|3." >&2; exit 1;;
esac
fi
# Print menu to stderr and read from /dev/tty so stdout only carries the token.
local ch="latest" sel=""
if [[ -t 0 ]]; then
echo "[?] Choose v2rayN release channel:" >&2
echo " 1) Latest (stable) [default]" >&2
echo " 2) Pre-release (preview)" >&2
echo " 3) Keep current (do nothing)" >&2
printf "Enter 1, 2 or 3 [default 1]: " >&2
if read -r sel </dev/tty; then
case "${sel:-}" in
2) ch="prerelease" ;;
3) ch="keep" ;;
*) ch="latest" ;;
esac
else
ch="latest"
fi
else
ch="latest"
fi
echo "$ch"
} }
get_latest_tag_latest() { VERSION="$VERSION_ARG"
# Resolve /releases/latest → tag_name
curl -fsSL "https://api.github.com/repos/2dust/v2rayN/releases/latest" \
| grep -Eo '"tag_name":\s*"v?[^"]+"' \
| head -n1 \
| sed -E 's/.*"tag_name":\s*"v?([^"]+)".*/\1/'
}
get_latest_tag_prerelease() {
# Resolve newest prerelease=true tag; prefer jq, fallback to sed/grep (no awk)
local json tag
json="$(curl -fsSL "https://api.github.com/repos/2dust/v2rayN/releases?per_page=20")" || return 1
# 1) Use jq if present
if command -v jq >/dev/null 2>&1; then
tag="$(printf '%s' "$json" \
| jq -r '[.[] | select(.prerelease==true)][0].tag_name' 2>/dev/null \
| sed 's/^v//')" || true
fi
# 2) Fallback to sed/grep only
if [[ -z "${tag:-}" || "${tag:-}" == "null" ]]; then
tag="$(printf '%s' "$json" \
| tr '\n' ' ' \
| sed 's/},[[:space:]]*{/\n/g' \
| grep -m1 -E '"prerelease"[[:space:]]*:[[:space:]]*true' \
| grep -Eo '"tag_name"[[:space:]]*:[[:space:]]*"v?[^"]+"' \
| head -n1 \
| sed -E 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v?([^"]+)".*/\1/')" || true
fi
[[ -n "${tag:-}" && "${tag:-}" != "null" ]] || return 1
printf '%s\n' "$tag"
}
git_try_checkout() {
# Try a series of refs and checkout when found.
local want="$1" ref=""
if git rev-parse --git-dir >/dev/null 2>&1; then
git fetch --tags --force --prune --depth=1 || true
if git rev-parse "refs/tags/v${want}" >/dev/null 2>&1; then
ref="v${want}"
elif git rev-parse "refs/tags/${want}" >/dev/null 2>&1; then
ref="${want}"
elif git rev-parse --verify "${want}" >/dev/null 2>&1; then
ref="${want}"
fi
if [[ -n "$ref" ]]; then
echo "[OK] Found ref '${ref}', checking out..."
git checkout -f "${ref}"
if [[ -f .gitmodules ]]; then
git submodule sync --recursive || true
git submodule update --init --recursive || true
fi
return 0
fi
fi
return 1
}
if git rev-parse --git-dir >/dev/null 2>&1; then
if [[ -n "${VERSION_ARG:-}" ]]; then
echo "[*] Trying to switch v2rayN repo to version: ${VERSION_ARG}"
if git_try_checkout "${VERSION_ARG#v}"; then
VERSION="${VERSION_ARG#v}"
else
echo "[WARN] Tag '${VERSION_ARG}' not found."
ch="$(choose_channel)"
if [[ "$ch" == "keep" ]]; then
echo "[*] Keep current repository state (no checkout)."
if git describe --tags --abbrev=0 >/dev/null 2>&1; then
VERSION="$(git describe --tags --abbrev=0)"
else
VERSION="0.0.0+git"
fi
VERSION="${VERSION#v}"
else
echo "[*] Resolving ${ch} tag from GitHub releases..."
tag=""
if [[ "$ch" == "prerelease" ]]; then
tag="$(get_latest_tag_prerelease || true)"
if [[ -z "$tag" ]]; then
echo "[WARN] Failed to resolve prerelease tag, falling back to latest."
tag="$(get_latest_tag_latest || true)"
fi
else
tag="$(get_latest_tag_latest || true)"
fi
[[ -n "$tag" ]] || { echo "[ERROR] Failed to resolve latest tag for channel '${ch}'."; exit 1; }
echo "[*] Latest tag for '${ch}': ${tag}"
git_try_checkout "$tag" || { echo "[ERROR] Failed to checkout '${tag}'."; exit 1; }
VERSION="${tag#v}"
fi
fi
else
ch="$(choose_channel)"
if [[ "$ch" == "keep" ]]; then
echo "[*] Keep current repository state (no checkout)."
if git describe --tags --abbrev=0 >/dev/null 2>&1; then
VERSION="$(git describe --tags --abbrev=0)"
else
VERSION="0.0.0+git"
fi
VERSION="${VERSION#v}"
else
echo "[*] Resolving ${ch} tag from GitHub releases..."
tag=""
if [[ "$ch" == "prerelease" ]]; then
tag="$(get_latest_tag_prerelease || true)"
if [[ -z "$tag" ]]; then
echo "[WARN] Failed to resolve prerelease tag, falling back to latest."
tag="$(get_latest_tag_latest || true)"
fi
else
tag="$(get_latest_tag_latest || true)"
fi
[[ -n "$tag" ]] || { echo "[ERROR] Failed to resolve latest tag for channel '${ch}'."; exit 1; }
echo "[*] Latest tag for '${ch}': ${tag}"
git_try_checkout "$tag" || { echo "[ERROR] Failed to checkout '${tag}'."; exit 1; }
VERSION="${tag#v}"
fi
fi
else
echo "[WARN] Current directory is not a git repo; cannot checkout version. Proceeding on current tree."
VERSION="${VERSION_ARG:-}"
if [[ -z "$VERSION" ]]; then
if git describe --tags --abbrev=0 >/dev/null 2>&1; then
VERSION="$(git describe --tags --abbrev=0)"
else
VERSION="0.0.0+git"
fi
fi
VERSION="${VERSION#v}"
fi
echo "[*] GUI version resolved as: ${VERSION}"
# ===== Helpers for core/rules download (use RID_DIR for arch sync) =====================
download_xray() {
# Download Xray core and install to outdir/xray
local outdir="$1" ver="${XRAY_VER:-}" url tmp zipname="xray.zip"
mkdir -p "$outdir"
if [[ -n "${XRAY_VER:-}" ]]; then ver="${XRAY_VER}"; fi
if [[ -z "$ver" ]]; then
ver="$(curl -fsSL https://api.github.com/repos/XTLS/Xray-core/releases/latest \
| grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true
fi
[[ -n "$ver" ]] || { echo "[xray] Failed to get version"; return 1; }
if [[ "$RID_DIR" == "linux-arm64" ]]; then
url="https://github.com/XTLS/Xray-core/releases/download/v${ver}/Xray-linux-arm64-v8a.zip"
else
url="https://github.com/XTLS/Xray-core/releases/download/v${ver}/Xray-linux-64.zip"
fi
echo "[+] Download xray: $url"
tmp="$(mktemp -d)"; trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN
curl -fL "$url" -o "$tmp/$zipname"
unzip -q "$tmp/$zipname" -d "$tmp"
install -Dm755 "$tmp/xray" "$outdir/xray"
}
download_singbox() {
# Download sing-box core and install to outdir/sing-box
local outdir="$1" ver="${SING_VER:-}" url tmp tarname="singbox.tar.gz" bin
mkdir -p "$outdir"
if [[ -n "${SING_VER:-}" ]]; then ver="${SING_VER}"; fi
if [[ -z "$ver" ]]; then
ver="$(curl -fsSL https://api.github.com/repos/SagerNet/sing-box/releases/latest \
| grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true
fi
[[ -n "$ver" ]] || { echo "[sing-box] Failed to get version"; return 1; }
if [[ "$RID_DIR" == "linux-arm64" ]]; then
url="https://github.com/SagerNet/sing-box/releases/download/v${ver}/sing-box-${ver}-linux-arm64.tar.gz"
else
url="https://github.com/SagerNet/sing-box/releases/download/v${ver}/sing-box-${ver}-linux-amd64.tar.gz"
fi
echo "[+] Download sing-box: $url"
tmp="$(mktemp -d)"; trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN
curl -fL "$url" -o "$tmp/$tarname"
tar -C "$tmp" -xzf "$tmp/$tarname"
bin="$(find "$tmp" -type f -name 'sing-box' | head -n1 || true)"
[[ -n "$bin" ]] || { echo "[!] sing-box unpack failed"; return 1; }
install -Dm755 "$bin" "$outdir/sing-box"
}
# ---- NEW: download_mihomo (REQUIRED in --netcore mode) ----
download_mihomo() {
# Download mihomo into outroot/bin/mihomo/mihomo
local outroot="$1"
local url=""
if [[ "$RID_DIR" == "linux-arm64" ]]; then
url="https://raw.githubusercontent.com/2dust/v2rayN-core-bin/refs/heads/master/v2rayN-linux-arm64/bin/mihomo/mihomo"
else
url="https://raw.githubusercontent.com/2dust/v2rayN-core-bin/refs/heads/master/v2rayN-linux-64/bin/mihomo/mihomo"
fi
echo "[+] Download mihomo: $url"
mkdir -p "$outroot/bin/mihomo"
curl -fL "$url" -o "$outroot/bin/mihomo/mihomo"
chmod +x "$outroot/bin/mihomo/mihomo" || true
}
# Move geo files to a unified path: outroot/bin
unify_geo_layout() {
local outroot="$1"
mkdir -p "$outroot/bin"
local names=( \
"geosite.dat" \
"geoip.dat" \
"geoip-only-cn-private.dat" \
"Country.mmdb" \
"geoip.metadb" \
)
for n in "${names[@]}"; do
# If file exists under bin/xray/, move it up to bin/
if [[ -f "$outroot/bin/xray/$n" ]]; then
mv -f "$outroot/bin/xray/$n" "$outroot/bin/$n"
fi
# If file already in bin/, leave it as-is
if [[ -f "$outroot/bin/$n" ]]; then
:
fi
done
}
# Download geo/rule assets; then unify to bin/
download_geo_assets() {
local outroot="$1"
local bin_dir="$outroot/bin"
local srss_dir="$bin_dir/srss"
mkdir -p "$bin_dir" "$srss_dir"
echo "[+] Download Xray Geo to ${bin_dir}"
curl -fsSL -o "$bin_dir/geosite.dat" \
"https://github.com/Loyalsoldier/V2ray-rules-dat/releases/latest/download/geosite.dat"
curl -fsSL -o "$bin_dir/geoip.dat" \
"https://github.com/Loyalsoldier/V2ray-rules-dat/releases/latest/download/geoip.dat"
curl -fsSL -o "$bin_dir/geoip-only-cn-private.dat" \
"https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat"
curl -fsSL -o "$bin_dir/Country.mmdb" \
"https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb"
echo "[+] Download sing-box rule DB & rule-sets"
curl -fsSL -o "$bin_dir/geoip.metadb" \
"https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geoip.metadb" || true
for f in \
geoip-private.srs geoip-cn.srs geoip-facebook.srs geoip-fastly.srs \
geoip-google.srs geoip-netflix.srs geoip-telegram.srs geoip-twitter.srs; do
curl -fsSL -o "$srss_dir/$f" \
"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-geoip/$f" || true
done
for f in \
geosite-cn.srs geosite-gfw.srs geosite-greatfire.srs \
geosite-geolocation-cn.srs geosite-category-ads-all.srs geosite-private.srs; do
curl -fsSL -o "$srss_dir/$f" \
"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-geosite/$f" || true
done
# Unify to bin/
unify_geo_layout "$outroot"
}
# Prefer the prebuilt v2rayN core bundle; then unify geo layout
download_v2rayn_bundle() {
local outroot="$1"
local url=""
if [[ "$RID_DIR" == "linux-arm64" ]]; then
url="https://raw.githubusercontent.com/2dust/v2rayN-core-bin/refs/heads/master/v2rayN-linux-arm64.zip"
else
url="https://raw.githubusercontent.com/2dust/v2rayN-core-bin/refs/heads/master/v2rayN-linux-64.zip"
fi
echo "[+] Try v2rayN bundle archive: $url"
local tmp zipname
tmp="$(mktemp -d)"; zipname="$tmp/v2rayn.zip"
curl -fL "$url" -o "$zipname" || { echo "[!] Bundle download failed"; return 1; }
unzip -q "$zipname" -d "$tmp" || { echo "[!] Bundle unzip failed"; return 1; }
if [[ -d "$tmp/bin" ]]; then
mkdir -p "$outroot/bin"
rsync -a "$tmp/bin/" "$outroot/bin/"
else
rsync -a "$tmp/" "$outroot/"
fi
rm -f "$outroot/v2rayn.zip" 2>/dev/null || true
# keep mihomo
# find "$outroot" -type d -name "mihomo" -prune -exec rm -rf {} + 2>/dev/null || true
local nested_dir
nested_dir="$(find "$outroot" -maxdepth 1 -type d -name 'v2rayN-linux-*' | head -n1 || true)"
if [[ -n "${nested_dir:-}" && -d "$nested_dir/bin" ]]; then
mkdir -p "$outroot/bin"
rsync -a "$nested_dir/bin/" "$outroot/bin/"
rm -rf "$nested_dir"
fi
# Unify to bin/
unify_geo_layout "$outroot"
echo "[+] Bundle extracted to $outroot"
}
# ===== Build results collection for --arch all ======================================== # ===== Build results collection for --arch all ========================================
BUILT_RPMS=() # Will collect absolute paths of built RPMs BUILT_RPMS=() # Will collect absolute paths of built RPMs
BUILT_ALL=0 # Flag to know if we should print the final summary BUILT_ALL=0 # Flag to know if we should print the final summary
# ===== Build (single-arch) function ==================================================== # ===== Build (single-arch) function ====================================================
build_for_arch() { build_for_arch() {
@@ -501,9 +157,20 @@ build_for_arch() {
local short="$1" local short="$1"
local rid rpm_target archdir local rid rpm_target archdir
case "$short" in case "$short" in
x64) rid="linux-x64"; rpm_target="x86_64"; archdir="x86_64" ;; x64)
arm64) rid="linux-arm64"; rpm_target="aarch64"; archdir="aarch64" ;; rid="linux-x64"
*) echo "[ERROR] Unknown arch '$short' (use x64|arm64)"; return 1;; rpm_target="x86_64"
archdir="x86_64"
;;
arm64)
rid="linux-arm64"
rpm_target="aarch64"
archdir="aarch64"
;;
*)
echo "[ERROR] Unknown arch '$short' (use x64|arm64)"
return 1
;;
esac esac
echo "[*] Building for target: $short (RID=$rid, RPM --target $rpm_target)" echo "[*] Building for target: $short (RID=$rid, RPM --target $rpm_target)"
@@ -515,6 +182,7 @@ build_for_arch() {
dotnet restore "$PROJECT" dotnet restore "$PROJECT"
dotnet publish "$PROJECT" \ dotnet publish "$PROJECT" \
-c Release -r "$rid" \ -c Release -r "$rid" \
--sc \
-p:PublishSingleFile=false \ -p:PublishSingleFile=false \
-p:SelfContained=true \ -p:SelfContained=true \
-p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeNativeLibrariesForSelfExtract=true
@@ -563,31 +231,13 @@ build_for_arch() {
mkdir -p "$WORKDIR/$PKGROOT/bin/xray" "$WORKDIR/$PKGROOT/bin/sing_box" mkdir -p "$WORKDIR/$PKGROOT/bin/xray" "$WORKDIR/$PKGROOT/bin/sing_box"
# Bundle / cores per-arch # Bundle / cores per-arch
if [[ "$FORCE_NETCORE" -eq 0 ]]; then if [[ "$WITH_CORE" == "xray" || "$WITH_CORE" == "both" ]]; then
if download_v2rayn_bundle "$WORKDIR/$PKGROOT"; then download_xray "$WORKDIR/$PKGROOT/bin/xray" || echo "[!] xray download failed (skipped)"
echo "[*] Using v2rayN bundle archive."
else
echo "[*] Bundle failed, fallback to separate core + rules."
if [[ "$WITH_CORE" == "xray" || "$WITH_CORE" == "both" ]]; then
download_xray "$WORKDIR/$PKGROOT/bin/xray" || echo "[!] xray download failed (skipped)"
fi
if [[ "$WITH_CORE" == "sing-box" || "$WITH_CORE" == "both" ]]; then
download_singbox "$WORKDIR/$PKGROOT/bin/sing_box" || echo "[!] sing-box download failed (skipped)"
fi
download_geo_assets "$WORKDIR/$PKGROOT" || echo "[!] Geo rules download failed (skipped)"
fi
else
echo "[*] --netcore specified: use separate core + rules."
if [[ "$WITH_CORE" == "xray" || "$WITH_CORE" == "both" ]]; then
download_xray "$WORKDIR/$PKGROOT/bin/xray" || echo "[!] xray download failed (skipped)"
fi
if [[ "$WITH_CORE" == "sing-box" || "$WITH_CORE" == "both" ]]; then
download_singbox "$WORKDIR/$PKGROOT/bin/sing_box" || echo "[!] sing-box download failed (skipped)"
fi
download_geo_assets "$WORKDIR/$PKGROOT" || echo "[!] Geo rules download failed (skipped)"
# ---- REQUIRED: always fetch mihomo in netcore mode, per-arch ----
download_mihomo "$WORKDIR/$PKGROOT" || echo "[!] mihomo download failed (skipped)"
fi fi
if [[ "$WITH_CORE" == "sing-box" || "$WITH_CORE" == "both" ]]; then
download_singbox "$WORKDIR/$PKGROOT/bin/sing_box" || echo "[!] sing-box download failed (skipped)"
fi
download_geo_assets "$WORKDIR/$PKGROOT" || echo "[!] Geo rules download failed (skipped)"
# Tarball # Tarball
mkdir -p "$SOURCEDIR" mkdir -p "$SOURCEDIR"
@@ -596,19 +246,19 @@ build_for_arch() {
# SPEC # SPEC
local SPECFILE="$SPECDIR/v2rayN.spec" local SPECFILE="$SPECDIR/v2rayN.spec"
mkdir -p "$SPECDIR" mkdir -p "$SPECDIR"
cat > "$SPECFILE" <<'SPEC' cat >"$SPECFILE" <<'SPEC'
%global debug_package %{nil} %global debug_package %{nil}
%undefine _debuginfo_subpackages %undefine _debuginfo_subpackages
%undefine _debugsource_packages %undefine _debugsource_packages
# Ignore outdated LTTng dependencies incorrectly reported by the .NET runtime (to avoid installation failures) # Ignore outdated LTTng dependencies incorrectly reported by the .NET runtime (to avoid installation failures)
%global __requires_exclude ^liblttng-ust\.so\..*$ %global __requires_exclude ^liblttng-ust\.so\..*$
Name: v2rayN Name: v2rayn-unofficial
Version: __VERSION__ Version: __VERSION__
Release: 1%{?dist} Release: __RELEASE__
Summary: v2rayN (Avalonia) GUI client for Linux (x86_64/aarch64) Summary: v2rayN (Avalonia) GUI client for Linux (x86_64/aarch64)
License: GPL-3.0-only License: GPL-3.0-only
URL: https://github.com/2dust/v2rayN URL: https://git.vlyaii.ru/voronin9032/v2rayN
BugURL: https://github.com/2dust/v2rayN/issues BugURL: https://github.com/2dust/v2rayN/issues
ExclusiveArch: aarch64 x86_64 ExclusiveArch: aarch64 x86_64
Source0: __PKGROOT__.tar.gz Source0: __PKGROOT__.tar.gz
@@ -617,6 +267,9 @@ Source0: __PKGROOT__.tar.gz
Requires: libX11, libXrandr, libXcursor, libXi, libXext, libxcb, libXrender, libXfixes, libXinerama, libxkbcommon Requires: libX11, libXrandr, libXcursor, libXi, libXext, libxcb, libXrender, libXfixes, libXinerama, libxkbcommon
Requires: fontconfig, freetype, cairo, pango, mesa-libEGL, mesa-libGL, xdg-utils Requires: fontconfig, freetype, cairo, pango, mesa-libEGL, mesa-libGL, xdg-utils
Conflicts: v2rayN
Obsoletes: v2rayN
%description %description
v2rayN Linux for Red Hat Enterprise Linux v2rayN Linux for Red Hat Enterprise Linux
Support vless / vmess / Trojan / http / socks / Anytls / Hysteria2 / Shadowsocks / tuic / WireGuard Support vless / vmess / Trojan / http / socks / Anytls / Hysteria2 / Shadowsocks / tuic / WireGuard
@@ -689,41 +342,9 @@ fi
%{_datadir}/icons/hicolor/256x256/apps/v2rayn.png %{_datadir}/icons/hicolor/256x256/apps/v2rayn.png
SPEC SPEC
# Autostart injection (inside %install) and %files entry
if [[ "$AUTOSTART" -eq 1 ]]; then
awk '
BEGIN{ins=0}
/^%post$/ && !ins {
print "# --- Autostart (.desktop) ---"
print "install -dm0755 %{buildroot}/etc/xdg/autostart"
print "cat > %{buildroot}/etc/xdg/autostart/v2rayn.desktop << '\''EOF'\''"
print "[Desktop Entry]"
print "Type=Application"
print "Name=v2rayN (Autostart)"
print "Exec=v2rayn"
print "X-GNOME-Autostart-enabled=true"
print "NoDisplay=false"
print "EOF"
ins=1
}
{print}
' "$SPECFILE" > "${SPECFILE}.tmp" && mv "${SPECFILE}.tmp" "$SPECFILE"
awk '
BEGIN{infiles=0; done=0}
/^%files$/ {infiles=1}
infiles && done==0 && $0 ~ /%{_datadir}\/icons\/hicolor\/256x256\/apps\/v2rayn\.png/ {
print
print "%config(noreplace) /etc/xdg/autostart/v2rayn.desktop"
done=1
next
}
{print}
' "$SPECFILE" > "${SPECFILE}.tmp" && mv "${SPECFILE}.tmp" "$SPECFILE"
fi
# Replace placeholders # Replace placeholders
sed -i "s/__VERSION__/${VERSION}/g" "$SPECFILE" sed -i "s/__VERSION__/${VERSION}/g" "$SPECFILE"
sed -i "s/__RELEASE__/${RPM_RELEASE}/g" "$SPECFILE"
sed -i "s/__PKGROOT__/${PKGROOT}/g" "$SPECFILE" sed -i "s/__PKGROOT__/${PKGROOT}/g" "$SPECFILE"
# ----- Select proper 'strip' per target arch on Ubuntu only (cross-binutils) ----- # ----- Select proper 'strip' per target arch on Ubuntu only (cross-binutils) -----
@@ -738,7 +359,7 @@ SPEC
STRIP_BIN="/usr/bin/aarch64-linux-gnu-strip" STRIP_BIN="/usr/bin/aarch64-linux-gnu-strip"
fi fi
if [[ -x "$STRIP_BIN" ]]; then if [[ -x "$STRIP_BIN" ]]; then
STRIP_ARGS=( --define "__strip $STRIP_BIN" ) STRIP_ARGS=(--define "__strip $STRIP_BIN")
fi fi
fi fi
@@ -758,7 +379,7 @@ SPEC
echo "Build done for $short. RPM at:" echo "Build done for $short. RPM at:"
local f local f
for f in "${TOPDIR}/RPMS/${archdir}/v2rayN-${VERSION}-1"*.rpm; do for f in "${TOPDIR}/RPMS/${archdir}/v2rayN-${VERSION}-${RPM_RELEASE}"*.rpm; do
[[ -e "$f" ]] || continue [[ -e "$f" ]] || continue
echo " $f" echo " $f"
BUILT_RPMS+=("$f") BUILT_RPMS+=("$f")
@@ -767,30 +388,30 @@ SPEC
# ===== Arch selection and build orchestration ========================================= # ===== Arch selection and build orchestration =========================================
case "${ARCH_OVERRIDE:-}" in case "${ARCH_OVERRIDE:-}" in
"") "")
# No --arch: use host architecture # No --arch: use host architecture
if [[ "$host_arch" == "aarch64" ]]; then if [[ "$host_arch" == "aarch64" ]]; then
build_for_arch arm64
else
build_for_arch x64
fi
;;
x64|amd64)
build_for_arch x64
;;
arm64|aarch64)
build_for_arch arm64 build_for_arch arm64
;; else
all)
BUILT_ALL=1
# Build x64 and arm64 separately; each package contains its own arch-only binaries.
build_for_arch x64 build_for_arch x64
build_for_arch arm64 fi
;; ;;
*) x64 | amd64)
echo "[ERROR] Unknown --arch '${ARCH_OVERRIDE}'. Use x64|arm64|all." build_for_arch x64
exit 1 ;;
;; arm64 | aarch64)
build_for_arch arm64
;;
all)
BUILT_ALL=1
# Build x64 and arm64 separately; each package contains its own arch-only binaries.
build_for_arch x64
build_for_arch arm64
;;
*)
echo "[ERROR] Unknown --arch '${ARCH_OVERRIDE}'. Use x64|arm64|all."
exit 1
;;
esac esac
# ===== Final summary if building both arches ========================================== # ===== Final summary if building both arches ==========================================

120
utils.sh Normal file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/env bash
download_xray() {
# Download Xray core and install to outdir/xray
local outdir="$1" ver="${XRAY_VER:-}" url tmp zipname="xray.zip"
mkdir -p "$outdir"
if [[ -n "${XRAY_VER:-}" ]]; then ver="${XRAY_VER}"; fi
if [[ -z "$ver" ]]; then
echo "Downloading latest xray"
ver="$(curl -fsSL https://api.github.com/repos/XTLS/Xray-core/releases/latest |
grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true
fi
if [[ -z "$ver" ]]; then
echo "[xray] Failed to get version"
return 1
fi
if [[ "$RID_DIR" == "linux-arm64" ]]; then
url="https://github.com/XTLS/Xray-core/releases/download/v${ver}/Xray-linux-arm64-v8a.zip"
else
url="https://github.com/XTLS/Xray-core/releases/download/v${ver}/Xray-linux-64.zip"
fi
echo "[+] Download xray: $url"
tmp="$(mktemp -d)"
trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN
curl -fL "$url" -o "$tmp/$zipname"
unzip -q "$tmp/$zipname" -d "$tmp"
install -Dm755 "$tmp/xray" "$outdir/xray"
}
download_singbox() {
# Download sing-box core and install to outdir/sing-box
local outdir="$1" ver="${SING_VER:-}" url tmp tarname="singbox.tar.gz" bin
mkdir -p "$outdir"
if [[ -n "${SING_VER:-}" ]]; then ver="${SING_VER}"; fi
if [[ -z "$ver" ]]; then
echo "Downloading latest sing-box"
ver="$(curl -fsSL https://api.github.com/repos/SagerNet/sing-box/releases/latest |
grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true
fi
if [[ -z "$ver" ]]; then
echo "[sing-box] Failed to get version"
return 1
fi
if [[ "$RID_DIR" == "linux-arm64" ]]; then
url="https://github.com/SagerNet/sing-box/releases/download/v${ver}/sing-box-${ver}-linux-arm64.tar.gz"
else
url="https://github.com/SagerNet/sing-box/releases/download/v${ver}/sing-box-${ver}-linux-amd64.tar.gz"
fi
echo "[+] Download sing-box: $url"
tmp="$(mktemp -d)"
trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN
curl -fL "$url" -o "$tmp/$tarname"
tar -C "$tmp" -xzf "$tmp/$tarname"
bin="$(find "$tmp" -type f -name 'sing-box' | head -n1 || true)"
[[ -n "$bin" ]] || {
echo "[!] sing-box unpack failed"
return 1
}
install -Dm755 "$bin" "$outdir/sing-box"
}
# Move geo files to a unified path: outroot/bin
unify_geo_layout() {
local outroot="$1"
mkdir -p "$outroot/bin"
local names=(
"geosite.dat"
"geoip.dat"
"geoip-only-cn-private.dat"
"Country.mmdb"
"geoip.metadb"
)
for n in "${names[@]}"; do
# If file exists under bin/xray/, move it up to bin/
if [[ -f "$outroot/bin/xray/$n" ]]; then
mv -f "$outroot/bin/xray/$n" "$outroot/bin/$n"
fi
# If file already in bin/, leave it as-is
if [[ -f "$outroot/bin/$n" ]]; then
:
fi
done
}
# Download geo/rule assets; then unify to bin/
download_geo_assets() {
local outroot="$1"
local bin_dir="$outroot/bin"
local srss_dir="$bin_dir/srss"
mkdir -p "$bin_dir" "$srss_dir"
echo "[+] Download Xray Geo to ${bin_dir}"
curl -fsSL -o "$bin_dir/geosite.dat" \
"https://github.com/Loyalsoldier/V2ray-rules-dat/releases/latest/download/geosite.dat"
curl -fsSL -o "$bin_dir/geoip.dat" \
"https://github.com/Loyalsoldier/V2ray-rules-dat/releases/latest/download/geoip.dat"
curl -fsSL -o "$bin_dir/geoip-only-cn-private.dat" \
"https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat"
curl -fsSL -o "$bin_dir/Country.mmdb" \
"https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb"
echo "[+] Download sing-box rule DB & rule-sets"
curl -fsSL -o "$bin_dir/geoip.metadb" \
"https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geoip.metadb" || true
for f in \
geoip-private.srs geoip-cn.srs geoip-facebook.srs geoip-fastly.srs \
geoip-google.srs geoip-netflix.srs geoip-telegram.srs geoip-twitter.srs; do
curl -fsSL -o "$srss_dir/$f" \
"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-geoip/$f" || true
done
for f in \
geosite-cn.srs geosite-gfw.srs geosite-greatfire.srs \
geosite-geolocation-cn.srs geosite-category-ads-all.srs geosite-private.srs; do
curl -fsSL -o "$srss_dir/$f" \
"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-geosite/$f" || true
done
# Unify to bin/
unify_geo_layout "$outroot"
}

View File

@@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>7.15.2</Version> <Version>7.15.4</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

View File

@@ -84,8 +84,7 @@ public class Global
public const string SingboxDirectDNSTag = "direct_dns"; public const string SingboxDirectDNSTag = "direct_dns";
public const string SingboxRemoteDNSTag = "remote_dns"; public const string SingboxRemoteDNSTag = "remote_dns";
public const string SingboxOutboundResolverTag = "outbound_resolver"; public const string SingboxLocalDNSTag = "local_local";
public const string SingboxFinalResolverTag = "final_resolver";
public const string SingboxHostsDNSTag = "hosts_dns"; public const string SingboxHostsDNSTag = "hosts_dns";
public const string SingboxFakeDNSTag = "fake_dns"; public const string SingboxFakeDNSTag = "fake_dns";

View File

@@ -1484,16 +1484,7 @@ public static class ConfigHandler
if (profileItem is null) if (profileItem is null)
{ {
profileItem = Hysteria2Fmt.ResolveFull2(strData, subRemarks); profileItem = Hysteria2Fmt.ResolveFull2(strData, subRemarks);
} }
if (profileItem is null)
{
profileItem = Hysteria2Fmt.ResolveFull(strData, subRemarks);
}
//Is naiveproxy configuration
if (profileItem is null)
{
profileItem = NaiveproxyFmt.ResolveFull(strData, subRemarks);
}
if (profileItem is null || profileItem.Address.IsNullOrEmpty()) if (profileItem is null || profileItem.Address.IsNullOrEmpty())
{ {
return -1; return -1;
@@ -2283,8 +2274,6 @@ public static class ConfigHandler
BlockBindingQuery = true, BlockBindingQuery = true,
DirectDNS = Global.DomainDirectDNSAddress.FirstOrDefault(), DirectDNS = Global.DomainDirectDNSAddress.FirstOrDefault(),
RemoteDNS = Global.DomainRemoteDNSAddress.FirstOrDefault(), RemoteDNS = Global.DomainRemoteDNSAddress.FirstOrDefault(),
SingboxOutboundsResolveDNS = Global.DomainDirectDNSAddress.FirstOrDefault(),
SingboxFinalResolveDNS = Global.DomainPureIPDNSAddress.FirstOrDefault()
}; };
} }

View File

@@ -4,7 +4,7 @@ public class ClashFmt : BaseFmt
{ {
public static ProfileItem? ResolveFull(string strData, string? subRemarks) public static ProfileItem? ResolveFull(string strData, string? subRemarks)
{ {
if (Contains(strData, "external-controller", "-port", "proxies")) if (Contains(strData, "rules", "-port", "proxies"))
{ {
var fileName = WriteAllText(strData, "yaml"); var fileName = WriteAllText(strData, "yaml");

View File

@@ -63,24 +63,6 @@ public class Hysteria2Fmt : BaseFmt
return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark); return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark);
} }
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
{
if (Contains(strData, "server", "up", "down", "listen", "<html>", "<body>"))
{
var fileName = WriteAllText(strData);
var profileItem = new ProfileItem
{
CoreType = ECoreType.hysteria,
Address = fileName,
Remarks = subRemarks ?? "hysteria_custom"
};
return profileItem;
}
return null;
}
public static ProfileItem? ResolveFull2(string strData, string? subRemarks) public static ProfileItem? ResolveFull2(string strData, string? subRemarks)
{ {
if (Contains(strData, "server", "auth", "up", "down", "listen")) if (Contains(strData, "server", "auth", "up", "down", "listen"))

View File

@@ -1,22 +0,0 @@
namespace ServiceLib.Handler.Fmt;
public class NaiveproxyFmt : BaseFmt
{
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
{
if (Contains(strData, "listen", "proxy", "<html>", "<body>"))
{
var fileName = WriteAllText(strData);
var profileItem = new ProfileItem
{
CoreType = ECoreType.naiveproxy,
Address = fileName,
Remarks = subRemarks ?? "naiveproxy_custom"
};
return profileItem;
}
return null;
}
}

View File

@@ -264,8 +264,6 @@ public class SimpleDNSItem
public bool? BlockBindingQuery { get; set; } public bool? BlockBindingQuery { get; set; }
public string? DirectDNS { get; set; } public string? DirectDNS { get; set; }
public string? RemoteDNS { get; set; } public string? RemoteDNS { get; set; }
public string? SingboxOutboundsResolveDNS { get; set; }
public string? SingboxFinalResolveDNS { get; set; }
public string? RayStrategy4Freedom { get; set; } public string? RayStrategy4Freedom { get; set; }
public string? SingboxStrategy4Direct { get; set; } public string? SingboxStrategy4Direct { get; set; }
public string? SingboxStrategy4Proxy { get; set; } public string? SingboxStrategy4Proxy { get; set; }

View File

@@ -592,7 +592,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Speed (M/s) 的本地化字符串。 /// 查找类似 Speed (MB/s) 的本地化字符串。
/// </summary> /// </summary>
public static string LvTestSpeed { public static string LvTestSpeed {
get { get {
@@ -2509,7 +2509,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Prevent domain-based routing rules from failing 的本地化字符串。 /// 查找类似 Block ECH and HTTP/3 availability checks when enabled 的本地化字符串。
/// </summary> /// </summary>
public static string TbBlockSVCBHTTPSQueriesTips { public static string TbBlockSVCBHTTPSQueriesTips {
get { get {
@@ -2607,6 +2607,24 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 V2ray Custom DNS 的本地化字符串。
/// </summary>
public static string TbCustomDnsRay {
get {
return ResourceManager.GetString("TbCustomDnsRay", resourceCulture);
}
}
/// <summary>
/// 查找类似 sing-box Custom DNS 的本地化字符串。
/// </summary>
public static string TbCustomDnsSingbox {
get {
return ResourceManager.GetString("TbCustomDnsSingbox", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Display GUI 的本地化字符串。 /// 查找类似 Display GUI 的本地化字符串。
/// </summary> /// </summary>
@@ -3039,6 +3057,15 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Via proxy — please ensure remote availability 的本地化字符串。
/// </summary>
public static string TbRemoteDNSTips {
get {
return ResourceManager.GetString("TbRemoteDNSTips", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Camouflage domain(host) 的本地化字符串。 /// 查找类似 Camouflage domain(host) 的本地化字符串。
/// </summary> /// </summary>
@@ -3174,15 +3201,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Bootstrap DNS (sing-box) 的本地化字符串。
/// </summary>
public static string TbSBBootstrapDNS {
get {
return ResourceManager.GetString("TbSBBootstrapDNS", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 sing-box Direct Resolution Strategy 的本地化字符串。 /// 查找类似 sing-box Direct Resolution Strategy 的本地化字符串。
/// </summary> /// </summary>
@@ -3192,15 +3210,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Resolve DNS server domains, requires IP 的本地化字符串。
/// </summary>
public static string TbSBFallbackDNSResolve {
get {
return ResourceManager.GetString("TbSBFallbackDNSResolve", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 sing-box Full Config Template 的本地化字符串。 /// 查找类似 sing-box Full Config Template 的本地化字符串。
/// </summary> /// </summary>
@@ -3219,24 +3228,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Resolve Outbound Domains 的本地化字符串。
/// </summary>
public static string TbSBOutboundDomainResolve {
get {
return ResourceManager.GetString("TbSBOutboundDomainResolve", resourceCulture);
}
}
/// <summary>
/// 查找类似 Outbound DNS Resolution (sing-box) 的本地化字符串。
/// </summary>
public static string TbSBOutboundsResolverDNS {
get {
return ResourceManager.GetString("TbSBOutboundsResolverDNS", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 sing-box Remote Resolution Strategy 的本地化字符串。 /// 查找类似 sing-box Remote Resolution Strategy 的本地化字符串。
/// </summary> /// </summary>
@@ -3372,24 +3363,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 V2ray DNS settings 的本地化字符串。
/// </summary>
public static string TbSettingsCoreDns {
get {
return ResourceManager.GetString("TbSettingsCoreDns", resourceCulture);
}
}
/// <summary>
/// 查找类似 sing-box DNS settings 的本地化字符串。
/// </summary>
public static string TbSettingsCoreDnsSingbox {
get {
return ResourceManager.GetString("TbSettingsCoreDnsSingbox", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Core: KCP settings 的本地化字符串。 /// 查找类似 Core: KCP settings 的本地化字符串。
/// </summary> /// </summary>
@@ -4275,9 +4248,9 @@ namespace ServiceLib.Resx {
/// <summary> /// <summary>
/// 查找类似 xray Freedom Resolution Strategy 的本地化字符串。 /// 查找类似 xray Freedom Resolution Strategy 的本地化字符串。
/// </summary> /// </summary>
public static string TbXrayFreedomResolveStrategy { public static string TbXrayFreedomStrategy {
get { get {
return ResourceManager.GetString("TbXrayFreedomResolveStrategy", resourceCulture); return ResourceManager.GetString("TbXrayFreedomStrategy", resourceCulture);
} }
} }

View File

@@ -675,8 +675,8 @@
<data name="TbSettingsCore" xml:space="preserve"> <data name="TbSettingsCore" xml:space="preserve">
<value>هسته: تنظیمات اولیه</value> <value>هسته: تنظیمات اولیه</value>
</data> </data>
<data name="TbSettingsCoreDns" xml:space="preserve"> <data name="TbCustomDnsRay" xml:space="preserve">
<value>تنظیمات V2ray DNS</value> <value>V2ray Custom DNS</value>
</data> </data>
<data name="TbSettingsCoreKcp" xml:space="preserve"> <data name="TbSettingsCoreKcp" xml:space="preserve">
<value>هسته: تنظیمات KCP</value> <value>هسته: تنظیمات KCP</value>
@@ -892,7 +892,7 @@
<value>تاخیر (میلی‌ثانیه)</value> <value>تاخیر (میلی‌ثانیه)</value>
</data> </data>
<data name="LvTestSpeed" xml:space="preserve"> <data name="LvTestSpeed" xml:space="preserve">
<value>سرعت (M/s)</value> <value>سرعت (MB/s)</value>
</data> </data>
<data name="FailedToRunCore" xml:space="preserve"> <data name="FailedToRunCore" xml:space="preserve">
<value>Core اجرا نشد، لطفاً گزارش را ببینید</value> <value>Core اجرا نشد، لطفاً گزارش را ببینید</value>
@@ -1011,8 +1011,8 @@
<data name="menuDNSSetting" xml:space="preserve"> <data name="menuDNSSetting" xml:space="preserve">
<value>تنظیمات DNS</value> <value>تنظیمات DNS</value>
</data> </data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve"> <data name="TbCustomDnsSingbox" xml:space="preserve">
<value>تنظیمات DNS sing-box</value> <value>sing-box Custom DNS</value>
</data> </data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve"> <data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>لطفا ساختار DNS را پر کنید، برای مشاهده سند کلیک کنید</value> <value>لطفا ساختار DNS را پر کنید، برای مشاهده سند کلیک کنید</value>
@@ -1419,19 +1419,10 @@
<data name="TbDomesticDNS" xml:space="preserve"> <data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value> <value>Domestic DNS</value>
</data> </data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve"> <data name="TbRemoteDNSTips" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value> <value>Via proxy — please ensure remote availability</value>
</data> </data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve"> <data name="TbXrayFreedomStrategy" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBBootstrapDNS" xml:space="preserve">
<value>Bootstrap DNS (sing-box)</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Resolve DNS server domains, requires IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value> <value>xray Freedom Resolution Strategy</value>
</data> </data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve"> <data name="TbSBDirectResolveStrategy" xml:space="preserve">
@@ -1471,7 +1462,7 @@
<value>Custom DNS Enabled, This Page's Settings Invalid</value> <value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data> </data>
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve"> <data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
<value>Prevent domain-based routing rules from failing</value> <value>Block ECH and HTTP/3 availability checks when enabled</value>
</data> </data>
<data name="FillCorrectConfigTemplateText" xml:space="preserve"> <data name="FillCorrectConfigTemplateText" xml:space="preserve">
<value>Please fill in the correct config template</value> <value>Please fill in the correct config template</value>

View File

@@ -675,8 +675,8 @@
<data name="TbSettingsCore" xml:space="preserve"> <data name="TbSettingsCore" xml:space="preserve">
<value>Core: alapbeállítások</value> <value>Core: alapbeállítások</value>
</data> </data>
<data name="TbSettingsCoreDns" xml:space="preserve"> <data name="TbCustomDnsRay" xml:space="preserve">
<value>V2ray DNS beállítások</value> <value>V2ray Custom DNS</value>
</data> </data>
<data name="TbSettingsCoreKcp" xml:space="preserve"> <data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Core: KCP beállítások</value> <value>Core: KCP beállítások</value>
@@ -892,7 +892,7 @@
<value>Késleltetés (ms)</value> <value>Késleltetés (ms)</value>
</data> </data>
<data name="LvTestSpeed" xml:space="preserve"> <data name="LvTestSpeed" xml:space="preserve">
<value>Sebesség (M/s)</value> <value>Sebesség (MB/s)</value>
</data> </data>
<data name="FailedToRunCore" xml:space="preserve"> <data name="FailedToRunCore" xml:space="preserve">
<value>Nem sikerült futtatni a Core-t, kérjük, ellenőrizze a prompt információt</value> <value>Nem sikerült futtatni a Core-t, kérjük, ellenőrizze a prompt információt</value>
@@ -1011,8 +1011,8 @@
<data name="menuDNSSetting" xml:space="preserve"> <data name="menuDNSSetting" xml:space="preserve">
<value>DNS beállítások</value> <value>DNS beállítások</value>
</data> </data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve"> <data name="TbCustomDnsSingbox" xml:space="preserve">
<value>sing-box DNS beállítások</value> <value>sing-box Custom DNS</value>
</data> </data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve"> <data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>Kérjük, töltse ki a DNS struktúrát, kattintson a dokumentum megtekintéséhez</value> <value>Kérjük, töltse ki a DNS struktúrát, kattintson a dokumentum megtekintéséhez</value>
@@ -1419,19 +1419,10 @@
<data name="TbDomesticDNS" xml:space="preserve"> <data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value> <value>Domestic DNS</value>
</data> </data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve"> <data name="TbRemoteDNSTips" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value> <value>Via proxy — please ensure remote availability</value>
</data> </data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve"> <data name="TbXrayFreedomStrategy" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBBootstrapDNS" xml:space="preserve">
<value>Bootstrap DNS (sing-box)</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Resolve DNS server domains, requires IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value> <value>xray Freedom Resolution Strategy</value>
</data> </data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve"> <data name="TbSBDirectResolveStrategy" xml:space="preserve">
@@ -1471,7 +1462,7 @@
<value>Custom DNS Enabled, This Page's Settings Invalid</value> <value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data> </data>
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve"> <data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
<value>Prevent domain-based routing rules from failing</value> <value>Block ECH and HTTP/3 availability checks when enabled</value>
</data> </data>
<data name="FillCorrectConfigTemplateText" xml:space="preserve"> <data name="FillCorrectConfigTemplateText" xml:space="preserve">
<value>Please fill in the correct config template</value> <value>Please fill in the correct config template</value>

View File

@@ -675,8 +675,8 @@
<data name="TbSettingsCore" xml:space="preserve"> <data name="TbSettingsCore" xml:space="preserve">
<value>Core: basic settings</value> <value>Core: basic settings</value>
</data> </data>
<data name="TbSettingsCoreDns" xml:space="preserve"> <data name="TbCustomDnsRay" xml:space="preserve">
<value>V2ray DNS settings</value> <value>V2ray Custom DNS</value>
</data> </data>
<data name="TbSettingsCoreKcp" xml:space="preserve"> <data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Core: KCP settings</value> <value>Core: KCP settings</value>
@@ -892,7 +892,7 @@
<value>Delay (ms)</value> <value>Delay (ms)</value>
</data> </data>
<data name="LvTestSpeed" xml:space="preserve"> <data name="LvTestSpeed" xml:space="preserve">
<value>Speed (M/s)</value> <value>Speed (MB/s)</value>
</data> </data>
<data name="FailedToRunCore" xml:space="preserve"> <data name="FailedToRunCore" xml:space="preserve">
<value>Failed to run Core, please check the prompt information</value> <value>Failed to run Core, please check the prompt information</value>
@@ -1011,8 +1011,8 @@
<data name="menuDNSSetting" xml:space="preserve"> <data name="menuDNSSetting" xml:space="preserve">
<value>DNS Settings</value> <value>DNS Settings</value>
</data> </data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve"> <data name="TbCustomDnsSingbox" xml:space="preserve">
<value>sing-box DNS settings</value> <value>sing-box Custom DNS</value>
</data> </data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve"> <data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>Please fill in DNS Structure, Click to view the document</value> <value>Please fill in DNS Structure, Click to view the document</value>
@@ -1419,19 +1419,10 @@
<data name="TbDomesticDNS" xml:space="preserve"> <data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value> <value>Domestic DNS</value>
</data> </data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve"> <data name="TbRemoteDNSTips" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value> <value>Via proxy — please ensure remote availability</value>
</data> </data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve"> <data name="TbXrayFreedomStrategy" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBBootstrapDNS" xml:space="preserve">
<value>Bootstrap DNS (sing-box)</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Resolve DNS server domains, requires IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value> <value>xray Freedom Resolution Strategy</value>
</data> </data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve"> <data name="TbSBDirectResolveStrategy" xml:space="preserve">
@@ -1471,7 +1462,7 @@
<value>Custom DNS Enabled, This Page's Settings Invalid</value> <value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data> </data>
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve"> <data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
<value>Prevent domain-based routing rules from failing</value> <value>Block ECH and HTTP/3 availability checks when enabled</value>
</data> </data>
<data name="FillCorrectConfigTemplateText" xml:space="preserve"> <data name="FillCorrectConfigTemplateText" xml:space="preserve">
<value>Please fill in the correct config template</value> <value>Please fill in the correct config template</value>

View File

@@ -675,8 +675,8 @@
<data name="TbSettingsCore" xml:space="preserve"> <data name="TbSettingsCore" xml:space="preserve">
<value>Ядро: базовые настройки</value> <value>Ядро: базовые настройки</value>
</data> </data>
<data name="TbSettingsCoreDns" xml:space="preserve"> <data name="TbCustomDnsRay" xml:space="preserve">
<value>Настройки DNS V2ray</value> <value>V2ray Custom DNS</value>
</data> </data>
<data name="TbSettingsCoreKcp" xml:space="preserve"> <data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Ядро: настройки KCP</value> <value>Ядро: настройки KCP</value>
@@ -1011,8 +1011,8 @@
<data name="menuDNSSetting" xml:space="preserve"> <data name="menuDNSSetting" xml:space="preserve">
<value>Настройки DNS</value> <value>Настройки DNS</value>
</data> </data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve"> <data name="TbCustomDnsSingbox" xml:space="preserve">
<value>Настройки DNS sing-box</value> <value>sing-box Custom DNS</value>
</data> </data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve"> <data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>Заполните структуру DNS, нажмите, чтобы открыть документ</value> <value>Заполните структуру DNS, нажмите, чтобы открыть документ</value>
@@ -1419,19 +1419,10 @@
<data name="TbDomesticDNS" xml:space="preserve"> <data name="TbDomesticDNS" xml:space="preserve">
<value>Внутренний DNS</value> <value>Внутренний DNS</value>
</data> </data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve"> <data name="TbRemoteDNSTips" xml:space="preserve">
<value>Резолвер DNS для исходящих (sing-box)</value> <value>Via proxy — please ensure remote availability</value>
</data> </data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve"> <data name="TbXrayFreedomStrategy" xml:space="preserve">
<value>Разрешать домены для исходящих соединений</value>
</data>
<data name="TbSBBootstrapDNS" xml:space="preserve">
<value>Bootstrap DNS (sing-box)</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Resolve DNS server domains, requires IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>Стратегия резолвинга Freedom (Xray)</value> <value>Стратегия резолвинга Freedom (Xray)</value>
</data> </data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve"> <data name="TbSBDirectResolveStrategy" xml:space="preserve">
@@ -1471,7 +1462,7 @@
<value>Включён пользовательский DNS — настройки на этой странице не применяются</value> <value>Включён пользовательский DNS — настройки на этой странице не применяются</value>
</data> </data>
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve"> <data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
<value>Предотвращает сбои доменных правил маршрутизации</value> <value>Block ECH and HTTP/3 availability checks when enabled</value>
</data> </data>
<data name="FillCorrectConfigTemplateText" xml:space="preserve"> <data name="FillCorrectConfigTemplateText" xml:space="preserve">
<value>Пожалуйста, заполните корректный шаблон конфигурации</value> <value>Пожалуйста, заполните корректный шаблон конфигурации</value>

View File

@@ -675,8 +675,8 @@
<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="TbCustomDnsRay" 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>
@@ -892,7 +892,7 @@
<value>延迟 (ms)</value> <value>延迟 (ms)</value>
</data> </data>
<data name="LvTestSpeed" xml:space="preserve"> <data name="LvTestSpeed" xml:space="preserve">
<value>速度 (M/s)</value> <value>速度 (MB/s)</value>
</data> </data>
<data name="FailedToRunCore" xml:space="preserve"> <data name="FailedToRunCore" xml:space="preserve">
<value>运行 Core 失败,请查看提示信息</value> <value>运行 Core 失败,请查看提示信息</value>
@@ -1008,8 +1008,8 @@
<data name="menuDNSSetting" xml:space="preserve"> <data name="menuDNSSetting" xml:space="preserve">
<value>DNS 设置</value> <value>DNS 设置</value>
</data> </data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve"> <data name="TbCustomDnsSingbox" xml:space="preserve">
<value>sing-box DNS 设置</value> <value>sing-box 自定义 DNS</value>
</data> </data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve"> <data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>请填写 DNS JSON 结构,点击查看文档</value> <value>请填写 DNS JSON 结构,点击查看文档</value>
@@ -1416,19 +1416,10 @@
<data name="TbDomesticDNS" xml:space="preserve"> <data name="TbDomesticDNS" xml:space="preserve">
<value>直连 DNS</value> <value>直连 DNS</value>
</data> </data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve"> <data name="TbRemoteDNSTips" xml:space="preserve">
<value>出站 DNS 解析sing-box</value> <value>通过代理,请确保远程可用</value>
</data> </data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve"> <data name="TbXrayFreedomStrategy" xml:space="preserve">
<value>解析出站域名</value>
</data>
<data name="TbSBBootstrapDNS" xml:space="preserve">
<value>Bootstrap DNS (sing-box)</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>解析 DNS 服务器域名,需指定为 IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray freedom 解析策略</value> <value>xray freedom 解析策略</value>
</data> </data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve"> <data name="TbSBDirectResolveStrategy" xml:space="preserve">
@@ -1468,7 +1459,7 @@
<value>自定义 DNS 已启用,此页面配置将无效</value> <value>自定义 DNS 已启用,此页面配置将无效</value>
</data> </data>
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve"> <data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
<value>避免域名分流规则失效</value> <value>开启后将阻止 ECH 和 HTTP/3 可用性查询</value>
</data> </data>
<data name="FillCorrectConfigTemplateText" xml:space="preserve"> <data name="FillCorrectConfigTemplateText" xml:space="preserve">
<value>请填写正确的配置模板</value> <value>请填写正确的配置模板</value>

View File

@@ -675,8 +675,8 @@
<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="TbCustomDnsRay" xml:space="preserve">
<value>V2ray DNS 設定</value> <value>V2ray Custom DNS</value>
</data> </data>
<data name="TbSettingsCoreKcp" xml:space="preserve"> <data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Core: KCP 設定</value> <value>Core: KCP 設定</value>
@@ -892,7 +892,7 @@
<value>延遲 (ms)</value> <value>延遲 (ms)</value>
</data> </data>
<data name="LvTestSpeed" xml:space="preserve"> <data name="LvTestSpeed" xml:space="preserve">
<value>速度 (M/s)</value> <value>速度 (MB/s)</value>
</data> </data>
<data name="FailedToRunCore" xml:space="preserve"> <data name="FailedToRunCore" xml:space="preserve">
<value>執行 Core 失敗,請查看提示訊息</value> <value>執行 Core 失敗,請查看提示訊息</value>
@@ -1008,8 +1008,8 @@
<data name="menuDNSSetting" xml:space="preserve"> <data name="menuDNSSetting" xml:space="preserve">
<value>DNS 設定</value> <value>DNS 設定</value>
</data> </data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve"> <data name="TbCustomDnsSingbox" xml:space="preserve">
<value>sing-box DNS 設定</value> <value>sing-box Custom DNS</value>
</data> </data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve"> <data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>請填寫 DNS JSON 結構,點擊查看檔案</value> <value>請填寫 DNS JSON 結構,點擊查看檔案</value>
@@ -1416,19 +1416,10 @@
<data name="TbDomesticDNS" xml:space="preserve"> <data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value> <value>Domestic DNS</value>
</data> </data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve"> <data name="TbRemoteDNSTips" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value> <value>Via proxy — please ensure remote availability</value>
</data> </data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve"> <data name="TbXrayFreedomStrategy" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBBootstrapDNS" xml:space="preserve">
<value>Bootstrap DNS (sing-box)</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Resolve DNS server domains, requires IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value> <value>xray Freedom Resolution Strategy</value>
</data> </data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve"> <data name="TbSBDirectResolveStrategy" xml:space="preserve">
@@ -1468,7 +1459,7 @@
<value>Custom DNS Enabled, This Page's Settings Invalid</value> <value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data> </data>
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve"> <data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
<value>Prevent domain-based routing rules from failing</value> <value>Block ECH and HTTP/3 availability checks when enabled</value>
</data> </data>
<data name="FillCorrectConfigTemplateText" xml:space="preserve"> <data name="FillCorrectConfigTemplateText" xml:space="preserve">
<value>Please fill in the correct config template</value> <value>Please fill in the correct config template</value>

View File

@@ -1,4 +1,4 @@
{ {
"domain": [ "domain": [
"amobile.music.tc.qq.com", "amobile.music.tc.qq.com",
"api-jooxtt.sanook.com", "api-jooxtt.sanook.com",
@@ -28,6 +28,7 @@
"swdownload.apple.com", "swdownload.apple.com",
"swquery.apple.com", "swquery.apple.com",
"swscan.apple.com", "swscan.apple.com",
"turn.cloudflare.com",
"trackercdn.kugou.com", "trackercdn.kugou.com",
"xnotify.xboxlive.com" "xnotify.xboxlive.com"
], ],

View File

@@ -235,7 +235,7 @@ public partial class CoreConfigSingboxService(Config config)
} }
singboxConfig.route.default_domain_resolver = new() singboxConfig.route.default_domain_resolver = new()
{ {
server = Global.SingboxFinalResolverTag server = Global.SingboxLocalDNSTag,
}; };
ret.Success = true; ret.Success = true;
@@ -308,7 +308,7 @@ public partial class CoreConfigSingboxService(Config config)
} }
singboxConfig.route.default_domain_resolver = new() singboxConfig.route.default_domain_resolver = new()
{ {
server = Global.SingboxFinalResolverTag server = Global.SingboxLocalDNSTag,
}; };
singboxConfig.route.rules.Clear(); singboxConfig.route.rules.Clear();

View File

@@ -43,7 +43,7 @@ public partial class CoreConfigSingboxService
}); });
} }
await GenOutboundDnsRule(node, singboxConfig, Global.SingboxOutboundResolverTag); await GenOutboundDnsRule(node, singboxConfig);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -58,16 +58,12 @@ public partial class CoreConfigSingboxService
var directDns = ParseDnsAddress(simpleDNSItem.DirectDNS); var directDns = ParseDnsAddress(simpleDNSItem.DirectDNS);
directDns.tag = Global.SingboxDirectDNSTag; directDns.tag = Global.SingboxDirectDNSTag;
directDns.domain_resolver = Global.SingboxFinalResolverTag; directDns.domain_resolver = Global.SingboxLocalDNSTag;
var remoteDns = ParseDnsAddress(simpleDNSItem.RemoteDNS); var remoteDns = ParseDnsAddress(simpleDNSItem.RemoteDNS);
remoteDns.tag = Global.SingboxRemoteDNSTag; remoteDns.tag = Global.SingboxRemoteDNSTag;
remoteDns.detour = Global.ProxyTag; remoteDns.detour = Global.ProxyTag;
remoteDns.domain_resolver = Global.SingboxFinalResolverTag; remoteDns.domain_resolver = Global.SingboxLocalDNSTag;
var resolverDns = ParseDnsAddress(simpleDNSItem.SingboxOutboundsResolveDNS);
resolverDns.tag = Global.SingboxOutboundResolverTag;
resolverDns.domain_resolver = Global.SingboxFinalResolverTag;
var hostsDns = new Server4Sbox var hostsDns = new Server4Sbox
{ {
@@ -112,10 +108,6 @@ public partial class CoreConfigSingboxService
{ {
remoteDns.domain_resolver = Global.SingboxHostsDNSTag; remoteDns.domain_resolver = Global.SingboxHostsDNSTag;
} }
if (resolverDns.server == host.Key)
{
resolverDns.domain_resolver = Global.SingboxHostsDNSTag;
}
if (directDns.server == host.Key) if (directDns.server == host.Key)
{ {
directDns.domain_resolver = Global.SingboxHostsDNSTag; directDns.domain_resolver = Global.SingboxHostsDNSTag;
@@ -126,7 +118,6 @@ public partial class CoreConfigSingboxService
singboxConfig.dns.servers ??= new List<Server4Sbox>(); singboxConfig.dns.servers ??= new List<Server4Sbox>();
singboxConfig.dns.servers.Add(remoteDns); singboxConfig.dns.servers.Add(remoteDns);
singboxConfig.dns.servers.Add(directDns); singboxConfig.dns.servers.Add(directDns);
singboxConfig.dns.servers.Add(resolverDns);
singboxConfig.dns.servers.Add(hostsDns); singboxConfig.dns.servers.Add(hostsDns);
// fake ip // fake ip
@@ -147,8 +138,13 @@ public partial class CoreConfigSingboxService
private async Task<Server4Sbox> GenDnsDomains(SingboxConfig singboxConfig, SimpleDNSItem? simpleDNSItem) private async Task<Server4Sbox> GenDnsDomains(SingboxConfig singboxConfig, SimpleDNSItem? simpleDNSItem)
{ {
var finalDns = ParseDnsAddress(simpleDNSItem.SingboxFinalResolveDNS); var finalDnsAddress = "local";
finalDns.tag = Global.SingboxFinalResolverTag; if (_config.TunModeItem.EnableTun)
{
finalDnsAddress = "dhcp://auto";
}
var finalDns = ParseDnsAddress(finalDnsAddress);
finalDns.tag = Global.SingboxLocalDNSTag;
singboxConfig.dns ??= new Dns4Sbox(); singboxConfig.dns ??= new Dns4Sbox();
singboxConfig.dns.servers ??= new List<Server4Sbox>(); singboxConfig.dns.servers ??= new List<Server4Sbox>();
singboxConfig.dns.servers.Add(finalDns); singboxConfig.dns.servers.Add(finalDns);
@@ -342,7 +338,7 @@ public partial class CoreConfigSingboxService
await GenDnsDomainsLegacyCompatible(singboxConfig, item); await GenDnsDomainsLegacyCompatible(singboxConfig, item);
} }
await GenOutboundDnsRule(node, singboxConfig, Global.SingboxFinalResolverTag); await GenOutboundDnsRule(node, singboxConfig);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -351,16 +347,17 @@ public partial class CoreConfigSingboxService
return 0; return 0;
} }
private async Task<int> GenDnsDomainsCompatible(SingboxConfig singboxConfig, DNSItem? dNSItem) private async Task<int> GenDnsDomainsCompatible(SingboxConfig singboxConfig, DNSItem? dnsItem)
{ {
var dns4Sbox = singboxConfig.dns ?? new(); var dns4Sbox = singboxConfig.dns ?? new();
dns4Sbox.servers ??= []; dns4Sbox.servers ??= [];
dns4Sbox.rules ??= []; dns4Sbox.rules ??= [];
var tag = Global.SingboxFinalResolverTag; var tag = Global.SingboxLocalDNSTag;
var localDnsAddress = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress;
var localDnsServer = ParseDnsAddress(localDnsAddress); var finalDnsAddress = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dnsItem?.DomainDNSAddress;
var localDnsServer = ParseDnsAddress(finalDnsAddress);
localDnsServer.tag = tag; localDnsServer.tag = tag;
dns4Sbox.servers.Add(localDnsServer); dns4Sbox.servers.Add(localDnsServer);
@@ -369,19 +366,19 @@ public partial class CoreConfigSingboxService
return await Task.FromResult(0); return await Task.FromResult(0);
} }
private async Task<int> GenDnsDomainsLegacyCompatible(SingboxConfig singboxConfig, DNSItem? dNSItem) private async Task<int> GenDnsDomainsLegacyCompatible(SingboxConfig singboxConfig, DNSItem? dnsItem)
{ {
var dns4Sbox = singboxConfig.dns ?? new(); var dns4Sbox = singboxConfig.dns ?? new();
dns4Sbox.servers ??= []; dns4Sbox.servers ??= [];
dns4Sbox.rules ??= []; dns4Sbox.rules ??= [];
var tag = Global.SingboxFinalResolverTag; var tag = Global.SingboxLocalDNSTag;
dns4Sbox.servers.Add(new() dns4Sbox.servers.Add(new()
{ {
tag = tag, tag = tag,
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress, address = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dnsItem?.DomainDNSAddress,
detour = Global.DirectTag, detour = Global.DirectTag,
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom, strategy = string.IsNullOrEmpty(dnsItem?.DomainStrategy4Freedom) ? null : dnsItem?.DomainStrategy4Freedom,
}); });
dns4Sbox.rules.Insert(0, new() dns4Sbox.rules.Insert(0, new()
{ {
@@ -412,7 +409,7 @@ public partial class CoreConfigSingboxService
return await Task.FromResult(0); return await Task.FromResult(0);
} }
private async Task<int> GenOutboundDnsRule(ProfileItem? node, SingboxConfig singboxConfig, string? server) private async Task<int> GenOutboundDnsRule(ProfileItem? node, SingboxConfig singboxConfig)
{ {
if (node == null) if (node == null)
{ {
@@ -439,7 +436,7 @@ public partial class CoreConfigSingboxService
singboxConfig.dns.rules ??= new List<Rule4Sbox>(); singboxConfig.dns.rules ??= new List<Rule4Sbox>();
singboxConfig.dns.rules.Insert(0, new Rule4Sbox singboxConfig.dns.rules.Insert(0, new Rule4Sbox
{ {
server = server, server = Global.SingboxLocalDNSTag,
domain = domain, domain = domain,
}); });

View File

@@ -9,13 +9,13 @@ public partial class CoreConfigSingboxService
singboxConfig.route.final = Global.ProxyTag; singboxConfig.route.final = Global.ProxyTag;
var item = _config.SimpleDNSItem; var item = _config.SimpleDNSItem;
var defaultDomainResolverTag = Global.SingboxOutboundResolverTag; var defaultDomainResolverTag = Global.SingboxDirectDNSTag;
var directDNSStrategy = item.SingboxStrategy4Direct.IsNullOrEmpty() ? Global.SingboxDomainStrategy4Out.FirstOrDefault() : item.SingboxStrategy4Direct; var directDNSStrategy = item.SingboxStrategy4Direct.IsNullOrEmpty() ? Global.SingboxDomainStrategy4Out.FirstOrDefault() : item.SingboxStrategy4Direct;
var rawDNSItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box); var rawDNSItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
if (rawDNSItem != null && rawDNSItem.Enabled == true) if (rawDNSItem != null && rawDNSItem.Enabled == true)
{ {
defaultDomainResolverTag = Global.SingboxFinalResolverTag; defaultDomainResolverTag = Global.SingboxLocalDNSTag;
directDNSStrategy = rawDNSItem.DomainStrategy4Freedom.IsNullOrEmpty() ? Global.SingboxDomainStrategy4Out.FirstOrDefault() : rawDNSItem.DomainStrategy4Freedom; directDNSStrategy = rawDNSItem.DomainStrategy4Freedom.IsNullOrEmpty() ? Global.SingboxDomainStrategy4Out.FirstOrDefault() : rawDNSItem.DomainStrategy4Freedom;
} }
singboxConfig.route.default_domain_resolver = new() singboxConfig.route.default_domain_resolver = new()

View File

@@ -354,7 +354,7 @@ public partial class CoreConfigV2rayService
return 0; return 0;
} }
private async Task<int> GenDnsDomainsCompatible(ProfileItem? node, JsonNode dns, DNSItem? dNSItem) private async Task<int> GenDnsDomainsCompatible(ProfileItem? node, JsonNode dns, DNSItem? dnsItem)
{ {
if (node == null) if (node == null)
{ {
@@ -393,7 +393,7 @@ public partial class CoreConfigV2rayService
{ {
var dnsServer = new DnsServer4Ray() var dnsServer = new DnsServer4Ray()
{ {
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress, address = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dnsItem?.DomainDNSAddress,
skipFallback = true, skipFallback = true,
domains = domainList domains = domainList
}; };

View File

@@ -13,8 +13,6 @@ public class DNSSettingViewModel : MyReactiveObject
[Reactive] public bool? BlockBindingQuery { get; set; } [Reactive] public bool? BlockBindingQuery { get; set; }
[Reactive] public string? DirectDNS { get; set; } [Reactive] public string? DirectDNS { get; set; }
[Reactive] public string? RemoteDNS { get; set; } [Reactive] public string? RemoteDNS { get; set; }
[Reactive] public string? SingboxOutboundsResolveDNS { get; set; }
[Reactive] public string? SingboxFinalResolveDNS { get; set; }
[Reactive] public string? RayStrategy4Freedom { get; set; } [Reactive] public string? RayStrategy4Freedom { get; set; }
[Reactive] public string? SingboxStrategy4Direct { get; set; } [Reactive] public string? SingboxStrategy4Direct { get; set; }
[Reactive] public string? SingboxStrategy4Proxy { get; set; } [Reactive] public string? SingboxStrategy4Proxy { get; set; }
@@ -76,8 +74,6 @@ public class DNSSettingViewModel : MyReactiveObject
DirectDNS = item.DirectDNS; DirectDNS = item.DirectDNS;
RemoteDNS = item.RemoteDNS; RemoteDNS = item.RemoteDNS;
RayStrategy4Freedom = item.RayStrategy4Freedom; RayStrategy4Freedom = item.RayStrategy4Freedom;
SingboxOutboundsResolveDNS = item.SingboxOutboundsResolveDNS;
SingboxFinalResolveDNS = item.SingboxFinalResolveDNS;
SingboxStrategy4Direct = item.SingboxStrategy4Direct; SingboxStrategy4Direct = item.SingboxStrategy4Direct;
SingboxStrategy4Proxy = item.SingboxStrategy4Proxy; SingboxStrategy4Proxy = item.SingboxStrategy4Proxy;
Hosts = item.Hosts; Hosts = item.Hosts;
@@ -107,8 +103,6 @@ public class DNSSettingViewModel : MyReactiveObject
_config.SimpleDNSItem.DirectDNS = DirectDNS; _config.SimpleDNSItem.DirectDNS = DirectDNS;
_config.SimpleDNSItem.RemoteDNS = RemoteDNS; _config.SimpleDNSItem.RemoteDNS = RemoteDNS;
_config.SimpleDNSItem.RayStrategy4Freedom = RayStrategy4Freedom; _config.SimpleDNSItem.RayStrategy4Freedom = RayStrategy4Freedom;
_config.SimpleDNSItem.SingboxOutboundsResolveDNS = SingboxOutboundsResolveDNS;
_config.SimpleDNSItem.SingboxFinalResolveDNS = SingboxFinalResolveDNS;
_config.SimpleDNSItem.SingboxStrategy4Direct = SingboxStrategy4Direct; _config.SimpleDNSItem.SingboxStrategy4Direct = SingboxStrategy4Direct;
_config.SimpleDNSItem.SingboxStrategy4Proxy = SingboxStrategy4Proxy; _config.SimpleDNSItem.SingboxStrategy4Proxy = SingboxStrategy4Proxy;
_config.SimpleDNSItem.Hosts = Hosts; _config.SimpleDNSItem.Hosts = Hosts;

View File

@@ -76,100 +76,65 @@
Width="300" Width="300"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
IsEditable="True" /> IsEditable="True" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBOutboundsResolverDNS}" />
<ComboBox
x:Name="cmbSBResolverDNS"
Grid.Row="3"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="3"
Grid.Column="2" Grid.Column="2"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBOutboundDomainResolve}" Text="{x:Static resx:ResUI.TbRemoteDNSTips}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="3"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBBootstrapDNS}" /> Text="{x:Static resx:ResUI.TbXrayFreedomStrategy}" />
<ComboBox
x:Name="cmbSBFinalResolverDNS"
Grid.Row="4"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBFallbackDNSResolve}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbXrayFreedomResolveStrategy}" />
<ComboBox <ComboBox
x:Name="cmbRayFreedomDNSStrategy" x:Name="cmbRayFreedomDNSStrategy"
Grid.Row="5" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
PlaceholderText="Default" /> PlaceholderText="Default" />
<TextBlock <TextBlock
Grid.Row="6" Grid.Row="4"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" /> Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" />
<ComboBox <ComboBox
x:Name="cmbSBDirectDNSStrategy" x:Name="cmbSBDirectDNSStrategy"
Grid.Row="6" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
PlaceholderText="Default" /> PlaceholderText="Default" />
<TextBlock <TextBlock
Grid.Row="7" Grid.Row="5"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" /> Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" />
<ComboBox <ComboBox
x:Name="cmbSBRemoteDNSStrategy" x:Name="cmbSBRemoteDNSStrategy"
Grid.Row="7" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
PlaceholderText="Default" /> PlaceholderText="Default" />
<TextBlock <TextBlock
Grid.Row="8" Grid.Row="6"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" /> Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" />
<ToggleSwitch <ToggleSwitch
x:Name="togAddCommonHosts" x:Name="togAddCommonHosts"
Grid.Row="8" Grid.Row="6"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
@@ -290,7 +255,7 @@
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}"> <TabItem Header="{x:Static resx:ResUI.TbCustomDnsRay}">
<DockPanel Margin="{StaticResource Margin8}"> <DockPanel Margin="{StaticResource Margin8}">
<Grid DockPanel.Dock="Top"> <Grid DockPanel.Dock="Top">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@@ -378,7 +343,7 @@
</DockPanel> </DockPanel>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}"> <TabItem Header="{x:Static resx:ResUI.TbCustomDnsSingbox}">
<DockPanel Margin="{StaticResource Margin8}"> <DockPanel Margin="{StaticResource Margin8}">
<Grid DockPanel.Dock="Top"> <Grid DockPanel.Dock="Top">
<Grid.RowDefinitions> <Grid.RowDefinitions>

View File

@@ -24,9 +24,7 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out; cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out; cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress; cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress;
cmbSBResolverDNS.ItemsSource = Global.DomainDirectDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress; cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress;
cmbSBFinalResolverDNS.ItemsSource = Global.DomainPureIPDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs; cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs;
cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms; cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms;
@@ -42,8 +40,6 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.SelectedItem).DisposeWith(disposables);

View File

@@ -13,7 +13,7 @@
<sys:Double x:Key="QrcodeWidth">400</sys:Double> <sys:Double x:Key="QrcodeWidth">400</sys:Double>
</UserControl.Resources> </UserControl.Resources>
<Grid Margin="32" RowDefinitions="Auto,Auto"> <Grid Margin="{StaticResource Margin8}" RowDefinitions="Auto,Auto">
<Image <Image
Name="imgQrcode" Name="imgQrcode"
Width="{StaticResource QrcodeWidth}" Width="{StaticResource QrcodeWidth}"

View File

@@ -100,65 +100,25 @@
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
IsEditable="True" IsEditable="True"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBOutboundsResolverDNS}" />
<ComboBox
x:Name="cmbSBResolverDNS"
Grid.Row="3"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="2" Grid.Column="2"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBOutboundDomainResolve}" Text="{x:Static resx:ResUI.TbRemoteDNSTips}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="3"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBBootstrapDNS}" /> Text="{x:Static resx:ResUI.TbXrayFreedomStrategy}" />
<ComboBox
x:Name="cmbSBFinalResolverDNS"
Grid.Row="4"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBFallbackDNSResolve}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbXrayFreedomResolveStrategy}" />
<ComboBox <ComboBox
x:Name="cmbRayFreedomDNSStrategy" x:Name="cmbRayFreedomDNSStrategy"
Grid.Row="5" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
@@ -166,7 +126,7 @@
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="6" Grid.Row="4"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -174,7 +134,7 @@
Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" /> Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" />
<ComboBox <ComboBox
x:Name="cmbSBDirectDNSStrategy" x:Name="cmbSBDirectDNSStrategy"
Grid.Row="6" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
@@ -182,7 +142,7 @@
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="7" Grid.Row="5"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -190,7 +150,7 @@
Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" /> Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" />
<ComboBox <ComboBox
x:Name="cmbSBRemoteDNSStrategy" x:Name="cmbSBRemoteDNSStrategy"
Grid.Row="7" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
@@ -198,7 +158,7 @@
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="8" Grid.Row="6"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -206,7 +166,7 @@
Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" /> Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" />
<ToggleButton <ToggleButton
x:Name="togAddCommonHosts" x:Name="togAddCommonHosts"
Grid.Row="8" Grid.Row="6"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
@@ -348,7 +308,7 @@
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}"> <TabItem Header="{x:Static resx:ResUI.TbCustomDnsRay}">
<DockPanel Margin="{StaticResource Margin8}"> <DockPanel Margin="{StaticResource Margin8}">
<Grid DockPanel.Dock="Top"> <Grid DockPanel.Dock="Top">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@@ -445,7 +405,7 @@
</DockPanel> </DockPanel>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}"> <TabItem Header="{x:Static resx:ResUI.TbCustomDnsSingbox}">
<DockPanel Margin="{StaticResource Margin8}"> <DockPanel Margin="{StaticResource Margin8}">
<Grid DockPanel.Dock="Top"> <Grid DockPanel.Dock="Top">
<Grid.RowDefinitions> <Grid.RowDefinitions>

View File

@@ -22,9 +22,7 @@ public partial class DNSSettingWindow
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out; cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out; cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress; cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress;
cmbSBResolverDNS.ItemsSource = Global.DomainDirectDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress; cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress;
cmbSBFinalResolverDNS.ItemsSource = Global.DomainPureIPDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs; cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs;
cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms; cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms;
@@ -40,8 +38,6 @@ public partial class DNSSettingWindow
this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.Text).DisposeWith(disposables);

View File

@@ -15,40 +15,41 @@
<sys:Double x:Key="QrcodeWidth">400</sys:Double> <sys:Double x:Key="QrcodeWidth">400</sys:Double>
</UserControl.Resources> </UserControl.Resources>
<Grid Margin="32"> <DockPanel Margin="{StaticResource Margin8}">
<Grid.RowDefinitions> <StackPanel Margin="{StaticResource Margin8}" DockPanel.Dock="Bottom">
<RowDefinition Height="Auto" /> <Button
<RowDefinition Height="Auto" /> Width="100"
<RowDefinition Height="80" /> HorizontalAlignment="Right"
</Grid.RowDefinitions> Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
Content="{x:Static resx:ResUI.menuClose}"
IsCancel="True"
IsDefault="True"
Style="{StaticResource DefButton}" />
</StackPanel>
<Image <Grid Margin="{StaticResource Margin8}">
x:Name="imgQrcode" <Grid.RowDefinitions>
Grid.Row="0" <RowDefinition Height="Auto" />
Width="{StaticResource QrcodeWidth}" <RowDefinition Height="Auto" />
Height="{StaticResource QrcodeWidth}" </Grid.RowDefinitions>
Stretch="UniformToFill" />
<TextBox <Image
x:Name="txtContent" x:Name="imgQrcode"
Grid.Row="1" Grid.Row="0"
Width="{StaticResource QrcodeWidth}" Width="{StaticResource QrcodeWidth}"
Margin="0,8" Height="{StaticResource QrcodeWidth}"
VerticalAlignment="Center" Stretch="UniformToFill" />
IsReadOnly="True"
MaxLines="3"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
<Button <TextBox
Grid.Row="2" x:Name="txtContent"
Width="100" Grid.Row="1"
Margin="{StaticResource Margin8}" Width="{StaticResource QrcodeWidth}"
HorizontalAlignment="Right" Margin="0,8"
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}" VerticalAlignment="Center"
Content="{x:Static resx:ResUI.menuClose}" IsReadOnly="True"
IsCancel="True" MaxLines="3"
IsDefault="True" TextWrapping="Wrap"
Style="{StaticResource DefButton}" /> VerticalScrollBarVisibility="Auto" />
</Grid> </Grid>
</DockPanel>
</UserControl> </UserControl>