Files
zapret-discord-youtube-linux/run_strategy.sh

136 lines
3.8 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")
# Remove surrounding quotes added by .bat conversion around path args
rule_value=$(echo "$rule_value" | sed -E 's/="([^"]*)"/=\1/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)"
cleanup_tmp() { rm -f "$TMP_ARGS" 2>/dev/null || true; }
trap cleanup_tmp 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