Implement the IRC protocol
This commit is contained in:
parent
d73369805c
commit
8e6bcdb0e5
1 changed files with 169 additions and 1 deletions
170
rowbot
170
rowbot
|
@ -88,13 +88,18 @@ else
|
||||||
log=1
|
log=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
nick=${opts[nick]:-rowbot-dev}
|
||||||
|
ident=${opts[ident]:-rowbot}
|
||||||
|
realname=${opts[realname]:-rowbot}
|
||||||
|
chan=${opts[chan]:-}
|
||||||
|
|
||||||
###
|
###
|
||||||
# net code
|
# net code
|
||||||
###
|
###
|
||||||
|
|
||||||
if [[ $tls = yes ]]; then
|
if [[ $tls = yes ]]; then
|
||||||
coproc sock { socat OPENSSL:"$server":"$port" -; }
|
coproc sock { socat OPENSSL:"$server":"$port" -; }
|
||||||
in_sock=${sock[0]} out_sock=${sock[1]}
|
exec {in_sock}<&"${sock[0]}" {out_sock}>&"${sock[1]}"
|
||||||
else
|
else
|
||||||
exec {sock}<>/dev/tcp/"$server"/"$port"
|
exec {sock}<>/dev/tcp/"$server"/"$port"
|
||||||
in_sock=$sock out_sock=$sock
|
in_sock=$sock out_sock=$sock
|
||||||
|
@ -104,18 +109,177 @@ send() {
|
||||||
local fmt
|
local fmt
|
||||||
printf -v fmt "$1" "${@:2}"
|
printf -v fmt "$1" "${@:2}"
|
||||||
printf '%s\r\n' "$fmt" >&"$out_sock"
|
printf '%s\r\n' "$fmt" >&"$out_sock"
|
||||||
|
debug "sending line: %s" "$fmt"
|
||||||
}
|
}
|
||||||
|
|
||||||
recv() {
|
recv() {
|
||||||
declare -n sock_line=$1
|
declare -n sock_line=$1
|
||||||
IFS= read -r "$1" <&"$in_sock"
|
IFS= read -r "$1" <&"$in_sock"
|
||||||
sock_line=${sock_line%$'\r'}
|
sock_line=${sock_line%$'\r'}
|
||||||
|
debug "received line: %s" "$sock_line"
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
# irc recv code
|
||||||
|
###
|
||||||
|
|
||||||
|
on_ERROR() {
|
||||||
|
error "${params[0]}"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
on_MODE() {
|
||||||
|
if (( ${#params[@]} == 2 )); then
|
||||||
|
info "%s sets mode(s) %s on %s" "$from" "${params[1]}" "${params[0]}"
|
||||||
|
else
|
||||||
|
warn "mode line was not handled: %s" "$orig_line"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
on_NOTICE() {
|
||||||
|
info "[%s/%s] %s" "$from" "${params[0]}" "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_PING() {
|
||||||
|
pong "${params[1]}"
|
||||||
|
debug "received ping: %s" "${params[0]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_PONG() {
|
||||||
|
debug "received pong: %s" "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_QUIT() {
|
||||||
|
info "%s has disconnected: %s" "$from" "${params[0]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_001() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
|
||||||
|
if [[ $chan ]]; then
|
||||||
|
join "$chan"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
ping "row your bot gently down the stream"
|
||||||
|
sleep 10
|
||||||
|
done &
|
||||||
|
|
||||||
|
trap "kill $!" EXIT
|
||||||
|
}
|
||||||
|
|
||||||
|
on_002() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_003() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_004() {
|
||||||
|
debug "%s " "${params[@]:1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -A isupport
|
||||||
|
|
||||||
|
on_005() {
|
||||||
|
local param key value
|
||||||
|
|
||||||
|
for param in "${params[@]:1:${#params[@]}-2}"; do
|
||||||
|
IFS== read -r key value <<< "$param"
|
||||||
|
isupport[$key]=$value
|
||||||
|
debug "isupport: %s = %s" "$key" "$value"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
on_250() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_251() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_252() {
|
||||||
|
info "There are %d operators online" "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_253() {
|
||||||
|
info "There are %d unknown connections" "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_254() {
|
||||||
|
info "There are %d channels formed" "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_255() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_265() {
|
||||||
|
info %s "${params[3]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_266() {
|
||||||
|
info %s "${params[3]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_372() {
|
||||||
|
info %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_375() {
|
||||||
|
debug %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_376() {
|
||||||
|
debug %s "${params[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
# irc send code
|
||||||
|
###
|
||||||
|
|
||||||
|
join() {
|
||||||
|
send "JOIN %s" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
nick() {
|
||||||
|
send "NICK %s" "$1"
|
||||||
|
info "changing nickname to %s" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ping() {
|
||||||
|
send "PING :%s" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
pong() {
|
||||||
|
send "PONG %s" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
privmsg() {
|
||||||
|
send "PRIVMSG %s :%s" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
user() {
|
||||||
|
send "USER %s * * :%s" "$ident" "$realname"
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
# utility hooks
|
||||||
|
##
|
||||||
|
|
||||||
|
hook_JOIN_greet() {
|
||||||
|
privmsg "${params[0]}" "Hello, $from!"
|
||||||
}
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
# driver
|
# driver
|
||||||
###
|
###
|
||||||
|
|
||||||
|
nick "$nick"
|
||||||
|
user "$ident" "$realname"
|
||||||
|
|
||||||
while recv line; do
|
while recv line; do
|
||||||
params=( )
|
params=( )
|
||||||
has_words=no
|
has_words=no
|
||||||
|
@ -150,6 +314,10 @@ while recv line; do
|
||||||
words=( )
|
words=( )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r hook; do
|
||||||
|
"$hook"
|
||||||
|
done < <(compgen -A function "hook_${cmd^^}_")
|
||||||
|
|
||||||
if hash "on_${cmd^^}" 2>/dev/null; then
|
if hash "on_${cmd^^}" 2>/dev/null; then
|
||||||
"on_${cmd^^}"
|
"on_${cmd^^}"
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue