#!/bin/bash # ============= MAIN INSTALLER SCRIPT ============= # Premium Installer with License Validation # ================================================= # Check if running as root if [ "$EUID" -ne 0 ]; then echo "Please run as root (use: sudo bash $0)" exit 1 fi # ========= CONFIGURATION ========= LICENSE_SERVER="https://ghcptz-5000.csb.app/api" CACHE_DIR="/etc/panel_installer" LICENSE_CACHE="$CACHE_DIR/license.cache" VALIDATION_FLAG="$CACHE_DIR/.validated" HWID_FILE="$CACHE_DIR/hwid" # ========= LICENSE VALIDATION ========= validate_license() { # Check if already validated in this session if [ -f "$VALIDATION_FLAG" ]; then return 0 fi # Check for cached validation if [ -f "$LICENSE_CACHE" ]; then local cached_key=$(grep -o '"license_key":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) local cached_hwid=$(grep -o '"hwid":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) local current_hwid=$(generate_hwid) if [ -n "$cached_key" ] && [ "$cached_hwid" = "$current_hwid" ]; then local validated_at=$(grep -o '"validated_at":[0-9]*' "$LICENSE_CACHE" | cut -d: -f2) local current_time=$(date +%s) local cache_age=$((current_time - validated_at)) local max_offline_age=604800 # 7 days if [ $cache_age -lt $max_offline_age ]; then # Mark as validated for this session touch "$VALIDATION_FLAG" return 0 else echo "License cache expired, re-validating..." fi fi fi # Show license prompt echo "========================================" echo " PREMIUM INSTALLER - LICENSE CHECK " echo "========================================" echo "" echo "This installer requires a valid license key." echo "Please enter your license key below." echo "" echo "Format: XXXXX-XXXXX-XXXXX-XXXXX" echo "" local attempts=0 local max_attempts=3 while [ $attempts -lt $max_attempts ]; do read -rp "License Key: " license_key # Clean input license_key=$(echo "$license_key" | tr '[:lower:]' '[:upper:]' | tr -d '[:space:]') # Check if user wants to exit if [ "$license_key" = "EXIT" ] || [ "$license_key" = "QUIT" ]; then echo "Installation cancelled" exit 1 fi # Validate format - Fixed to match 5-5-5-5 format if ! echo "$license_key" | grep -qE '^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$'; then echo "✗ Invalid format. Expected: XXXXX-XXXXX-XXXXX-XXXXX" attempts=$((attempts + 1)) echo "" continue fi # Validate with server if validate_with_server "$license_key"; then # Mark as validated for this session touch "$VALIDATION_FLAG" echo "" return 0 else attempts=$((attempts + 1)) if [ $attempts -lt $max_attempts ]; then echo "Please try again ($((max_attempts - attempts)) attempts remaining)" echo "" fi fi done echo "✗ Maximum attempts reached. Exiting." exit 1 } # ========= HELPER FUNCTIONS ========= generate_hwid() { if [ -f "$HWID_FILE" ]; then cat "$HWID_FILE" return fi local hwid_parts="" # Collect system information if [ -f "/etc/machine-id" ]; then hwid_parts="${hwid_parts}$(cat /etc/machine-id 2>/dev/null || echo "NOMACHINEID")" fi if [ -f "/proc/cpuinfo" ]; then cpu_id=$(grep -m1 "serial" /proc/cpuinfo 2>/dev/null | awk '{print $3}') if [ -n "$cpu_id" ]; then hwid_parts="${hwid_parts}${cpu_id}" else cpu_model=$(grep -m1 "model name" /proc/cpuinfo 2>/dev/null | md5sum | cut -c1-16) hwid_parts="${hwid_parts}${cpu_model}" fi fi mac_address=$(ip link show 2>/dev/null | awk '/ether/ {print $2; exit}' | tr -d ':') if [ -n "$mac_address" ]; then hwid_parts="${hwid_parts}${mac_address}" fi if [ -z "$hwid_parts" ]; then hwid_parts=$(date +%s%N | sha256sum | head -c 32) fi HWID=$(echo -n "$hwid_parts" | sha256sum | awk '{print $1}') echo "$HWID" > "$HWID_FILE" chmod 600 "$HWID_FILE" echo "$HWID" } validate_with_server() { local license_key="$1" local hwid=$(generate_hwid) local hostname=$(hostname) local ip_address=$(hostname -I | awk '{print $1}' 2>/dev/null || echo "127.0.0.1") echo -n "Validating license" for i in {1..3}; do echo -n "." sleep 0.3 done echo "" # Debug: Show request details # echo "DEBUG: License: $license_key" # echo "DEBUG: HWID: $hwid" # echo "DEBUG: Hostname: $hostname" # echo "DEBUG: Server: $LICENSE_SERVER/validate" local response=$(curl -s -X POST "$LICENSE_SERVER/validate" \ -H "Content-Type: application/json" \ -d "{\"license_key\":\"$license_key\",\"hwid\":\"$hwid\",\"hostname\":\"$hostname\"}" \ --max-time 10 2>/dev/null) # Debug: Show full response # echo "DEBUG: Response: $response" if [ $? -eq 0 ] && [ -n "$response" ]; then # Check if valid field exists and is true local valid=$(echo "$response" | grep -o '"valid":[^,}]*' | cut -d: -f2 | tr -d ' "') # Debug: echo "DEBUG: Valid field: '$valid'" if [ "$valid" = "true" ]; then # Cache the successful validation cat > "$LICENSE_CACHE" << EOF { "license_key": "$license_key", "hwid": "$hwid", "hostname": "$hostname", "ip_address": "$ip_address", "validated_at": $(date +%s), "validated_date": "$(date '+%Y-%m-%d %H:%M:%S')" } EOF chmod 600 "$LICENSE_CACHE" echo "✓ License validated successfully!" # Also extract and show the message local message=$(echo "$response" | grep -o '"message":"[^"]*"' | cut -d'"' -f4) if [ -n "$message" ]; then echo "Message: $message" fi return 0 else # Try to get error message local message=$(echo "$response" | grep -o '"message":"[^"]*"' | cut -d'"' -f4) if [ -n "$message" ]; then echo "✗ $message" else # Try alternative parsing for message message=$(echo "$response" | sed -n 's/.*"message":"\([^"]*\)".*/\1/p') if [ -n "$message" ]; then echo "✗ $message" else echo "✗ License invalid (no valid field in response)" # Debug: echo "Full response: $response" fi fi return 1 fi else if [ $? -eq 28 ]; then echo "✗ Connection timeout. Please check your internet connection." elif [ $? -eq 7 ]; then echo "✗ Cannot connect to license server. Make sure it's running." else echo "✗ Failed to validate license (server error or no response)" fi return 1 fi } display_license_info() { if [ -f "$LICENSE_CACHE" ]; then echo -e "\n${CYAN}=== LICENSE INFORMATION ===${NC}" # Extract license info cached_key=$(grep -o '"license_key":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) hwid=$(grep -o '"hwid":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) hostname=$(grep -o '"hostname":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) ip_address=$(grep -o '"ip_address":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) validated_at=$(grep -o '"validated_at":[0-9]*' "$LICENSE_CACHE" | cut -d: -f2) validated_date=$(grep -o '"validated_date":"[^"]*"' "$LICENSE_CACHE" 2>/dev/null | cut -d'"' -f4) # Display license info if [ -n "$cached_key" ]; then # Format: XXXXX-XXXXX-XXXXX-XXXXX if echo "$cached_key" | grep -qE '^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$'; then echo "License: $cached_key" else echo "License: ${cached_key:0:8}...${cached_key: -4}" fi # Display status current_hwid=$(generate_hwid) if [ "$hwid" = "$current_hwid" ]; then echo "Status: ${GREEN}Valid ✓${NC}" else echo "Status: ${YELLOW}HWID Mismatch ⚠${NC}" fi # Display machine info if [ -n "$hostname" ]; then echo "Hostname: $hostname" fi if [ -n "$ip_address" ]; then echo "IP Address: $ip_address" fi # Display validation time if [ -n "$validated_date" ]; then echo "Validated: $validated_date" elif [ -n "$validated_at" ]; then validated_date=$(date -d "@$validated_at" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "Unknown") echo "Validated: $validated_date" fi # Check if validation is recent (within 7 days) if [ -n "$validated_at" ]; then current_time=$(date +%s) cache_age=$((current_time - validated_at)) max_offline_age=604800 # 7 days if [ $cache_age -gt $max_offline_age ]; then echo -e "${YELLOW}Warning: License cache expired (${cache_age} seconds old)${NC}" fi fi else echo "License: Not found in cache" fi else echo -e "\n${CYAN}=== LICENSE INFORMATION ===${NC}" echo "No license information available" fi } # ========= INITIAL SETUP ========= # Create cache directory mkdir -p "$CACHE_DIR" chmod 700 "$CACHE_DIR" # Colors for output RED='\033[1;31m' GREEN='\033[1;32m' YELLOW='\033[1;33m' BLUE='\033[1;34m' CYAN='\033[1;36m' NC='\033[0m' # Run license validation (only if needed) validate_license # ========= CONTINUE WITH NORMAL INSTALLER ========= # Define module directory MODULE_DIR="/tmp/panel_installer_modules" # Clean up previous modules rm -rf "$MODULE_DIR" mkdir -p "$MODULE_DIR" # Download all modules from GitHub download_module() { local module_name="$1" local url="https://raw.githubusercontent.com/TS-25/SRJ-THEME/main/${module_name}.sh" echo "Downloading $module_name..." if curl -s "$url" -o "$MODULE_DIR/$module_name.sh"; then chmod +x "$MODULE_DIR/$module_name.sh" echo "✓ $module_name downloaded" return 0 else echo "✗ Failed to download $module_name" return 1 fi } # Simple logging functions (will be overridden by core_setup) print_success() { echo -e "${GREEN}✓${NC} $1"; } print_error() { echo -e "${RED}✗${NC} $1"; } print_warning() { echo -e "${YELLOW}⚠${NC} $1"; } print_info() { echo -e "${BLUE}ℹ${NC} $1"; } # Simple display header (will be overridden by core_setup) display_header() { clear echo -e "${CYAN}" echo "╔══════════════════════════════════════╗" echo "║ PREMIUM PANEL INSTALLER ║" echo "║ License Verified ✓ ║" echo "╚══════════════════════════════════════╝${NC}" echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "" } # Simple main menu (will be overridden by loaded modules) show_main_menu() { echo "Main Menu:" echo "1) Install Panels" echo "2) Install Themes" echo "3) Install Addons" echo "4) System Information" echo "5) Exit" echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } # Download required modules echo "" print_info "Downloading installer modules..." if download_module "core_setup" && \ download_module "panel_installer" && \ download_module "theme_installer" && \ download_module "addon_installer"; then # Load all modules if source "$MODULE_DIR/core_setup.sh" 2>/dev/null; then print_success "Core module loaded" else print_error "Failed to load core module" exit 1 fi if source "$MODULE_DIR/panel_installer.sh" 2>/dev/null; then print_success "Panel module loaded" else print_warning "Panel module failed to load" fi if source "$MODULE_DIR/theme_installer.sh" 2>/dev/null; then print_success "Theme module loaded" else print_warning "Theme module failed to load" fi if source "$MODULE_DIR/addon_installer.sh" 2>/dev/null; then print_success "Addon module loaded" else print_warning "Addon module failed to load" fi print_success "All modules loaded successfully!" echo "" else print_error "Failed to download required modules" echo "Please check your internet connection and try again." exit 1 fi # ========= MAIN LOOP ========= while true; do display_header show_main_menu read -rp "Select option: " main_choice case $main_choice in 1) # Panels if type show_panel_menu &>/dev/null && type handle_panel_choice &>/dev/null; then while true; do display_header show_panel_menu if ! handle_panel_choice; then break fi echo -e "\n${YELLOW}Press Enter to continue...${NC}" read -r done else print_error "Panel installer module not available" sleep 2 fi ;; 2) # Themes if type show_theme_menu &>/dev/null && type handle_theme_choice &>/dev/null; then while true; do display_header show_theme_menu if ! handle_theme_choice; then break fi echo -e "\n${YELLOW}Press Enter to continue...${NC}" read -r done else print_error "Theme installer module not available" sleep 2 fi ;; 3) # Addons if type show_addon_menu &>/dev/null && type handle_addon_choice &>/dev/null; then while true; do display_header show_addon_menu if ! handle_addon_choice; then break fi echo -e "\n${YELLOW}Press Enter to continue...${NC}" read -r done else print_error "Addon installer module not available" sleep 2 fi ;; 4) # System Info display_header echo -e "${CYAN}=== SYSTEM INFORMATION ===${NC}" # Detect panel PANEL_PATH="" if [ -d "/var/www/pterodactyl" ]; then PANEL_PATH="/var/www/pterodactyl" PANEL_TYPE="Pterodactyl" elif [ -d "/var/www/reviactyl" ]; then PANEL_PATH="/var/www/reviactyl" PANEL_TYPE="Reviactyl" elif [ -d "/var/www/panel" ]; then PANEL_PATH="/var/www/panel" PANEL_TYPE="Generic" fi echo "Panel Type: ${PANEL_TYPE:-Not detected}" echo "Panel Path: ${PANEL_PATH:-Not found}" echo "Blueprint: $(command -v blueprint >/dev/null && echo "Installed" || echo "Not installed")" echo "System: $(uname -s -r)" echo "Hostname: $(hostname)" echo "IP Address: $(hostname -I | awk '{print $1}' 2>/dev/null || echo "Not available")" # Display license information display_license_info echo -e "\n${YELLOW}Press Enter to continue...${NC}" read -r ;; 5) # Exit display_header echo "Thank you for using Premium Panel Installer!" echo "" print_success "Goodbye!" # Clean up session validation flag rm -f "$VALIDATION_FLAG" exit 0 ;; *) print_error "Invalid option" sleep 1 ;; esac done