#!/usr/bin/perl
################################################################################
# #
# ############################################################################ #
# # Title : xchat random topic generator # #
# # Description : Randomly picks and sets a topic for a channel from a file. # #
# # Coded by : Justin "HEYO--!" Lee # #
# # Version : 0.3c # #
# # Date : 2008-12-06 # #
# # License : GNU General Public License v.2 # #
# # Copyright (C) 2008 Justin Lee <kool.name at gmail.com> # #
# ############################################################################ #
# #
# ############################################################################ #
# # This program is free software; you can redistribute it and/or # #
# # modify it under the terms of the GNU General Public License version 2 # #
# # as published by the Free Software Foundation. # #
# # # #
# # This program is distributed in the hope that it will be useful, # #
# # but WITHOUT ANY WARRANTY; without even the implied warranty of # #
# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # #
# # GNU General Public License for more details. # #
# # # #
# # You should have received a copy of the GNU General Public License # #
# # along with this program; if not, write to the Free Software # #
# # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # #
# # 02110-1301, USA. Or, see: <http://www.gnu.org/licenses/> # #
# ############################################################################ #
# #
################################################################################
use strict;
Xchat::register('XTP', '0.1c', 'Randomly picks and sets a topic for a channel from a file.');
Xchat::hook_command('tadd', 'topic_catch');
Xchat::hook_print('Channel Message', 'topic_watch');
## preferences ##
my $topic_dir = Xchat::get_info('xchatdir');
my $topic_file = 'rtopics.txt';
my $topic_set_time = '3600000'; # 60 minutes
my $topic_prefix = '#51: ';
my $channel = '#51';
my $topic_trigger = '!topic';
my $topics_to_read = 30;
my $topic_autoset = 0;
## stop editing ##
my @topic; # I hate global vars
my %prefix = (
'~' => 5,
'&' => 4,
'@' => 3,
'%' => 2,
'+' => 1,
'' => 0
);
chdir($topic_dir) or die;
if ($topic_autoset) {
Xchat::hook_timer(60000,"topic_set"); # autoset in one minute
} else {
timer_check(); # don't autoset, set in $time ms
}
Xchat::print('XTP: Loaded.');
sub topic_set {
timer_check() unless shift; # reset the timer
topic_build() unless scalar @topic; # build the queue if needed
Xchat::command("topic $channel $topic_prefix @{[ pop(@topic) ]}",$channel) or warn;
return Xchat::EAT_NONE;
}
sub topic_build {
open(TOPICS,"<$topic_file") or die;
my $line; $. = 0; # reset position to zero
while ($. < $topics_to_read and $line = <TOPICS>) {
chomp($line);
next if $line =~ /^(\s*)$/o; # skip blank lines
$line =~ s/^\s+//o; # clean up the remainder
$line =~ s/\s+$//o;
push(@topic,$line); # add it to the main queue
}
fisher_yates_shuffle(\@topic); # shuffle the queue
if ($. < $topics_to_read) { # less lines than the limit
close(TOPICS) or warn;
} else {
open(NT,">$topic_file.new") or die; # open a new file
print NT "$_\n" foreach grep { chomp; !/^(\s*)$/o } <TOPICS>, @topic; # @topic at the end
close(TOPICS) or warn; # close the files
close(NT) or warn;
rename($topic_file,"$topic_file.bak"); # rename to backup
rename("$topic_file.new",$topic_file); # rename to original
unlink("$topic_file.bak") or die; # remove the backup
}
}
sub topic_watch {
return unless uc(Xchat::get_info('channel')) eq uc($channel);
Xchat::set_context(Xchat::find_context($channel));
my $user = Xchat::user_info($_[0][0]);
return unless $prefix{$user->{'prefix'}} >= 2;
my @line = split(/\s+/,$_[0][1]);
return unless $line[0] =~ /^($topic_trigger)$/oi;
if ($#line == 0) {
topic_set(1);
} else {
shift(@line);
topic_add(@line);
}
return Xchat::EAT_NONE;
}
sub topic_catch {
shift(@{$_[0]}); # drop "/tadd" or "!topic"
topic_add(@{$_[0]});
}
sub topic_add {
open(TOPICS,">>$topic_file") or die; # open
print TOPICS "\n@_\n"; # add line
close(TOPICS) or warn; # close
}
sub timer_check { # reset the timer
if ($topic_set_time and $topic_set_time > 0) {
Xchat::hook_timer($topic_set_time,"topic_set");
}
}
sub fisher_yates_shuffle { # cookbook
my $array = shift;
my $i;
for ($i = @$array; --$i; ) {
my $j = int rand ($i+1);
next if $i == $j;
@$array[$i,$j] = @$array[$j,$i];
}
}