summaryrefslogtreecommitdiffstats
path: root/scripts/len.pl
blob: fbcc75950de09e74e9f0fcd80cf1ef4894f3713a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# $Id: len.pl 4 2006-03-11 18:30:09Z ch $

use Irssi 20020324;
use 5.005_62;
use strict;
use vars qw($VERSION %IRSSI);

$VERSION = '1.0.0';
#$VERSION = '1.0.0 SVN ($LastChangedRevision: 4 $)';
%IRSSI = (
          authors     => 'Clemens Heidinger',
          changed     => '$LastChangedDate: 2006-03-11 19:30:09 +0100 (Sat, 11 Mar 2006) $',
          commands    => 'len',
          contact     => 'heidinger@dau.pl',
          description => 'If you try to get a nick with 11 characters but only ' .
                         '9 are allowed, this script will prevent the '          .
                         'nickchange. The same for too long topics, kickmsgs, '  .
                         'partmsgs and quitmsgs.',
          license     => 'BSD',
          name        => 'len',
         );

################################################################################
#                                                                              #
# CHANGELOG                                                                    #
#                                                                              #
# 2006-03-11    release 1.0.0                                                  #
#               No big changes. As the script is stable for quite a while,     #
#               this is the 1.0.0 release.                                     #
#                                                                              #
# 2005-01-28    release 0.4.0                                                  #
#               Splitted up 005 event messages will cause no trouble anymore   #
#                                                                              #
# 2004-04-26    release 0.3.2                                                  #
#               minor changes                                                  #
#                                                                              #
# 2003-01-18    release 0.3.1                                                  #
#               - revised help-message                                         #
#               - minor changes                                                #
#                                                                              #
# 2003-01-18    release 0.3.0                                                  #
#               %data-hash moved to extern file specified in setting           #
#               len_data_file                                                  #
#                                                                              #
# 2002-10-02    release 0.2.1                                                  #
#               Changed output format of /len                                  #
#                                                                              #
# 2002-09-27    release 0.2.0                                                  #
#               Added command /len with a table containing the values for      #
#               NICKLEN etc. and tips if these values haven't been received    #
#               from the server yet                                            #
#                                                                              #
# 2002-09-26    release 0.1.0                                                  #
#               initial release                                                #
#                                                                              #
################################################################################

################################################################################
# Register commands
################################################################################

Irssi::command_bind('len', \&command_len);

################################################################################
# Register settings
################################################################################

# String
Irssi::settings_add_str('misc', 'len_data_file', "$ENV{HOME}/.len");

################################################################################
# Register signals
################################################################################

Irssi::signal_add_first('command kick', \&signal_command_kick);
Irssi::signal_add_first('command nick', \&signal_command_nick);
Irssi::signal_add_first('command part', \&signal_command_part);
Irssi::signal_add_first('command quit', \&signal_command_quit);
Irssi::signal_add_first('command topic', \&signal_command_topic);
Irssi::signal_add_last('event 005', \&signal_event_005);

################################################################################
# Register themes
################################################################################

Irssi::theme_register(['len_print', '[$0] {line_start} $1']);

################################################################################
# Global Variables
################################################################################

# Put values of the settings in %option-hash

our %option;

# Most IRC-Server send a message containing the values for NICKLEN, TOPICLEN
# and KICKLEN.
# Well, some server do not send this message. Get these values from %data-hash
# stored in file specified in setting len_data_file.

our %data;

################################################################################
# Code run once at start
################################################################################

print CLIENTCRAP "len.pl $VERSION loaded. For further information type %9/len%9";

################################################################################
# Subroutines (commands)
################################################################################

sub command_len {
	my ($data, $server, $witem) = @_;
	my $output;

	unless ($server and defined($server)) {
		print_out("First connect to a server...");
		return;
	}

	read_file();

	my $kicklen  = sprintf "%-8s", $data{$server->{tag}}{kicklen};
	my $nicklen  = sprintf "%-8s", $data{$server->{tag}}{nicklen};
	my $partlen  = sprintf "%-8s", $data{$server->{tag}}{partlen};
	my $quitlen  = sprintf "%-8s", $data{$server->{tag}}{quitlen};
	my $topiclen = sprintf "%-9s", $data{$server->{tag}}{topiclen};

	$output = &fix(<<"	END");
	|=========|=================|
	|         | max. characters |
	|=========|=================|
	| kickmsg | $kicklen        |
	|---------|-----------------|
	| nick    | $nicklen        |
	|---------|-----------------|
	| partmsg | $partlen        |
	|---------|-----------------|
	| quitmsg | $quitlen        |
	|---------|-----------------|
	| topic   | $topiclen       |
	|---------|-----------------|
	END

	unless ($kicklen   =~ /\d/ &&
	        $nicklen   =~ /\d/ &&
	        $partlen   =~ /\d/ &&
	        $quitlen   =~ /\d/ &&
	        $topiclen  =~ /\d/)
	{
		$output .= &fix(<<"		END");

		Obviously there are some values missing.
		When you connect to a server most send you a message (numeric 005)
		with the proper values for the maximal nick length, topic length etc.
		If you loaded this script after connecting to "$server->{tag}"
		you should reconnect.
		If this doesn't help, the server is not sending the message with these
		values.
		The following alternatives remain:
		  * Use another server of the same network and cross your fingers
		    that it'll send the message.
		  * Find out the values and adjust the data hash in the file
		    specified in the setting len_data_file.
		    The file might look like this:

		    %{ \$data{$server->{tag}} } = (
		        'kicklen'  => <value>,
		        'nicklen'  => <value>,
		        'partlen'  => <value>,
		        'quitlen'  => <value>,
		        'topiclen' => <value>,
		    );

		    %{ \$data{someOtherNetwork} } = (
		        'kicklen'  => 160,
		        'nicklen'  => 9,
		        'partlen'  => 160,
		        'quitlen'  => 160,
		        'topiclen' => 160,
		    );
		END
	}

	foreach my $line (split /\n/, $output) {
		Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'len_print', $server->{tag}, $line);
	}
}

################################################################################
# Subroutines (signals)
################################################################################

sub signal_command_kick {
	my ($command, $server, $witem) = @_;

	return unless ($server and defined($server));

	read_file();

	# Syntax for /kick:
	# KICK [<channel>] <nicks> [<reason>]
	# We want to isolate <reason> to know how long it is

	# delete [<channel>] <nicks>
	$command =~ s/^\s*           # Start of String and optional some whitespace
	              (?:            # Grouping
	              \#\S+          # This is <channel>
	              )?             # End of Grouping, <channel> is optional
	              [ ]?           # Maybe a single space
	              \S+            # Everything not whitespace. These are the nicks.
	              [ ]?           # Maybe a single space
	             //x;            # Delete everything

	# The rest of $command is the kickmsg
	my $kickmsg = $command;

	my $len = length($kickmsg);
	my $maxlen = $data{$server->{tag}}{kicklen};

	if ($maxlen > 0 && $len > $maxlen) {
		print_out("kickmsg too long! ($len/$maxlen)");
		Irssi::signal_stop();
	}
}

sub signal_command_nick {
	my ($nick, $server, $witem) = @_;

	return unless ($server and defined($server));

	read_file();

	my $len = length($nick);
	my $maxlen = $data{$server->{tag}}{nicklen};

	if ($maxlen > 0 && $len > $maxlen) {
		print_out("Nick too long! ($len/$maxlen)");
		Irssi::signal_stop();
	}
}

sub signal_command_part {
	my ($command, $server, $witem) = @_;

	return unless ($server and defined($server));

	read_file();

	# Syntax for /part:
	# PART [<channels>] [<message>]
	# So we want to get rid of the channels to isolate the partmsg

	# Delete [<channels>]
	$command =~ s/^#\S+ //;

	# The rest of $command is the partmsg
	my $partmsg = $command;

	my $len = length($partmsg);
	my $maxlen = $data{$server->{tag}}{partlen};

	if ($maxlen > 0 && $len > $maxlen) {
		print_out("partmsg too long! ($len/$maxlen)");
		Irssi::signal_stop();
	}
}

sub signal_command_quit {
	my ($quitmsg, $server, $witem) = @_;

	return unless ($server and defined($server));

	read_file();

	my $len = length($quitmsg);
	my $maxlen = $data{$server->{tag}}{quitlen};

	if ($maxlen > 0 && $len > $maxlen) {
		print_out("quitmsg too long! ($len/$maxlen)");
		Irssi::signal_stop();
	}
}

sub signal_command_topic {
	my ($command, $server, $witem) = @_;

	return unless ($server and defined($server));

	read_file();

	# Syntax for /topic:
	# TOPIC [-delete] [<channel>] [<topic>]
	# We want to isolate <reason> to know how long it is

	# Delete <channel>
	$command =~ s/^#\S+ //;

	# The rest of $command is the topic
	my $topic = $command;

	my $len = length($topic);
	my $maxlen = $data{$server->{tag}}{topiclen};

	if ($maxlen > 0 && $len > $maxlen) {
		print_out("Topic too long! ($len/$maxlen)");
		Irssi::signal_stop();
	}
}

# Most server send this message containig the values for NICKLEN etc. on
# connect (event 005).

sub signal_event_005 {
	my ($server, $string) = @_;

	if ($string =~ /KICKLEN=(\d+)/) {
		$data{$server->{tag}}{kicklen} = $1;
		$data{$server->{tag}}{partlen} = $1;
		$data{$server->{tag}}{quitlen} = $1;
	}
	if ($string =~ /NICKLEN=(\d+)/) {
		$data{$server->{tag}}{nicklen} = $1;
	}
	if ($string =~ /TOPICLEN=(\d+)/) {
		$data{$server->{tag}}{topiclen} = $1;
	}
}

################################################################################
# Helper subroutines
################################################################################

sub fix {
	my $string = shift;
	$string =~ s/^\t+//gm;
	return $string;
}

sub print_err {
	my $text = shift;

	print CLIENTCRAP '%Rlen.pl error%n: ' . $text;
}

sub print_out {
	my $text = shift;

	print CLIENTCRAP '%9len.pl%9: ' . $text;
}

sub read_file {
	set_settings();

	my $file = $option{len_data_file};

	unless (-e $file && -r $file) {
		return;
	}
	unless (my $return = do $file) {
		if ($@) {
			print_err("parsing $file failed: $@");
		}
		unless (defined($return)) {
			print_err("'do $file' failed");
		}
	}
}

sub set_settings {
	# String
	$option{len_data_file} = Irssi::settings_get_str('len_data_file');
}