Files
zapret-discord-youtube-linux/run_strategy.sh
OpenCode Agent 62ec6c5749 fix(core): critical fixes for service menu, autotest, strategy runner, dependencies
- 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.
2026-05-10 22:47:48 +04:00

132 lines
3.6 KiB
Bash
Executable File

#!/bin/bash
# run_strategy.sh - Generic strategy runner using .conf files
# Loads strategies/strategy_name.conf, substitutes variables, runs nfqws.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
# Require root for firewall/nfqueue manipulation
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
print_red "[!] This script must be run as root (or with sudo)"
echo " sudo $0"
exit 1
fi
STRATEGY="${1:-general}"
CONF_FILE="$SCRIPT_DIR/strategies/${STRATEGY}.conf"
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 setup
load_user_lists
get_game_filter
# Function to parse conf and build args
parse_conf_args() {
local conf="$1"
local -a args=()
while IFS= read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^# ]] && continue
[[ -z "$line" ]] && continue
[[ "$line" =~ ^RULE[0-9]+= ]] || continue
local rule_value="${line#*=}"
# 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")
# 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 into array
local rule_arr=()
read -ra rule_arr <<< "$rule_value"
for arg in "${rule_arr[@]}"; do
args+=("$arg")
done
args+=("--new")
done < "$conf"
# Remove trailing --new
local last_idx=$(( ${#args[@]} - 1 ))
if [[ $last_idx -ge 0 ]] && [[ "${args[$last_idx]}" == "--new" ]]; then
unset 'args[last_idx]'
fi
# Return via echo (space-separated, properly quoted)
printf '%s\n' "${args[@]}"
}
# Build args in main shell using temp file
cd "$SCRIPT_DIR"
TMP_ARGS="$(mktemp /tmp/zapret_args.XXXXXX)"
trap "rm -f '\$TMP_ARGS'" EXIT
parse_conf_args "$CONF_FILE" > "$TMP_ARGS"
# 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
# Read args into array from file
CLEAN_ARGS=()
while IFS= read -r arg; do
[[ -n "$arg" ]] && CLEAN_ARGS+=("$arg")
done < "$TMP_ARGS"
rm -f "$TMP_ARGS"
trap - EXIT
# Setup firewall and start nfqws
check_nfqws || exit 1
tcp_enable_timestamps
setup_firewall
# Trap cleanup on SIGTERM/SIGINT (e.g. from systemd or autotest kill)
cleanup_strategy() {
print_yellow ""
print_yellow "[*] Caught stop signal, cleaning up..."
pkill -f "nfqws.*qnum=$NFQUEUE_NUM" 2>/dev/null || true
cleanup_firewall >/dev/null 2>&1 || true
exit 0
}
trap cleanup_strategy SIGTERM SIGINT
echo ""
print_cyan "[*] Starting strategy: $STRATEGY"
print_cyan "[*] $(describe_strategy "$SCRIPT_DIR/general_${STRATEGY}.sh")"
echo ""
# Start nfqws in background so this shell handles signals and cleanup
"$BIN_DIR/nfqws" --qnum=$NFQUEUE_NUM "${CLEAN_ARGS[@]}" &
NFQWS_PID=$!
wait "$NFQWS_PID"
EXIT_CODE=$?
# If nfqws exited on its own, cleanup firewall
cleanup_firewall >/dev/null 2>&1 || true
exit $EXIT_CODE