1#
2# Commands: /ASCII, /COLSAY, /COLME, /COLTOPIC, /COLKICK, /COLQUIT
3# Usage:
4#	/ASCII [-c1234] [-f <fontname>] [-p <prefix>] [-l|-s|-m <where>] <text>
5#	/COLSAY [-1234] [-m <where>] <text>
6#	/COLME [-1234] <text>
7#	/COLTOPIC [-1234] <text>
8#	/COLKICK [-1234] [nick(,nick_1,...,nick_n)] <reason>
9#	/COLQUIT [-1234] <reason>
10# Settings:
11#	/SET ascii_figlet_path [path]
12#	/SET ascii_default_font [fontname]
13#	/SET ascii_default_colormode [1-4]
14#	/SET ascii_default_prefix [prefix]
15#	/SET ascii_default_kickreason [reason]
16#	/SET ascii_default_quitreason [reason]
17#
18# Script is bassed on figlet.
19#
20
21use strict;
22use Irssi;
23use Irssi::Irc;
24
25use vars qw($VERSION %IRSSI);
26
27$VERSION = "1.6.3";
28%IRSSI = (
29	"authors"       => "Marcin Rozycki",
30	"contact"       => "derwan\@irssi.pl",
31	"name"          => "ascii-art",
32	"description"   => "Ascii-art bassed on figlet. Available commands: /ASCII, /COLSAY, /COLME, /COLTOPIC, /COLKICK, /COLQUIT.",
33	"url"           => "http://derwan.irssi.pl",
34	"license"       => "GNU GPL v2",
35	"changed"       => "Fri Jun 21 17:17:53 CEST 2002"
36);
37
38use IPC::Open3;
39
40# defaults
41my $ascii_default_font = "small.flf";
42my $ascii_default_kickreason = "Irssi BaBy!";
43my $ascii_default_quitreason = "I Quit!";
44my $ascii_last_color = undef;
45my @ascii_colors = (12, 12, 12, 9, 5, 4, 13, 8, 7, 3, 11, 10, 2, 6, 6, 6, 6, 10, 8, 7, 4, 3, 9, 11, 2, 12, 13, 5);
46
47# registering themes
48Irssi::theme_register([
49	'ascii_not_connected',		'%_$0:%_ You\'re not connected to server',
50	'ascii_not_window',		'%_$0:%_ Not joined to any channel or query window',
51	'ascii_not_chanwindow',		'%_$0:%_ Not joined to any channel',
52	'ascii_not_chanop',		'%_$0:%_ You\'re not channel operator in {hilight $1}',
53	'ascii_figlet_notfound',	'%_Ascii:%_ Cannot execute {hilight $0} - file not found or bad permissions',
54	'ascii_figlet_notset',		'%_Ascii:%_ Cannot find external program %_figlet%_, usign /SET ascii_figlet_path [path], to set it',
55	'ascii_cmd_syntax',		'%_$0:%_ $1, usage: $2',
56	'ascii_figlet_error',		'%_Ascii: Figlet returns error:%_ $0-',
57	'ascii_fontlist',		'%_Ascii:%_ Available fonts [in $0]: $1 ($2)',
58	'ascii_empty_fontlist',		'%_Ascii:%_ Cannot find figlet fonts in $0',
59	'ascii_unknown_fontdir',	'%_Ascii:%_ Cannot find figlet fontdir',
60	'ascii_show_line',		'$0-'
61
62]);
63
64# str find_figlet_path()
65sub find_figlet_path {
66	foreach my $dir (split(/\:/, $ENV{'PATH'}))
67	{
68		return "$dir/figlet" if ($dir and -x "$dir/figlet");
69	}
70}
71
72# int randcolor()
73sub randcolor {
74	return $ascii_colors[int(rand(12)+2)];
75}
76
77# str colorline($colormode, $text)
78sub colorline {
79	my ($colormode, $text) = @_;
80	my $colortext = undef;
81	my $last = ($ascii_last_color) ? $ascii_last_color : randcolor();
82	my $indx = $last;
83
84	if ($colormode =~ /3/) {
85		$ascii_last_color = randcolor();
86	}elsif ($colormode =~ /4/) {
87		$ascii_last_color = $ascii_colors[$last];
88	}elsif ($colormode !~ /2/) {
89		$ascii_last_color = $ascii_colors[14+$last];
90	}
91
92	while ($text =~ /./g)
93	{
94		my $char = "$&";
95
96		if ($colormode =~ /3/) {
97			while ($indx == $last) { $indx = randcolor(); };
98			$last = $indx;
99		}elsif ($colormode =~ /4/) {
100			$indx = $ascii_colors[$indx];
101		}elsif ($last) {
102			$indx = $ascii_colors[$last];
103			undef $last;
104		} else {
105			$indx = $ascii_colors[$indx];
106			$last = $indx + 14;
107		};
108
109		$colortext .= $char, next if ($char eq " ");
110		$colortext .= "\003" . sprintf("%02d", $indx) . $char;
111		$colortext .= $char if ($char eq ",");
112	};
113
114	return $colortext;
115};
116
117# int colormode()
118sub colormode {
119	my $mode = Irssi::settings_get_int("ascii_default_colormode");
120	$mode =~ s/-//g;
121	return (!$mode or $mode > 4) ? 1 : $mode;
122};
123
124# bool ascii_test($command, $flags, $server, $window)
125sub ascii_test {
126	my ($cmd, $test, $server, $window) = @_;
127
128	if ($test =~ /s/ and !$server || !$server->{connected}) {
129		Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_connected", $cmd);
130		return 0;
131	};
132	if ($test =~ /W/ and !$window || $window->{type} !~ /(channel|query)/i) {
133		Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_window", $cmd);
134		return 0;
135	};
136	if ($test =~ /(w|o)/ and !$window || $window->{type} !~ /channel/i) {
137		Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_chanwindow", $cmd);
138		return 0;
139	};
140	if ($test =~ /o/ and !$window->{chanop}) {
141		Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_chanop", $cmd, Irssi::active_win()->get_active_name());
142		return 0;
143	};
144
145	return 1;
146}
147
148# void cmd_ascii()
149# handles /ascii
150sub cmd_ascii
151{
152	my $usage = "/ASCII [-c1234] [-f <fontname>] [-p <prefix>] [-l|-s|-m <where>] <text>";
153	my $font = Irssi::settings_get_str("ascii_default_font");
154	my $prefix = Irssi::settings_get_str("ascii_default_prefix");
155	my ($arguments, $server, $witem) = @_;
156	my ($text, $cmd, $mode);
157
158	$font = $ascii_default_font unless ($font);
159	$ascii_last_color = randcolor();
160
161	my $figlet = Irssi::settings_get_str("ascii_figlet_path");
162	if (!$figlet or !(-x $figlet)) {
163		my $theme = ($figlet) ? "ascii_figlet_notfound" : "ascii_figlet_notset";
164		Irssi::printformat(MSGLEVEL_CRAP, $theme, $figlet);
165		return;
166	};
167
168	my @foo = split(/ +/, $arguments);
169	while ($_ = shift(@foo))
170	{
171		/^-l$/ and show_figlet_fonts($figlet), return;
172		/^-c$/ and $mode = colormode(), next;
173		/^-(1|2|3|4)$/ and s/-//g, $mode = $_, next;
174		/^-f$/ and $font = shift(@foo), next;
175		/^-p$/ and $prefix = shift(@foo), next;
176		/^-m$/ and $cmd = shift(@foo), next;
177		/^-s$/ and $cmd =  0, next;
178		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Ascii", "Unknown argument: $_", $usage), return;
179		$text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo);
180		last;
181	}
182
183	unless (length($text)) {
184		Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Ascii", "Missing arguments", $usage);
185		return;
186	};
187
188	if ($cmd eq "") {
189		return unless (ascii_test("Ascii", "sW", $server, $witem));
190		$cmd = Irssi::active_win()->get_active_name();
191	} elsif ($cmd ne "0" and !ascii_test("Ascii", "s", $server, $witem)) {
192		return;
193	}
194
195	my $pid = open3(*FIGIN, *FIGOUT, *FIGERR, $figlet, qw(-k -f), $font, $text);
196
197	while (<FIGOUT>)
198	{
199		chomp;
200		next unless (/[^ ]/);
201		$_ = colorline($mode, $_) if ($mode);
202		Irssi::printformat(MSGLEVEL_CLIENTCRAP, "ascii_show_line", $prefix.$_), next if ($cmd eq "0");
203		$server->command("msg $cmd $prefix$_");
204	}
205
206	while (<FIGERR>)
207	{
208		chomp;
209		Irssi::printformat(MSGLEVEL_CRAP, "ascii_figlet_error", $_);
210	};
211
212	close FIGIN;
213	close FIGOUT;
214	close FIGERR;
215
216	waitpid $pid, 0;
217}
218
219# void show_figlet_fonts(figlet path)
220sub show_figlet_fonts {
221	my @fontlist;
222	if (my $fontdir = `"$_[0]" -I 2 2>/dev/null`) {
223		chomp $fontdir;
224		foreach my $font (glob $fontdir."/*.flf")
225		{
226			$font =~ s/^$fontdir\///;
227			$font =~ s/\.flf$//;
228			push @fontlist, $font;
229		}
230		if ($#fontlist < 0) {
231			Irssi::printformat(MSGLEVEL_CRAP, "ascii_fontlist_empty", $fontdir);
232		} else {
233			Irssi::printformat(MSGLEVEL_CRAP, "ascii_fontlist", $fontdir, join(", ", @fontlist), scalar(@fontlist));
234		}
235	} else {
236		Irssi::printformat(MSGLEVEL_CRAP, "ascii_unknown_fontdir");
237	}
238}
239
240# void cmd_colsay()
241# handles /colsay
242sub cmd_colsay {
243	my $usage = "/COLSAY [-1234] [-m <where>] <text>";
244	my ($arguments, $server, $witem) = @_;
245	my ($cmd, $text);
246	my $mode = colormode();
247
248	$ascii_last_color = randcolor();
249
250	my @foo = split(/ /, $arguments);
251	while ($_ = shift(@foo))
252	{
253		/^-(1|2|3|4)$/ and $mode = $_, next;
254		/^-m$/i and $cmd = shift(@foo), next;
255		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colsay", "Unknown argument: $_", $usage), return;
256		$text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo);
257		last;
258	};
259
260	unless (length($text)) {
261		Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colsay", "Missing arguments", $usage);
262		return;
263	};
264
265	if ($cmd) {
266		return unless (ascii_test("Colsay", "s", $server, $witem));
267	} else {
268		return unless (ascii_test("Colsay", "sW", $server, $witem));
269		$cmd = Irssi::active_win()->get_active_name();
270	};
271
272	$server->command("msg $cmd ".colorline($mode, $text));
273}
274
275
276sub cmd_colme {
277	my $usage = "/COLME [-1234] <text>";
278	my ($arguments, $server, $witem) = @_;
279	my $mode = colormode();
280	my $text;
281
282	$ascii_last_color = randcolor();
283
284	my @foo = split(/ /, $arguments);
285	while ($_ = shift(@foo))
286	{
287		/^-(1|2|3|4)$/ and $mode = $_, next;
288		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colme", "Unknown argument: $_", $usage), return;
289		$text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo);
290		last;
291	};
292
293	unless (length($text)) {
294		Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colme", "Missing arguments", $usage);
295		return;
296	};
297
298	return unless (ascii_test("Colme", "sW", $server, $witem));
299	$witem->command("me ".colorline($mode, $text));
300}
301
302# void cmd_coltopic()
303# handles /coltopic
304sub cmd_coltopic {
305	my $usage = "/COLTOPIC [-1234] <text>";
306	my ($arguments, $server, $witem) = @_;
307	my $mode = colormode();
308	my $text;
309
310	$ascii_last_color = randcolor();
311
312	my @foo = split(/ /, $arguments);
313	while ($_ = shift(@foo))
314	{
315		/^-(1|2|3|4)$/ and $mode = $_, next;
316		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Coltopic", "Unknown argument: $_", $usage), return;
317		$text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo);
318		last;
319	};
320
321	unless (length($text)) {
322		Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Coltopic", "Missing arguments", $usage);
323		return;
324	};
325
326	return unless (ascii_test("Coltopic", "sw", $server, $witem));
327
328	$server->command("topic " . Irssi::active_win()->get_active_name() . " " . colorline($mode, $text));
329};
330
331# void cmd_colkick()
332# handles /colkick
333sub cmd_colkick {
334	my $usage = "/COLKICK [-1234] [nick(,nick_1,...,nick_n)] <reason>";
335	my ($arguments, $server, $witem) = @_;
336	my $kickreason = Irssi::settings_get_str("ascii_default_kickreason");
337	my $mode = colormode();
338	my $who = undef;
339
340	$ascii_last_color = randcolor();
341	$kickreason = $ascii_default_kickreason unless ($kickreason);
342
343	my @foo = split(/ /, $arguments);
344	while ($_ = shift(@foo))
345	{
346		/^-(1|2|3|4)$/ and $mode = $_, next;
347		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colkick", "Unknown argument: $_", $usage), return;
348		$kickreason = join(" ", @foo) if ($#foo >= 0);
349		$who = $_;
350		last;
351	};
352
353	if (!$who or !length($kickreason)) {
354		Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colkick", "Missing arguments", $usage);
355		return;
356	};
357
358	return unless (ascii_test("Colkick", "swo", $server, $witem));
359	$witem->command("kick $who ".colorline($mode, $kickreason));
360};
361
362# void cmd_colquit()
363# handles /colquit
364sub cmd_colquit {
365	my $usage = "/COLQUIT [-1234] <reason>";
366	my ($arguments, $server, $witem) = @_;
367	my $quitreason = Irssi::settings_get_str("ascii_default_quitreason");
368	my $mode = colormode();
369
370	$ascii_last_color = randcolor();
371	$quitreason = $ascii_default_quitreason unless ($quitreason);
372
373	my @foo = split(/ /, $arguments);
374	while ($_ = shift(@foo))
375	{
376		/^-(1|2|3|4)$/ and $mode = $_, next;
377		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colquit", "Unknown argument: $_", $usage), return;
378		$quitreason = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo);
379		last;
380	};
381
382	unless (length($quitreason)) {
383		Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colquit", "Missing arguments", $usage);
384		return;
385	};
386
387	return unless (ascii_test("Colquit", "s", $server, $witem));
388	$server->command("quit " . colorline($mode, $quitreason));
389}
390
391# registering settings
392Irssi::settings_add_str("misc", "ascii_default_font", $ascii_default_font);
393Irssi::settings_add_str("misc", "ascii_default_kickreason", $ascii_default_kickreason);
394Irssi::settings_add_str("misc", "ascii_default_quitreason", $ascii_default_quitreason);
395Irssi::settings_add_str("misc", "ascii_default_prefix", "");
396Irssi::settings_add_int("misc", "ascii_default_colormode", 1);
397Irssi::settings_add_str("misc", "ascii_figlet_path", find_figlet_path);
398
399# binding commands
400Irssi::command_bind("ascii", "cmd_ascii");
401Irssi::command_bind("colsay", "cmd_colsay");
402Irssi::command_bind("colme", "cmd_colme");
403Irssi::command_bind("coltopic", "cmd_coltopic");
404Irssi::command_bind("colkick", "cmd_colkick");
405Irssi::command_bind("colquit", "cmd_colquit");
406