mirror of
https://github.com/2dust/v2rayN.git
synced 2026-03-01 05:33:04 +00:00
Compare commits
6 commits
9c20beb6da
...
3e675bfaa6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e675bfaa6 | ||
|
|
ee70bb5398 | ||
|
|
f24ae0b79b | ||
|
|
f5501e2187 | ||
|
|
73b36a20d8 | ||
|
|
6f0b172b5e |
5 changed files with 50 additions and 31 deletions
|
|
@ -10,7 +10,7 @@ if [[ -r /etc/os-release ]]; then
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "[ERROR] Unsupported system: $NAME ($ID)."
|
echo "[ERROR] Unsupported system: $NAME ($ID)."
|
||||||
echo "This script only supports Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS."
|
echo "This script only supports Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS or Ubuntu/Debian."
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -483,11 +483,20 @@ build_for_arch() {
|
||||||
trap '[[ -n "${WORKDIR:-}" ]] && rm -rf "$WORKDIR"' RETURN
|
trap '[[ -n "${WORKDIR:-}" ]] && rm -rf "$WORKDIR"' RETURN
|
||||||
|
|
||||||
# rpmbuild topdir selection
|
# rpmbuild topdir selection
|
||||||
local TOPDIR SPECDIR SOURCEDIR
|
local TOPDIR SPECDIR SOURCEDIR USE_TOPDIR_DEFINE
|
||||||
rpmdev-setuptree
|
if [[ "$ID" =~ ^(rhel|rocky|almalinux|centos)$ ]]; then
|
||||||
TOPDIR="${HOME}/rpmbuild"
|
rpmdev-setuptree
|
||||||
SPECDIR="${TOPDIR}/SPECS"
|
TOPDIR="${HOME}/rpmbuild"
|
||||||
SOURCEDIR="${TOPDIR}/SOURCES"
|
SPECDIR="${TOPDIR}/SPECS"
|
||||||
|
SOURCEDIR="${TOPDIR}/SOURCES"
|
||||||
|
USE_TOPDIR_DEFINE=0
|
||||||
|
else
|
||||||
|
TOPDIR="${WORKDIR}/rpmbuild"
|
||||||
|
SPECDIR="${TOPDIR}/SPECS}"
|
||||||
|
SOURCEDIR="${TOPDIR}/SOURCES"
|
||||||
|
mkdir -p "${SPECDIR}" "${SOURCEDIR}" "${TOPDIR}/BUILD" "${TOPDIR}/RPMS" "${TOPDIR}/SRPMS"
|
||||||
|
USE_TOPDIR_DEFINE=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Stage publish content
|
# Stage publish content
|
||||||
mkdir -p "$WORKDIR/$PKGROOT"
|
mkdir -p "$WORKDIR/$PKGROOT"
|
||||||
|
|
@ -524,6 +533,8 @@ 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
|
||||||
|
|
@ -577,12 +588,6 @@ https://github.com/2dust/v2rayN
|
||||||
install -dm0755 %{buildroot}/opt/v2rayN
|
install -dm0755 %{buildroot}/opt/v2rayN
|
||||||
cp -a * %{buildroot}/opt/v2rayN/
|
cp -a * %{buildroot}/opt/v2rayN/
|
||||||
|
|
||||||
install -dm0755 %{buildroot}%{_sysconfdir}/sudoers.d
|
|
||||||
cat > %{buildroot}%{_sysconfdir}/sudoers.d/v2rayn-mihomo-deny << 'EOF'
|
|
||||||
ALL ALL=(ALL) !/home/*/.local/share/v2rayN/bin/mihomo/mihomo
|
|
||||||
EOF
|
|
||||||
chmod 0440 %{buildroot}%{_sysconfdir}/sudoers.d/v2rayn-mihomo-deny
|
|
||||||
|
|
||||||
# Launcher (prefer native ELF first, then DLL fallback)
|
# Launcher (prefer native ELF first, then DLL fallback)
|
||||||
install -dm0755 %{buildroot}%{_bindir}
|
install -dm0755 %{buildroot}%{_bindir}
|
||||||
cat > %{buildroot}%{_bindir}/v2rayn << 'EOF'
|
cat > %{buildroot}%{_bindir}/v2rayn << 'EOF'
|
||||||
|
|
@ -636,7 +641,6 @@ fi
|
||||||
/opt/v2rayN
|
/opt/v2rayN
|
||||||
%{_datadir}/applications/v2rayn.desktop
|
%{_datadir}/applications/v2rayn.desktop
|
||||||
%{_datadir}/icons/hicolor/256x256/apps/v2rayn.png
|
%{_datadir}/icons/hicolor/256x256/apps/v2rayn.png
|
||||||
%config(noreplace) /etc/sudoers.d/v2rayn-mihomo-deny
|
|
||||||
SPEC
|
SPEC
|
||||||
|
|
||||||
# Autostart injection (inside %install) and %files entry
|
# Autostart injection (inside %install) and %files entry
|
||||||
|
|
@ -676,8 +680,35 @@ SPEC
|
||||||
sed -i "s/__VERSION__/${VERSION}/g" "$SPECFILE"
|
sed -i "s/__VERSION__/${VERSION}/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) -----
|
||||||
|
# NOTE: We define only __strip to point to the target-arch strip.
|
||||||
|
# DO NOT override __brp_strip (it must stay the brp script path).
|
||||||
|
local STRIP_ARGS=()
|
||||||
|
if [[ "$ID" == "ubuntu" ]]; then
|
||||||
|
local STRIP_BIN=""
|
||||||
|
if [[ "$short" == "x64" ]]; then
|
||||||
|
STRIP_BIN="/usr/bin/x86_64-linux-gnu-strip"
|
||||||
|
else
|
||||||
|
STRIP_BIN="/usr/bin/aarch64-linux-gnu-strip"
|
||||||
|
fi
|
||||||
|
if [[ -x "$STRIP_BIN" ]]; then
|
||||||
|
STRIP_ARGS=( --define "__strip $STRIP_BIN" )
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Build RPM for this arch (force rpm --target to match compile arch)
|
# Build RPM for this arch (force rpm --target to match compile arch)
|
||||||
rpmbuild -ba "$SPECFILE" --target "$rpm_target"
|
if [[ "$USE_TOPDIR_DEFINE" -eq 1 ]]; then
|
||||||
|
rpmbuild -ba "$SPECFILE" --define "_topdir $TOPDIR" --target "$rpm_target" "${STRIP_ARGS[@]}"
|
||||||
|
else
|
||||||
|
rpmbuild -ba "$SPECFILE" --target "$rpm_target" "${STRIP_ARGS[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy temporary rpmbuild to ~/rpmbuild on Debian/Ubuntu path
|
||||||
|
if [[ "$USE_TOPDIR_DEFINE" -eq 1 ]]; then
|
||||||
|
mkdir -p "$HOME/rpmbuild"
|
||||||
|
rsync -a "$TOPDIR"/ "$HOME/rpmbuild"/
|
||||||
|
TOPDIR="$HOME/rpmbuild"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Build done for $short. RPM at:"
|
echo "Build done for $short. RPM at:"
|
||||||
local f
|
local f
|
||||||
|
|
|
||||||
|
|
@ -339,13 +339,13 @@ public class Utils
|
||||||
return new();
|
return new();
|
||||||
}
|
}
|
||||||
var userHostsMap = hostsContent
|
var userHostsMap = hostsContent
|
||||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(line => line.Trim())
|
.Select(line => line.Trim())
|
||||||
// skip full-line comments
|
// skip full-line comments
|
||||||
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith('#'))
|
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith('#'))
|
||||||
// ensure line still contains valid parts
|
// ensure line still contains valid parts
|
||||||
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
||||||
.Select(line => line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
|
.Select(line => line.Split([' ', '\t'], StringSplitOptions.RemoveEmptyEntries))
|
||||||
.Where(parts => parts.Length >= 2)
|
.Where(parts => parts.Length >= 2)
|
||||||
.GroupBy(parts => parts[0])
|
.GroupBy(parts => parts[0])
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,9 @@ public static class CoreConfigHandler
|
||||||
var ids = selecteds.Where(serverTestItem => !serverTestItem.IndexId.IsNullOrEmpty())
|
var ids = selecteds.Where(serverTestItem => !serverTestItem.IndexId.IsNullOrEmpty())
|
||||||
.Select(serverTestItem => serverTestItem.IndexId!)
|
.Select(serverTestItem => serverTestItem.IndexId!)
|
||||||
.ToList();
|
.ToList();
|
||||||
var nodes = await AppManager.Instance.GetProfileItemsByIndexIds(ids);
|
foreach (var id in ids)
|
||||||
foreach (var node in nodes)
|
|
||||||
{
|
{
|
||||||
|
var node = await AppManager.Instance.GetProfileItem(id) ?? new();
|
||||||
await FillNodeContext(context, node, false);
|
await FillNodeContext(context, node, false);
|
||||||
}
|
}
|
||||||
if (coreType == ECoreType.sing_box)
|
if (coreType == ECoreType.sing_box)
|
||||||
|
|
|
||||||
|
|
@ -230,18 +230,6 @@ public sealed class AppManager
|
||||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId);
|
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<ProfileItem>> GetProfileItemsByIndexIds(List<string> indexIds)
|
|
||||||
{
|
|
||||||
var ids = indexIds.Where(id => id.IsNotEmpty()).Distinct().ToList();
|
|
||||||
if (ids.Count == 0)
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>()
|
|
||||||
.Where(it => ids.Contains(it.IndexId))
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks)
|
public async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks)
|
||||||
{
|
{
|
||||||
if (remarks.IsNullOrEmpty())
|
if (remarks.IsNullOrEmpty())
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ public partial class CoreConfigSingboxService
|
||||||
if (!string.IsNullOrEmpty(simpleDnsItem?.DirectExpectedIPs))
|
if (!string.IsNullOrEmpty(simpleDnsItem?.DirectExpectedIPs))
|
||||||
{
|
{
|
||||||
var ipItems = simpleDnsItem.DirectExpectedIPs
|
var ipItems = simpleDnsItem.DirectExpectedIPs
|
||||||
.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
|
.Split([',', ';'], StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(s => s.Trim())
|
.Select(s => s.Trim())
|
||||||
.Where(s => !string.IsNullOrEmpty(s))
|
.Where(s => !string.IsNullOrEmpty(s))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue