use Switch; use Gaim; use DBI; use strict; %::PLUGIN_INFO = ( perl_api_version => 2, name => "IMBBS", version => "0.1", summary => "IM BBS for Gaim", description => "", author => "Charlie Brej ", url => "http://brej.org/imbbs/", load => "plugin_load", unload => "plugin_unload" ); sub plugin_init { return %::PLUGIN_INFO; } my $plugin; my $database; my $usetimeout = 1; my %functions = ("dict" => ["dict", \&sub_dict, "dict [database] word"], "spell" => ["spell", \&sub_spell, "spell word" ], # "slashdot" => ["slashdot", \&sub_slashdot,"slashdot" ], "help" => ["help", \&sub_help, "help" ], "news" => ["news", \&sub_news, "news" ], "timeout" => ["timeout", \&sub_timeout, "" ], "soundex" => ["soundex", \&sub_soundex, "soundex" ], "leet" => ["leet", \&sub_leet, "leet" ], ); sub got_msg { my ($account, $who, $message, $flags) = @_; print "\n:".$message.":\n"; while($message =~ s/<.*?>//) {}; #HTML si t3h sux0r! my $key; my $found=0; foreach $key (keys %functions) { if ($message =~ /^$functions{$key}[0]/){ my $func = $functions{$key}[1]; $message = &$func($message, $who, $account); $found=1; last; } } if(!$found) {$message = sub_unknown($message);} send_msg($account, $who, $message); } sub send_msg { my ($account, $who, $message) = @_; my $dummy; my $conv = Gaim::Conversation::new($dummy, 1, $account, $who); if ($conv) { $conv = Gaim::Conversation::get_im_data($conv); my @lines = split ("\n",$message); $message=""; my $count=10; my $subcount=4; foreach (@lines){ $subcount--; $message .= "\n".$_; if(!$subcount){ if (!$count--) {last;} Gaim::Conversation::IM::send($conv,$message); $message=""; $subcount = 4; } } Gaim::Conversation::IM::send($conv,$message); } } sub sub_spell { use Lingua::Ispell; Lingua::Ispell::allow_compounds(1); my $message = shift; $message =~ s/^spell //; my $temp = $message; $message = "Spell Checker:\n"; for my $r ( Lingua::Ispell::spellcheck( $temp ) ) { if ( $r->{'type'} eq 'ok' ) { # as in the case of 'hello' $message .= "'$r->{'term'}' was found in the dictionary.\n"; } elsif ( $r->{'type'} eq 'root' ) { # as in the case of 'hacking' $message .= "'$r->{'term'}' can be formed from root '$r->{'root'}'\n"; } elsif ( $r->{'type'} eq 'miss' ) { # as in the case of 'perl' $message .= "'$r->{'term'}' was not found in the dictionary;\n"; $message .= "Near misses: @{$r->{'misses'}}\n"; } elsif ( $r->{'type'} eq 'guess' ) { # as in the case of 'salmoning' $message .= "'$r->{'term'}' was not found in the dictionary;\n"; $message .= "Root/affix Guesses: @{$r->{'guesses'}}\n"; } elsif ( $r->{'type'} eq 'compound' ) { # as in the case of 'fruithammer' $message .= "'$r->{'term'}' is a valid compound word.\n"; } elsif ( $r->{'type'} eq 'none' ) { # as in the case of 'shrdlu' $message .= "No match for term '$r->{'term'}'\n"; } # and numbers are skipped entirely, as in the case of 42. } $message =~ s/\n*$//; return $message; } sub sub_dict { my $message = shift; $message =~ s/^dict\ +//; my $database = 'gcide'; my @words = split(" ", $message); $message = ""; foreach (@words){ if ( $_ =~ /^\[.*\]$/) { $_ =~ s/^\[(.*)\]$/$1/; $database = $_; } else { $message .= "$_ "; } } use Net::Dict; $message =~ s/\ +$//; my $dict = Net::Dict->new('dict.org'); my $h = $dict->define($message); $message = "Dictionary lookup of $message:\n"; my $databases=""; foreach my $i (@{$h}) { my ($db, $def) = @{$i}; $def =~ s/\[.*\]//g; while($def =~ s/\n\ *\n/\n/) {}; $def = "".$def; $def =~ s/([.\n])/$1<\/b\>\ /; if ($database eq "all" or $db eq $database){ $message .= $def; } else{ if (!($db eq '')) {$databases .= "$db:".$dict->dbTitle($db)."\n";} } } $message .= "Other databases:\n$databases"; $message =~ s/[\n\ ]+$//; return $message; } sub sub_slashdot { my $message; use XML::RSS::Parser; use FileHandle; my $p = XML::RSS::Parser->new; my $fh = FileHandle->new('/tmp/slashdot'); my $feed = $p->parse_file($fh); # output some values my $feed_title = $feed->query('/channel/title'); #$message .= $feed_title->text_content; my $count = $feed->item_count; #$message .= " ($count)\n"; foreach my $i ( $feed->query('//item') ) { $message .= ''; $message .= $i->query('title')->text_content; $message .= "\n"; my $description = $i->query('description')->text_content; while($description =~ s/<.*?>//) {}; $message .= $description; $message .= "\n"; } while($message =~ s/\n\n/\n/) {}; return $message; } sub sub_soundex { my ($message, $who, $account) = @_; $message =~ s/^soundex\ +//; use Text::Soundex; $message = Text::Soundex::soundex ($message); return $message; } sub sub_leet { my ($message, $who, $account) = @_; $message =~ s/^leet\ +//; $_ = $message; tr /[:UPPER:]/[:LOWER:]/; s/are/R/g; s/you/U/g; s/elite/leet/g; s/the/da/g; s/ks/x/g; s/ck/x/g; s/hacker/haxor/g; s/own/pwn/g; tr /ABCDEFGHIJKLMNOPQRSTUVWXYZ/4BCD3FGH1JK1MN0PQR57UVWXY2/; tr /abcdefghijklmnopqrstuvwxyz/@bcd3fgh1jk1mn0pqr57uvwxy2/; $message = $_; return $message; } sub sub_string { my ($message, $who, $account) = @_; $message =~ s/^string\ +//; $message = $_; return $message; } sub sub_news { my ($message, $who, $account) = @_; $message =~ s/^news\ +//; my $messagein = $message; $message = ""; if ($messagein =~ /^subscribe\ /){ $messagein =~ s/^subscribe\ +//; $messagein =~ s/\*/\%/g; my $query = $database->prepare("SELECT `name` FROM `newsservices` WHERE name LIKE ?"); print (":$messagein:"); $query->execute($messagein); while (my @row = $query->fetchrow_array ) { $message .= "Added: ".$row[0]."\n"; my $query = $database->prepare("REPLACE INTO `newssubscriptions` (`name`, `account`, `newsservice`) VALUES (?,?,?)"); $query->execute($who, Gaim::Account::get_protocol_name($account), $row[0]); } } if ($messagein =~ /^unsubscribe\ /){ $messagein =~ s/^unsubscribe\ +//; $messagein =~ s/\*/\%/g; my $query = $database->prepare("SELECT `name` FROM `newsservices` WHERE name LIKE ?"); print (":$messagein:"); $query->execute($messagein); while (my @row = $query->fetchrow_array ) { $message .= "Deleted: ".$row[0]."\n"; my $query = $database->prepare("DELETE FROM `newssubscriptions` WHERE (`name`, `account`, `newsservice`) = (?,?,?)"); $query->execute($who, Gaim::Account::get_protocol_name($account), $row[0]); } } $message .= "Subscribed news services:\n"; restore_database(); my $query = $database->prepare("SELECT `newsservice` FROM `newssubscriptions` WHERE `name` = ? and `account` = ?"); $query->execute($who, Gaim::Account::get_protocol_name($account)); while (my @row = $query->fetchrow_array ) { $message .= $row[0]."\n"; } $message .= "Available news services:\n"; restore_database(); my $query = $database->prepare("SELECT `name` FROM `newsservices`"); $query->execute(); while (my @row = $query->fetchrow_array ) { $message .= $row[0]."\n"; } return $message; } sub sub_timeout { if ($usetimeout eq 1) { $usetimeout = 0; } else { $usetimeout = 1; timeout(); } return "Timeouts=$usetimeout"; } sub timeout { restore_database(); my $addressquery = $database->prepare("SELECT address FROM newsnew"); $addressquery->execute(); while (my @addressrow = $addressquery->fetchrow_array ) { my $address = $addressrow[0]; my $query = $database->prepare("SELECT DISTINCT name, account, newssubscriptions.newsservice, title, description FROM newssubscriptions JOIN newsnew on newsnew.newsservice = newssubscriptions.newsservice WHERE address = ?"); $query->execute($address); while (my @row = $query->fetchrow_array ) { my $name = $row[0]; my $account_name = $row[1]; my $newsservice = $row[2]; my $title = $row[3]; my $description = $row[4]; while($description =~ s/<.*?>//) {}; my @accounts = Gaim::Accounts::get_all_active(); my $account; foreach (@accounts){ if (Gaim::Account::get_protocol_name($_) eq $account_name){ $account = $_; last; } } my $message; if ($account_name eq 'AIM/ICQ') {$message = "News: $newsservice\n$title\n$description";} if ($account_name eq 'Jabber') {$message = "News: $newsservice\n$title\n$description";} elsif ($account_name eq 'MSN') {$message = "News: $newsservice\n$title\n$address\n$description";} elsif ($account_name eq 'Yahoo'){$message = "News: $newsservice\n$title\n$address\n$description";} else {$message = "News: $newsservice\n$title\n$description";} send_msg($account, $name, $message); } my $query = $database->prepare("DELETE FROM `newsnew` WHERE `address` = ?"); $query->execute($address); } print "timeout\n"; if ($usetimeout eq 1) {Gaim::timeout_add($plugin, 10, \&timeout);} return ""; } sub sub_unknown { my $message = shift; $message = "Unknown function:".$message."\n"; $message .= "For Help type 'help'"; return $message; } sub sub_help { my $message = shift; $message = "Available commands:\n"; foreach my $key (keys %functions) { $message .= $functions{$key}[2]."\n"; } return $message; } sub plugin_load { $plugin = shift; Gaim::signal_connect(Gaim::Conversation::gaim_conversations_get_handle, "received-im-msg", $plugin, \&got_msg, 0); restore_database(); #Gaim::timeout_add($plugin, 10, \&timeout); } sub plugin_unload { my $plugin = shift; } sub restore_database{ if (!$database or $database->ping){ $database = DBI->connect("dbi:mysql:database=imbbs;host=localhost;port=3306", "root", "") or die "Couldn't connect to database: " . DBI->errstr; } }