Files
zapret-discord-youtube-linux/sync_from_upstream.sh
T
Stitch505 2a6a358baf feat(ru): full Russia/offline support (#RF)
- Add lib/download_helper.sh: proxy detection, GitHub mirrors, offline cache, tarball fallback
- Rewrite install_nfqws.sh: offline bundle support, bol-van/zapret via git clone + tarball + mirror fallback
- Rewrite sync_from_upstream.sh: proxy aware, --offline flag, graceful degradation
- Add prepare_offline_bundle.sh: create tar.gz with sources + lists + fake bins on machine WITH internet
- Add .env.example: GITHUB_PROXY, HTTPS_PROXY configuration
- Update install.sh: check GitHub reachability, suggest proxy/offline, --offline flag
- Update README: Russia section at top, Offline section, VPN/proxy examples, .env guide
2026-05-10 20:11:08 +04:00

227 lines
7.1 KiB
Bash

#!/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