html/mood.pl
1 #!/usr/bin/perl
2 #
3 # This script tracks the general mood in a channel.
4 #
5 #
6 # Changelog:
7 # 19.03.2002
8 # *first release
9 #
10 # 20.03.2002
11 # *some regexp tweaking
12 #
13 # 07.04.2002
14 # *own messages can be interpreted
15
16 use strict;
17
18 use vars qw($VERSION %IRSSI);
19
20 $VERSION = "20031207";
21 %IRSSI = (
22 authors => "Stefan 'tommie' Tomanek",
23 contact => "stefan\@pico.ruhr.de",
24 name => "Mood",
25 description => "Keeps track of the channel mood",
26 license => "GPLv2",
27 sbitems => "moodbar",
28 changed => "$VERSION",
29 );
30
31 use Irssi;
32 use Irssi::TextUI;
33 use vars qw(%channels $eye $refresh $shouting $bored_mouth);
34
35 sub find_smiley {
36 my ($msg) = @_;
37 my $eyes = '[:=8;]';
38 my $noses = '[\-\o]?';
39 my $sad = '[\(\<\[]';
40 my $happy = '[\)\>\]D]';
41 my %smiley = ($eyes.$noses.$happy => 10,
42 $sad.$noses.$eyes => 10,
43 $eyes.$noses.$sad => -10,
44 $happy.$noses.$eyes => -10,
45 $eyes.'\.+'.$noses.$sad => -20,
46 $happy.$noses.'\.+'.$eyes => -20,
47 );
48 foreach (keys(%smiley)) {
49 return($smiley{$_}) if ($msg =~ m/.*($_).*/);
50 }
51 return 0;
52 }
53
54 sub event_event_privmsg {
55 my ($server, $data, $nick, $address) = @_;
56 my ($target, $msg) = split(/ :/, $data,2);
57 change_mood($target, find_smiley($msg));
58 }
59
60 sub event_message_own_public {
61 my ($server, $msg, $target) = @_;
62 change_mood($target, find_smiley($msg));
63 }
64
65 sub event_message_kick {
66 my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
67 change_mood($channel, -20);
68 }
69
70 sub event_ban_new {
71 my ($channel, $ban) = @_;
72 my $name = $channel->{name};
73 change_mood($name, -20);
74 }
75
76 sub event_ban_remove {
77 my ($channel, $ban) = @_;
78 my $name = $channel->{name};
79 change_mood($name, 20);
80 }
81
82 sub event_netsplit_new {
83 my ($netsplit) = @_;
84 #FIXME Not Idea :)
85 #Irssi::print $netsplit->{nick};
86 }
87
88 sub event_window_hilight {
89 my ($window) = @_;
90 open_mouth();
91 }
92
93 sub change_mood {
94 my ($name, $points) = @_;
95 if (not exists $channels{$name}) {
96 $channels{lc $name} = 0;
97 }
98 $channels{lc $name} += $points;
99 mood_refresh();
100 }
101
102 sub draw_smiley {
103 my ($points) = @_;
104
105 my $mouth = $bored_mouth;
106 my $nose = Irssi::settings_get_str('mood_nose');
107
108 if ($points > 20) { $mouth = 'D'; }
109 elsif ($points > 0) { $mouth = ')'; }
110 elsif ($points <-20) { $mouth = '<'; }
111 elsif ($points < 0) { $mouth = '('; }
112 if ($shouting) { $mouth = 'O' };
113 return $eye.$nose.$mouth;
114 }
115
116 sub mood_show {
117 my ($item, $get_size_only) = @_;
118 my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
119
120 if (ref $win && ($win->{type}) and $win->{type} eq "CHANNEL") {
121 my $target = lc $win->{name};
122 my $face = draw_smiley($channels{$target});
123 my $format = "{sb ".$face."}";
124 $item->{min_size} = $item->{max_size} = length($face);
125 $item->default_handler($get_size_only, $format, 0, 1);
126 } else {
127 $item->{min_size} = $item->{max_size} = 0;
128 }
129 }
130
131 sub mood_decay {
132 foreach (keys %channels) {
133 if ($channels{$_} < 0) {
134 $channels{$_}++;
135 mood_refresh() if (! draw_smiley($channels{$_}) eq draw_smiley($channels{$_}-1));
136 } elsif ($channels{$_} > 0) {
137 $channels{$_}--;
138 mood_refresh() if (! draw_smiley($channels{$_}) eq draw_smiley($channels{$_}+1));
139 }
140 }
141 }
142
143 sub close_eyes {
144 ($refresh) && Irssi::timeout_remove($refresh);
145 $eye = '|';
146 mood_refresh();
147 $refresh=Irssi::timeout_add(200, 'open_eyes' , undef);
148 }
149
150 sub open_eyes {
151 ($refresh) && Irssi::timeout_remove($refresh);
152 $eye = ':';
153 mood_refresh();
154 my $min_delay = Irssi::settings_get_int('mood_blink');
155 my $next_close = int( rand()*6000 + $min_delay );
156 $refresh=Irssi::timeout_add($next_close, 'close_eyes', undef);
157 }
158
159 sub open_mouth {
160 $shouting = 1;
161 mood_refresh();
162 Irssi::timeout_add(2000, 'close_mouth', undef);
163 }
164
165 sub close_mouth {
166 Irssi::timeout_remove('close_mouth');
167 $shouting = 0;
168 mood_refresh();
169 }
170
171 sub mood_refresh {
172 Irssi::statusbar_items_redraw('moodbar');
173 }
174
175 sub change_bored_mouth {
176 $bored_mouth = ('\\\\\\\\', '|', '/')[int( rand(3) )];
177 }
178
179 #Irssi::signal_add('window item hilight', 'event_window_hilight');
180 Irssi::signal_add('event privmsg', 'event_event_privmsg');
181 Irssi::signal_add('message own_public', 'event_message_own_public');
182 Irssi::signal_add('message kick','event_message_kick');
183 Irssi::signal_add('ban new','event_ban_new');
184 Irssi::signal_add('ban remove','event_ban_remove');
185 Irssi::signal_add('netsplit new','event_netsplit_new');
186
187 Irssi::settings_add_int('misc', 'mood_blink', 6000);
188 Irssi::settings_add_str('misc', 'mood_nose', '-');
189
190 Irssi::statusbar_item_register('moodbar', 0, 'mood_show');
191
192 Irssi::timeout_add(5000, 'mood_decay', undef);
193 Irssi::timeout_add(10000, 'change_bored_mouth', undef);
194
195 close_mouth;
196 change_bored_mouth();
197 open_eyes();