- service.sh: split service_remove into internal (no prompts) and interactive versions to prevent 'eternal wait' when installing new strategy. Install now calls service_remove_internal > /dev/null instead of service_remove. Also filter strategy list to general*.sh only to avoid clutter. Systemd ExecStart now points to run_strategy.sh <name> consistently. - run_strategy.sh: add SIGTERM/SIGINT trap cleanup_strategy() that kills nfqws and cleans up firewall. Prevents stale nfqws/firewall rules after autotest kill. Also handles nfqws exit gracefully with final cleanup. - autotest.sh: rewritten to test strategies by config name (not wrapper filename). Stop now sends SIGTERM to wrapper (which triggers trap cleanup) instead of bare kill. Added extra sleep after stop to let trap fire. Auto-install ExecStart fixed to run_strategy.sh <strategy>. - setup.sh: added libmnl-dev and zlib1g-dev to Ubuntu/Debian dependency install to prevent build failures (missing libmnl/libmnl.h and zlib.h). - general*.sh: removed UTF-8 BOM (0xEF 0xBB 0xBF) that caused 'exec format error' when running scripts on Linux. All 19 wrappers cleaned. - ensure_wrappers.sh: always rewrite wrappers to ensure no stale BOM or paths. Fixes: eternal wait on menu option 1, nfqws build failure, stale processes after test.
227 lines
7.1 KiB
Bash
Executable File
227 lines
7.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# sync_from_upstream.sh - Merge upstream Flowseal changes into Linux version
|
|
# Handles: proxy (HTTPS_PROXY), offline bundle, lists, .service/hosts, .service/version
|
|
# Works even if GitHub blocked (with proxy or offline bundle)
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/lib/download_helper.sh"
|
|
|
|
UPSTREAM_REPO="https://github.com/Flowseal/zapret-discord-youtube.git"
|
|
TMP_DIR="/tmp/zapret-upstream-$$"
|
|
LOCAL_VERSION_FILE="$SCRIPT_DIR/.service/version.txt"
|
|
STRATEGIES_DIR="$SCRIPT_DIR/strategies"
|
|
|
|
echo ""
|
|
echo "=============================================="
|
|
echo " Upstream Sync"
|
|
echo " Source: $UPSTREAM_REPO"
|
|
echo "=============================================="
|
|
echo ""
|
|
|
|
mkdir -p "$STRATEGIES_DIR"
|
|
|
|
# Load proxy settings
|
|
load_proxy
|
|
|
|
# Detect if offline mode requested
|
|
OFFLINE_MODE=0
|
|
if [[ "${1:-}" == "--offline" ]]; then
|
|
OFFLINE_MODE=1
|
|
echo "[*] OFFLINE MODE: skipping network, using local files only"
|
|
fi
|
|
|
|
REBUILD_FLAG=0
|
|
UPDATE_COUNT=0
|
|
NEW_COUNT=0
|
|
|
|
# Attempt to clone/update upstream
|
|
if [[ "$OFFLINE_MODE" -eq 0 ]]; then
|
|
echo "[*] Cloning upstream (with fallback)..."
|
|
if ! clone_repo_fallback "Flowseal/zapret-discord-youtube" "main" "$TMP_DIR"; then
|
|
echo ""
|
|
echo "[WARN] Cannot reach upstream GitHub."
|
|
echo " Check proxy, VPN, or prepare_offline_bundle.sh"
|
|
echo ""
|
|
read -rp "Continue in offline mode (skip sync)? [Y/n]: " ans
|
|
if [[ "${ans:-Y}" == [yY]* ]]; then
|
|
OFFLINE_MODE=1
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Read versions
|
|
LOCAL_VER=$(cat "$LOCAL_VERSION_FILE" 2>/dev/null | tr -d '[:space:]')
|
|
UPSTREAM_VER=$(cat "$TMP_DIR/.service/version.txt" 2>/dev/null | tr -d '[:space:]')
|
|
[[ -z "$LOCAL_VER" ]] && LOCAL_VER="unknown"
|
|
[[ -z "$UPSTREAM_VER" ]] && UPSTREAM_VER="unknown"
|
|
|
|
echo "Local version: $LOCAL_VER"
|
|
echo "Upstream version: $UPSTREAM_VER"
|
|
|
|
if [[ "$UPSTREAM_VER" != "$LOCAL_VER" ]]; then
|
|
REBUILD_FLAG=1
|
|
echo "[*] Version changed: $LOCAL_VER → $UPSTREAM_VER"
|
|
fi
|
|
|
|
# ======================
|
|
# MERGE LISTS
|
|
# ======================
|
|
echo "[*] Merging upstream lists..."
|
|
merge_list() {
|
|
local file="$1"
|
|
local src=""
|
|
if [[ -d "$TMP_DIR" ]] && [[ -f "$TMP_DIR/lists/$file" ]]; then
|
|
src="$TMP_DIR/lists/$file"
|
|
elif [[ -f "$SCRIPT_DIR/.bundle/$file" ]]; then
|
|
src="$SCRIPT_DIR/.bundle/$file"
|
|
echo " [CACHED] lists/$file (from offline bundle)"
|
|
else
|
|
echo " [SKIP] lists/$file (not available)"
|
|
return
|
|
fi
|
|
cp "$src" "$SCRIPT_DIR/lists/$file"
|
|
echo " [OK] lists/$file"
|
|
}
|
|
merge_list "list-general.txt"
|
|
merge_list "list-google.txt"
|
|
merge_list "list-exclude.txt"
|
|
merge_list "ipset-exclude.txt"
|
|
|
|
if [[ -f "$SCRIPT_DIR/.service/ipset_filter_loaded" ]] || [[ -f "$SCRIPT_DIR/.service/ipset_filter_any" ]]; then
|
|
merge_list "ipset-all.txt" 2>/dev/null || true
|
|
fi
|
|
|
|
# ======================
|
|
# MERGE .service/hosts + version
|
|
# ======================
|
|
echo "[*] Merging .service files..."
|
|
|
|
if [[ -d "$TMP_DIR" ]] && [[ -f "$TMP_DIR/.service/hosts" ]]; then
|
|
cp "$TMP_DIR/.service/hosts" "$SCRIPT_DIR/.service/hosts"
|
|
echo " [OK] .service/hosts (GitHub, Telegram, Discord static IPs)"
|
|
REBUILD_FLAG=1
|
|
elif [[ -f "$SCRIPT_DIR/.bundle/hosts" ]]; then
|
|
cp "$SCRIPT_DIR/.bundle/hosts" "$SCRIPT_DIR/.service/hosts"
|
|
echo " [OK] .service/hosts (from offline bundle)"
|
|
REBUILD_FLAG=1
|
|
else
|
|
echo " [SKIP] .service/hosts (not available)"
|
|
fi
|
|
|
|
if [[ -d "$TMP_DIR" ]] && [[ -f "$TMP_DIR/.service/version.txt" ]]; then
|
|
echo "$UPSTREAM_VER-linux" > "$LOCAL_VERSION_FILE"
|
|
echo " [OK] .service/version.txt → $UPSTREAM_VER-linux"
|
|
REBUILD_FLAG=1
|
|
fi
|
|
|
|
# ======================
|
|
# PARSE NEW .bat STRATEGIES → .conf
|
|
# ======================
|
|
echo "[*] Checking for new upstream strategies..."
|
|
|
|
parse_bat_to_conf() {
|
|
local src="$1"
|
|
local name_raw
|
|
name_raw=$(basename "$src" .bat)
|
|
local name
|
|
name=$(echo "$name_raw" | sed -E 's/general[[:space:]]*//; s/\(|\)//g; s/^[[:space:]]+|[[:space:]]+$//g; s/ /_/g')
|
|
[[ -z "$name" ]] && name="general"
|
|
local conf_name="$STRATEGIES_DIR/${name}.conf"
|
|
|
|
local raw_args
|
|
# Join lines ending with ^, find winws.exe block
|
|
raw_args=$(cat "$src" | tr '\n' ' ' | \
|
|
sed 's/\^/ /g' | \
|
|
sed -E 's/start[^"]*"[^"]*"[^"]*"[^"*]*"//i; s/ *\/min //i; s/\^//g')
|
|
|
|
# Extract after winws.exe
|
|
raw_args=$(echo "$raw_args" | sed -n 's/.*winws\.exe[^"]*"\?//pi')
|
|
|
|
# Remove --wf-* (Windows-only)
|
|
raw_args=$(echo "$raw_args" | sed -E 's/--wf-tcp=[^ "]+//g; s/--wf-udp=[^ "]+//g')
|
|
|
|
# Normalize paths
|
|
raw_args=$(echo "$raw_args" | sed 's|\\|/|g')
|
|
raw_args=$(echo "$raw_args" | sed -E 's|"?%BIN%/|"%BIN%/|g; s|"?%LISTS%/|"%LISTS%/|g')
|
|
|
|
# Replace vars
|
|
raw_args=$(echo "$raw_args" | sed 's/%GameFilterTCP%/%GAME_TCP%/g; s/%GameFilterUDP%/%GAME_UDP%/g')
|
|
|
|
# Split by --new into RULE1=... RULEN=...
|
|
echo "# Strategy: $name" > "$conf_name"
|
|
echo "# Auto-converted from upstream: $name_raw.bat" >> "$conf_name"
|
|
echo "# Version: ${UPSTREAM_VER:-unknown}" >> "$conf_name"
|
|
echo "" >> "$conf_name"
|
|
|
|
local i=1
|
|
local rule
|
|
while IFS= read -r rule; do
|
|
rule=$(echo "$rule" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
|
[[ -z "$rule" ]] && continue
|
|
echo "RULE${i}=${rule}" >> "$conf_name"
|
|
i=$((i + 1))
|
|
done <<< "$(echo "$raw_args" | awk 'BEGIN{RS="--new"; ORS="\n"}{print}')"
|
|
}
|
|
|
|
# Only scan if upstream cloned
|
|
if [[ -d "$TMP_DIR" ]]; then
|
|
for bat in "$TMP_DIR"/general*.bat; do
|
|
[[ -f "$bat" ]] || continue
|
|
bat_name=$(basename "$bat")
|
|
[[ "$bat_name" == "service.bat" ]] && continue
|
|
|
|
strategy_name=$(echo "$bat_name" | sed -E 's/^general[[:space:]]*//; s/\(|\)//g; s/\.bat$//; s/ /_/g')
|
|
[[ -z "$strategy_name" ]] && strategy_name="general"
|
|
conf_file="$STRATEGIES_DIR/${strategy_name}.conf"
|
|
|
|
if [[ -f "$conf_file" ]]; then
|
|
# Simple update: mark for manual review
|
|
parse_bat_to_conf "$bat"
|
|
UPDATE_COUNT=$((UPDATE_COUNT + 1))
|
|
echo " [CHANGED] Strategy updated: $bat_name → $strategy_name.conf"
|
|
REBUILD_FLAG=1
|
|
else
|
|
parse_bat_to_conf "$bat"
|
|
NEW_COUNT=$((NEW_COUNT + 1))
|
|
echo " [NEW] Strategy detected: $bat_name → $strategy_name.conf"
|
|
REBUILD_FLAG=1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [[ $NEW_COUNT -gt 0 ]]; then
|
|
echo " [INFO] $NEW_COUNT new strategy(ies) auto-converted."
|
|
echo " [WARN] Please verify new strategies manually before using."
|
|
fi
|
|
if [[ $UPDATE_COUNT -gt 0 ]]; then
|
|
echo " [INFO] $UPDATE_COUNT strategy(ies) updated from upstream."
|
|
fi
|
|
if [[ $NEW_COUNT -eq 0 ]] && [[ $UPDATE_COUNT -eq 0 ]]; then
|
|
echo " [OK] All strategies up to date."
|
|
fi
|
|
|
|
# Cleanup upstream clone
|
|
rm -rf "$TMP_DIR"
|
|
|
|
# ======================
|
|
# ENSURE WRAPPERS
|
|
# ======================
|
|
echo "[*] Checking strategy wrappers (general*.sh)..."
|
|
bash "$SCRIPT_DIR/ensure_wrappers.sh" 2>/dev/null || true
|
|
|
|
# ======================
|
|
# REPORT
|
|
# ======================
|
|
echo "[*] Sync complete."
|
|
if [[ "$REBUILD_FLAG" -eq 1 ]]; then
|
|
echo "[*] REBUILD NEEDED: run ./update.sh or ./install.sh"
|
|
exit 2
|
|
else
|
|
echo "[*] No changes detected."
|
|
exit 0
|
|
fi
|