source: tags/debian_version_0_6_3/event.lisp

Last change on this file was 76, checked in by Erik Huelsmann, 19 years ago

Make default behaviours obey rpl_isupport parameters advertized by the server.

  • variable.lisp (*default-isupport-values*): New.
  • utility.lisp (irc-string-downcase): New. Method to do case mapping required to canonicalize entity (channel, nick) identity names. (parse-isupport-multivalue-argument): New. Parse isupport string used in multi-value argument-values as used for CHANLIMIT, CHANMODES, IDCHAN and others.
  • protocol.lisp (connection:server-capabilities): New. This slot stores the assoc list of parameter keys and their values. (case-map-name): New. Returns the case-mapping used for a connection. (re-apply-case-mapping): New. Make sure all nicks and channels have been mapped using the same function. Also assures all hashes are based on the same mapping function. (add-default-hooks): Add irc-rpl_isupport-message to the default hooks list. (normalize-channel-name): Add connection parameter; use case-mapping active for the given connection. (make-channel): Add a connection to be passed in order to be able to do name-normalization. (make-user): Add connection parameter in order to be able to do name-normalization. (canonicalize-nickname): Use server-advertized nickname prefixes to determine how to canonicalize. (normalize-nickname): Use connections case-mapping to do normalization. (find-or-make-user): Pass connection in call to make-user. (find-channel, find-user, change-nickname): Update callers of normalize-nickname, normalize-channel-name and canonicalize-nickname
  • command.lisp (connect): Change instance creation order; creating a user requires a connection now.
  • event.lisp (default-hook [irc-rpl_isupport-message]): New. Implement default hook message for rpl_isupport message. Make sure that default values do get set. (default-hook [irc-rpl_list-message,

irc-join-message]): Update caller of make-channel.

(default-hook [irc-rpl_namreply-message]): Update caller of
canonicalize-nickname.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1;;;; $Id: event.lisp 76 2005-01-20 23:59:19Z ehuelsmann $
2;;;; $Source$
3
4;;;; See LICENSE for licensing information.
5
6(in-package :irc)
7
8(defgeneric irc-message-event (message)
9  (:documentation "Upon receipt of an IRC message from the
10connection's stream, irc-message-event will be called with the
11message."))
12
13(defmethod irc-message-event ((message irc-message))
14  (apply-to-hooks message)
15  (client-log (connection message) message "UNHANDLED-EVENT:"))
16
17
18(defgeneric default-hook (message)
19  (:documentation "Minimum action to be executed upon reception
20of the IRC message to keep the connection, channel and user
21objects in sync."))
22
23(defmethod default-hook ((message irc-rpl_isupport-message))
24  (let* ((capabilities (cdr (arguments message)))
25         (connection (connection message))
26         (current-case-mapping (case-map-name connection)))
27    (setf (server-capabilities connection)
28          (let ((new-values (mapcar #'(lambda (x)
29                                        (let ((eq-pos (position #\= x)))
30                                          (if eq-pos
31                                              (list (subseq x 0 eq-pos)
32                                                    (subseq x (1+ eq-pos)))
33                                            (list x)))) capabilities)))
34            (mapcar #'(lambda (x)
35                        (or (assoc x new-values :test #'string=)
36                            (assoc x *default-isupport-values*
37                                   :test #'string=)))
38                    (remove-duplicates
39                     (mapcar #'first (append new-values
40                                             *default-isupport-values*))
41                             :test #'string=))))
42
43    (when (not (equal current-case-mapping
44                      (case-map-name connection)))
45      ;; we need to re-normalize nicks and channel names
46      (re-apply-case-mapping connection))))
47
48(defmethod default-hook ((message irc-rpl_whoisuser-message))
49  (let ((user (find-user (connection message)
50                         (second (arguments message))))
51        (realname (trailing-argument message))
52        (username (third (arguments message)))
53        (hostname (fourth (arguments message))))
54    (when user
55      (setf (realname user) realname)
56      (setf (username user) username)
57      (setf (hostname user) hostname))))
58
59(defmethod default-hook ((message irc-rpl_list-message))
60  (let ((connection (connection message))
61        (channel (second (arguments message)))
62        (user-count (parse-integer (or (third (arguments message)) "0")))
63        (topic (trailing-argument message)))
64    (add-channel connection (or (find-channel connection channel)
65                                (make-channel connection
66                                              :name channel
67                                              :topic topic
68                                              :user-count user-count)))))
69
70(defmethod default-hook ((message irc-rpl_topic-message))
71  (setf (topic (find-channel (connection message)
72                             (second (arguments message))))
73        (trailing-argument message)))
74
75(defmethod default-hook ((message irc-rpl_namreply-message))
76  (let* ((connection (connection message))
77         (channel (find-channel connection (car (last (arguments message))))))
78    (dolist (nickname (tokenize-string (trailing-argument message)))
79      (let ((user (find-or-make-user connection
80                                     (canonicalize-nickname connection
81                                                            nickname)
82                                     :username (user message)
83                                     :hostname (host message))))
84        (unless (equal user (user connection))
85          (add-user connection user)
86          (add-user channel user))))))
87
88(defmethod default-hook ((message irc-ping-message))
89  (pong (connection message) (trailing-argument message)))
90
91(defmethod default-hook ((message irc-join-message))
92  (let* ((connection (connection message))
93         (user (find-or-make-user
94                (connection message)
95                (source message)
96                :hostname (host message)
97                :username (user message)))
98         (channel (or (find-channel connection (trailing-argument message))
99                      (make-channel connection
100                                    :name (trailing-argument message)))))
101    (if (self-message-p message)
102        (add-channel connection channel)
103        (progn
104          (add-user connection user)
105          (add-user channel user)))))
106
107(defmethod default-hook ((message irc-topic-message))
108  (setf (topic (find-channel (connection message)
109                             (first (arguments message))))
110        (trailing-argument message)))
111
112(defmethod default-hook ((message irc-part-message))
113  (let* ((connection (connection message))
114         (channel (find-channel connection (first (arguments message))))
115         (user (find-user connection (source message))))
116    (if (self-message-p message)
117        (remove-channel user channel)
118        (remove-user channel user))))
119
120(defmethod default-hook ((message irc-quit-message))
121  (let ((connection (connection message)))
122    (remove-user-everywhere connection (find-user connection (source message)))))
123
124(defmethod default-hook ((message irc-nick-message))
125  (let ((con (connection message)))
126    (change-nickname con (find-user con (source message))
127                     (trailing-argument message))))
128
129(defmethod default-hook ((message irc-kick-message))
130  (let* ((connection (connection message))
131         (channel (find-channel connection (first (arguments message))))
132         (user (find-user connection (second (arguments message)))))
133    (if (self-message-p message)
134        (remove-channel user channel)
135        (remove-user channel user))))
136
137(defmethod default-hook ((message ctcp-time-message))
138  (multiple-value-bind (second minute hour date month year day) (get-decoded-time)
139    (send-irc-message
140     (connection message)
141     :notice (make-ctcp-message
142              (format nil "TIME ~A"
143                      (make-time-message second minute hour date month year day)))
144     (source message))))
145
146(defmethod default-hook ((message ctcp-source-message))
147  (send-irc-message
148   (connection message)
149   :notice (make-ctcp-message
150            (format nil "SOURCE ~A:~A:~A"
151                    *download-host*
152                    *download-directory*
153                    *download-file*))
154   (source message)))
155
156(defmethod default-hook ((message ctcp-finger-message))
157  (let* ((user (user (connection message)))
158         (finger-info (if (not (zerop (length (realname user))))
159                          (realname user)
160                          (nickname user))))
161    (send-irc-message
162     (connection message)
163     :notice (make-ctcp-message
164              (format nil "FINGER ~A" finger-info))
165     (source message))))
166
167(defmethod default-hook ((message ctcp-version-message))
168  (send-irc-message
169   (connection message)
170   :notice (make-ctcp-message
171            (format nil "VERSION ~A" *ctcp-version*))
172   (source message)))
173
174(defmethod default-hook ((message ctcp-ping-message))
175  (send-irc-message
176   (connection message)
177   :notice (make-ctcp-message
178            (format nil "PING ~A" (trailing-argument message)))
179   (source message)))
180
181(defmethod irc-message-event ((message ctcp-dcc-chat-request-message))
182  (apply-to-hooks message)
183  (client-log (connection message) message))
184;  (when (automatically-accept-dcc-connections (configuration (connection message)))
185;    (let* ((user (find-user (connection message) (source message)))
186;           (args (tokenize-string (trailing-argument message)))
187;           (remote-address (hbo-to-vector-quad (parse-integer (fourth args))))
188;           (remote-port (parse-integer (fifth args) :junk-allowed t)))
189;      (push (make-dcc-connection :user user
190;                                 :remote-address remote-address
191;                                 :remote-port remote-port)
192;            *dcc-connections*))))
193 
194(defmethod irc-message-event ((message ctcp-dcc-send-request-message))
195  (apply-to-hooks message)
196  (client-log (connection message) message))
197;  (when (automatically-accept-dcc-downloads (configuration (connection message)))
198;    (let* ((user (find-user (connection message) (source message)))
199;           (args (tokenize-string (trailing-argument message)))
200;           (filename (third args))
201;           (remote-address (hbo-to-vector-quad (parse-integer (fourth args))))
202;           (remote-port (parse-integer (fifth args)))
203;           (filesize (parse-integer (sixth args) :junk-allowed t)))
204;      (let ((dcc-connection (make-dcc-connection :user user
205;                                                 :remote-address remote-address
206;                                                 :remote-port remote-port)))
207;      (with-open-file (stream filename :direction :output
208;                              :if-exists :supersede)
209;        (write-sequence (read-message-loop dcc-connection) stream))))))
210 
Note: See TracBrowser for help on using the repository browser.