1 package Onis::Plugins::Core;
6 use Carp (qw(confess));
15 Plugin for the main table and the hourly-statistics. This is the most
16 complicated plugin so far.
20 use Onis::Config (qw(get_config));
21 use Onis::Html (qw(html_escape get_filehandle));
22 use Onis::Language (qw(translate));
23 use Onis::Users (qw(get_realname get_link get_image chatter_to_name));
24 use Onis::Data::Core (qw(get_all_nicks nick_to_ident ident_to_nick get_main_nick register_plugin));
25 use Onis::Data::Persistent ();
27 @Onis::Plugins::Core::EXPORT_OK = (qw(get_core_nick_counters get_sorted_nicklist nick_is_in_main_table));
28 @Onis::Plugins::Core::ISA = ('Exporter');
30 our $NickLinesCounter = Onis::Data::Persistent->new ('NickLinesCounter', 'nick',
32 lines00 lines01 lines02 lines03 lines04 lines05 lines06 lines07 lines08 lines09 lines10 lines11
33 lines12 lines13 lines14 lines15 lines16 lines17 lines18 lines19 lines20 lines21 lines22 lines23
36 our $NickWordsCounter = Onis::Data::Persistent->new ('NickWordsCounter', 'nick',
38 words00 words01 words02 words03 words04 words05 words06 words07 words08 words09 words10 words11
39 words12 words13 words14 words15 words16 words17 words18 words19 words20 words21 words22 words23
42 our $NickCharsCounter = Onis::Data::Persistent->new ('NickCharsCounter', 'nick',
44 chars00 chars01 chars02 chars03 chars04 chars05 chars06 chars07 chars08 chars09 chars10 chars11
45 chars12 chars13 chars14 chars15 chars16 chars17 chars18 chars19 chars20 chars21 chars22 chars23
49 our $QuoteCache = Onis::Data::Persistent->new ('QuoteCache', 'key', qw(epoch text));
50 our $QuotePtr = Onis::Data::Persistent->new ('QuotePtr', 'nick', qw(pointer));
52 our $QuoteData = {}; # Is generated before output. Nicks are merged according to Data::Core.
53 our $NickData = {}; # Same as above, but for nicks rather than quotes.
54 our $SortedNicklist = [];
56 our $NicksInMainTable = {};
58 our @H_IMAGES = qw#dark-theme/h-red.png dark-theme/h-blue.png dark-theme/h-yellow.png dark-theme/h-green.png#;
59 our $QuoteCacheSize = 10;
63 our $SORT_BY = 'LINES';
64 our $DISPLAY_LINES = 'BOTH';
65 our $DISPLAY_WORDS = 'NONE';
66 our $DISPLAY_CHARS = 'NONE';
67 our $DISPLAY_TIMES = 0;
68 our $DISPLAY_IMAGES = 0;
69 our $DEFAULT_IMAGE = '';
70 our $BAR_HEIGHT = 130;
75 =head1 CONFIGURATION OPTIONS
79 =item B<quote_cache_size>: I<10>
81 Sets how many quotes are cached and, at the end, one is chosen at random.
85 if (get_config ('quote_cache_size'))
87 my $tmp = get_config ('quote_cache_size');
89 $QuoteCacheSize = $tmp if ($tmp);
92 =item B<quote_min>: I<30>
94 Minimum number of characters in a line to be included in the quote-cache.
98 if (get_config ('quote_min'))
100 my $tmp = get_config ('quote_min');
102 $QuoteMin = $tmp if ($tmp);
104 =item B<quote_max>: I<80>
106 Maximum number of characters in a line to be included in the quote-cache.
110 if (get_config ('quote_max'))
112 my $tmp = get_config ('quote_max');
114 $QuoteMax = $tmp if ($tmp);
117 =item B<min_word_length>: I<5>
119 Sets how many word-characters in a row are considered to be a word. Or, in more
120 normal terms: Sets the minimum length for words..
124 if (get_config ('min_word_length'))
126 my $tmp = get_config ('min_word_length');
128 $WORD_LENGTH = $tmp if ($tmp);
131 =item B<display_lines>: I<BOTH>
133 Choses wether to display B<lines> as I<BAR>, I<NUMBER>, I<BOTH> or not at all
138 if (get_config ('display_lines'))
140 my $tmp = get_config ('display_lines');
143 if (($tmp eq 'NONE') or ($tmp eq 'BAR') or ($tmp eq 'NUMBER') or ($tmp eq 'BOTH'))
145 $DISPLAY_LINES = $tmp;
149 $tmp = get_config ('display_lines');
150 print STDERR $/, __FILE__, ": ``display_lines'' has been set to the invalid value ``$tmp''. ",
151 $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``both''.";
155 =item B<display_words>: I<NONE>
161 if (get_config ('display_words'))
163 my $tmp = get_config ('display_words');
166 if (($tmp eq 'NONE') or ($tmp eq 'BAR') or ($tmp eq 'NUMBER') or ($tmp eq 'BOTH'))
168 $DISPLAY_WORDS = $tmp;
172 $tmp = get_config ('display_words');
173 print STDERR $/, __FILE__, ": ``display_words'' has been set to the invalid value ``$tmp''. ",
174 $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``none''.";
178 =item B<display_chars>: I<NONE>
184 if (get_config ('display_chars'))
186 my $tmp = get_config ('display_chars');
189 if (($tmp eq 'NONE') or ($tmp eq 'BAR') or ($tmp eq 'NUMBER') or ($tmp eq 'BOTH'))
191 $DISPLAY_CHARS = $tmp;
195 $tmp = get_config ('display_chars');
196 print STDERR $/, __FILE__, ": ``display_chars'' has been set to the invalid value ``$tmp''. ",
197 $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``none''.";
201 =item B<display_times>: I<false>
203 Wether or not to display a fixed width bar that shows when a user is most
208 if (get_config ('display_times'))
210 my $tmp = get_config ('display_times');
212 if ($tmp =~ m/true|on|yes/i)
216 elsif ($tmp =~ m/false|off|no/i)
222 print STDERR $/, __FILE__, ": ``display_times'' has been set to the invalid value ``$tmp''. ",
223 $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''.";
227 =item B<display_images>: I<false>
229 Wether or not to display images in the main ranking.
233 if (get_config ('display_images'))
235 my $tmp = get_config ('display_images');
237 if ($tmp =~ m/true|on|yes/i)
241 elsif ($tmp =~ m/false|off|no/i)
247 print STDERR $/, __FILE__, ": ``display_times'' has been set to the invalid value ``$tmp''. ",
248 $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''.";
252 =item B<default_image>: I<http://www.url.org/image.png>
254 Sets the URL to the default image. This is included as-is in the HTML. You have
255 to take care of (absolute) paths yourself.
259 if (get_config ('default_image'))
261 $DEFAULT_IMAGE = get_config ('default_image');
264 =item B<sort_by>: I<LINES>
266 Sets by which field the output has to be sorted. This is completely independent
267 from B<display_lines>, B<display_words> and B<display_chars>. Valid options are
268 I<LINES>, I<WORDS> and I<CHARS>.
272 if (get_config ('sort_by'))
274 my $tmp = get_config ('sort_by');
277 if (($tmp eq 'LINES') or ($tmp eq 'WORDS') or ($tmp eq 'CHARS'))
283 $tmp = get_config ('sort_by');
284 print STDERR $/, __FILE__, ": ``sort_by'' has been set to the invalid value ``$tmp''. ",
285 $/, __FILE__, ": Valid values are ``lines'' and ``words''. Using default value ``lines''.";
289 =item B<horizontal_images>: I<image1>, I<image2>, I<image3>, I<image4>
291 Sets the B<four> images used for horizontal bars/graphs. As above: You have to
292 take care of correctness of paths yourself.
296 if (get_config ('horizontal_images'))
298 my @tmp = get_config ('horizontal_images');
301 if (scalar (@tmp) != 4)
303 print STDERR $/, __FILE__, ": The number of horizontal images is not four. The output might look weird.", $/;
306 for ($i = 0; $i < 4; $i++)
308 if (!defined ($tmp[$i]))
313 $H_IMAGES[$i] = $tmp[$i];
317 =item B<bar_height>: I<130>
319 Sets the height (in pixels) of the highest vertical graph.
323 if (get_config ('bar_height'))
325 my $tmp = get_config ('bar_height');
327 $BAR_HEIGHT = $tmp if ($tmp >= 10);
330 =item B<bar_width>: I<100>
332 Sets the width (in pixels) of the widest horizontal graph.
336 if (get_config ('bar_width'))
338 my $tmp = get_config ('bar_width');
340 $BAR_WIDTH = $tmp if ($tmp >= 10);
343 =item B<longlines>: I<50>
345 Sets the number of rows of the main ranking table.
349 if (get_config ('longlines'))
351 my $tmp = get_config ('longlines');
353 $LongLines = $tmp if ($tmp);
356 =item B<shortlines>: I<10>
358 Sets the number of rows of the "they didn't write so much" table. There are six
359 persons per line; you set the number of lines.
365 if (get_config ('shortlines'))
367 my $tmp = get_config ('shortlines');
369 if ($tmp or ($tmp == 0))
375 register_plugin ('TEXT', \&add);
376 register_plugin ('ACTION', \&add);
377 register_plugin ('OUTPUT', \&output);
379 my $VERSION = '$Id$';
380 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
388 my $nick = $data->{'nick'};
389 my $ident = $data->{'ident'};
390 my $hour = int ($data->{'hour'});
391 my $host = $data->{'host'};
392 my $text = $data->{'text'};
393 my $type = $data->{'type'};
394 my $time = $data->{'epoch'};
396 my $words = scalar (@{$data->{'words'}});
397 my $chars = length ($text);
399 if ($type eq 'ACTION')
401 $chars -= (length ($nick) + 3);
404 my @counter = $NickLinesCounter->get ($nick);
407 @counter = qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0);
410 $NickLinesCounter->put ($nick, @counter);
412 @counter = $NickWordsCounter->get ($nick);
415 @counter = qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0);
417 $counter[$hour] += $words;
418 $NickWordsCounter->put ($nick, @counter);
420 @counter = $NickCharsCounter->get ($nick);
423 @counter = qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0);
425 $counter[$hour] += $chars;
426 $NickCharsCounter->put ($nick, @counter);
428 if ((length ($text) >= $QuoteMin)
429 and (length ($text) <= $QuoteMax))
431 my ($pointer) = $QuotePtr->get ($nick);
434 my $key = sprintf ("%s:%02i", $nick, $pointer);
436 $QuoteCache->put ($key, $time, $text);
438 $pointer = ($pointer + 1) % $QuoteCacheSize;
439 $QuotePtr->put ($nick, $pointer);
446 for (get_all_nicks ())
449 my $main = get_main_nick ($nick);
451 if (!defined ($NickData->{$main}))
455 lines => [qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)],
456 words => [qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)],
457 chars => [qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)],
464 my @counter = $NickLinesCounter->get ($nick);
468 for (my $i = 0; $i < 24; $i++)
470 $NickData->{$main}{'lines'}[$i] += $counter[$i];
471 $sum += $counter[$i];
473 $NickData->{$main}{'lines_total'} += $sum;
476 @counter = $NickWordsCounter->get ($nick);
480 for (my $i = 0; $i < 24; $i++)
482 $NickData->{$main}{'words'}[$i] += $counter[$i];
483 $sum += $counter[$i];
485 $NickData->{$main}{'words_total'} += $sum;
488 @counter = $NickCharsCounter->get ($nick);
492 for (my $i = 0; $i < 24; $i++)
494 $NickData->{$main}{'chars'}[$i] += $counter[$i];
495 $sum += $counter[$i];
497 $NickData->{$main}{'chars_total'} += $sum;
500 if (!defined ($QuoteData->{$main}))
502 $QuoteData->{$main} = [];
506 for ($QuoteCache->keys ())
509 my ($nick, $num) = split (m/:/, $key);
510 my $main = get_main_nick ($nick);
512 my ($epoch, $text) = $QuoteCache->get ($key);
513 die unless (defined ($text));
515 if (!defined ($QuoteData->{$main}))
519 elsif (scalar (@{$QuoteData->{$main}}) < $QuoteCacheSize)
521 push (@{$QuoteData->{$main}}, [$epoch, $text]);
528 for (my $i = 0; $i < $QuoteCacheSize; $i++)
530 if ($QuoteData->{$main}[$i][0] < $min)
533 $min = $QuoteData->{$main}[$i][0];
539 $QuoteData->{$main}[$insert] = [$epoch, $text];
554 my $max = 0; # the most lines that were written in one hour..
555 my $total = 0; # the total amount of lines we wrote..
556 my $factor = 0; # used to find a bar's height
558 my @data = qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0);
560 my @img_urls = get_config ('vertical_images');
563 @img_urls = qw#images/ver0n.png images/ver1n.png images/ver2n.png images/ver3n.png#;
566 my $fh = get_filehandle () or die;
568 # this for loop looks for the most amount of lines in one hour and sets
570 for (keys %$NickData)
574 for (my $i = 0; $i < 24; $i++)
576 $data[$i] += $NickData->{$nick}{'chars'}[$i];
580 for (my $i = 0; $i < 24; $i++)
582 $max = $data[$i] if ($max < $data[$i]);
592 $factor = (($BAR_HEIGHT - 1) / $max);
594 my $header = translate ('When do we actually talk here?');
595 print $fh "<h2>$header</h2>\n",
596 qq#<table class="hours">\n#,
597 qq# <tr class="bars">\n#;
599 # this for circles through the four colors. Each color represents six hours.
600 # (4 * 6 hours = 24 hours)
601 for (my $i = 0; $i <= 3; $i++)
603 for (my $j = 0; $j < 6; $j++)
605 my $hour = (($i * 6) + $j);
606 if (!defined ($data[$hour]))
611 my $height = sprintf ("%.2f", 95 * $data[$hour] / $max);
612 my $img = $img_urls[$i];
614 print $fh qq# <td class="bar vertical"><img src="$img" class="first last" style="height: $height\%;" alt="" /></td>\n#;
617 print $fh qq# </tr>\n <tr class="counter">\n#;
618 for (my $i = 0; $i < 24; $i++)
620 my $percent = sprintf ("%.1f", 100 * $data[$i] / $total);
621 print $fh qq# <td class="counter">$percent\%</td>\n#;
624 print $fh " </tr>\n",
625 qq# <tr class="numeration">\n#;
626 print $fh map { qq# <td class="numeration">$_</td>\n# } (0 .. 23);
627 print $fh " </tr>\n",
635 my @nicks = keys (%$NickData);
637 return unless (@nicks);
645 my $fh = get_filehandle () or die;
647 my $sort_field = lc ($SORT_BY);
652 ($tmp) = sort { $NickData->{$b}{'lines_total'} <=> $NickData->{$a}{'lines_total'} } (@nicks);
653 $max_lines = $NickData->{$tmp}{'lines_total'} || 0;
655 ($tmp) = sort { $NickData->{$b}{'words_total'} <=> $NickData->{$a}{'words_total'} } (@nicks);
656 $max_words = $NickData->{$tmp}{'words_total'} || 0;
658 ($tmp) = sort { $NickData->{$b}{'chars_total'} <=> $NickData->{$a}{'chars_total'} } (@nicks);
659 $max_chars = $NickData->{$tmp}{'chars_total'} || 0;
661 $trans = translate ('Most active nicks');
663 print $fh "<h2>$trans</h2>\n";
664 if ($SORT_BY eq 'LINES')
666 $trans = translate ('Nicks sorted by numbers of lines written');
668 elsif ($SORT_BY eq 'WORDS')
670 $trans = translate ('Nicks sorted by numbers of words written');
672 else # ($SORT_BY eq 'CHARS')
674 $trans = translate ('Nicks sorted by numbers of characters written');
676 print $fh "<p>($trans)</p>\n";
680 <table class="big_ranking">
682 <td class="invis"> </td>
686 $trans = translate ('Image');
687 print $fh " <th>$trans</th>\n";
691 $trans = translate ('Nick');
692 print $fh " <th>$trans</th>\n";
694 if ($DISPLAY_LINES ne 'NONE')
696 my $span = $DISPLAY_LINES eq 'BOTH' ? ' colspan="2"' : '';
697 $trans = translate ('Number of Lines');
698 print $fh " <th$span>$trans</th>\n";
700 if ($DISPLAY_WORDS ne 'NONE')
702 my $span = $DISPLAY_WORDS eq 'BOTH' ? ' colspan="2"' : '';
703 $trans = translate ('Number of Words');
704 print $fh " <th$span>$trans</th>\n";
706 if ($DISPLAY_CHARS ne 'NONE')
708 my $span = $DISPLAY_CHARS eq 'BOTH' ? ' colspan="2"' : '';
709 $trans = translate ('Number of Characters');
710 print $fh " <th$span>$trans</th>\n";
714 $trans = translate ('When?');
715 print $fh " <th>$trans</th>\n";
718 $trans = translate ('Random Quote');
719 print $fh " <th>$trans</th>\n",
722 @$SortedNicklist = sort
724 $NickData->{$b}{"${sort_field}_total"} <=> $NickData->{$a}{"${sort_field}_total"}
729 for (@$SortedNicklist)
732 my $ident = nick_to_ident ($nick);
733 my $name = chatter_to_name ("$nick!$ident");
734 my $print = $name || $nick;
738 # As long as we didn't hit the
739 # $LongLines-limit we continue
741 if ($linescount <= $LongLines)
743 $NicksInMainTable->{$nick} = $linescount;
745 my $quote = translate ('-- no quote available --');
747 if (@{$QuoteData->{$nick}})
749 my $num = scalar (@{$QuoteData->{$nick}});
750 my $rand = int (rand ($num));
752 $quote = html_escape ($QuoteData->{$nick}[$rand][1]);
760 $link = get_link ($name);
761 $image = get_image ($name);
762 $realname = get_realname ($name);
766 qq# <td class="numeration"># . $linescount . "</td>\n";
770 if ($DEFAULT_IMAGE and !$image)
772 $image = $DEFAULT_IMAGE;
775 print $fh qq# <td class="image">#;
780 print $fh qq#<a href="$link">#;
782 print $fh qq#<img src="$image" alt="$name" />#;
795 my $title = $realname;
798 $title = "User: $name; " if ($name);
799 $title .= "Ident: $ident";
801 print $fh qq# <td class="nick" title="$title">#;
805 print $fh qq#<a href="$link">$print</a></td>\n#
809 print $fh qq#$print</td>\n#;
812 if ($DISPLAY_LINES ne 'NONE')
814 if (($DISPLAY_LINES eq 'BOTH') or ($DISPLAY_LINES eq 'NUMBER'))
816 my $num = $NickData->{$nick}{'lines_total'};
817 print $fh qq( <td class="counter">$num</td>\n);
819 if (($DISPLAY_LINES eq 'BOTH') or ($DISPLAY_LINES eq 'BAR'))
821 my $code = bar ($max_lines, $NickData->{$nick}{'lines'});
822 print $fh qq( <td class="bar horizontal">$code</td>\n);
826 if ($DISPLAY_WORDS ne 'NONE')
828 if (($DISPLAY_WORDS eq 'BOTH') or ($DISPLAY_WORDS eq 'NUMBER'))
830 my $num = $NickData->{$nick}{'words_total'};
831 print $fh qq( <td class="counter">$num</td>\n);
833 if (($DISPLAY_WORDS eq 'BOTH') or ($DISPLAY_WORDS eq 'BAR'))
835 my $code = bar ($max_words, $NickData->{$nick}{'words'});
836 print $fh qq( <td class="bar horizontal">$code</td>\n);
840 if ($DISPLAY_CHARS ne 'NONE')
842 if (($DISPLAY_CHARS eq 'BOTH') or ($DISPLAY_CHARS eq 'NUMBER'))
844 my $num = $NickData->{$nick}{'chars_total'};
845 print $fh qq( <td class="counter">$num</td>\n);
847 if (($DISPLAY_CHARS eq 'BOTH') or ($DISPLAY_CHARS eq 'BAR'))
849 my $code = bar ($max_chars, $NickData->{$nick}{'chars'});
850 print $fh qq( <td class="bar horizontal">$code</td>\n);
856 my $code = bar ($NickData->{$nick}{'chars_total'}, $NickData->{$nick}{'chars'});
857 print $fh qq# <td class="bar">$code</td>\n#;
860 print $fh qq# <td class="quote">$quote</td>\n#,
863 if ($linescount == $LongLines)
865 print $fh "</table>\n\n";
869 # Ok, we have too many people to
870 # list them all so we start a
871 # smaller table and just list the
872 # names.. (Six names per line..)
873 elsif ($linescount <= ($LongLines + 6 * $ShortLines))
875 my $row_in_this_table = int (($linescount - $LongLines - 1) / 6);
876 my $col_in_this_table = ($linescount - $LongLines - 1) % 6;
879 if ($SORT_BY eq 'LINES')
881 $total = $NickData->{$nick}{'lines_total'};
883 elsif ($SORT_BY eq 'WORDS')
885 $total = $NickData->{$nick}{'words_total'};
887 else # ($SORT_BY eq 'CHARS')
889 $total = $NickData->{$nick}{'chars_total'};
892 my $title = $name ? get_realname ($name) : '';
895 $title = "User: $name; " if ($name);
896 $title .= "Ident: $ident";
899 if ($row_in_this_table == 0 and $col_in_this_table == 0)
901 $trans = translate ("They didn't write so much");
902 print $fh "<h2>$trans</h2>\n",
903 qq#<table class="small_ranking">\n#,
907 if ($col_in_this_table == 0 and $row_in_this_table != 0)
909 print $fh " </tr>\n",
913 print $fh qq# <td title="$title">$print ($total)</td>\n#;
915 if ($row_in_this_table == $ShortLines and $col_in_this_table == 5)
917 print $fh " </tr>\n",
922 # There is no else. There are
923 # just too many people around.
924 # I might add a "There are xyz
925 # unmentioned nicks"-line..
928 if (($linescount > $LongLines)
929 and ($linescount <= ($LongLines + 6 * $ShortLines)))
931 my $col = ($linescount - $LongLines - 1) % 6;
935 print $fh qq# <td> </td>\n#;
939 print $fh " </tr>\n";
942 if ($linescount != $LongLines)
944 print $fh "</table>\n\n";
948 # this is called by "&ranking ();" and prints the horizontal usage-bar in the
949 # detailed nick-table
955 confess () unless (ref ($source) eq 'ARRAY');
957 # BAR_WIDTH is a least 10
963 for ($i = 0; $i < 4; $i++)
966 my $img = $H_IMAGES[$i];
969 for ($j = 0; $j < 6; $j++)
971 my $hour = ($i * 6) + $j;
972 $sum += $source->[$hour];
975 $width = sprintf ("%.2f", 95 * $sum / $max_num);
977 $retval .= qq#<img src="$img" style="width: $width%;"#;
978 if ($i == 0) { $retval .= qq# class="first"#; }
979 elsif ($i == 3) { $retval .= qq# class="last"#; }
980 $retval .= qq( alt="$sum" />);
986 =head1 EXPORTED FUNCTIONS
990 =item B<get_core_nick_counters> (I<$nick>)
992 Returns a hash-ref that containes all the nick-counters available. It looks
996 lines => [qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)],
997 words => [qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)],
998 chars => [qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)],
1006 sub get_core_nick_counters
1010 if (!defined ($NickData->{$nick}))
1015 return ($NickData->{$nick});
1018 =item B<get_sorted_nicklist> ()
1020 Returns an array-ref that containes all nicks, sorted by the field given in the
1025 sub get_sorted_nicklist
1027 return ($SortedNicklist);
1030 =item B<nick_is_in_main_table> (I<$nick>)
1032 Returns the position of the nick in the main table or zero if it is not in the
1037 sub nick_is_in_main_table
1041 return (defined ($NicksInMainTable->{$nick}) ? $NicksInMainTable->{$nick} : 0);
1048 Florian octo Forster E<lt>octo at verplant.orgE<gt>