1#!/usr/local/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
16use strict;
17
18use 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
31use Irssi;
32use Irssi::TextUI;
33use vars qw(%channels $eye $refresh $shouting $bored_mouth);
34
35sub 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
54sub 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
60sub event_message_own_public {
61    my ($server, $msg, $target) = @_;
62    change_mood($target, find_smiley($msg));
63}
64
65sub event_message_kick {
66    my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
67    change_mood($channel, -20);
68}
69
70sub event_ban_new {
71    my ($channel, $ban) = @_;
72    my $name = $channel->{name};
73    change_mood($name, -20);
74}
75
76sub event_ban_remove {
77    my ($channel, $ban) = @_;
78    my $name = $channel->{name};
79    change_mood($name, 20);
80}
81
82sub event_netsplit_new {
83    my ($netsplit) = @_;
84    #FIXME Not Idea :)
85    #Irssi::print $netsplit->{nick};
86}
87
88sub event_window_hilight {
89    my ($window) = @_;
90    open_mouth();
91}
92
93sub 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
102sub 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
116sub 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
131sub 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
143sub close_eyes {
144    ($refresh) && Irssi::timeout_remove($refresh);
145    $eye = '|';
146    mood_refresh();
147    $refresh=Irssi::timeout_add(200, 'open_eyes' , undef);
148}
149
150sub 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
159sub open_mouth {
160    $shouting = 1;
161    mood_refresh();
162    Irssi::timeout_add(2000, 'close_mouth', undef);
163}
164
165sub close_mouth {
166    Irssi::timeout_remove('close_mouth');
167    $shouting = 0;
168    mood_refresh();
169}
170
171sub mood_refresh {
172    Irssi::statusbar_items_redraw('moodbar');
173}
174
175sub change_bored_mouth {
176    $bored_mouth = ('\\\\\\\\', '|', '/')[int( rand(3) )];
177}
178
179#Irssi::signal_add('window item hilight', 'event_window_hilight');
180Irssi::signal_add('event privmsg', 'event_event_privmsg');
181Irssi::signal_add('message own_public', 'event_message_own_public');
182Irssi::signal_add('message kick','event_message_kick');
183Irssi::signal_add('ban new','event_ban_new');
184Irssi::signal_add('ban remove','event_ban_remove');
185Irssi::signal_add('netsplit new','event_netsplit_new');
186
187Irssi::settings_add_int('misc', 'mood_blink', 6000);
188Irssi::settings_add_str('misc', 'mood_nose', '-');
189
190Irssi::statusbar_item_register('moodbar', 0, 'mood_show');
191
192Irssi::timeout_add(5000, 'mood_decay', undef);
193Irssi::timeout_add(10000, 'change_bored_mouth', undef);
194
195close_mouth;
196change_bored_mouth();
197open_eyes();
198