diff --git a/modules/wordtrack/wordtrack.sh b/modules/wordtrack/wordtrack.sh new file mode 100644 index 0000000..2e1b7a9 --- /dev/null +++ b/modules/wordtrack/wordtrack.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +# Word tracking command module + +# shellcheck disable=SC1091 +[ -f functions.sh ] && source functions.sh + +name="$1" +channelName="$2" +shift 2 + +categoriesFile="triggers/wordtrack/categories.sh" + +sanitize_nick() { + local rawName="$1" + local safeName="$rawName" + + safeName="${safeName%%!*}" + safeName="${safeName%%[[:space:]]*}" + safeName="${safeName//[^a-zA-Z0-9_\[\]\{\}\\|\^-]/}" + safeName="${safeName:0:30}" + + printf '%s' "$safeName" +} + +show_stats() { + local targetUser="$1" + local dataDir="triggers/wordtrack/data/${channelName}" + local userDataFile="${dataDir}/${targetUser}.dat" + local statsMessage + local -a statsParts + local category + local count + local levelsArrayName + local currentLevel + local nextThreshold + local threshold + local remaining + + if [[ ! -f "$userDataFile" ]]; then + msg "$channelName" "$name: ${targetUser} has not been tracked yet." + return 0 + fi + + declare -A userCounts + while IFS='=' read -r category count; do + userCounts["$category"]="$count" + done < "$userDataFile" + + statsMessage="${targetUser}'s word tracking stats: " + + # shellcheck disable=SC2154 + for category in "${categories[@]}"; do + count="${userCounts[$category]:-0}" + + if ((count > 0)); then + levelsArrayName="${category}Levels" + declare -n levelsRef="$levelsArrayName" + + currentLevel="Unranked" + nextThreshold="" + + for threshold in $(printf '%s\n' "${!levelsRef[@]}" | sort -n); do + if ((count >= threshold)); then + currentLevel="${levelsRef[$threshold]}" + elif [[ -z "$nextThreshold" ]]; then + nextThreshold="$threshold" + fi + done + unset -n levelsRef + + if [[ -n "$nextThreshold" ]]; then + remaining=$((nextThreshold - count)) + statsParts+=("${category}: ${currentLevel} (${count}/${nextThreshold}, ${remaining} to next)") + else + statsParts+=("${category}: ${currentLevel} (MAX LEVEL - ${count} words)") + fi + fi + done + + if [[ ${#statsParts[@]} -eq 0 ]]; then + msg "$channelName" "$name: ${targetUser} has not earned any levels yet." + else + statsMessage+=$(IFS=' | '; echo "${statsParts[*]}") + msg "$channelName" "$statsMessage" + fi +} + +subCommand="$1" +shift || true + +if [[ ! -f "$categoriesFile" ]]; then + msg "$channelName" "The wordtrack trigger has not been configured." + exit 0 +fi + +# shellcheck disable=SC1090,SC1091 +source "$categoriesFile" + +case "$subCommand" in +stats) + targetRaw="${1:-$name}" + targetUser="$(sanitize_nick "$targetRaw")" + + if [[ -z "$targetUser" ]]; then + msg "$channelName" "$name: Please provide a valid nickname." + exit 0 + fi + + show_stats "$targetUser" + ;; +""|help) + msg "$channelName" "$name: Usage: wordtrack stats [nick]" + ;; +*) + msg "$channelName" "$name: Unknown subcommand. Available: stats" + ;; +esac