refactor: module-based strategy architecture

- Add sync_from_upstream.sh: clones Flowseal repo, merges lists/hosts, auto-detects new .bat strategies
- Add strategies/*.conf config files (extracted from .bat)
- Rewrite run_strategy.sh: loads .conf, substitutes %BIN%/%LISTS%/%GAME_*% using sed (no envsubst)
- Rewrite update.sh: pipeline is now sync→rebuild→test→install
- Add ensure_wrappers.sh: auto-creates general_*.sh wrappers from .conf
- Fix all 'local outside function' runtime bugs
- install.sh now calls sync_from_upstream.sh first
This commit is contained in:
2026-05-10 19:46:14 +04:00
parent b75d75931d
commit 7aeb16856d
6 changed files with 477 additions and 535 deletions

31
ensure_wrappers.sh Normal file
View File

@@ -0,0 +1,31 @@
#!/bin/bash
# ensure_wrappers.sh - Create all general*.sh wrappers from strategies/*.conf
# Run after adding new .conf strategies.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for conf in "$SCRIPT_DIR/strategies"/*.conf; do
[[ -f "$conf" ]] || continue
name=$(basename "$conf" .conf)
wrapper="$SCRIPT_DIR/general_${name}.sh"
# Skip general.sh as special case (name = general)
if [[ "$name" == "general" ]]; then
wrapper="$SCRIPT_DIR/general.sh"
fi
if [[ ! -f "$wrapper" ]]; then
echo "[*] Creating wrapper: $(basename "$wrapper")$name"
cat > "$wrapper" <<EOF
#!/bin/bash
# Auto-generated wrapper: $name
SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
exec "\$SCRIPT_DIR/run_strategy.sh" "$name"
EOF
chmod +x "$wrapper"
fi
done
echo "[OK] All wrappers checked."

View File

@@ -30,6 +30,9 @@ if [[ "${ans:-Y}" != [yY]* ]]; then
exit 0
fi
# Step 0: Sync upstream lists and strategies
bash "$SCRIPT_DIR/sync_from_upstream.sh" || true
# Step 1: Setup
echo ""
echo "[*] Step 1/4: Running setup..."

View File

@@ -1,356 +1,102 @@
#!/bin/bash
# run_strategy.sh - Generic strategy runner using .conf files
# Loads strategies/strategy_name.conf, substitutes variables, runs nfqws.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
STRATEGY="${1:-general}"
CONF_FILE="$SCRIPT_DIR/strategies/${STRATEGY}.conf"
# Load settings
if [[ ! -f "$CONF_FILE" ]]; then
print_red "[ERROR] Strategy config not found: $CONF_FILE"
print_yellow "[*] Known strategies:"
for f in "$SCRIPT_DIR/strategies"/*.conf; do
[[ -f "$f" ]] || continue
local name
name=$(basename "$f" .conf)
echo " - $name"
done
exit 1
fi
# Pre-run
bash "$SCRIPT_DIR/service.sh" status_zapret >/dev/null 2>&1 || true
bash "$SCRIPT_DIR/service.sh" check_updates >/dev/null 2>&1 || true
bash "$SCRIPT_DIR/service.sh" load_game_filter >/dev/null 2>&1 || true
bash "$SCRIPT_DIR/service.sh" load_user_lists >/dev/null 2>&1 || true
load_user_lists
get_game_filter
# Build dynamic game filter args
TCP_GAME=""
UDP_GAME=""
[[ -n "$GameFilterTCP" ]] && TCP_GAME="--filter-tcp=$GameFilterTCP"
[[ -n "$GameFilterUDP" ]] && UDP_GAME="--filter-udp=$GameFilterUDP"
# Function to parse conf and build args
parse_conf_args() {
local conf="$1"
local -a args=()
# Common rule 1: UDP 443 general
RULE1=(
--filter-udp=443
--hostlist="$LISTS_DIR/list-general.txt"
--hostlist="$LISTS_DIR/list-general-user.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude-user.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt"
)
while IFS= read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^# ]] && continue
[[ -z "$line" ]] && continue
[[ "$line" =~ ^RULE[0-9]+= ]] || continue
# Common rule 2: UDP discord/stun
RULE2=(
--filter-udp=19294-19344,50000-50100
--filter-l7=discord,stun
)
local rule_value="${line#*=}"
# Common rule 6: UDP 443 ipset-all
RULE6=(
--filter-udp=443
--ipset="$LISTS_DIR/ipset-all.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude-user.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt"
)
# Substitute variables using sed (no envsubst dependency)
rule_value=$(echo "$rule_value" | sed \
-e "s|%BIN%|$BIN_DIR|g" \
-e "s|%LISTS%|$LISTS_DIR|g" \
-e "s|%GAME_TCP%|${GameFilterTCP:-}|g" \
-e "s|%GAME_UDP%|${GameFilterUDP:-}|g")
# Common rule 9: UDP game filter
RULE9=()
if [[ -n "$UDP_GAME" ]]; then
RULE9+=("$UDP_GAME")
fi
RULE9+=(
--ipset="$LISTS_DIR/ipset-all.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt"
)
# Skip rule if game filter placeholders remain but filter is empty
if [[ "$rule_value" == *'%GAME_TCP%'* ]] && [[ -z "${GameFilterTCP:-}" ]]; then
continue
fi
if [[ "$rule_value" == *'%GAME_UDP%'* ]] && [[ -z "${GameFilterUDP:-}" ]]; then
continue
fi
# Parse strategy-specific args
case "$STRATEGY" in
general)
# Rule 3
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
# Rule 4
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
# Rule 5
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_4pda_to.bin")
# Rule 6 extra
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
# Rule 7
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_4pda_to.bin")
# Rule 8
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_4pda_to.bin")
# Rule 9 extra
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
# Parse into array
local rule_arr=()
read -ra rule_arr <<< "$rule_value"
for arg in "${rule_arr[@]}"; do
args+=("$arg")
done
args+=("--new")
done < "$conf"
ALT)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n3)
;;
# Remove trailing --new
local last_idx=$(( ${#args[@]} - 1 ))
if [[ $last_idx -ge 0 ]] && [[ "${args[$last_idx]}" == "--new" ]]; then
unset 'args[last_idx]'
fi
ALT2)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
# Return via echo (space-separated, properly quoted)
printf '%s\n' "${args[@]}"
}
ALT3)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n4)
;;
# Build args in main shell using temp file
cd "$SCRIPT_DIR"
TMP_ARGS="$(mktemp /tmp/zapret_args.XXXXXX)"
trap "rm -f '\$TMP_ARGS'" EXIT
ALT4)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
parse_conf_args "$CONF_FILE" > "$TMP_ARGS"
ALT5)
RULE3=(--filter-l3=ipv4 --filter-tcp=80,443,2053,2083,2087,2096,8443 --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata,multidisorder)
RULE4=()
RULE5=()
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=()
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata,multidisorder --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4)
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=14 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n3)
;;
ALT6)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT7)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-pos=2,sniext+1 --dpi-desync-split-seqovl=679 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-pos=2,sniext+1 --dpi-desync-split-seqovl=679 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-pos=2,sniext+1 --dpi-desync-split-seqovl=679 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata)
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4)
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT8)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT9)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts,md5sig --dpi-desync-hostfakesplit-mod=host=ozon.ru)
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru)
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru)
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT10)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT11)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=664 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=664 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-split-seqovl=664 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n4)
;;
FAKE_TLS_AUTO)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multidisorder --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
FAKE_TLS_AUTO_ALT)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
FAKE_TLS_AUTO_ALT2)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
FAKE_TLS_AUTO_ALT3)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
SIMPLE_FAKE)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
SIMPLE_FAKE_ALT)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
SIMPLE_FAKE_ALT2)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fake-tls-mod=none)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru,altorder=1 --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru,altorder=1 --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru,altorder=1 --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
*)
echo "Unknown strategy: $STRATEGY"
echo "Valid strategies: general, ALT, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9, ALT10, ALT11, FAKE_TLS_AUTO, FAKE_TLS_AUTO_ALT, FAKE_TLS_AUTO_ALT2, FAKE_TLS_AUTO_ALT3, SIMPLE_FAKE, SIMPLE_FAKE_ALT, SIMPLE_FAKE_ALT2"
exit 1
;;
esac
# Build final args
FINAL_ARGS=()
# Rule 1: UDP 443 general
FINAL_ARGS+=("${RULE1[@]}")
FINAL_ARGS+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
FINAL_ARGS+=(--new)
# Rule 2: UDP discord/stun
FINAL_ARGS+=("${RULE2[@]}")
FINAL_ARGS+=(--dpi-desync=fake --dpi-desync-fake-discord="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-fake-stun="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-repeats=6)
FINAL_ARGS+=(--new)
# Rule 3
if [[ ${#RULE3[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE3[@]}")
FINAL_ARGS+=(--new)
# If no args parsed
if [[ ! -s "$TMP_ARGS" ]]; then
print_red "[ERROR] No arguments parsed from $CONF_FILE"
rm -f "$TMP_ARGS"
exit 1
fi
# Rule 4
if [[ ${#RULE4[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE4[@]}")
FINAL_ARGS+=(--new)
fi
# Read args into array from file
CLEAN_ARGS=()
while IFS= read -r arg; do
[[ -n "$arg" ]] && CLEAN_ARGS+=("$arg")
done < "$TMP_ARGS"
# Rule 5
if [[ ${#RULE5[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE5[@]}")
FINAL_ARGS+=(--new)
fi
rm -f "$TMP_ARGS"
trap - EXIT
# Rule 6
FINAL_ARGS+=("${RULE6[@]}")
FINAL_ARGS+=(--new)
# Rule 7
if [[ ${#RULE7[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE7[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 8
if [[ ${#RULE8[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE8[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 9
FINAL_ARGS+=("${RULE9[@]}")
run_nfqws "$0" "${FINAL_ARGS[@]}"
run_nfqws "$0" "${CLEAN_ARGS[@]}"

22
strategies/general.conf Normal file
View File

@@ -0,0 +1,22 @@
# Strategy: general
# Description: Standard multisplit strategy
# Based on: general.bat (Flowseal 1.9.8c)
# Common rules
RULE1=--filter-udp=443 --hostlist="%LISTS%/list-general.txt" --hostlist="%LISTS%/list-general-user.txt" --hostlist-exclude="%LISTS%/list-exclude.txt" --hostlist-exclude="%LISTS%/list-exclude-user.txt" --ipset-exclude="%LISTS%/ipset-exclude.txt" --ipset-exclude="%LISTS%/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="%BIN%/quic_initial_www_google_com.bin"
RULE2=--filter-udp=19294-19344,50000-50100 --filter-l7=discord,stun --dpi-desync=fake --dpi-desync-fake-discord="%BIN%/quic_initial_dbankcloud_ru.bin" --dpi-desync-fake-stun="%BIN%/quic_initial_dbankcloud_ru.bin" --dpi-desync-repeats=6
RULE3=--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="%BIN%/tls_clienthello_www_google_com.bin"
RULE4=--filter-tcp=443 --hostlist="%LISTS%/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="%BIN%/tls_clienthello_www_google_com.bin"
RULE5=--filter-tcp=80,443 --hostlist="%LISTS%/list-general.txt" --hostlist="%LISTS%/list-general-user.txt" --hostlist-exclude="%LISTS%/list-exclude.txt" --hostlist-exclude="%LISTS%/list-exclude-user.txt" --ipset-exclude="%LISTS%/ipset-exclude.txt" --ipset-exclude="%LISTS%/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="%BIN%/tls_clienthello_4pda_to.bin"
RULE6=--filter-udp=443 --ipset="%LISTS%/ipset-all.txt" --hostlist-exclude="%LISTS%/list-exclude.txt" --hostlist-exclude="%LISTS%/list-exclude-user.txt" --ipset-exclude="%LISTS%/ipset-exclude.txt" --ipset-exclude="%LISTS%/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="%BIN%/quic_initial_www_google_com.bin"
RULE7=--filter-tcp=80,443,8443 --ipset="%LISTS%/ipset-all.txt" --hostlist-exclude="%LISTS%/list-exclude.txt" --hostlist-exclude="%LISTS%/list-exclude-user.txt" --ipset-exclude="%LISTS%/ipset-exclude.txt" --ipset-exclude="%LISTS%/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="%BIN%/tls_clienthello_4pda_to.bin"
RULE8=--filter-tcp=%GAME_TCP% --ipset="%LISTS%/ipset-all.txt" --ipset-exclude="%LISTS%/ipset-exclude.txt" --ipset-exclude="%LISTS%/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="%BIN%/tls_clienthello_4pda_to.bin"
RULE9=--filter-udp=%GAME_UDP% --ipset="%LISTS%/ipset-all.txt" --ipset-exclude="%LISTS%/ipset-exclude.txt" --ipset-exclude="%LISTS%/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="%BIN%/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2

220
sync_from_upstream.sh Normal file
View File

@@ -0,0 +1,220 @@
#!/bin/bash
# sync_from_upstream.sh - Merge upstream Flowseal changes into Linux version
# Handles: lists, .service/hosts, .service/version, auto-detection of NEW .bat strategies
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
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"
mkdir -p "$STRATEGIES_DIR"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Clone upstream with 60s timeout
log_msg "[*] Cloning upstream Flowseal/zapret-discord-youtube..."
if ! git clone --depth=1 --single-branch --branch main "$UPSTREAM_REPO" "$TMP_DIR" 2>/dev/null; then
log_msg "[FAIL] Could not clone upstream. Check internet/DNS."
rm -rf "$TMP_DIR"
exit 1
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"
log_msg "Local version: $LOCAL_VER"
log_msg "Upstream version: $UPSTREAM_VER"
REBUILD_FLAG=0
if [[ "$UPSTREAM_VER" != "$LOCAL_VER" ]]; then
REBUILD_FLAG=1
log_msg "[*] Version changed: $LOCAL_VER$UPSTREAM_VER"
fi
# ======================
# MERGE LISTS
# ======================
log_msg "[*] Merging upstream lists..."
merge_list() {
local file="$1"
local src="$TMP_DIR/lists/$file"
local dst="$SCRIPT_DIR/lists/$file"
if [[ ! -f "$src" ]]; then
log_msg " [SKIP] Upstream missing: lists/$file"
return
fi
cp "$src" "$dst"
log_msg " [OK] lists/$file"
}
merge_list "list-general.txt"
merge_list "list-google.txt"
merge_list "list-exclude.txt"
merge_list "ipset-exclude.txt"
# Only update ipset-all if placeholder or enabled
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
# ======================
log_msg "[*] Merging .service files..."
if [[ -f "$TMP_DIR/.service/hosts" ]]; then
cp "$TMP_DIR/.service/hosts" "$SCRIPT_DIR/.service/hosts"
log_msg " [OK] .service/hosts (GitHub, Telegram, Discord static IPs)"
REBUILD_FLAG=1
fi
if [[ -f "$TMP_DIR/.service/version.txt" ]]; then
echo "$UPSTREAM_VER-linux" > "$LOCAL_VERSION_FILE"
log_msg " [OK] .service/version.txt → $UPSTREAM_VER-linux"
REBUILD_FLAG=1
fi
# ======================
# PARSE NEW .bat STRATEGIES → .conf
# ======================
log_msg "[*] Checking for new upstream strategies..."
NEW_COUNT=0
UPDATE_COUNT=0
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')
[[ -z "$name" ]] && name="general"
local conf_name="$STRATEGIES_DIR/${name}.conf"
# Extract winws arguments after "winws.exe ...parameters..."
# Step 1: Find all lines after winws.exe, clean line continuations (^) and quotes
local raw_args
raw_args=$(sed -n '/winws\.exe/I,${ p }' "$src" | \
sed 's/\^//g' | \
tr '\n' ' ' | \
sed -E 's/start[^"]*"[^"]*"[^"]*"[^"]*"//i; s/ *\/min //i')
# Step 2: Remove the winws.exe binary path and WF filters (Windows-only --wf-*)
raw_args=$(echo "$raw_args" | sed -E 's/[^ ]*winws\.exe//i; s/--wf-tcp=[^ ]+//; s/--wf-udp=[^ ]+//')
# Step 3: Fix Windows paths to placeholders
# "...bin\file.bin" → %BIN%/file.bin
raw_args=$(echo "$raw_args" | sed -E 's/"%BIN%\\([^"]*)"/\%BIN%\/\1/g')
raw_args=$(echo "$raw_args" | sed -E 's/%BIN%\\([^ ]*)/\%BIN%\/\1/g')
raw_args=$(echo "$raw_args" | sed -E 's/"%LISTS%\\([^"]*)"/\%LISTS%\/\1/g')
raw_args=$(echo "$raw_args" | sed -E 's/%LISTS%\\([^ ]*)/\%LISTS%\/\1/g')
# Remove stray quotes
raw_args=$(echo "$raw_args" | tr -d '\"')
# Step 4: Replace Windows variables with Linux placeholders
raw_args=$(echo "$raw_args" | sed 's/%GameFilterTCP%/%GAME_TCP%/g; s/%GameFilterUDP%/%GAME_UDP%/g')
# Step 5: Split by --new into RULE1..9
local rule_num=1
local current_rule=""
# Convert --new separated rules into lines
echo "# Strategy: $name" > "$conf_name"
echo "# Auto-generated from upstream: $name_raw.bat" >> "$conf_name"
echo "# Version: $UPSTREAM_VER" >> "$conf_name"
echo "" >> "$conf_name"
# Use awk to split by --new
echo "$raw_args" | awk '{
split($0, parts, " --new");
for (i=1; i<=length(parts); i++) {
gsub(/^[[:space:]]+|[[:space:]]+$/, "", parts[i]);
if (parts[i] != "") {
print "RULE" i "=" parts[i];
}
}
}' >> "$conf_name"
}
for bat in "$TMP_DIR"/general*.bat; do
[[ -f "$bat" ]] || continue
bat_name=$(basename "$bat")
[[ "$bat_name" == "service.bat" ]] && continue
# Normalize conf name
strategy_name=$(echo "$bat_name" | sed -E 's/^general[[:space:]]*//; s/\(|\)//g; s/\.bat$//')
[[ -z "$strategy_name" ]] && strategy_name="general"
conf_file="$STRATEGIES_DIR/${strategy_name}.conf"
if [[ -f "$conf_file" ]]; then
# Check if upstream strategy changed (compare hash)
remote_hash=$(md5sum "$bat" 2>/dev/null | awk '{print $1}')
local_hash=$(md5sum "$conf_file" 2>/dev/null | awk '{print $1}')
if [[ "$remote_hash" != "$(grep '^# hash:' "$conf_file" 2>/dev/null | awk '{print $3}')" ]]; then
log_msg " [CHANGED] Strategy updated: $bat_name$strategy_name.conf"
parse_bat_to_conf "$bat"
UPDATE_COUNT=$((UPDATE_COUNT + 1))
REBUILD_FLAG=1
fi
else
log_msg " [NEW] Detected upstream strategy: $bat_name$strategy_name.conf"
parse_bat_to_conf "$bat"
NEW_COUNT=$((NEW_COUNT + 1))
REBUILD_FLAG=1
fi
done
if [[ $NEW_COUNT -gt 0 ]]; then
log_msg " [INFO] $NEW_COUNT new strategy(ies) auto-converted."
log_msg " [WARN] Please verify new strategies manually before using."
fi
if [[ $UPDATE_COUNT -gt 0 ]]; then
log_msg " [INFO] $UPDATE_COUNT strategy(ies) updated from upstream."
fi
if [[ $NEW_COUNT -eq 0 ]] && [[ $UPDATE_COUNT -eq 0 ]]; then
log_msg " [OK] All strategies up to date."
fi
# Cleanup
rm -rf "$TMP_DIR"
# ======================
# CHECK if general*.sh wrappers exist for all .conf
# ======================
log_msg "[*] Checking strategy wrappers (general*.sh)..."
for conf in "$STRATEGIES_DIR"/*.conf; do
[[ -f "$conf" ]] || continue
local name
name=$(basename "$conf" .conf)
local wrapper="$SCRIPT_DIR/general_${name}.sh"
if [[ ! -f "$wrapper" ]]; then
# Create wrapper
cat > "$wrapper" <<EOF
#!/bin/bash
# Auto-generated wrapper for strategy: $name
SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
exec "\$SCRIPT_DIR/run_strategy.sh" "$name"
EOF
chmod +x "$wrapper"
log_msg " [OK] Created wrapper: $(basename "$wrapper")"
fi
done
# ======================
# REPORT
# ======================
log_msg "[*] Sync complete."
if [[ "$REBUILD_FLAG" -eq 1 ]]; then
log_msg "[*] REBUILD NEEDED: run ./update.sh or ./install.sh"
exit 2
else
log_msg "[*] No changes detected."
exit 0
fi

336
update.sh
View File

@@ -1,15 +1,12 @@
#!/bin/bash
# update.sh - Auto-update, auto-build, auto-test, auto-install pipeline
# Full automation: download updates → rebuild nfqws → test strategies → install working one
# update.sh - Full auto-pipeline: sync upstream → update → build → test → install
# Version: 2.0
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
GITHUB_REPO="Flowseal/zapret-discord-youtube"
GITHUB_RAW="https://raw.githubusercontent.com/$GITHUB_REPO/main"
GITHUB_RELEASES="https://github.com/$GITHUB_REPO/releases"
LOCAL_VERSION_FILE="$SCRIPT_DIR/.service/version.txt"
UPDATE_LOG="$SCRIPT_DIR/.service/update.log"
@@ -19,100 +16,51 @@ log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$UPDATE_LOG"
}
# Check remote version
check_remote_version() {
local remote_ver
remote_ver=$(curl -sfL "$GITHUB_RAW/.service/version.txt" 2>/dev/null | head -n1 | tr -d '[:space:]')
if [[ -z "$remote_ver" ]]; then
log_msg "ERROR: Failed to fetch remote version"
# Check if nfqws binary is healthy
verify_nfqws() {
local bin="$BIN_DIR/nfqws"
if [[ ! -x "$bin" ]]; then
log_msg "[FAIL] nfqws binary missing or not executable: $bin"
return 1
fi
echo "$remote_ver"
}
# Update lists and scripts (non-destructive)
update_files() {
log_msg "[*] Updating lists and scripts from GitHub..."
for file in list-general.txt list-google.txt list-exclude.txt ipset-exclude.txt; do
local url="$GITHUB_RAW/lists/$file"
local dest="$SCRIPT_DIR/lists/$file"
if curl -sfL "$url" -o "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
log_msg " [OK] Updated lists/$file"
else
log_msg " [SKIP] lists/$file (unavailable)"
fi
done
if [[ -f "$SCRIPT_DIR/.service/ipset_filter_loaded" ]] || [[ -f "$SCRIPT_DIR/.service/ipset_filter_any" ]]; then
local url="$GITHUB_RAW/.service/ipset-all.txt"
local dest="$SCRIPT_DIR/lists/ipset-all.txt"
if curl -sfL "$url" -o "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
log_msg " [OK] Updated lists/ipset-all.txt"
fi
fi
for file in lib/functions.sh utils/test_zapret.sh utils/targets.txt; do
local url="$GITHUB_RAW/$file"
local dest="$SCRIPT_DIR/$file"
if curl -sfL "$url" -o "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
log_msg " [OK] Updated $file"
fi
done
log_msg "[*] File update complete."
}
# Rebuild nfqws with verification
rebuild_nfqws() {
log_msg "[*] Rebuilding nfqws..."
if ! bash "$SCRIPT_DIR/install_nfqws.sh"; then
log_msg "[FAIL] nfqws build script failed."
if ! "$bin" --help >/dev/null 2>&1; then
log_msg "[FAIL] nfqws binary does not run (segfault?)"
return 1
fi
# Verify binary exists
if [[ ! -x "$BIN_DIR/nfqws" ]]; then
log_msg "[FAIL] nfqws binary not found after build."
return 1
fi
# Verify binary can start (quick help check)
if ! "$BIN_DIR/nfqws" --help >/dev/null 2>&1; then
log_msg "[FAIL] nfqws binary built but does not execute."
return 1
fi
log_msg "[OK] nfqws rebuilt and verified."
log_msg "[OK] nfqws binary verified."
return 0
}
# Run autotest to find working strategy and install it
run_autotest_pipeline() {
log_msg "[*] Running auto-test pipeline to find working strategy..."
# Rebuild nfqws
rebuild_nfqws() {
log_msg "[*] Rebuilding nfqws..."
if bash "$SCRIPT_DIR/install_nfqws.sh"; then
verify_nfqws
else
log_msg "[FAIL] Build script failed."
return 1
fi
}
# Stop any existing service first
# Run autotest pipeline
run_pipeline_autotest() {
log_msg "[*] Running auto-test pipeline..."
if command -v systemctl >/dev/null 2>&1; then
systemctl stop zapret.service 2>/dev/null || true
fi
cleanup_firewall >/dev/null 2>&1 || true
sleep 2
# Run autotest in auto mode
if bash "$SCRIPT_DIR/autotest.sh" --auto; then
log_msg "[OK] Auto-test found working strategy and installed it."
bash "$SCRIPT_DIR/autotest.sh" --auto && {
log_msg "[OK] Auto-test: working strategy found and installed."
return 0
else
log_msg "[FAIL] Auto-test did not find any working strategy."
} || {
log_msg "[WARN] Auto-test: no working strategy found."
return 1
fi
}
}
# Restart service if installed
# Restart systemd service
restart_service() {
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-enabled zapret.service >/dev/null 2>&1; then
@@ -123,120 +71,111 @@ restart_service() {
fi
}
# Full pipeline: update → build → test → install
# Step 0: Sync upstream
do_sync() {
log_msg "[*] Step 0: Syncing upstream strategies, lists, hosts..."
bash "$SCRIPT_DIR/sync_from_upstream.sh" 2>&1 | tee -a "$UPDATE_LOG"
local sync_status=${PIPESTATUS[0]}
case "$sync_status" in
0) log_msg "[OK] Sync complete, no rebuild needed."
SYNC_REBUILD=0
;;
2) log_msg "[OK] Sync complete, REBUILD FLAGGED (new version or lists changed)."
SYNC_REBUILD=1
;;
*) log_msg "[WARN] Sync encountered errors (exit $sync_status). Continue anyway."
SYNC_REBUILD=0
;;
esac
}
# Step 1-4: Main pipeline
full_pipeline() {
local mode="${1:-interactive}"
local force="${2:-no}"
if [[ "$mode" == "interactive" ]]; then
[[ "$mode" == "interactive" ]] && {
echo ""
echo "=============================================="
echo " Zapret Full Auto Pipeline"
echo " Zapret Full Auto Pipeline v2.0"
echo " Current: $LOCAL_VERSION"
echo "=============================================="
echo ""
fi
# Step 1: Check remote version
log_msg "[*] Step 1/4: Checking for updates..."
local remote_version
remote_version=$(check_remote_version) || {
log_msg "Could not check remote version."
if [[ "$mode" == "interactive" ]]; then
read -rp "Continue with local rebuild anyway? [y/N]: " ans
[[ "$ans" == [yY]* ]] || exit 1
else
exit 1
fi
remote_version="$LOCAL_VERSION"
}
if [[ "$mode" == "interactive" ]]; then
echo "Remote version: $remote_version"
echo "Local version: $LOCAL_VERSION"
echo ""
# Step 0: Always sync upstream first
do_sync
# Determine if we need to rebuild
local need_rebuild=0
if [[ "$force" == "yes" ]]; then
log_msg "[*] Force rebuild requested."
need_rebuild=1
elif [[ "${SYNC_REBUILD:-0}" -eq 1 ]]; then
log_msg "[*] Rebuild flagged by sync."
need_rebuild=1
fi
# Decide whether to update
local do_update=0
if [[ "$remote_version" != "$LOCAL_VERSION" ]]; then
do_update=1
log_msg "New version available: $remote_version"
elif [[ "$force" == "yes" ]]; then
log_msg "Force rebuild requested."
do_update=1
if [[ "$need_rebuild" -eq 0 ]] && [[ "$mode" == "interactive" ]]; then
read -rp "No upstream changes detected. Force rebuild + re-test? [y/N]: " ans
[[ "$ans" == [yY]* ]] && need_rebuild=1
fi
if [[ "$do_update" -eq 0 ]]; then
log_msg "No update needed."
if [[ "$mode" == "interactive" ]]; then
read -rp "Rebuild nfqws and re-test anyway? [y/N]: " ans
[[ "$ans" == [yY]* ]] || {
echo "[*] Nothing to do. Exiting."
exit 0
}
else
log_msg "Exiting (no update, no force)."
exit 0
fi
fi
# Step 2: Update files
if [[ "$remote_version" != "$LOCAL_VERSION" ]]; then
log_msg "[*] Step 2/4: Updating files from GitHub..."
update_files
echo "LOCAL_VERSION=\"$remote_version-linux\"" > "$LOCAL_VERSION_FILE"
else
log_msg "[*] Step 2/4: Skipping file update (same version, force mode)."
fi
# Step 3: Rebuild nfqws with verification
log_msg "[*] Step 3/4: Rebuilding nfqws..."
if ! rebuild_nfqws; then
log_msg "[CRITICAL] Build failed. Aborting."
if [[ "$mode" == "interactive" ]]; then
read -rp "Press Enter to exit..."
fi
exit 1
fi
# Step 4: Auto-test and install
log_msg "[*] Step 4/4: Auto-testing strategies..."
if run_autotest_pipeline; then
log_msg "[SUCCESS] Pipeline complete: updated, built, tested, installed."
else
log_msg "[WARNING] Build OK, but no working strategy found."
log_msg " You may need to adjust parameters manually."
fi
if [[ "$mode" == "interactive" ]]; then
echo ""
print_green "=============================================="
print_green " Full Pipeline Complete!"
print_green " Version: $(cat "$LOCAL_VERSION_FILE" 2>/dev/null || echo $LOCAL_VERSION)"
print_green "=============================================="
echo ""
systemctl status zapret --no-pager 2>/dev/null || true
fi
}
# Auto mode (for cron/systemd timers)
auto_mode() {
log_msg "Auto-update started..."
local remote_version
remote_version=$(check_remote_version) || {
log_msg "Update check failed. Exiting."
exit 1
}
if [[ "$remote_version" == "$LOCAL_VERSION" ]]; then
log_msg "No update needed."
if [[ "$need_rebuild" -eq 0 ]]; then
log_msg "[*] No rebuild needed. Exiting."
exit 0
fi
log_msg "New version found: $remote_version"
full_pipeline auto no
# Step 1: Update version marker
log_msg "[*] Step 1: Updating version marker..."
local upstream_ver
upstream_ver=$(cat "$LOCAL_VERSION_FILE" 2>/dev/null || echo "$LOCAL_VERSION")
echo "$upstream_ver" > "$LOCAL_VERSION_FILE"
# Step 2: Rebuild nfqws
log_msg "[*] Step 2: Rebuilding nfqws..."
if ! rebuild_nfqws; then
log_msg "[CRITICAL] Build failed. Aborting."
exit 1
fi
# Step 3: Auto-test
log_msg "[*] Step 3: Auto-testing strategies..."
run_pipeline_autotest || true
# Step 4: Restart
log_msg "[*] Step 4: Restarting service..."
restart_service
log_msg "[SUCCESS] Full pipeline complete."
[[ "$mode" == "interactive" ]] && {
echo ""
print_green "=============================================="
print_green " Pipeline Complete!"
print_green " Version: $(cat "$LOCAL_VERSION_FILE" 2>/dev/null || echo "$LOCAL_VERSION")"
print_green "=============================================="
systemctl status zapret --no-pager 2>/dev/null || true
}
}
# Non-interactive cron mode
auto_mode() {
log_msg "Auto-update started..."
log_msg "[*] Syncing upstream..."
bash "$SCRIPT_DIR/sync_from_upstream.sh" --auto 2>&1 | tee -a "$UPDATE_LOG"
local sync_status=${PIPESTATUS[0]}
if [[ "$sync_status" -ne 2 ]]; then
log_msg "No update needed or sync failed. Exiting."
exit 0
fi
log_msg "Update detected, running full pipeline..."
rebuild_nfqws || { log_msg "[FAIL] Rebuild failed."; exit 1; }
run_pipeline_autotest || true
restart_service
log_msg "Auto-update finished."
}
@@ -246,48 +185,29 @@ FORCE="no"
while [[ $# -gt 0 ]]; do
case "$1" in
--auto|-a)
MODE="auto"
shift
;;
--force|-f)
FORCE="yes"
shift
;;
--full-auto)
# Fully non-interactive: even if same version, rebuild and re-test
MODE="auto"
FORCE="yes"
shift
;;
--auto|-a) MODE="auto"; shift ;;
--force|-f) FORCE="yes"; shift ;;
--full-auto) MODE="auto"; FORCE="yes"; shift ;;
--help|-h)
cat <<EOF
Usage: $0 [OPTIONS]
Usage: sudo ./update.sh [OPTIONS]
Zapret Update Pipeline: checks version → updates files → rebuilds nfqws → auto-tests → installs.
Full pipeline: sync upstream lists/hosts/version → rebuild nfqws → test → install.
Options:
--auto, -a Non-interactive mode (for cron/systemd timers)
--auto, -a Non-interactive (for cron/systemd timers)
--force, -f Force rebuild even if versions match
--full-auto Same as --auto --force (rebuild + re-test always)
--full-auto Same as --auto --force (always rebuild + re-test)
--help, -h Show this help
Interactive mode (default):
sudo ./update.sh
Full automation (no questions, always rebuilds and re-tests):
sudo ./update.sh --full-auto
For systemd timer (daily auto-update):
sudo ./update.sh --auto
Examples:
sudo ./update.sh # interactive prompt
sudo ./update.sh --full-auto # headless, always rebuild
sudo ./update.sh --auto # headless, only if upstream changed
EOF
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage."
exit 1
;;
*) echo "Unknown: $1"; exit 1 ;;
esac
done