129 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env bash
 | |
| 
 | |
| # Word tracking trigger - monitors messages and tracks word usage
 | |
| 
 | |
| # shellcheck disable=SC1091
 | |
| [ -f functions.sh ] && source functions.sh
 | |
| # shellcheck disable=SC1091
 | |
| [ -f triggers/wordtrack/categories.sh ] && source triggers/wordtrack/categories.sh
 | |
| 
 | |
| name="$1"
 | |
| channelName="$2"
 | |
| shift 2
 | |
| message="$*"
 | |
| 
 | |
| # Sanitize username (extract just the nickname, max 30 chars per IRC RFC)
 | |
| # Remove any IRC protocol remnants, hostmask info, etc.
 | |
| name="${name%%!*}"        # Remove hostmask if present
 | |
| name="${name%%[[:space:]]*}"  # Remove any trailing data
 | |
| name="${name//[^a-zA-Z0-9_\[\]\{\}\\|\^-]/}"  # Only allow valid IRC nick chars
 | |
| name="${name:0:30}"       # Limit to max IRC nickname length
 | |
| 
 | |
| # If name is empty or invalid after sanitization, skip
 | |
| if [[ -z "$name" ]]; then
 | |
|     exit 0
 | |
| fi
 | |
| 
 | |
| # Sanitize channel name (remove any IRC protocol remnants)
 | |
| channelName="${channelName%%[[:space:]]*}"
 | |
| channelName="${channelName//[^a-zA-Z0-9#_-]/}"
 | |
| 
 | |
| # Only process if we have a valid channel name starting with #
 | |
| if [[ ! "$channelName" =~ ^#[a-zA-Z0-9_-]+$ ]]; then
 | |
|     exit 0
 | |
| fi
 | |
| 
 | |
| # Convert message to lowercase for case-insensitive matching
 | |
| messageLower="${message,,}"
 | |
| 
 | |
| # Create data directory for this channel if it doesn't exist
 | |
| dataDir="triggers/wordtrack/data/${channelName}"
 | |
| mkdir -p "$dataDir"
 | |
| 
 | |
| # User data file
 | |
| userDataFile="${dataDir}/${name}.dat"
 | |
| 
 | |
| # Load existing user data
 | |
| declare -A userCounts
 | |
| if [[ -f "$userDataFile" ]]; then
 | |
|     while IFS='=' read -r category count; do
 | |
|         userCounts["$category"]="$count"
 | |
|     done < "$userDataFile"
 | |
| fi
 | |
| 
 | |
| # Track which categories had level-ups
 | |
| declare -a levelUps
 | |
| 
 | |
| # Process each category
 | |
| # shellcheck disable=SC2154
 | |
| for category in "${categories[@]}"; do
 | |
|     # Get the word array and levels array for this category
 | |
|     levelsArrayName="${category}Levels"
 | |
| 
 | |
|     # Check if message contains any words from this category
 | |
|     wordCount=0
 | |
|     wordsArrayNameClean="${category}Words"
 | |
|     declare -n wordsRef="$wordsArrayNameClean"
 | |
| 
 | |
|     for word in "${wordsRef[@]}"; do
 | |
|         # Count all occurrences of this word in the message
 | |
|         wordLower="${word,,}"
 | |
|         tempMessage="$messageLower"
 | |
|         while [[ "$tempMessage" =~ $wordLower ]]; do
 | |
|             ((wordCount++))
 | |
|             # Remove the matched word to find more occurrences
 | |
|             tempMessage="${tempMessage/$wordLower/}"
 | |
|         done
 | |
|     done
 | |
| 
 | |
|     unset -n wordsRef
 | |
| 
 | |
|     # If words were found, update the counter
 | |
|     if ((wordCount > 0)); then
 | |
|         oldCount="${userCounts[$category]:-0}"
 | |
|         newCount=$((oldCount + wordCount))
 | |
|         userCounts["$category"]="$newCount"
 | |
| 
 | |
|         # Check for level-up
 | |
|         oldLevel=""
 | |
|         newLevel=""
 | |
| 
 | |
|         # Get the thresholds for this category using nameref
 | |
|         declare -n levelsRef="$levelsArrayName"
 | |
| 
 | |
|         # Get old level
 | |
|         for threshold in $(printf '%s\n' "${!levelsRef[@]}" | sort -n); do
 | |
|             if ((oldCount >= threshold)); then
 | |
|                 oldLevel="${levelsRef[$threshold]}"
 | |
|             fi
 | |
|         done
 | |
| 
 | |
|         # Get new level
 | |
|         for threshold in $(printf '%s\n' "${!levelsRef[@]}" | sort -n); do
 | |
|             if ((newCount >= threshold)); then
 | |
|                 newLevel="${levelsRef[$threshold]}"
 | |
|             fi
 | |
|         done
 | |
| 
 | |
|         # If level changed, record the level-up
 | |
|         if [[ -n "$newLevel" && "$newLevel" != "$oldLevel" ]]; then
 | |
|             levelUps+=("$category:$newLevel:$newCount")
 | |
|         fi
 | |
| 
 | |
|         # Clean up nameref
 | |
|         unset -n levelsRef
 | |
|     fi
 | |
| done
 | |
| 
 | |
| # Save updated user data
 | |
| : > "$userDataFile"
 | |
| for category in "${!userCounts[@]}"; do
 | |
|     echo "${category}=${userCounts[$category]}" >> "$userDataFile"
 | |
| done
 | |
| 
 | |
| # Announce level-ups
 | |
| for levelUp in "${levelUps[@]}"; do
 | |
|     IFS=':' read -r category level count <<< "$levelUp"
 | |
|     msg "$channelName" "$name just leveled up in ${category}! You are now a ${level} with ${count} words!"
 | |
| done
 |