Compare commits

..

4 commits

Author SHA1 Message Date
2dust
6ffb3bd30c up 7.14.8
Some checks failed
release Linux / build (Release) (push) Has been cancelled
release macOS / build (Release) (push) Has been cancelled
release Windows desktop (Avalonia UI) / build (Release) (push) Has been cancelled
release Windows / build (Release) (push) Has been cancelled
2025-09-08 18:48:56 +08:00
2dust
2826444ffc Code clean 2025-09-08 18:45:21 +08:00
JieXu
56c3e9c46d
Fix package-appimage.sh bugs. (#7904)
* Update package-appimage.sh

* Delete pkg2appimage.yml
2025-09-08 18:02:54 +08:00
th1nker
0770e30034
fix: 修正获取系统hosts (#7903)
- 修复当host的记录存在行尾注释时,无法将其添加到dns.host中

示例hosts
```
127.0.0.1 test1.com
127.0.0.1 test2.com # test
```
在之前仅仅会添加`127.0.0.1 test1.com`这条记录,而忽略另一条
2025-09-08 18:02:44 +08:00
13 changed files with 78 additions and 77 deletions

View file

@ -1,14 +1,67 @@
#!/bin/bash #!/bin/bash
set -euo pipefail
# Install deps
sudo apt update -y sudo apt update -y
sudo apt install -y libfuse2 sudo apt install -y libfuse2 wget file
wget -O pkg2appimage https://github.com/AppImageCommunity/pkg2appimage/releases/download/continuous/pkg2appimage-1eceb30-x86_64.AppImage
chmod a+x pkg2appimage # Get tools
export AppImageOutputArch=$OutputArch wget -qO appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
export OutputPath=$OutputPath64 chmod +x appimagetool
./pkg2appimage ./pkg2appimage.yml
mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage # x86_64 AppDir
export AppImageOutputArch=$OutputArchArm APPDIR_X64="AppDir-x86_64"
export OutputPath=$OutputPathArm64 rm -rf "$APPDIR_X64"
./pkg2appimage ./pkg2appimage.yml mkdir -p "$APPDIR_X64/usr/lib/v2rayN" "$APPDIR_X64/usr/bin" "$APPDIR_X64/usr/share/applications" "$APPDIR_X64/usr/share/pixmaps"
mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage 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/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"
chmod +x "$APPDIR_X64/AppRun"
ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_X64/usr/bin/v2rayN"
cat > "$APPDIR_X64/v2rayN.desktop" <<EOF
[Desktop Entry]
Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
Exec=v2rayN
Icon=v2rayN
Terminal=false
Type=Application
Categories=Network;
EOF
install -Dm644 "$APPDIR_X64/v2rayN.desktop" "$APPDIR_X64/usr/share/applications/v2rayN.desktop"
ARCH=x86_64 ./appimagetool "$APPDIR_X64" "v2rayN-${OutputArch}.AppImage"
file "v2rayN-${OutputArch}.AppImage" | grep -q 'x86-64'
# aarch64 AppDir
APPDIR_ARM64="AppDir-aarch64"
rm -rf "$APPDIR_ARM64"
mkdir -p "$APPDIR_ARM64/usr/lib/v2rayN" "$APPDIR_ARM64/usr/bin" "$APPDIR_ARM64/usr/share/applications" "$APPDIR_ARM64/usr/share/pixmaps"
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/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"
chmod +x "$APPDIR_ARM64/AppRun"
ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_ARM64/usr/bin/v2rayN"
cat > "$APPDIR_ARM64/v2rayN.desktop" <<EOF
[Desktop Entry]
Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
Exec=v2rayN
Icon=v2rayN
Terminal=false
Type=Application
Categories=Network;
EOF
install -Dm644 "$APPDIR_ARM64/v2rayN.desktop" "$APPDIR_ARM64/usr/share/applications/v2rayN.desktop"
# aarch64 runtime
wget -qO runtime-aarch64 https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-aarch64
chmod +x runtime-aarch64
# build aarch64 AppImage
ARCH=aarch64 ./appimagetool --runtime-file ./runtime-aarch64 "$APPDIR_ARM64" "v2rayN-${OutputArchArm}.AppImage"
file "v2rayN-${OutputArchArm}.AppImage" | grep -q 'ARM aarch64'

View file

@ -1,37 +0,0 @@
app: v2rayN
binpatch: true
ingredients:
script:
- export FileName="v2rayN-${AppImageOutputArch}.zip"
- wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/${FileName}"
- 7z x $FileName -aoa
- cp -rf v2rayN-${AppImageOutputArch}/* $OutputPath
script:
- mkdir -p usr/bin usr/lib
- cp -rf $OutputPath usr/lib/v2rayN
- echo "When this file exists, app will not store configs under this folder" > usr/lib/v2rayN/NotStoreConfigHere.txt
- ln -sf usr/lib/v2rayN/v2rayN usr/bin/v2rayN
- chmod a+x usr/lib/v2rayN/v2rayN
- find usr -type f -exec sh -c 'file "{}" | grep -qi "executable" && chmod +x "{}"' \;
- install -Dm644 usr/lib/v2rayN/v2rayN.png v2rayN.png
- install -Dm644 usr/lib/v2rayN/v2rayN.png usr/share/pixmaps/v2rayN.png
- cat > v2rayN.desktop <<EOF
- [Desktop Entry]
- Name=v2rayN
- Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
- Exec=v2rayN
- Icon=v2rayN
- Terminal=false
- Type=Application
- Categories=Network;
- EOF
- install -Dm644 v2rayN.desktop usr/share/applications/v2rayN.desktop
- cat > AppRun <<\EOF
- #!/bin/sh
- HERE="$(dirname "$(readlink -f "${0}")")"
- cd ${HERE}/usr/lib/v2rayN
- exec ${HERE}/usr/lib/v2rayN/v2rayN $@
- EOF
- chmod a+x AppRun

View file

@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>7.14.7</Version> <Version>7.14.8</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

View file

@ -582,9 +582,9 @@ public class Utils
if (host.StartsWith("#")) if (host.StartsWith("#"))
continue; continue;
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (hostItem.Length != 2) if (hostItem.Length < 2)
continue; continue;
systemHosts.Add(hostItem.Last(), hostItem.First()); systemHosts.Add(hostItem[1], hostItem[0]);
} }
} }
} }

View file

@ -1,7 +1,6 @@
using System.Reactive; using System.Reactive;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels; namespace ServiceLib.ViewModels;

View file

@ -1,27 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using DynamicData; using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels; namespace ServiceLib.ViewModels;
public class ProfilesSelectViewModel : MyReactiveObject public class ProfilesSelectViewModel : MyReactiveObject
{ {
#region private prop #region private prop
private List<ProfileItem> _lstProfile;
private string _serverFilter = string.Empty; private string _serverFilter = string.Empty;
private Dictionary<string, bool> _dicHeaderSort = new(); private Dictionary<string, bool> _dicHeaderSort = new();
private string _subIndexId = string.Empty; private string _subIndexId = string.Empty;
// ConfigType filter state: default include-mode with all types selected // ConfigType filter state: default include-mode with all types selected
private List<EConfigType> _filterConfigTypes = new(); private List<EConfigType> _filterConfigTypes = new();
private bool _filterExclude = false; private bool _filterExclude = false;
#endregion private prop #endregion private prop
@ -66,6 +61,7 @@ public class ProfilesSelectViewModel : MyReactiveObject
_config = AppManager.Instance.Config; _config = AppManager.Instance.Config;
_updateView = updateView; _updateView = updateView;
_subIndexId = _config.SubIndexId ?? string.Empty; _subIndexId = _config.SubIndexId ?? string.Empty;
#region WhenAnyValue && ReactiveCommand #region WhenAnyValue && ReactiveCommand
this.WhenAnyValue( this.WhenAnyValue(
@ -130,6 +126,7 @@ public class ProfilesSelectViewModel : MyReactiveObject
_updateView?.Invoke(EViewAction.CloseWindow, null); _updateView?.Invoke(EViewAction.CloseWindow, null);
return true; return true;
} }
#endregion Actions #endregion Actions
#region Servers && Groups #region Servers && Groups
@ -168,7 +165,6 @@ public class ProfilesSelectViewModel : MyReactiveObject
private async Task RefreshServersBiz() private async Task RefreshServersBiz()
{ {
var lstModel = await GetProfileItemsEx(_subIndexId, _serverFilter); var lstModel = await GetProfileItemsEx(_subIndexId, _serverFilter);
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? [];
ProfileItems.Clear(); ProfileItems.Clear();
ProfileItems.AddRange(lstModel); ProfileItems.AddRange(lstModel);
@ -211,9 +207,6 @@ public class ProfilesSelectViewModel : MyReactiveObject
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter) private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
{ {
var lstModel = await AppManager.Instance.ProfileItems(_subIndexId, filter); var lstModel = await AppManager.Instance.ProfileItems(_subIndexId, filter);
//await ConfigHandler.SetDefaultServer(_config, lstModel);
lstModel = (from t in lstModel lstModel = (from t in lstModel
select new ProfileItemModel select new ProfileItemModel
{ {

View file

@ -13,6 +13,7 @@ public class RoutingRuleSettingViewModel : MyReactiveObject
[Reactive] [Reactive]
public RoutingItem SelectedRouting { get; set; } public RoutingItem SelectedRouting { get; set; }
public IObservableCollection<RulesItemModel> RulesItems { get; } = new ObservableCollectionExtended<RulesItemModel>(); public IObservableCollection<RulesItemModel> RulesItems { get; } = new ObservableCollectionExtended<RulesItemModel>();
[Reactive] [Reactive]

View file

@ -1,17 +1,12 @@
using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Avalonia.VisualTree;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;

View file

@ -3,7 +3,6 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using ReactiveUI; using ReactiveUI;
using v2rayN.Desktop.Base; using v2rayN.Desktop.Base;
using System.Threading.Tasks;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;

View file

@ -3,7 +3,6 @@ using Avalonia;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using ReactiveUI; using ReactiveUI;
using v2rayN.Desktop.Base; using v2rayN.Desktop.Base;
using System.Threading.Tasks;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;

View file

@ -3,10 +3,8 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;
using Splat;
using v2rayN.Base; using v2rayN.Base;
namespace v2rayN.Views; namespace v2rayN.Views;
@ -34,7 +32,6 @@ public partial class ProfilesSelectWindow
ViewModel = new ProfilesSelectViewModel(UpdateViewHandler); ViewModel = new ProfilesSelectViewModel(UpdateViewHandler);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.OneWayBind(ViewModel, vm => vm.ProfileItems, v => v.lstProfiles.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.ProfileItems, v => v.lstProfiles.ItemsSource).DisposeWith(disposables);
@ -44,6 +41,8 @@ public partial class ProfilesSelectWindow
this.Bind(ViewModel, vm => vm.SelectedSub, v => v.lstGroup.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSub, v => v.lstGroup.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme);
} }
public void AllowMultiSelect(bool allow) public void AllowMultiSelect(bool allow)
@ -190,5 +189,6 @@ public partial class ProfilesSelectWindow
// Trigger selection finalize when Confirm is clicked // Trigger selection finalize when Confirm is clicked
ViewModel?.SelectFinish(); ViewModel?.SelectFinish();
} }
#endregion Event #endregion Event
} }

View file

@ -119,7 +119,7 @@ public partial class ProfilesView
if (obj is null) if (obj is null)
return false; return false;
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
case EViewAction.ProfilesFocus: case EViewAction.ProfilesFocus:
lstProfiles.Focus(); lstProfiles.Focus();

View file

@ -1,6 +1,5 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Threading;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;