1 # -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*-
2 ################################
4 ################################
6 package BotModules::Karma;
11 # RegisterConfig - Called when initialised, should call registerVariables
14 $self->SUPER::RegisterConfig(@_);
15 $self->registerVariables(
16 # [ name, save?, settable? ]
17 ['scores', 1, 1, {}], # nick => total karma.
18 ['privateScores', 1, 1, {}], # nick => nick karma nick karma...
19 ['secondsDelayRequired', 1, 1, 20],
20 ['_lastspoken', 0, 0, {}], # nick => nick => time
28 '' => 'A karma tracker. If you have authenticated (using the \'auth\' command) then it will also keep track of your own setting of people\'s karma, as well as the total of everyone\'s settings. Use the \'rank\' command to find someone\'s karma rank.',
29 '++' => 'Increase someone\'s karma. Syntax: victim++',
30 '--' => 'Decrease someone\'s karma. Syntax: victim--',
31 'rank' => 'Find someone\'s karma level. Omit the victim\'s name to get a complete listing of everyone\'s karma (long). Syntax: \'rank victim\' or just \'rank\'',
37 my ($event, $message) = @_;
38 if ($message =~ /^(\S+)\+\+$/os) {
39 $self->ChangeKarma($event, $1, 1);
40 } elsif ($message =~ /^(\S+)\-\-$/os) {
41 $self->ChangeKarma($event, $1, -1);
42 } elsif ($message =~ /^\s*(?:karma\s+)?ranks?[?\s]*$/os) {
43 $self->ReportKarmaRanks($event, $1);
44 } elsif ($message =~ /^\s*karma(?:\s+rank)?\s+(\S+)[?\s]*$/os or
45 $message =~ /^\s*(?:karma\s+)?rank\s+(\S+)[?\s]*$/os) {
46 $self->ReportKarma($event, $1);
48 return $self->SUPER::Told(@_);
50 return 0; # dealt with it...
55 my ($event, $message) = @_;
56 if ($message =~ /^(\S*[^-+\s])\+\+$/os) {
57 $self->ChangeKarma($event, $1, 1);
58 } elsif ($message =~ /^(\S*[^-+\s])\-\-$/os) {
59 $self->ChangeKarma($event, $1, -1);
61 return $self->SUPER::Told(@_);
63 return 0; # we've dealt with it, no need to do anything else.
68 my ($event, $who, $delta) = @_;
69 $self->debug("$who += $delta requested");
70 if ((defined($self->{'_lastSpoken'}->{$event->{'user'}})) and
71 (defined($self->{'_lastSpoken'}->{$event->{'user'}}->{lc $who})) and
72 (($event->{'time'} - $self->{'_lastSpoken'}->{$event->{'user'}}->{lc $who}) <= $self->{'secondsDelayRequired'})) {
73 $self->{'_lastSpoken'}->{$event->{'user'}}->{lc $who} = $self->{'_lastSpoken'}->{$event->{'user'}}->{lc $who}+5;
74 my $delay = $self->{'secondsDelayRequired'} - ($event->{'time'} - $self->{'_lastSpoken'}->{$event->{'user'}}->{lc $who});
75 $self->directSay($event, "You will have to wait another $delay seconds before being able to change ${who}'s karma.");
77 if (not defined($self->{'_lastSpoken'}->{$event->{'user'}})) {
78 $self->{'_lastSpoken'}->{$event->{'user'}} = {};
80 $self->{'_lastSpoken'}->{$event->{'user'}}->{lc $who} = $event->{'time'};
81 if (lc $event->{'from'} eq lc $who) {
86 if ($event->{'channel'} ne '') {
87 $self->{'scores'}->{lc $who} += $delta;
88 if ($self->{'scores'}->{lc $who} == 0) {
89 delete($self->{'scores'}->{lc $who});
92 my $nick = lc $event->{'userName'};
94 if (not defined($self->{"privateScores"}->{$nick})) {
95 $self->{"privateScores"}->{$nick} = (lc($who) . ' ' . $delta);
97 my %privateScores = split(' ', $self->{"privateScores"}->{$nick});
98 $privateScores{lc $who} += $delta;
99 if ($privateScores{lc $who} == 0) {
100 delete($privateScores{lc $who});
102 my @privateScores = %privateScores;
104 $self->{'privateScores'}->{$nick} = "@privateScores";
106 } elsif ($event->{'channel'} eq '') {
107 $self->say($event, 'For private stats, you need to authenticate. Use the \'newuser\' and \'auth\' commands.');
115 my ($event, $who) = @_;
116 if (not defined($self->{'scores'}->{lc $who})) {
117 $self->say($event, "$who has no karma.");
119 my $karma = $self->{'scores'}->{lc $who};
120 my @order = sort { $self->{'scores'}->{$b} <=> $self->{'scores'}->{$a} } keys(%{$self->{'scores'}});
122 if (scalar(@order)) {
123 user: foreach my $user (@order) {
125 if (lc $user eq lc $who) {
130 $self->say($event, "$who has $karma points of karma (rank $rank).");
132 if ($event->{'channel'} eq '') {
133 $nick = lc $event->{'userName'};
135 if (not defined($self->{"privateScores"}->{$nick})) {
136 $self->say($event, "You have not given anyone any karma.");
138 my %privateScores = split(' ', $self->{"privateScores"}->{$nick});
139 my $karma = $privateScores{lc $who};
141 if (not defined($karma)) {
142 $self->say($event, "You have not given $who any karma.");
144 $self->say($event, "You have given $who $karma points of karma.");
148 $self->say($event, 'For private stats, you need to authenticate. Use the \'newuser\' and \'auth\' commands.');
153 sub ReportKarmaRanks {
156 my @order = sort { $self->{'scores'}->{$b} <=> $self->{'scores'}->{$a} } keys(%{$self->{'scores'}});
157 if (scalar(@order)) {
158 if ($event->{'channel'} ne '') {
160 my $score = $self->{'scores'}->{$top};
161 $self->say($event, "The person with the most karma is $top with $score points.");
163 $self->directSay($event, "Global rankings:");
164 $self->ReportKarmaRanksList($event, \@order, $self->{'scores'});
166 if ($event->{'channel'} eq '') {
167 $nick = lc $event->{'userName'};
169 if (defined($self->{"privateScores"}->{$nick})) {
170 my %privateScores = split(' ', $self->{"privateScores"}->{$nick});
171 @order = sort { $privateScores{$b} <=> $privateScores{$a} } keys(%privateScores);
172 if (scalar(@order)) {
173 $self->directSay($event, "Personal rankings:");
174 $self->ReportKarmaRanksList($event, \@order, \%privateScores);
176 $self->say($event, "I seem to have lost track of the people to which you gave karma points.");
179 $self->say($event, "You have not given anyone karma.");
182 $self->say($event, 'For private stats, you need to authenticate. Use the \'newuser\' and \'auth\' commands.');
187 sub ReportKarmaRanksList {
189 my($event, $order, $scores) = @_;
191 foreach my $entry (@$order) {
192 my $score = $scores->{$entry};
193 $self->directSay($event, "$rank. $entry ($score)");