#!/bin/bash source "$(dirname "$0")/common.sh" # Challenge categories and levels declare -A CHALLENGE_CATEGORIES=( ["file"]="File System Operations" ["perm"]="Permissions & Security" ["text"]="Text Processing" ["proc"]="Process Management" ["net"]="Network Operations" ) # Challenge definitions with detailed metadata # Format: type|name|difficulty|skills|task|hints|setup_requirements|verification_criteria declare -A CHALLENGES=( # Level 1: File Operations ["1.1"]="file_search|Find Recent Files|1|file_ops,search|Find all .conf files modified in the last 24 hours and save the list to recent_configs.txt|Try using find with -mtime|none|output_file=recent_configs.txt;file_count=10" ["1.2"]="file_count|File Statistics|1|file_ops,search|Generate a report showing count of files by extension|Consider using find and awk|none|report_exists=true;extension_count=5" ["1.3"]="file_organize|Smart File Organizer|2|file_ops|Create directories for different file types and sort files accordingly|Look into file command|none|dir_structure=complete;files_sorted=true" ["1.4"]="file_cleanup|System Cleanup|2|file_ops,search|Find and list all empty files and zero-byte files|Combine find with size tests|none|empty_files_found=true;report_generated=true" ["1.5"]="file_dedup|Duplicate Hunter|3|file_ops,search|Find and handle duplicate files using md5sum|Consider using sort and uniq|none|duplicates_identified=true;report_accurate=true" # Level 2: Permissions ["2.1"]="perm_basic|Permission Fundamentals|1|permissions|Set up basic file permissions following security best practices|Remember user-group-others order|users=app_user1|permissions_correct=true;ownership_correct=true" ["2.2"]="perm_acl|ACL Master|2|permissions|Implement complex ACL rules for multiple users|Look into setfacl usage|users=app_user1,app_user2|acl_rules_correct=true" ["2.3"]="perm_special|Special Permission Bits|2|permissions|Configure SUID/SGID permissions correctly|Understanding special bits|none|special_bits_correct=true" ["2.4"]="perm_recursive|Directory Tree Fix|3|permissions|Fix permissions recursively while maintaining security|Consider find with exec|none|tree_permissions_correct=true" ["2.5"]="perm_audit|Security Auditor|3|permissions|Perform security audit and generate detailed report|Use stat and lsattr|none|audit_complete=true;report_detailed=true" # Level 3: Text Processing ["3.1"]="text_search|Log Detective|1|text_proc,search|Find and analyze specific patterns in log files|grep with context|none|patterns_found=true;count_correct=true" ["3.2"]="text_extract|Data Extraction Pro|2|text_proc|Extract and format specific fields from log files|awk is your friend|none|fields_extracted=true;format_correct=true" ["3.3"]="text_transform|Format Converter|2|text_proc|Transform data between different formats|sed for substitution|none|transformation_correct=true" ["3.4"]="text_report|Report Generator|3|text_proc|Create a detailed system report from various logs|Combine multiple tools|none|report_complete=true;format_valid=true" ["3.5"]="text_analyze|Pattern Analyzer|3|text_proc,search|Analyze complex error patterns and generate statistics|Use grep with perl regex|none|analysis_complete=true;stats_accurate=true" ) # Challenge verification functions verify_challenge() { local challenge_id=$1 local start_time=$2 IFS='|' read -r type name difficulty skills task hints requirements criteria <<< "${CHALLENGES[$challenge_id]}" # Check prerequisites if ! check_requirements "$requirements"; then log_message "ERROR" "Challenge prerequisites not met" return 1 } # Record attempt record_attempt "$challenge_id" "$start_time" # Run specific verification local category=${type%%_*} case "$category" in "file") verify_file_challenge "$challenge_id" "$criteria" ;; "perm") verify_permission_challenge "$challenge_id" "$criteria" ;; "text") verify_text_challenge "$challenge_id" "$criteria" ;; *) log_message "ERROR" "Unknown challenge category: $category" ;; esac } # Check challenge prerequisites check_requirements() { local requirements=$1 [[ "$requirements" == "none" ]] && return 0 IFS=';' read -ra REQS <<< "$requirements" for req in "${REQS[@]}"; do IFS='=' read -r key value <<< "$req" case "$key" in "users") for user in ${value//,/ }; do if ! id "$user" &>/dev/null; then log_message "ERROR" "Required user $user not found" return 1 fi done ;; # Add more requirement checks as needed esac done return 0 } # Verify file-related challenges verify_file_challenge() { local challenge_id=$1 local criteria=$2 local result=0 IFS=';' read -ra CHECKS <<< "$criteria" for check in "${CHECKS[@]}"; do IFS='=' read -r key value <<< "$check" case "$key" in "output_file") [[ -f "$value" ]] && ((result++)) ;; "file_count") [[ "$(find "$CHALLENGE_DIR/files" -type f | wc -l)" -eq "$value" ]] && ((result++)) ;; # Add more specific checks esac done verify_result "$challenge_id" "$result" "${#CHECKS[@]}" "File challenge verification" } # Verify permission-related challenges verify_permission_challenge() { local challenge_id=$1 local criteria=$2 local result=0 IFS=';' read -ra CHECKS <<< "$criteria" for check in "${CHECKS[@]}"; do IFS='=' read -r key value <<< "$check" case "$key" in "users") for user in ${value//,/ }; do if ! id "$user" &>/dev/null; then log_message "ERROR" "Required user $user not found" return 1 fi done ;; # Add more permission checks as needed esac done verify_result "$challenge_id" "$result" "${#CHECKS[@]}" "Permission challenge verification" } # Verify text-related challenges verify_text_challenge() { local challenge_id=$1 local criteria=$2 local result=0 IFS=';' read -ra CHECKS <<< "$criteria" for check in "${CHECKS[@]}"; do IFS='=' read -r key value <<< "$check" case "$key" in "patterns_found") [[ "$(grep -c "$value" "$CHALLENGE_DIR/files/logs/"*.log)" -ge 1 ]] && ((result++)) ;; "count_correct") [[ "$(grep -c "$value" "$CHALLENGE_DIR/files/logs/"*.log)" -eq "$value" ]] && ((result++)) ;; # Add more text checks as needed esac done verify_result "$challenge_id" "$result" "${#CHECKS[@]}" "Text challenge verification" } # Record challenge attempt record_attempt() { local challenge_id=$1 local start_time=$2 local duration=$(($(date +%s) - start_time)) local command_count=$(grep -c "^$start_time" "$COMMAND_LOG") echo "$challenge_id,$(get_attempt_number "$challenge_id"),$start_time,$command_count,$duration,0" >> "$ATTEMPT_FILE" } # Get attempt number for challenge get_attempt_number() { local challenge_id=$1 local attempts=$(grep -c "^$challenge_id," "$ATTEMPT_FILE") echo $((attempts + 1)) } # Enhanced result verification with detailed feedback verify_result() { local challenge_id=$1 local actual=$2 local expected=$3 local message=$4 local end_time=$(date +%s) if [[ "$actual" == "$expected" ]]; then log_message "SUCCESS" "Challenge $challenge_id: $message" update_challenge_status "$challenge_id" "1" "$end_time" # Calculate bonus points local duration=$((end_time - start_time)) local command_count=$(get_command_count "$challenge_id") local bonus_points=$(calculate_bonus_points "$duration" "$command_count") award_points "$challenge_id" "$((100 + bonus_points))" return 0 else log_message "ERROR" "Challenge $challenge_id: Completed $actual/$expected checks" update_challenge_status "$challenge_id" "0" "$end_time" return 1 fi } # Calculate bonus points based on time and efficiency calculate_bonus_points() { local duration=$1 local command_count=$2 local time_bonus=0 local efficiency_bonus=0 # Time bonus if [[ "$duration" -lt 60 ]]; then time_bonus=50 elif [[ "$duration" -lt 120 ]]; then time_bonus=25 fi # Efficiency bonus if [[ "$command_count" -le 3 ]]; then efficiency_bonus=50 elif [[ "$command_count" -le 5 ]]; then efficiency_bonus=25 fi echo $((time_bonus + efficiency_bonus)) } # Get challenge details with color formatting get_challenge_details() { local challenge_id=$1 IFS='|' read -r type name difficulty skills task hints requirements _ <<< "${CHALLENGES[$challenge_id]}" cat << EOF ${BOLD}Challenge ${challenge_id}${NC}: ${YELLOW}$name${NC} ${BLUE}Difficulty${NC}: $(printf '★%.0s' $(seq 1 "$difficulty")) ${BLUE}Skills${NC}: $skills ${BLUE}Task${NC}: $task ${BLUE}Hint${NC}: $hints EOF } # Update challenge status update_challenge_status() { local challenge_id=$1 local success=$2 local end_time=$3 # Update attempt status sed -i "$ s/,0$/,$success/" "$ATTEMPT_FILE" # Record completion if successful if [[ "$success" == "1" ]]; then echo "$challenge_id,$end_time,completed,${CHALLENGES[$challenge_id]}" >> "$PROGRESS_FILE" fi } # List available challenges list_challenges() { echo -e "\n${BOLD}Available Challenges:${NC}" for challenge_id in "${!CHALLENGES[@]}"; do IFS='|' read -r type name difficulty skills task hints requirements _ <<< "${CHALLENGES[$challenge_id]}" if ! is_challenge_completed "$challenge_id"; then echo -e "\n${YELLOW}Challenge $challenge_id${NC} ($difficulty★)" echo "Type: $type" echo "Skills: $skills" echo "Task: $task" fi done }