mirror of
https://github.com/2dust/v2rayN.git
synced 2025-08-23 19:36:55 +00:00
Compare commits
No commits in common. "master" and "7.14.2" have entirely different histories.
13 changed files with 12 additions and 108 deletions
36
.github/workflows/build-linux.yml
vendored
36
.github/workflows/build-linux.yml
vendored
|
@ -98,38 +98,4 @@ jobs:
|
||||||
file: ${{ github.workspace }}/v2rayN*.zip
|
file: ${{ github.workspace }}/v2rayN*.zip
|
||||||
tag: ${{ github.event.inputs.release_tag }}
|
tag: ${{ github.event.inputs.release_tag }}
|
||||||
file_glob: true
|
file_glob: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|
||||||
# release RHEL package
|
|
||||||
- name: Package RPM (RHEL-family)
|
|
||||||
if: github.event.inputs.release_tag != ''
|
|
||||||
run: |
|
|
||||||
chmod 755 package-rhel.sh
|
|
||||||
# Build for both x86_64 and aarch64 in one go (explicit version passed; no --buildfrom)
|
|
||||||
./package-rhel.sh "${{ github.event.inputs.release_tag }}" --arch all
|
|
||||||
|
|
||||||
- name: Collect RPMs into workspace
|
|
||||||
if: github.event.inputs.release_tag != ''
|
|
||||||
run: |
|
|
||||||
mkdir -p "${{ github.workspace }}/dist/rpm"
|
|
||||||
rsync -av "$HOME/rpmbuild/RPMS/" "${{ github.workspace }}/dist/rpm/"
|
|
||||||
# Rename to requested filenames
|
|
||||||
find "${{ github.workspace }}/dist/rpm" -name "v2rayN-*-1.x86_64.rpm" -exec mv {} "${{ github.workspace }}/dist/rpm/v2rayN-linux-rhel-x64.rpm" \; || true
|
|
||||||
find "${{ github.workspace }}/dist/rpm" -name "v2rayN-*-1.aarch64.rpm" -exec mv {} "${{ github.workspace }}/dist/rpm/v2rayN-linux-rhel-arm64.rpm" \; || true
|
|
||||||
|
|
||||||
- name: Upload RPM artifacts
|
|
||||||
if: github.event.inputs.release_tag != ''
|
|
||||||
uses: actions/upload-artifact@v4.6.2
|
|
||||||
with:
|
|
||||||
name: v2rayN-rpm
|
|
||||||
path: |
|
|
||||||
${{ github.workspace }}/dist/rpm/**/*.rpm
|
|
||||||
|
|
||||||
- name: Upload RPMs to release
|
|
||||||
uses: svenstaro/upload-release-action@v2
|
|
||||||
if: github.event.inputs.release_tag != ''
|
|
||||||
with:
|
|
||||||
file: ${{ github.workspace }}/dist/rpm/**/*.rpm
|
|
||||||
tag: ${{ github.event.inputs.release_tag }}
|
|
||||||
file_glob: true
|
|
||||||
prerelease: true
|
|
|
@ -332,7 +332,6 @@ download_xray() {
|
||||||
# Download Xray core and install to outdir/xray
|
# Download Xray core and install to outdir/xray
|
||||||
local outdir="$1" ver="${XRAY_VER:-}" url tmp zipname="xray.zip"
|
local outdir="$1" ver="${XRAY_VER:-}" url tmp zipname="xray.zip"
|
||||||
mkdir -p "$outdir"
|
mkdir -p "$outdir"
|
||||||
if [[ -n "${XRAY_VER:-}" ]]; then ver="${XRAY_VER}"; fi
|
|
||||||
if [[ -z "$ver" ]]; then
|
if [[ -z "$ver" ]]; then
|
||||||
ver="$(curl -fsSL https://api.github.com/repos/XTLS/Xray-core/releases/latest \
|
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
|
| grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true
|
||||||
|
@ -354,7 +353,6 @@ download_singbox() {
|
||||||
# Download sing-box core and install to outdir/sing-box
|
# Download sing-box core and install to outdir/sing-box
|
||||||
local outdir="$1" ver="${SING_VER:-}" url tmp tarname="singbox.tar.gz" bin
|
local outdir="$1" ver="${SING_VER:-}" url tmp tarname="singbox.tar.gz" bin
|
||||||
mkdir -p "$outdir"
|
mkdir -p "$outdir"
|
||||||
if [[ -n "${SING_VER:-}" ]]; then ver="${SING_VER}"; fi
|
|
||||||
if [[ -z "$ver" ]]; then
|
if [[ -z "$ver" ]]; then
|
||||||
ver="$(curl -fsSL https://api.github.com/repos/SagerNet/sing-box/releases/latest \
|
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
|
| grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true
|
||||||
|
@ -374,22 +372,6 @@ download_singbox() {
|
||||||
install -Dm755 "$bin" "$outdir/sing-box"
|
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/xray/
|
# Move geo files to a unified path: outroot/bin/xray/
|
||||||
unify_geo_layout() {
|
unify_geo_layout() {
|
||||||
local outroot="$1"
|
local outroot="$1"
|
||||||
|
@ -469,8 +451,7 @@ download_v2rayn_bundle() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f "$outroot/v2rayn.zip" 2>/dev/null || true
|
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
|
||||||
# find "$outroot" -type d -name "mihomo" -prune -exec rm -rf {} + 2>/dev/null || true
|
|
||||||
|
|
||||||
local nested_dir
|
local nested_dir
|
||||||
nested_dir="$(find "$outroot" -maxdepth 1 -type d -name 'v2rayN-linux-*' | head -n1 || true)"
|
nested_dir="$(find "$outroot" -maxdepth 1 -type d -name 'v2rayN-linux-*' | head -n1 || true)"
|
||||||
|
@ -580,8 +561,6 @@ build_for_arch() {
|
||||||
download_singbox "$WORKDIR/$PKGROOT/bin/sing_box" || echo "[!] sing-box download failed (skipped)"
|
download_singbox "$WORKDIR/$PKGROOT/bin/sing_box" || echo "[!] sing-box download failed (skipped)"
|
||||||
fi
|
fi
|
||||||
download_geo_assets "$WORKDIR/$PKGROOT" || echo "[!] Geo rules download failed (skipped)"
|
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
|
||||||
|
|
||||||
# Tarball
|
# Tarball
|
||||||
|
@ -604,7 +583,6 @@ Release: 1%{?dist}
|
||||||
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://github.com/2dust/v2rayN
|
||||||
BugURL: https://github.com/2dust/v2rayN/issues
|
|
||||||
ExclusiveArch: aarch64 x86_64
|
ExclusiveArch: aarch64 x86_64
|
||||||
Source0: __PKGROOT__.tar.gz
|
Source0: __PKGROOT__.tar.gz
|
||||||
|
|
||||||
|
@ -613,11 +591,10 @@ Requires: libX11, libXrandr, libXcursor, libXi, libXext, libxcb, libXrende
|
||||||
Requires: fontconfig, freetype, cairo, pango, mesa-libEGL, mesa-libGL
|
Requires: fontconfig, freetype, cairo, pango, mesa-libEGL, mesa-libGL
|
||||||
|
|
||||||
%description
|
%description
|
||||||
v2rayN Linux for Red Hat Enterprise Linux
|
v2rayN GUI client built with Avalonia.
|
||||||
Support vless / vmess / Trojan / http / socks / Anytls / Hysteria2 / Shadowsocks / tuic / WireGuard
|
Installs self-contained publish under /opt/v2rayN and a launcher 'v2rayn'.
|
||||||
Support Red Hat Enterprise Linux / Fedora Linux / Rocky Linux / AlmaLinux / CentOS
|
Cores (if bundled): /opt/v2rayN/bin/xray, /opt/v2rayN/bin/sing_box.
|
||||||
For more information, Please visit our website
|
Geo files for Xray are placed at /opt/v2rayN/bin/xray; launcher will symlink them into user's XDG data dir on first run.
|
||||||
https://github.com/2dust/v2rayN
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -n __PKGROOT__
|
%setup -q -n __PKGROOT__
|
||||||
|
@ -668,7 +645,7 @@ cat > %{buildroot}%{_datadir}/applications/v2rayn.desktop << 'EOF'
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=v2rayN
|
Name=v2rayN
|
||||||
Comment=v2rayN for Red Hat Enterprise Linux
|
Comment=GUI client for Xray / sing-box
|
||||||
Exec=v2rayn
|
Exec=v2rayn
|
||||||
Icon=v2rayn
|
Icon=v2rayn
|
||||||
Terminal=false
|
Terminal=false
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.14.3</Version>
|
<Version>7.14.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace ServiceLib.Handler.Fmt;
|
namespace ServiceLib.Handler.Fmt;
|
||||||
|
|
||||||
public class HtmlPageFmt : BaseFmt
|
public class HtmlPageFmt : BaseFmt
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
<x:Double x:Key="IconButtonWidth">32</x:Double>
|
<x:Double x:Key="IconButtonWidth">32</x:Double>
|
||||||
<x:Double x:Key="IconButtonHeight">32</x:Double>
|
<x:Double x:Key="IconButtonHeight">32</x:Double>
|
||||||
<x:Double x:Key="MenuFlyoutMaxHeight">1000</x:Double>
|
|
||||||
|
|
||||||
<Thickness x:Key="Margin2">2</Thickness>
|
<Thickness x:Key="Margin2">2</Thickness>
|
||||||
<Thickness x:Key="MarginLr4">4,0</Thickness>
|
<Thickness x:Key="MarginLr4">4,0</Thickness>
|
||||||
|
|
|
@ -16,7 +16,6 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_config = AppManager.Instance.Config;
|
_config = AppManager.Instance.Config;
|
||||||
Loaded += Window_Loaded;
|
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
|
@ -101,9 +100,4 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
|
||||||
{
|
{
|
||||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
btnCancel.Focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateVie
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_config = AppManager.Instance.Config;
|
_config = AppManager.Instance.Config;
|
||||||
Loaded += Window_Loaded;
|
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
|
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
|
@ -50,8 +49,4 @@ public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateVie
|
||||||
{
|
{
|
||||||
ProcUtils.ProcessStart("https://github.com/2dust/v2rayN/wiki/Description-of-some-ui#%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF%E8%AE%BE%E7%BD%AE");
|
ProcUtils.ProcessStart("https://github.com/2dust/v2rayN/wiki/Description-of-some-ui#%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF%E8%AE%BE%E7%BD%AE");
|
||||||
}
|
}
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
btnCancel.Focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ public partial class GlobalHotkeySettingWindow : WindowBase<GlobalHotkeySettingV
|
||||||
btnReset.Click += btnReset_Click;
|
btnReset.Click += btnReset_Click;
|
||||||
|
|
||||||
HotkeyManager.Instance.IsPause = true;
|
HotkeyManager.Instance.IsPause = true;
|
||||||
Loaded += Window_Loaded;
|
|
||||||
this.Closing += (s, e) => HotkeyManager.Instance.IsPause = false;
|
this.Closing += (s, e) => HotkeyManager.Instance.IsPause = false;
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
|
|
||||||
|
@ -135,8 +134,4 @@ public partial class GlobalHotkeySettingWindow : WindowBase<GlobalHotkeySettingV
|
||||||
|
|
||||||
return res.ToString();
|
return res.ToString();
|
||||||
}
|
}
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
btnCancel.Focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ServiceLib.Manager;
|
using ServiceLib.Manager;
|
||||||
using v2rayN.Desktop.Base;
|
using v2rayN.Desktop.Base;
|
||||||
|
@ -15,7 +14,6 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
Loaded += Window_Loaded;
|
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
_config = AppManager.Instance.Config;
|
_config = AppManager.Instance.Config;
|
||||||
|
|
||||||
|
@ -211,8 +209,4 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||||
ViewModel.destOverride = clbdestOverride.SelectedItems.Cast<string>().ToList();
|
ViewModel.destOverride = clbdestOverride.SelectedItems.Cast<string>().ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
btnCancel.Focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
Loaded += Window_Loaded;
|
|
||||||
this.Closing += RoutingSettingWindow_Closing;
|
this.Closing += RoutingSettingWindow_Closing;
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
this.KeyDown += RoutingSettingWindow_KeyDown;
|
this.KeyDown += RoutingSettingWindow_KeyDown;
|
||||||
|
@ -135,8 +134,4 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
btnCancel.Focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Input;
|
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using DialogHostAvalonia;
|
using DialogHostAvalonia;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
|
@ -20,9 +19,7 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
menuClose.Click += menuClose_Click;
|
menuClose.Click += menuClose_Click;
|
||||||
Loaded += Window_Loaded;
|
|
||||||
this.Closing += SubSettingWindow_Closing;
|
this.Closing += SubSettingWindow_Closing;
|
||||||
this.KeyDown += SubSettingWindow_KeyDown;
|
|
||||||
ViewModel = new SubSettingViewModel(UpdateViewHandler);
|
ViewModel = new SubSettingViewModel(UpdateViewHandler);
|
||||||
lstSubscription.DoubleTapped += LstSubscription_DoubleTapped;
|
lstSubscription.DoubleTapped += LstSubscription_DoubleTapped;
|
||||||
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
|
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
|
||||||
|
@ -109,16 +106,4 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SubSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Key == Key.Escape)
|
|
||||||
{
|
|
||||||
menuClose_Click(null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
lstSubscription.Focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using v2rayN.Manager;
|
||||||
|
|
||||||
namespace v2rayN.Manager;
|
namespace v2rayN.Manager;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue