1IRC::Utils(3) User Contributed Perl Documentation IRC::Utils(3)
2
3
4
6 IRC::Utils - Common utilities for IRC-related tasks
7
9 use strict;
10 use warnings;
11
12 use IRC::Utils ':ALL';
13
14 my $nickname = '^Lame|BOT[moo]';
15 my $uppercase_nick = uc_irc($nickname);
16 my $lowercase_nick = lc_irc($nickname);
17
18 print "They're equivalent\n" if eq_irc($uppercase_nick, $lowercase_nick);
19
20 my $mode_line = 'ov+b-i Bob sue stalin*!*@*';
21 my $hashref = parse_mode_line($mode_line);
22
23 my $banmask = 'stalin*';
24 my $full_banmask = normalize_mask($banmask);
25
26 if (matches_mask($full_banmask, 'stalin!joe@kremlin.ru')) {
27 print "EEK!";
28 }
29
30 my $decoded = irc_decode($raw_irc_message);
31 print $decoded, "\n";
32
33 if (has_color($message)) {
34 print 'COLOR CODE ALERT!\n";
35 }
36
37 my $results_hashref = matches_mask_array(\@masks, \@items_to_match_against);
38
39 my $nick = parse_user('stalin!joe@kremlin.ru');
40 my ($nick, $user, $host) = parse_user('stalin!joe@kremlin.ru');
41
43 The functions in this module take care of many of the tasks you are
44 faced with when working with IRC. Mode lines, ban masks, message
45 encoding and formatting, etc.
46
48 "uc_irc"
49 Takes one mandatory parameter, a string to convert to IRC uppercase,
50 and one optional parameter, the casemapping of the ircd (which can be
51 'rfc1459', 'strict-rfc1459' or 'ascii'. Default is 'rfc1459'). Returns
52 the IRC uppercase equivalent of the passed string.
53
54 "lc_irc"
55 Takes one mandatory parameter, a string to convert to IRC lowercase,
56 and one optional parameter, the casemapping of the ircd (which can be
57 'rfc1459', 'strict-rfc1459' or 'ascii'. Default is 'rfc1459'). Returns
58 the IRC lowercase equivalent of the passed string.
59
60 "eq_irc"
61 Takes two mandatory parameters, IRC strings (channels or nicknames) to
62 compare. A third, optional parameter specifies the casemapping. Returns
63 true if the two strings are equivalent, false otherwise
64
65 # long version
66 lc_irc($one, $map) eq lc_irc($two, $map)
67
68 # short version
69 eq_irc($one, $two, $map)
70
71 "parse_mode_line"
72 Takes a list representing an IRC mode line. Returns a hashref.
73 Optionally you can also supply an arrayref and a hashref to specify
74 valid channel modes (default: "[qw(beI k l imnpstaqr)]") and status
75 modes (default: "{o => '@', h => '%', v => '+'}"), respectively.
76
77 If the modeline couldn't be parsed the hashref will be empty. On
78 success the following keys will be available in the hashref:
79
80 'modes', an arrayref of normalised modes;
81
82 'args', an arrayref of applicable arguments to the modes;
83
84 Example:
85
86 my $hashref = parse_mode_line( 'ov+b-i', 'Bob', 'sue', 'stalin*!*@*' );
87
88 # $hashref will be:
89 {
90 modes => [ '+o', '+v', '+b', '-i' ],
91 args => [ 'Bob', 'sue', 'stalin*!*@*' ],
92 }
93
94 "normalize_mask"
95 Takes one parameter, a string representing an IRC mask. Returns a
96 normalised full mask.
97
98 Example:
99
100 $fullbanmask = normalize_mask( 'stalin*' );
101
102 # $fullbanmask will be: 'stalin*!*@*';
103
104 "matches_mask"
105 Takes two parameters, a string representing an IRC mask and something
106 to match against the IRC mask, such as a nick!user@hostname string.
107 Returns a true value if they match, a false value otherwise.
108 Optionally, one may pass the casemapping (see "uc_irc"), as this
109 function uses "uc_irc" internally.
110
111 "matches_mask_array"
112 Takes two array references, the first being a list of strings
113 representing IRC masks, the second a list of somethings to test against
114 the masks. Returns an empty hashref if there are no matches. Otherwise,
115 the keys will be the masks matched, each value being an arrayref of the
116 strings that matched it. Optionally, one may pass the casemapping (see
117 "uc_irc"), as this function uses "uc_irc" internally.
118
119 "unparse_mode_line"
120 Takes one argument, a string representing a number of mode changes.
121 Returns a condensed version of the changes.
122
123 my $mode_line = unparse_mode_line('+o+o+o-v+v');
124 $mode_line is now '+ooo-v+v'
125
126 "gen_mode_change"
127 Takes two arguments, strings representing a set of IRC user modes
128 before and after a change. Returns a string representing what changed.
129
130 my $mode_change = gen_mode_change('abcde', 'befmZ');
131 $mode_change is now '-acd+fmZ'
132
133 "parse_user"
134 Takes one parameter, a string representing a user in the form
135 nick!user@hostname. In a scalar context it returns just the nickname.
136 In a list context it returns a list consisting of the nick, user and
137 hostname, respectively.
138
139 "is_valid_chan_name"
140 Takes one argument, a channel name to validate. Returns true or false
141 if the channel name is valid or not. You can supply a second argument,
142 an array of characters of allowed channel prefixes. Defaults to "['#',
143 '&']".
144
145 "is_valid_nick_name"
146 Takes one argument, a nickname to validate. Returns true or false if
147 the nickname is valid or not.
148
149 "numeric_to_name"
150 Takes an IRC server numerical reply code (e.g. '001') as an argument,
151 and returns the corresponding name (e.g. 'RPL_WELCOME').
152
153 "name_to_numeric"
154 Takes an IRC server reply name (e.g. 'RPL_WELCOME') as an argument, and
155 returns the corresponding numerical code (e.g. '001').
156
157 "has_color"
158 Takes one parameter, a string of IRC text. Returns true if it contains
159 any IRC color codes, false otherwise. Useful if you want your bot to
160 kick users for (ab)using colors. :)
161
162 "has_formatting"
163 Takes one parameter, a string of IRC text. Returns true if it contains
164 any IRC formatting codes, false otherwise.
165
166 "strip_color"
167 Takes one parameter, a string of IRC text. Returns the string stripped
168 of all IRC color codes.
169
170 "strip_formatting"
171 Takes one parameter, a string of IRC text. Returns the string stripped
172 of all IRC formatting codes.
173
174 "decode_irc"
175 This function takes a byte string (i.e. an unmodified IRC message) and
176 returns a text string. Since the source encoding might have been UTF-8,
177 you should store it with UTF-8 or some other Unicode encoding in your
178 file/database/whatever to be safe. For a more detailed discussion, see
179 "ENCODING".
180
181 use IRC::Utils qw(decode_irc);
182
183 sub message_handler {
184 my ($nick, $channel, $message) = @_;
185
186 # not wise, $message is a byte string of unkown encoding
187 print $message, "\n";
188
189 $message = decode_irc($what);
190
191 # good, $message is a text string
192 print $message, "\n";
193 }
194
196 Use the following constants to add formatting and mIRC color codes to
197 IRC messages.
198
199 Normal text:
200
201 NORMAL
202
203 Formatting:
204
205 BOLD
206 UNDERLINE
207 REVERSE
208 ITALIC
209 FIXED
210
211 Colors:
212
213 WHITE
214 BLACK
215 BLUE
216 GREEN
217 RED
218 BROWN
219 PURPLE
220 ORANGE
221 YELLOW
222 LIGHT_GREEN
223 TEAL
224 LIGHT_CYAN
225 LIGHT_BLUE
226 PINK
227 GREY
228 LIGHT_GREY
229
230 Individual non-color formatting codes can be cancelled with their
231 corresponding constant, but you can also cancel all of them at once
232 with "NORMAL". To cancel the effect of color codes, you must use
233 "NORMAL". which of course has the side effect of cancelling all other
234 formatting codes as well.
235
236 $msg = 'This word is '.YELLOW.'yellow'.NORMAL.' while this word is'.BOLD.'bold'.BOLD;
237 $msg = UNDERLINE.BOLD.'This sentence is both underlined and bold.'.NORMAL;
238
240 Messages
241 The only encoding requirement the IRC protocol places on its messages
242 is that they be 8-bits and ASCII-compatible. This has resulted in most
243 of the Western world settling on ASCII-compatible Latin-1 (usually
244 Microsoft's CP1252, a Latin-1 variant) as a convention. Recently,
245 popular IRC clients (mIRC, xchat, certain irssi configurations) have
246 begun sending a mixture of CP1252 and UTF-8 over the wire to allow more
247 characters without breaking backward compatibility (too much). They
248 send CP1252 encoded messages if the characters fit within that
249 encoding, otherwise falling back to UTF-8, and likewise autodetecting
250 the encoding (UTF-8 or CP1252) of incoming messages. Since writing
251 text with mixed encoding to a file, terminal, or database is not a good
252 idea, you need a way to decode messages from IRC. "decode_irc" will do
253 that.
254
255 Channel names
256 The matter is complicated further by the fact that some servers allow
257 non-ASCII characters in channel names. IRC modules generally don't
258 explicitly encode or decode any IRC traffic, but they do have to
259 concatenate parts of a message (e.g. a channel name and a message)
260 before sending it over the wire. So when you do something like
261 "privmsg($channel, 'æði')", where $channel is the unmodified channel
262 name (a byte string) you got from an earlier IRC message, the channel
263 name will get double-encoded when concatenated with your message (a
264 non-ASCII text string) if the channel name contains non-ASCII bytes.
265
266 To prevent this, you can't simply decode the channel name and then use
267 it. '#æði' in CP1252 is not the same channel as '#æði' in UTF-8, since
268 they are encoded as different sequences of bytes, and the IRC server
269 only cares about the byte representation. Therefore, when using a
270 channel name you got from the server (e.g. when replying to message),
271 you should use the original byte string (before it has been decoded
272 with "decode_irc"), and encode any other parameters (with
273 "encode_utf8") so that your message will be concatenated correctly. At
274 some point, you'll probably want to print the channel name, write it to
275 a log file or use it in a filename, so you'll eventually have to decode
276 it, at which point the UTF-8 "#æði" and CP1252 "#æði" will have to be
277 considered equivalent.
278
279 use Encode qw(encode_utf8 encode);
280
281 sub message_handler {
282 # these three are all byte strings
283 my ($nick, $channel, $message) = @_;
284
285 # bad: if $channel has any non-ASCII bytes, they will get double-encoded
286 privmsg($channel, 'æði');
287
288 # bad: if $message has any non-ASCII bytes, they will get double-encoded
289 privmsg('#æði', $message);
290
291 # good: both are byte strings already, so they will concatenate correctly
292 privmsg($channel, $message);
293
294 # good: both are text strings (Latin1 as per Perl's default), so
295 # they'll be concatenated correctly
296 privmsg('#æði', 'æði');
297
298 # good: similar to the last one, except now they're using UTF-8, which
299 # means that the channel is actually not the same as above
300 use utf8;
301 privmsg('#æði', 'æði');
302
303 # good: $channel and $msg_bytes are both byte strings
304 my $msg_bytes = encode_utf8('æði');
305 privmsg($channel, $msg_bytes);
306
307 # good: $chan_bytes and $message are both byte strings
308 # here we're sending a message to the utf8-encoded #æði
309 my $utf8_bytes = encode_utf8('#æði');
310 privmsg($utf8_bytes, $message);
311
312 # good: $chan_bytes and $message are both byte strings
313 # here we're sending a message to the cp1252-encoded #æði
314 my $cp1252_bytes = encode('cp1252', '#æði');
315 privmsg($cp1252_bytes, $message);
316
317 # bad: $channel is in an undetermined encoding
318 log_message("Got message from $channel");
319
320 # good: using the decoded version of $channel
321 log_message("Got message from ".decode_irc($channel));
322 }
323
324 See also Encode, perluniintro, perlunitut, perlunicode, and perlunifaq.
325
327 Hinrik Örn Sigurðsson <hinrik.sig@gmail.com> ("Hinrik" irc.perl.org, or
328 "literal" @ FreeNode).
329
330 Chris "BinGOs" Williams <chris@bingosnet.co.uk>
331
333 POE::Component::IRC
334
335 POE::Component::Server::IRC
336
337
338
339perl v5.36.0 2023-01-20 IRC::Utils(3)