You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.6 KiB
127 lines
3.6 KiB
#lang racket
|
|
|
|
;; These functions build strings for requisite IRC commands
|
|
(require "commands.rkt")
|
|
(require "database.rkt")
|
|
(require "config.rkt")
|
|
|
|
; PRIVMSG command
|
|
(define (privmsg target msg)
|
|
(format "PRIVMSG ~a :~a"
|
|
target
|
|
msg))
|
|
|
|
; USER command
|
|
(define (usermsg username realname)
|
|
(format
|
|
"USER ~a 0 * :~a" username realname))
|
|
|
|
; JOIN command
|
|
(define (join channel)
|
|
(format
|
|
"JOIN :~a" channel))
|
|
|
|
; PART command
|
|
(define (part channel reason)
|
|
(format
|
|
"PART ~a :~a"
|
|
channel
|
|
reason))
|
|
|
|
; QUIT command
|
|
(define (quit reason)
|
|
(format "QUIT :~a"
|
|
reason))
|
|
|
|
; NICK command
|
|
(define (nick nickname)
|
|
(format "NICK ~a" nickname))
|
|
|
|
; PING/PONG command
|
|
(define (pingpong pingorpong message)
|
|
(match pingorpong
|
|
["ping" (format "PING :~a" message)]
|
|
["pong"
|
|
(format "PONG ~a" message)]))
|
|
|
|
;; Parses IRC responses
|
|
;; turns a list of words into a string
|
|
;; and skips the first character
|
|
(define content->string
|
|
(compose
|
|
string-tail
|
|
(lambda (words)
|
|
(string-join words " "))))
|
|
|
|
(define (parse-hostmask hostmask)
|
|
(match (regexp-split #rx"!" hostmask)
|
|
[(list nick host)
|
|
(match (regexp-split #rx"@" host)
|
|
[(list username hostname) (list (string-tail nick)
|
|
username
|
|
hostname)])]))
|
|
;; This function parses the raw IRC messages
|
|
;; the output is intended to be used with the callback handler
|
|
(define (parse-message message)
|
|
(match message
|
|
['nil 'nil]
|
|
[_ (match (regexp-split #rx" " message)
|
|
;; Matches a ping
|
|
[(list "PING" content) (list "PING" content)]
|
|
|
|
;; Matches a private message command
|
|
[(list-rest hostmask "PRIVMSG" channel content)
|
|
(list "PRIVMSG" (parse-hostmask hostmask) channel
|
|
(content->string content))]
|
|
|
|
;; Matches a Quit command
|
|
[(list-rest hostmask "QUIT" _) (list "QUIT" (parse-hostmask hostmask))]
|
|
|
|
;; Matches a Join command
|
|
[(list-rest hostmask "JOIN" (list channel))
|
|
(list "JOIN" (parse-hostmask hostmask) (string-tail channel))]
|
|
[_ 'nil])]))
|
|
|
|
;; Callback handler
|
|
;;This is how callback functions are chosen
|
|
;;First we parse the IRC messages with parse-message
|
|
;;then we use pattern matching to decide which callback
|
|
;;function will be called
|
|
;;It should be easy to add support for new IRC codes this way
|
|
(define ((register-callbacks
|
|
privmsg-response
|
|
quit-response
|
|
join-response)
|
|
message)
|
|
|
|
(match message
|
|
['nil 'nil]
|
|
[_ (match (parse-message (strip-newlines message)) ;MUST strip newlines and carriage returns
|
|
; private message handler (called when we receive a private message)
|
|
; First match to see if they are messaging us and not a channel! Or else we end up in an infinite loop
|
|
[(list "PRIVMSG" userinfo channel content)
|
|
(privmsg-response
|
|
((curry privmsg) (me? channel (first userinfo)))
|
|
userinfo
|
|
content
|
|
join
|
|
((curry part) (first userinfo)))]
|
|
; JOIN handler (called when a user joins the channel)
|
|
[(list "JOIN" userinfo channel) (join-response
|
|
((curry privmsg)
|
|
channel)
|
|
userinfo)]
|
|
; QUIT handler (called when a user quits)
|
|
[(list "QUIT" userinfo) (quit-response userinfo)]
|
|
; PING handler (called when we receive a PING)
|
|
[(list "PING" message)
|
|
(pingpong "pong" message)]
|
|
[_ 'nil])]))
|
|
|
|
;; Check if a nick is the bot or not
|
|
(define (me? channel recipient)
|
|
(cond
|
|
[(string=? irc-username channel) recipient]
|
|
(else channel)))
|
|
|
|
(provide (all-defined-out))
|