146 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env bash
 | 
						|
[ -f functions.sh ] && source functions.sh
 | 
						|
 | 
						|
who="${1%!*}"
 | 
						|
who="${who//:}"
 | 
						|
shift
 | 
						|
# shellcheck disable=SC2034  # Used in action strings via execute_action
 | 
						|
chan="$1"
 | 
						|
shift
 | 
						|
 | 
						|
keywordsFile="triggers/keywords/keywords.cfg"
 | 
						|
 | 
						|
# Function to process random selection syntax: {random:opt1|opt2|opt3}
 | 
						|
process_random() {
 | 
						|
    local text="$1"
 | 
						|
    while [[ "$text" =~ \{random:([^}]+)\} ]]; do
 | 
						|
        local options="${BASH_REMATCH[1]}"
 | 
						|
        IFS='|' read -ra optArray <<< "$options"
 | 
						|
        local selected="${optArray[$((RANDOM % ${#optArray[@]}))]}"
 | 
						|
        text="${text/\{random:$options\}/$selected}"
 | 
						|
    done
 | 
						|
    echo "$text"
 | 
						|
}
 | 
						|
 | 
						|
# Safe execution function - only allows predefined IRC functions
 | 
						|
execute_action() {
 | 
						|
    local action="$1"
 | 
						|
 | 
						|
    # Parse the action to extract function name and arguments
 | 
						|
    if [[ "$action" =~ ^msg[[:space:]]+(\"[^\"]+\"|[^[:space:]]+)[[:space:]]+(.+)$ ]]; then
 | 
						|
        local target="${BASH_REMATCH[1]}"
 | 
						|
        local message="${BASH_REMATCH[2]}"
 | 
						|
        # Remove quotes from target and message if present
 | 
						|
        target="${target//\"/}"
 | 
						|
        # Safely expand only $chan and $who variables - NO EVAL
 | 
						|
        message="${message//\"\$chan\"/$chan}"
 | 
						|
        message="${message//\$chan/$chan}"
 | 
						|
        message="${message//\"\$who\"/$who}"
 | 
						|
        message="${message//\$who/$who}"
 | 
						|
        message="${message//\$\{chan\}/$chan}"
 | 
						|
        message="${message//\$\{who\}/$who}"
 | 
						|
        message="$(process_random "$message")"
 | 
						|
        msg "$target" "$message"
 | 
						|
    elif [[ "$action" =~ ^act[[:space:]]+(\"[^\"]+\"|[^[:space:]]+)[[:space:]]+(.+)$ ]]; then
 | 
						|
        local target="${BASH_REMATCH[1]}"
 | 
						|
        local message="${BASH_REMATCH[2]}"
 | 
						|
        # Remove quotes from target and message if present
 | 
						|
        target="${target//\"/}"
 | 
						|
        # Safely expand only $chan and $who variables - NO EVAL
 | 
						|
        message="${message//\"\$chan\"/$chan}"
 | 
						|
        message="${message//\$chan/$chan}"
 | 
						|
        message="${message//\"\$who\"/$who}"
 | 
						|
        message="${message//\$who/$who}"
 | 
						|
        message="${message//\$\{chan\}/$chan}"
 | 
						|
        message="${message//\$\{who\}/$who}"
 | 
						|
        message="$(process_random "$message")"
 | 
						|
        act "$target" "$message"
 | 
						|
    elif [[ "$action" =~ ^reply[[:space:]]+(\"[^\"]+\"|[^[:space:]]+)[[:space:]]+(.+)$ ]]; then
 | 
						|
        local target="${BASH_REMATCH[1]}"
 | 
						|
        local message="${BASH_REMATCH[2]}"
 | 
						|
        # Remove quotes from target and message if present
 | 
						|
        target="${target//\"/}"
 | 
						|
        # Safely expand only $chan and $who variables - NO EVAL
 | 
						|
        message="${message//\"\$chan\"/$chan}"
 | 
						|
        message="${message//\$chan/$chan}"
 | 
						|
        message="${message//\"\$who\"/$who}"
 | 
						|
        message="${message//\$who/$who}"
 | 
						|
        message="${message//\$\{chan\}/$chan}"
 | 
						|
        message="${message//\$\{who\}/$who}"
 | 
						|
        message="$(process_random "$message")"
 | 
						|
        reply "$target" "$message"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
# Load keywords from config file into associative array
 | 
						|
declare -A keywords
 | 
						|
if [[ -f "$keywordsFile" ]]; then
 | 
						|
    while IFS='|' read -r keyword action percentage || [[ -n "$keyword" ]]; do
 | 
						|
        # Skip comments and empty lines
 | 
						|
        [[ "$keyword" =~ ^[[:space:]]*# ]] && continue
 | 
						|
        [[ -z "$keyword" ]] && continue
 | 
						|
 | 
						|
        # Trim whitespace
 | 
						|
        keyword="${keyword#"${keyword%%[![:space:]]*}"}"
 | 
						|
        keyword="${keyword%"${keyword##*[![:space:]]}"}"
 | 
						|
        action="${action#"${action%%[![:space:]]*}"}"
 | 
						|
        action="${action%"${action##*[![:space:]]}"}"
 | 
						|
        percentage="${percentage#"${percentage%%[![:space:]]*}"}"
 | 
						|
        percentage="${percentage%"${percentage##*[![:space:]]}"}"
 | 
						|
 | 
						|
        # Store in array (key includes ~ prefix for multi-word triggers)
 | 
						|
        if [[ -n "$percentage" ]]; then
 | 
						|
            keywords["$keyword"]="$action $percentage"
 | 
						|
        else
 | 
						|
            keywords["$keyword"]="$action"
 | 
						|
        fi
 | 
						|
    done < "$keywordsFile"
 | 
						|
fi
 | 
						|
 | 
						|
# Process single-word triggers
 | 
						|
wordList="$(echo "${@,,}" | tr '[:space:]' $'\n' | sort -u)"
 | 
						|
for w in ${wordList//[[:punct:]]/} ; do
 | 
						|
    if [[ -n "${keywords[${w,,}]}" && "$lastWordMatch" != "${keywords[${w,,}]}" ]]; then
 | 
						|
        keywordAction="${keywords[${w,,}]}"
 | 
						|
        # Check if the last element is a percentage
 | 
						|
        if [[ "$keywordAction" =~ (.*)\ ([0-9]+)%$ ]]; then
 | 
						|
            command="${BASH_REMATCH[1]}"
 | 
						|
            percentage="${BASH_REMATCH[2]}"
 | 
						|
            # Generate random number between 1-100 and only respond if within percentage
 | 
						|
            randomNum=$((RANDOM % 100 + 1))
 | 
						|
            if [[ $randomNum -le $percentage ]]; then
 | 
						|
                execute_action "$command"
 | 
						|
            fi
 | 
						|
        else
 | 
						|
            # No percentage specified, always respond
 | 
						|
            execute_action "$keywordAction"
 | 
						|
        fi
 | 
						|
        lastWordMatch="${keywords[${w,,}]}"
 | 
						|
    fi
 | 
						|
done
 | 
						|
 | 
						|
# Process multi-word triggers (those starting with ~)
 | 
						|
wordList="$(echo "${@,,}" | tr -d '[:space:]')"
 | 
						|
for trigger in "${!keywords[@]}"; do
 | 
						|
    if [[ "$trigger" =~ ^~ ]]; then
 | 
						|
        # Remove the ~ prefix for matching
 | 
						|
        triggerPattern="${trigger#\~}"
 | 
						|
        if [[ "${wordList,,}" =~ .*${triggerPattern}.* ]]; then
 | 
						|
            keywordAction="${keywords[$trigger]}"
 | 
						|
            # Check if the last element is a percentage
 | 
						|
            if [[ "$keywordAction" =~ (.*)\ ([0-9]+)%$ ]]; then
 | 
						|
                command="${BASH_REMATCH[1]}"
 | 
						|
                percentage="${BASH_REMATCH[2]}"
 | 
						|
                # Generate random number between 1-100 and only respond if within percentage
 | 
						|
                randomNum=$((RANDOM % 100 + 1))
 | 
						|
                if [[ $randomNum -le $percentage ]]; then
 | 
						|
                    execute_action "$command"
 | 
						|
                fi
 | 
						|
            else
 | 
						|
                # No percentage specified, always respond
 | 
						|
                execute_action "$keywordAction"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
done
 |