|
@@ -6,9 +6,11 @@
|
|
(prefix-in movie-night: "chat.rkt"))
|
|
(prefix-in movie-night: "chat.rkt"))
|
|
(provide (all-defined-out))
|
|
(provide (all-defined-out))
|
|
|
|
|
|
-
|
|
|
|
|
|
+;; Each channel a user joins is associated with a WS connection
|
|
(define movie-night-ws-url (make-parameter "wss://stream.ihatebeinga.live/ws"))
|
|
(define movie-night-ws-url (make-parameter "wss://stream.ihatebeinga.live/ws"))
|
|
|
|
|
|
|
|
+(define-type Channel-List (Listof (Pairof String WS)))
|
|
|
|
+
|
|
(: users (Listof String))
|
|
(: users (Listof String))
|
|
(define users '())
|
|
(define users '())
|
|
|
|
|
|
@@ -44,9 +46,11 @@
|
|
;; other connections
|
|
;; other connections
|
|
(thread
|
|
(thread
|
|
(lambda ()
|
|
(lambda ()
|
|
|
|
+ ;; TODO: custodian should be part of irc-connection
|
|
(define user-conn (accept-irc-connection in out cust))
|
|
(define user-conn (accept-irc-connection in out cust))
|
|
|
|
+ (define channels '())
|
|
(thread (lambda ()
|
|
(thread (lambda ()
|
|
- (handle-user-messages user-conn cust)))))))
|
|
|
|
|
|
+ (handle-user-messages user-conn channels cust)))))))
|
|
|
|
|
|
;; When we accept a new IRC connection we need to do several things:
|
|
;; When we accept a new IRC connection we need to do several things:
|
|
;; 1. Receive the user nick/user information
|
|
;; 1. Receive the user nick/user information
|
|
@@ -74,29 +78,9 @@
|
|
|
|
|
|
(file-stream-buffer-mode out 'line)
|
|
(file-stream-buffer-mode out 'line)
|
|
|
|
|
|
- ;; TODO:
|
|
|
|
- ;; Defining ws-c and conn simulateneously like that is asking for trouble
|
|
|
|
- ;; inb4 a race condition
|
|
|
|
- (: ws-c WS)
|
|
|
|
- (define ws-c
|
|
|
|
- (movie-night:make-connection
|
|
|
|
- (movie-night-ws-url)
|
|
|
|
- nick
|
|
|
|
- #:on-join (lambda ([n : String]) (on-join conn n))
|
|
|
|
- #:on-leave (lambda ([n : String]) (on-leave conn n))
|
|
|
|
- #:on-name-change (lambda ([n1 : String] [n2 : String])
|
|
|
|
- (on-name-change conn n1 n2))
|
|
|
|
- #:on-users (lambda ([l : (Listof String)])
|
|
|
|
- (set! users l) (notify-users conn))
|
|
|
|
- #:on-chat (lambda ([from : String] [msg : String])
|
|
|
|
- (on-chat conn from msg))
|
|
|
|
- #:on-response (lambda ([msg : String]) (on-response conn msg))
|
|
|
|
- #:on-notify (lambda ([msg : String]) (on-response conn msg))
|
|
|
|
- #:on-topic (lambda ([topic : String]) (on-topic conn topic))
|
|
|
|
- #:on-close-conn (lambda () (custodian-shutdown-all cust))))
|
|
|
|
(: conn irc-connection)
|
|
(: conn irc-connection)
|
|
- (define conn (irc-connection in out nick user ws-c))
|
|
|
|
- ;;(set-irc-connection-ws-conn! conn ws-c)
|
|
|
|
|
|
+ (define conn (irc-connection in out nick user))
|
|
|
|
+
|
|
(welcome-user conn)
|
|
(welcome-user conn)
|
|
(void (thread (lambda () (ping-pong-thread conn))))
|
|
(void (thread (lambda () (ping-pong-thread conn))))
|
|
conn)
|
|
conn)
|
|
@@ -186,10 +170,13 @@
|
|
;; of 333 > the frequency of PINGs
|
|
;; of 333 > the frequency of PINGs
|
|
;; so the client should respond to the PING within
|
|
;; so the client should respond to the PING within
|
|
;; some number of seconds in order to keep the connection alive
|
|
;; some number of seconds in order to keep the connection alive
|
|
-(: handle-user-messages (-> irc-connection Custodian Nothing))
|
|
|
|
-(define (handle-user-messages conn custodian)
|
|
|
|
|
|
+;; XXX this is a galaxy brain version of making sure that the connection stays alive
|
|
|
|
+;; ideally this should be rewritten
|
|
|
|
+(: handle-user-messages (-> irc-connection Channel-List Custodian Nothing))
|
|
|
|
+(define (handle-user-messages conn channels custodian)
|
|
(define nick (irc-connection-nick conn))
|
|
(define nick (irc-connection-nick conn))
|
|
(define msg (read-from-client conn #:timeout 333))
|
|
(define msg (read-from-client conn #:timeout 333))
|
|
|
|
+ (log-info (format "Raw irc-message: ~a" msg))
|
|
(match msg
|
|
(match msg
|
|
[(irc-message _ "PING" (list ping))
|
|
[(irc-message _ "PING" (list ping))
|
|
(send-to-client conn
|
|
(send-to-client conn
|
|
@@ -202,26 +189,14 @@
|
|
[(irc-message _ "NICK" params)
|
|
[(irc-message _ "NICK" params)
|
|
;; TODO: propagate this info along the WS
|
|
;; TODO: propagate this info along the WS
|
|
(set-irc-connection-nick! conn (car params))]
|
|
(set-irc-connection-nick! conn (car params))]
|
|
|
|
+ ;; TODO: implement PART as well
|
|
[(irc-message _ "JOIN" (list chan))
|
|
[(irc-message _ "JOIN" (list chan))
|
|
- #:when (equal? chan channel)
|
|
|
|
- (define c (irc-connection-ws-conn conn))
|
|
|
|
- (ws:send-join c (irc-connection-nick conn) "#00FFAA")
|
|
|
|
-
|
|
|
|
- (send-to-client conn (irc-message
|
|
|
|
- (format "~a!~a@lolcathost"
|
|
|
|
- (irc-connection-nick conn)
|
|
|
|
- (irc-connection-user conn))
|
|
|
|
- "JOIN"
|
|
|
|
- (list channel)))
|
|
|
|
- (send-to-client conn (irc-message
|
|
|
|
- ":lolcathost"
|
|
|
|
- RPL_TOPIC
|
|
|
|
- (list nick channel ":chatting hard")))
|
|
|
|
-
|
|
|
|
- (sleep 1.5) ;; is there a way around going to sleep? :-<
|
|
|
|
- (ws:send-users c)]
|
|
|
|
|
|
+ #:when (and (equal? chan channel)
|
|
|
|
+ (not (member chan channels)))
|
|
|
|
+ (define ws (join-new-channel conn chan custodian))
|
|
|
|
+ (set! channels (cons (cons chan ws) channels))]
|
|
[(irc-message _ "MODE" (cons chan _))
|
|
[(irc-message _ "MODE" (cons chan _))
|
|
- #:when (equal? chan channel)
|
|
|
|
|
|
+ #:when (channel-joined? chan channels)
|
|
(send-to-client conn (irc-message
|
|
(send-to-client conn (irc-message
|
|
":lolcathost"
|
|
":lolcathost"
|
|
RPL_CHANNELMODEIS
|
|
RPL_CHANNELMODEIS
|
|
@@ -233,7 +208,7 @@
|
|
(list nick " /list not implemented ")))
|
|
(list nick " /list not implemented ")))
|
|
]
|
|
]
|
|
[(irc-message _ "WHO" (list chan))
|
|
[(irc-message _ "WHO" (list chan))
|
|
- #:when (equal? chan channel)
|
|
|
|
|
|
+ #:when (channel-joined? chan channels)
|
|
(send-to-client conn (irc-message
|
|
(send-to-client conn (irc-message
|
|
":lolcathost"
|
|
":lolcathost"
|
|
RPL_WHOREPLY
|
|
RPL_WHOREPLY
|
|
@@ -262,10 +237,12 @@
|
|
RPL_ENDOFWHOIS
|
|
RPL_ENDOFWHOIS
|
|
(list nick target ":End of /WHOIS list")))]
|
|
(list nick target ":End of /WHOIS list")))]
|
|
[(irc-message _ "PRIVMSG" (list chan msg))
|
|
[(irc-message _ "PRIVMSG" (list chan msg))
|
|
- #:when (equal? chan channel)
|
|
|
|
- (send-ws-message conn msg)]
|
|
|
|
- [(irc-message _ "STATS" '())
|
|
|
|
- (send-ws-message conn "/STATS")]
|
|
|
|
|
|
+ (define ws (lookup-ws-conn channels chan))
|
|
|
|
+ (when ws
|
|
|
|
+ (ws:send-message ws msg))]
|
|
|
|
+ ;; TODO imlement STATS again
|
|
|
|
+ ;; [(irc-message _ "STATS" '())
|
|
|
|
+ ;; (send-ws-message conn "/STATS")]
|
|
[(irc-message _ "MOTD" _)
|
|
[(irc-message _ "MOTD" _)
|
|
(send-to-client conn (irc-message
|
|
(send-to-client conn (irc-message
|
|
":lolcathost"
|
|
":lolcathost"
|
|
@@ -289,13 +266,55 @@
|
|
(void)]
|
|
(void)]
|
|
[(var msg)
|
|
[(var msg)
|
|
(log-warning (format "ircd.rkt/handle-user-message: unknown message: ~a" msg))])
|
|
(log-warning (format "ircd.rkt/handle-user-message: unknown message: ~a" msg))])
|
|
- (handle-user-messages conn custodian))
|
|
|
|
|
|
+ (handle-user-messages conn channels custodian))
|
|
|
|
+
|
|
|
|
+(: join-new-channel (-> irc-connection String Custodian WS))
|
|
|
|
+(define (join-new-channel conn channel-name cust)
|
|
|
|
+ (: ws-c WS)
|
|
|
|
+ (define ws-c
|
|
|
|
+ (movie-night:make-connection
|
|
|
|
+ (movie-night-ws-url)
|
|
|
|
+ (irc-connection-nick conn)
|
|
|
|
+ #:on-join (lambda ([n : String]) (on-join conn n))
|
|
|
|
+ #:on-leave (lambda ([n : String]) (on-leave conn n))
|
|
|
|
+ #:on-name-change (lambda ([n1 : String] [n2 : String])
|
|
|
|
+ (on-name-change conn n1 n2))
|
|
|
|
+ #:on-users (lambda ([l : (Listof String)])
|
|
|
|
+ (set! users l) (notify-users conn))
|
|
|
|
+ #:on-chat (lambda ([from : String] [msg : String])
|
|
|
|
+ (on-chat conn from msg))
|
|
|
|
+ #:on-response (lambda ([msg : String]) (on-response conn msg))
|
|
|
|
+ #:on-notify (lambda ([msg : String]) (on-response conn msg))
|
|
|
|
+ #:on-topic (lambda ([topic : String]) (on-topic conn topic))
|
|
|
|
+ #:on-close-conn (lambda () (custodian-shutdown-all cust))))
|
|
|
|
+
|
|
|
|
+ (ws:send-join ws-c (irc-connection-nick conn) "#00FFAA")
|
|
|
|
+
|
|
|
|
+ (send-to-client conn (irc-message
|
|
|
|
+ (format "~a!~a@lolcathost"
|
|
|
|
+ (irc-connection-nick conn)
|
|
|
|
+ (irc-connection-user conn))
|
|
|
|
+ "JOIN"
|
|
|
|
+ (list channel)))
|
|
|
|
+ (send-to-client conn (irc-message
|
|
|
|
+ ":lolcathost"
|
|
|
|
+ RPL_TOPIC
|
|
|
|
+ (list (irc-connection-nick conn) channel ":chatting hard")))
|
|
|
|
+
|
|
|
|
+ (sleep 1.5) ;; is there a way around going to sleep? :-<
|
|
|
|
+ (ws:send-users ws-c)
|
|
|
|
+ ws-c)
|
|
|
|
|
|
|
|
|
|
;; Utils
|
|
;; Utils
|
|
-(: send-ws-message (-> irc-connection String Void))
|
|
|
|
-(define (send-ws-message conn msg)
|
|
|
|
- (ws:send-message (irc-connection-ws-conn conn) msg))
|
|
|
|
|
|
+(: lookup-ws-conn (-> Channel-List String (U WS False)))
|
|
|
|
+(define (lookup-ws-conn ls x)
|
|
|
|
+ (define v (assoc x ls))
|
|
|
|
+ (and v (cdr v)))
|
|
|
|
+
|
|
|
|
+(: channel-joined? (-> String Channel-List Boolean))
|
|
|
|
+(define (channel-joined? x channels)
|
|
|
|
+ (if (assoc x channels) #t #f))
|
|
|
|
|
|
(: welcome-user (-> irc-connection Void))
|
|
(: welcome-user (-> irc-connection Void))
|
|
(define (welcome-user conn)
|
|
(define (welcome-user conn)
|