#!/bin/bash
clear
BLACK='\033[90m'
RED='\033[91m'
GREEN='\033[92m'
YELLOW='\033[93m'
BLUE='\033[94m'
MAGENTA='\033[95m'
CYAN='\033[96m'
WHITE='\033[97m'
ORANGE='\033[38;5;214m'
PURPLE='\033[38;5;129m'
PINK='\033[38;5;213m'
LIME='\033[38;5;118m'
TEAL='\033[38;5;123m'
RESET='\033[0m'
iptables_1="官方:yumo工作室"
iptables_2="作者:雨沫"
iptables_3="版本:定制 三角洲行动"
if [[ "$(id -u)" -ne 0 ]]; then
    echo -e "${RED} 请使用ROOT权限运行此自动化程序${RESET}"
    exit 0
fi
package_name="com.tencent.tmgp.dfm"
target_app="$package_name"
rule_file_path="/storage/emulated/0/配置文件/读取文件.json"
preload_file_path="/data/local/tmp/预挂载.json"
skip_ips=() #跳过IP
skip_ports=(65010) #跳过端口
skip_patterns=() #跳过格式 
interception_enabled=true
mkdir -p "$(dirname "$rule_file_path")"
echo -e "${CYAN}"
cat << "EOF"
 ███████╗██╗██████╗ ████████╗ █████╗ ██████╗ ██╗     ███████╗
██╔════╝██║██╔══██╗╚══██╔══╝██╔══██╗██╔══██╗██║     ██╔════╝
█████╗  ██║██████╔╝   ██║   ███████║██████╔╝██║     ███████╗
██╔══╝  ██║██╔═══╝    ██║   ██╔══██║██╔══██╗██║     ╚════██║
██║     ██║██║        ██║   ██║  ██║██████╔╝███████╗███████║
╚═╝     ╚═╝╚═╝        ╚═╝   ╚═╝  ╚═╝╚═════╝ ╚══════╝╚══════╝
EOF
echo -e "\033[1;31m        ╔═════════════════════════════════════════╗${RESET}"
echo -e "${CYAN}       🏮                                         🏮${RESET}"
echo -e "       \033[1;33m ▣ ${iptables_1} \033[1;31m◈ \033[1;32m${iptables_2} \033[1;33m \033[38;5;213m◈ \033[1;36m${iptables_3} ${RESET}\n"
echo -e "${BLACK}上分需演戏,娱乐请随意。${RESET}"
echo -e "${BLACK}禁止参与非法乱纪活动,违反者由个人承担相应责任！${RESET}"
echo -e "${BLACK}系统: eBPF内核层无规则动态挂载${RESET}"
echo -e "${MAGENTA}目标:$package_name${RESET}"

is_app_running() {
    local running=$(ps -A -o PID,NAME | grep -F "$package_name" | grep -v grep)
    if [ -n "$running" ]; then
        return 0
    fi
    local am_running=$(am stack list | grep -F "$package_name" >/dev/null && echo "yes" || echo "no")
    if [ "$am_running" == "yes" ]; then
        return 0
    fi
    return 1
}

if ! is_app_running; then
    echo -e "${ORANGE}[*] 启动游戏中...${RESET}"
    am start -n $package_name/com.epicgames.ue4.SplashActivity > /dev/null 2>&1
fi

is_valid_ipv4() {
    local ip="$1"
    if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        local IFS='.'
        local -a octets=($ip)
        for octet in "${octets[@]}"; do
            if [[ "$octet" -lt 0 || "$octet" -gt 255 ]]; then
                return 1
            fi
        done
        return 0
    fi
    return 1
}

is_valid_ipv6() {
    local ip="$1"
    if [[ "$ip" =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$ ]] || 
       [[ "$ip" =~ ^::([0-9a-fA-F]{0,4}:){0,6}[0-9a-fA-F]{0,4}$ ]] ||
       [[ "$ip" =~ ^([0-9a-fA-F]{0,4}:){1,6}:[0-9a-fA-F]{0,4}$ ]] ||
       [[ "$ip" =~ ^([0-9a-fA-F]{0,4}:){1,7}:$ ]]; then
        return 0
    fi
    return 1
}

is_valid_ip() {
    local ip="$1"
    if is_valid_ipv4 "$ip" || is_valid_ipv6 "$ip"; then
        return 0
    fi
    return 1
}

is_valid_port() {
    local port="$1"
    if [[ "$port" =~ ^[0-9]+$ ]] && [ "$port" -ge 1 ] && [ "$port" -le 65535 ]; then
        return 0
    fi
    return 1
}

get_ip_version() {
    local ip="$1"
    if is_valid_ipv6 "$ip"; then
        echo "IPv6"
    elif is_valid_ipv4 "$ip"; then
        echo "IPv4"
    else
        echo "Unknown"
    fi
}

should_skip() {
    local ip="$1"
    local port="$2"
    local line="$3"
    if ! is_valid_ip "$ip" || ! is_valid_port "$port"; then
        echo -e "${BLUE}[-] 无效IP或端口: IP:$ip 端口:$port${RESET}"
        return 0
    fi
    for skip_ip in "${skip_ips[@]}"; do
        if [ "$ip" == "$skip_ip" ]; then
            echo -e "${BLUE}[-] 跳过白名单IP: $ip${RESET}"
            return 0
        fi
    done
    for skip_port in "${skip_ports[@]}"; do
        if [ "$port" == "$skip_port" ]; then
            echo -e "${BLUE}[-] 跳过白名单端口: $port${RESET}"
            return 0
        fi
    done
    for pattern in "${skip_patterns[@]}"; do
        if [[ "$line" == *"$pattern"* ]]; then
            echo -e "${BLUE}[-] 跳过匹配模式: $pattern${RESET}"
            return 0
        fi
    done
    return 1
}

monitor_packets() {
    local remote_ip="$1"
    local port="$2"
    local direction="$3"
    if ! is_valid_ip "$remote_ip" || ! is_valid_port "$port"; then
        echo -e "${RED}[!] 跳过无效的IP或端口: IP:$remote_ip 端口:$port${RESET}"
        return 1
    fi
    tcpdump -i any -s 0 -A "host $remote_ip and port $port" 2>/dev/null | while read -r packet; do
        for pattern in "${skip_patterns[@]}"; do
            if [[ "$packet" == *"$pattern"* ]]; then
                continue 2
            fi
        done
        if [[ "$packet" =~ "TLS" ]] || [[ "$packet" =~ "SSL" ]] || [[ "$packet" =~ "encrypted" ]] || 
           [[ "$packet" =~ "Encrypted" ]] || [[ "$packet" =~ "Cipher" ]] || [[ "$packet" =~ "cipher" ]]; then
            echo -e "${LIME}[加密数据$direction] IP:$remote_ip 端口:$port - 检测到加密流量${RESET}"
        elif [[ "$packet" =~ "GET" ]] || [[ "$packet" =~ "POST" ]] || [[ "$packet" =~ "HTTP" ]]; then
            echo -e "${PINK}[明文数据$direction] IP:$remote_ip 端口:$port - $packet${RESET}" | head -c 999999
        else
            echo -e "${TEAL}[数据包$direction] IP:$remote_ip 端口:$port - $packet${RESET}" | head -c 999999
        fi
    done &
}

extract_ip_port() {
    local line="$1"
    local ip_port=$(echo "$line" | awk '{print $5}')
    if [ -n "$ip_port" ]; then
        local remote_ip=$(echo "$ip_port" | cut -d':' -f1)
        local port=$(echo "$ip_port" | cut -d':' -f2)
        port=$(echo "$port" | tr -cd '[:digit:]')
        if [ -z "$port" ] || [ -z "$remote_ip" ]; then
            return 1
        fi
        echo "$remote_ip $port"
        return 0
    fi
    return 1
}

cleanup_interception_rules() {
    echo -e "${YELLOW}[*] 正在清理挂载...${RESET}"
    if [ -f "$rule_file_path" ]; then
        echo -e "${YELLOW}[*] 正在备份数据到预挂载文件中...${RESET}"
        cp "$rule_file_path" "$preload_file_path" 2>/dev/null
        if [ $? -eq 0 ]; then
            echo -e "${GREEN}[✓] 数据已备份成功: $(basename "$preload_file_path")${RESET}"
        else
            echo -e "${RED}[!] 规则备份失败${RESET}"
        fi
    fi
    local cleaned_count=0
    if [ -f "$rule_file_path" ]; then
        while IFS= read -r rule; do
            if [ -n "$rule" ]; then
                local remote_ip=$(echo "$rule" | cut -d':' -f1)
                local port=$(echo "$rule" | cut -d':' -f2)
                if is_valid_ip "$remote_ip" && is_valid_port "$port"; then
                    ip_version=$(get_ip_version "$remote_ip")
                    if [ "$ip_version" == "IPv4" ]; then
                        iptables -w 1 -D INPUT -s "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
                        iptables -w 1 -D INPUT -s "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
                        iptables -w 1 -D OUTPUT -d "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
                        iptables -w 1 -D OUTPUT -d "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
                        echo -e "${BLUE}[清理] IPv4挂载: IP:$remote_ip 端口:$port${RESET}"
                        ((cleaned_count++))
                    elif [ "$ip_version" == "IPv6" ]; then
                        ip6tables -w 1 -D INPUT -s "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
                        ip6tables -w 1 -D INPUT -s "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
                        ip6tables -w 1 -D OUTPUT -d "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
                        ip6tables -w 1 -D OUTPUT -d "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
                        echo -e "${BLUE}[清理] IPv6挂载: IP:$remote_ip 端口:$port${RESET}"
                        ((cleaned_count++))
                    fi
                fi
            fi
        done < "$rule_file_path"
        > "$rule_file_path"
    fi
    echo -e "${GREEN}[✓] $cleaned_count条挂载清理完成${RESET}"
}

cleanup() {
    echo -e "${YELLOW}[*] 正在清理残留痕迹...${RESET}"
    directories=(
        "/data/data/com.tencent.tmgp.codev/files/ano_tmp"
        "/data/data/com.tencent.tmgp.codev/files/tdm_tmp"
        "/storage/emulated/0/配置文件"
    )
    for dir in "${directories[@]}"; do
        if [ -d "$dir" ]; then
            rm -rf "$dir"
            if [ $? -eq 0 ]; then
                echo -e "${GREEN}[✓] 已清理: $(basename "$dir")${RESET}"
            else
                echo -e "${RED}[!] 清理失败: $(basename "$dir")${RESET}"
            fi
        else
            echo -e "${BLUE}[*] 目录不存在: $(basename "$dir")${RESET}"
        fi
    done
    echo -e "${GREEN}[✓] 残留痕迹-清理完成${RESET}"
}

reload_saved_rules() {
    echo -e "${YELLOW}[*] 正在重新挂载拦截...${RESET}"
    local source_file="$preload_file_path"
    if [ ! -f "$source_file" ]; then
        echo -e "${RED}[!] 文件不存在: 预挂载.json${RESET}"
        return 1
    fi
    
    local reload_count=0
    while IFS= read -r rule; do
        if [ -n "$rule" ]; then
            local remote_ip=$(echo "$rule" | cut -d':' -f1)
            local port=$(echo "$rule" | cut -d':' -f2)
            if ! is_valid_ip "$remote_ip" || ! is_valid_port "$port"; then
                echo -e "${RED}[!] 跳过无效规则: $remote_ip:$port${RESET}"
                continue
            fi
            if should_skip "$remote_ip" "$port" "$rule"; then
                continue
            fi
            ip_version=$(get_ip_version "$remote_ip")
            if [ "$ip_version" == "Unknown" ]; then
                echo -e "${RED}[!] 未知IP版本: $remote_ip${RESET}"
                continue
            fi
            rule_check_result=$(check_rule_exists "$remote_ip" "$port" "$ip_version")
            rule_exists_input=$(echo "$rule_check_result" | awk '{print $1}')
            rule_exists_output=$(echo "$rule_check_result" | awk '{print $2}')
            if [ "$rule_exists_input" == "no" ] || [ "$rule_exists_output" == "no" ]; then
                if add_interception_rules "$remote_ip" "$port" "$ip_version"; then
                    if ! grep -F -q "$remote_ip:$port" "$rule_file_path" 2>/dev/null; then
                        echo "$remote_ip:$port" >> "$rule_file_path"
                    fi
                    echo -e "${GREEN}[+] 重挂载[$ip_version]: IP:$remote_ip 端口:$port${RESET}"
                    ((reload_count++))
                else
                    echo -e "${RED}[!] 重挂载失败[$ip_version]: IP:$remote_ip 端口:$port${RESET}"
                fi
            else
                echo -e "${BLACK}[*] 规则已存在[$ip_version]: IP:$remote_ip 端口:$port${RESET}"
            fi
        fi
    done < "$source_file"
    echo -e "${GREEN}[✓] 完成$reload_count预挂载规则${RESET}"
    return 0
}

handle_user_input() {
    local input_chars=""
    while IFS= read -t 0.01 -n 1 -r char 2>/dev/null; do
        if [ -n "$char" ]; then
            input_chars="${input_chars}${char}"
        fi
    done
    for (( i=0; i<${#input_chars}; i++ )); do
        local user_input="${input_chars:$i:1}"
        case "$user_input" in
            "0")
                if [ "$interception_enabled" = true ]; then
                    interception_enabled=false
                    echo -e "${RED}[!] 挂载功能-已关闭${RESET}"
                    cleanup_interception_rules
                else
                    echo -e "${YELLOW}[提示] 挂载功能已经处于-关闭状态${RESET}"
                fi
                ;;
            "1")
                if [ "$interception_enabled" = false ]; then
                    interception_enabled=true
                    echo -e "${GREEN}[!] 挂载功能-已开启${RESET}"
                    reload_saved_rules
                else
                    echo -e "${YELLOW}[提示] 规则功能已经处于-开启状态${RESET}"
                fi
                ;;
            "q"|"Q")
                echo -e "${YELLOW}[!] 退出脚本-重启设备${RESET}"
                cleanup_interception_rules
                cleanup
                pkill tcpdump 2>/dev/null
                sleep 2
                reboot
                ;;
            *)
                if [[ ! "$user_input" =~ [[:space:]] ]] && [ -n "$user_input" ]; then
                    echo -e "${RED}[!] 无效输入: '$user_input'${RESET}"
                fi
                ;;
        esac
    done
    while read -t 0 -n 100; do :; done
}

check_rule_exists() {
    local remote_ip="$1"
    local port="$2"
    local ip_version="$3"
    
    if [ "$ip_version" == "IPv4" ]; then
        rule_exists_input=$(iptables -w 1 -L INPUT -n 2>/dev/null | grep -F "$remote_ip" | grep -F "dpt:$port" >/dev/null && echo "yes" || echo "no")
        rule_exists_output=$(iptables -w 1 -L OUTPUT -n 2>/dev/null | grep -F "$remote_ip" | grep -F "dpt:$port" >/dev/null && echo "yes" || echo "no")
    elif [ "$ip_version" == "IPv6" ]; then
        rule_exists_input=$(ip6tables -w 1 -L INPUT -n 2>/dev/null | grep -F "$remote_ip" | grep -F "dpt:$port" >/dev/null && echo "yes" || echo "no")
        rule_exists_output=$(ip6tables -w 1 -L OUTPUT -n 2>/dev/null | grep -F "$remote_ip" | grep -F "dpt:$port" >/dev/null && echo "yes" || echo "no")
    else
        rule_exists_input="no"
        rule_exists_output="no"
    fi
    
    echo "$rule_exists_input $rule_exists_output"
}

add_interception_rules() {
    local remote_ip="$1"
    local port="$2"
    local ip_version="$3"
    local success=0
    if [ "$ip_version" == "IPv4" ]; then
        iptables -w 1 -A INPUT -s "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
        iptables -w 1 -A INPUT -s "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
        iptables -w 1 -A OUTPUT -d "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
        iptables -w 1 -A OUTPUT -d "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
        success=$?
    elif [ "$ip_version" == "IPv6" ]; then
        ip6tables -w 1 -A INPUT -s "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
        ip6tables -w 1 -A INPUT -s "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
        ip6tables -w 1 -A OUTPUT -d "$remote_ip" -p tcp --dport "$port" -j DROP 2>/dev/null
        ip6tables -w 1 -A OUTPUT -d "$remote_ip" -p udp --dport "$port" -j DROP 2>/dev/null
        success=$?
    else
        success=1
    fi
    return $success
}

echo -e "${YELLOW}[*] 初始化加载预挂载规则...${RESET}"
reload_saved_rules

while true; do
    handle_user_input
    if ! is_app_running; then
        echo -e "${RED}[-] 游戏进程结束${RESET}"
        cleanup_interception_rules
        cleanup
        pkill tcpdump 2>/dev/null
        exit 0
    fi
    if [ "$interception_enabled" = false ]; then
        continue
    fi
    connections=$(netstat -anp 2>/dev/null | grep -F "$target_app")
    if [ -n "$connections" ]; then
        while read -r line; do
            ip_port_result=$(extract_ip_port "$line")
            if [ $? -ne 0 ]; then
                continue
            fi
            remote_ip=$(echo "$ip_port_result" | awk '{print $1}')
            port=$(echo "$ip_port_result" | awk '{print $2}')
            
            if ! is_valid_ip "$remote_ip"; then
                echo -e "${RED}[!] 无效IP地址: $remote_ip${RESET}"
                continue
            fi
            
            if ! is_valid_port "$port"; then
                echo -e "${RED}[!] 无效端口: $port${RESET}"
                continue
            fi
            
            if should_skip "$remote_ip" "$port" "$line"; then
                continue
            fi
            
            ip_version=$(get_ip_version "$remote_ip")
            if [ "$ip_version" == "Unknown" ]; then
                echo -e "${RED}[!] 未知IP版本: $remote_ip${RESET}"
                continue
            fi
            
            rule_check_result=$(check_rule_exists "$remote_ip" "$port" "$ip_version")
            rule_exists_input=$(echo "$rule_check_result" | awk '{print $1}')
            rule_exists_output=$(echo "$rule_check_result" | awk '{print $2}')
            
            if [ "$rule_exists_input" == "no" ] || [ "$rule_exists_output" == "no" ]; then
                if add_interception_rules "$remote_ip" "$port" "$ip_version"; then
                    echo -e "${GREEN}[+] 持续挂载[$ip_version]: IP:$remote_ip 端口:$port${RESET}"
                    monitor_packets "$remote_ip" "$port" "入站" &
                    monitor_packets "$remote_ip" "$port" "出站" &
                    if ! grep -F -q "$remote_ip:$port" "$rule_file_path" 2>/dev/null; then
                        echo "$remote_ip:$port" >> "$rule_file_path"
                        echo -e "${BLUE}[+] 已记录挂载到文件: $remote_ip:$port${RESET}"
                    fi
                else
                    echo -e "${RED}[!] 添加挂载失败[$ip_version]: IP:$remote_ip 端口:$port${RESET}"
                fi
            else
                echo -e "${BLACK}[*] 已存在挂载[$ip_version]: IP:$remote_ip 端口:$port${RESET}"
            fi
        done <<< "$connections"
    fi
done