Commit Diff


commit - b15a3128cdaa0f3f1a2013f45cb8dd71560b7cd4
commit + c62b325b973092b8ce0cf3e11d5e273c570c3379
blob - /dev/null
blob + 5de58945dcbd237991749bfa288156f3e452d889 (mode 755)
--- /dev/null
+++ bin/zncTest.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+#
+
+use strict;
+use warnings;
+
+use lib qw(./lib);
+use IRCNOW::Database;
+
+use IRCNOW::IO::IRC;
+use IRCNOW::Acct;
+
+use IRCNOW::IO qw(:DEBUG);
+$verbosity=ALL;
+#my $dbase='/var/www/botnow/botnow.db';
+#debug(INFO, "Loading Database $dbase");
+#my $botnowDB = IRCNOW::Database->new(dbpath=>$dbase);
+
+use Data::Dumper;
+
+#my $acct=new IRCNOW::Acct();
+#print $acct->newpass() . "\n";
+
+my $irc = new IRCNOW::IO::IRC(
+	localnet => 'ircnow',
+	staff => 'izzyb',
+	nick => 'cliNow',
+	host => '127.0.0.1',
+	port => 1337,
+	pass => 'Secerate!pwd',
+	expires => 1800,
+	networks => 'ircnow',
+	chans => '#bottest',
+	teamchans => '',
+);
+
+
+
+$irc->{bots}->[0]->{actions} = [
+	'privmsg *status :Traffic',
+	'privmsg *status :listusers',
+	'privmsg *controlpanel :listusers',
+	'privmsg #bottest : ',
+];
+
+
+
+$irc->run();
+
blob - 8f38a942c8bcdc6e0d6284a5c170fd6e22f82e2a
blob + 419c632a0712d04cf232a732c16d45f3f4bbd529
--- lib/IRCNOW/IO/IRC.pm
+++ lib/IRCNOW/IO/IRC.pm
@@ -1,9 +1,13 @@
 package IRCNOW::IO::IRC;
 use strict;
 use warnings;
+use Carp;
+use Data::Dumper;
+
 use lib qw(./lib);
 use IRCNOW::IO qw(:DEBUG);
 
+
 use IO::Socket;
 use IO::Select;
 
@@ -27,6 +31,7 @@ our @bots;
 our $localnet;
 our @stafflist;
 our @networks;
+our %tables;
 
 sub new {
 	my $class = shift;
@@ -36,6 +41,7 @@ sub new {
 		call => $call,
 		stafflist => \@stafflist,
 		networks => \@networks,
+		tables => \%tables,
 	};
 	# verify we have all required params
 	my @required = qw(networks staff localnet nick host port pass expires chans teamchans);
@@ -205,6 +211,98 @@ sub isstaff {
 	return 0;
 }
 
+sub parse_zncTable {
+	my $self = shift;
+	my $tableName = shift;
+	my $text = shift;
+	$self->{tables}->{$tableName} = {phase=>0,data=>[]} unless exists $self->{tables}->{$tableName};
+	my $thisTable = $self->{tables}->{$tableName};
+	if (substr($text, 0,1) eq '+') {
+		$thisTable->{phase}++;
+		if ($thisTable->{phase} >= 3 ) { # Third + is bottom of table
+			# end of table 
+			$thisTable->{phase}=0;
+			debug(ALL, "Table Data for $tableName");
+			debug(ALL, Dumper($thisTable));
+			# XXX Do something useful here
+		}
+	} else {  # this line begins with '|'
+		# | field1     | field2     | field3        |
+		my $fields = [ split ('\s*\|\s+', $text) ];
+		shift @$fields; # Get rid of empty field before first |
+		$fields->[-1] =~ s/\s*\|$//; #remove trailing whitespace and | from last record
+		if ( $thisTable->{phase} == 1 ) {
+			# This must be the header line
+			$thisTable->{header} = $fields;
+			# Capture field names
+		} else {
+			# Capture rows of data
+			push @{$thisTable->{data}}, $fields;
+		}
+	}
+}
+# message in channel starting with '!' or a PRIVMSG to the bot.
+# $response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i)
+sub parse_commands {
+	my ($self, $bot, $response, @params) = @_;
+	my ($hostmask, $sendnick, $host, $target, $text) = @params;
+	my $nick = $self->{nick};
+	my $staff = $self->{staff};
+	chomp($response);
+	#debug(ALL, "-->COMMAND--> $response");
+	if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$nick.?$/) {
+		debug(ALL, "TEXT: $text");
+		if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) {
+			debug(ERRORS, "ERROR: nonexistent: $1");
+		} elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") {
+			debug(ERRORS, "ERROR: disconnected: $bot->{name}");
+		} elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) {
+			debug(ALL, "Module $1 already loaded\n");
+		} elsif ($text =~ /^Disconnected from IRC.*$/) {
+			debug(ERRORS, "ERROR: $bot->{name}: $text");
+		} elsif ($text =~ /^[|+]/) {
+			my $tableName = "$target/" . $bot->{name};
+			$self->parse_zncTable($tableName, $text);
+		} else {
+			debug(ERRORS, "ERROR: Unexpected: $response");
+		}
+	} elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) {
+		my ($cmd, $text) = ($1, $2);
+		debug(ALL, qq{<<COMMAND: $cmd; TEXT: $text>>});
+		my $hand = $staff; # TODO fix later
+		if ($target =~ /^#/) {
+			foreach my $c (@{$call->{pub}}) {
+				if ($cmd eq $c->{cmd}) {
+					my $proc = $c->{proc};
+					$proc->($bot, $sendnick, $host, $hand, $target, $text);
+				}
+			}
+		} else {
+			foreach my $c (@{$call->{msg}}) {
+				if ($cmd eq $c->{cmd}) {
+					my $proc = $c->{proc};
+					$proc->($bot, $sendnick, $host, $hand, $text);
+				}
+			}
+		}
+	} else {
+		my $hand = $staff; # TODO fix later
+		if ($target =~ /^#/) {
+			foreach my $c (@{$call->{pubm}}) {
+				my $proc = $c->{proc};
+				$proc->($bot, $sendnick, $host, $hand, $target, $text);
+			}
+		} else {
+			foreach my $c (@{$call->{msgm}}) {
+				my $proc = $c->{proc};
+				$proc->($bot, $sendnick, $host, $hand, $text);
+			}
+		}
+	}
+	debug(ALL, "$hostmask $target $text");
+}
+
+
 sub parse_response {
 		my ($self, $bot, $response) = @_;
 		my $staff=$self->{staff};
@@ -213,12 +311,17 @@ sub parse_response {
 		my $expires=$self->{expires};
 		my $chans=$self->{chans};
 		my $teamchans=$self->{teamchans};
+		my $tables=$self->{tables};
 
 		if ($response =~ /^PING :(.*)\r\n$/i) {
 			$self->putserv($bot, "PONG :$1");
 		} elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) {
 			my ($type, $target, $text) = ($1, $2, $3);
+			chomp $response;
+			debug(ALL, "ZNC: Response = $response");
+			debug(ALL, "ZNC: type = $type, target = $target, text = $text");
 			if ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Password required") {
+				debug(ALL, "ZNC: putserv( 'PASS $nick/$bot->{name}:$pass' )");
 				$self->putserv($bot, "PASS $nick/$bot->{name}:$pass");
 				if ($bot->{name} =~ /^$localnet$/i) {
 					$self->putserv($bot, "OPER $nick $pass");
@@ -240,59 +343,13 @@ sub parse_response {
 				debug(ALL, "Debug type: $type, target: $target, text: $text");
 			}
 		} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) {
-			chomp($response);
-			debug(ALL, "-->COMMAND--> $response");
-			my ($hostmask, $sendnick, $host, $target, $text) = ($1, $2, $3, $4, $5);
-			if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$nick.?$/) {
-				if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) {
-					debug(ERRORS, "ERROR: nonexistent: $1");
-				} elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") {
-					debug(ERRORS, "ERROR: disconnected: $bot->{name}");
-				} elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) {
-					debug(ALL, "Module $1 already loaded\n");
-				} elsif ($text =~ /^Disconnected from IRC.*$/) {
-					debug(ERRORS, "ERROR: $bot->{name}: $text");
-				} elsif ($text =~ /^|/) {
-					debug(ERRORS, "ERROR: $bot->{name}: $text");
-				} else {
-					debug(ERRORS, "ERROR: Unexpected: $response");
-				}
-			} elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) {
-				my ($cmd, $text) = ($1, $2);
-				debug(ALL, qq{<<COMMAND: $cmd; TEXT: $text>>});
-				my $hand = $staff; # TODO fix later
-				if ($target =~ /^#/) {
-					foreach my $c (@{$call->{pub}}) {
-						if ($cmd eq $c->{cmd}) {
-							my $proc = $c->{proc};
-							$proc->($bot, $sendnick, $host, $hand, $target, $text);
-						}
-					}
-				} else {
-					foreach my $c (@{$call->{msg}}) {
-						if ($cmd eq $c->{cmd}) {
-							my $proc = $c->{proc};
-							$proc->($bot, $sendnick, $host, $hand, $text);
-						}
-					}
-				}
-			} else {
-				my $hand = $staff; # TODO fix later
-				if ($target =~ /^#/) {
-					foreach my $c (@{$call->{pubm}}) {
-						my $proc = $c->{proc};
-						$proc->($bot, $sendnick, $host, $hand, $target, $text);
-					}
-				} else {
-					foreach my $c (@{$call->{msgm}}) {
-						my $proc = $c->{proc};
-						$proc->($bot, $sendnick, $host, $hand, $text);
-					}
-				}
-			}
-			debug(ALL, "$hostmask $target $text");
+			# my ($hostmask, $sendnick, $host, $target, $text) = ($1,$2,$3,$4,$5);
+			$self->parse_commands($bot, $response,$1,$2,$3,$4,$5);
 		} elsif($response =~ /^:([^ ]+) NOTICE ([^ ]+) :(.*)\r\n$/i) {
 			my ($hostmask, $target, $text) = ($1, $2, $3);
+			chomp $response;
+			debug(ALL, "NOTICE: ". $response);
+			debug(ALL, "NOTICE: hostmask = $hostmask, target = $target, text = $text");
 			if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
 				my ($sendnick, $host) = ($1, $2);
 				my $hand = $staff; # TODO fix later
@@ -313,11 +370,12 @@ sub parse_response {
 					}
 				}
 			}
-			debug(ALL, "$hostmask NOTICE $target $text");
 #:portlane.se.quakenet.org NOTICE guava :Highest connection count: 1541 (1540 clients)
 #:portlane.se.quakenet.org NOTICE guava :on 2 ca 2(4) ft 20(20) tr
 		} elsif($response =~ /^:([^ ]+) MODE ([^ ]+) ([^ ]+)\s*(.*)\r\n$/i) {
 			my ($hostmask, $chan, $change, $targets) = ($1, $2, $3, $4);
+			debug(ALL, "NOTICE: $response");
+			debug(ALL, "NOTICE: hostmask = $hostmask, chan = $chan, change = $change, targets = $targets");
 			if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
 				my ($sendnick, $host) = ($1, $2);
 				my $hand = $staff; # TODO fix later
@@ -490,25 +548,46 @@ sub parse_response {
 		}
 }
 
+
+sub parse_actions {
+	my $self=shift;
+	foreach my $b (@{$self->{bots}}) {
+		if (exists $b->{actions}) {
+			my $action = shift @{$b->{actions}} || '';
+			if ($action ne "") {
+				debug(ALL, "ACTION <---  $action");
+				$self->putserv($b,$action);
+			}
+		}
+	}
+}
+
+
 sub run {
 	my $self=shift;
 	my $bots=$self->{bots};
 	my $call=$self->{call};
 	my $sel = $self->{sockets};
-	while(my @ready = $sel->can_read) {
-		my ($bot, $response);
-		foreach my $socket (@ready) {
-			foreach my $b (@$bots) {
-				if($socket == $b->{sock}) {
-					$bot = $b;
-					last;
+	while(1) {
+		my @ready = $sel->can_read(1);
+		if(@ready) {
+			my ($bot, $response);
+			foreach my $socket (@ready) {
+				foreach my $b (@$bots) {
+					if($socket == $b->{sock}) {
+						$bot = $b;
+						last;
+					}
 				}
+				if (!defined($response = <$socket>)) {
+					debug(ERRORS, "ERROR ".$bot->{name}." has no response:");
+					next;
+				}
+				$self->parse_response($bot,$response);
 			}
-			if (!defined($response = <$socket>)) {
-				debug(ERRORS, "ERROR ".$bot->{name}." has no response:");
-				next;
-			}
-			$self->parse_response($bot,$response);
+		} else { # Nothing to read for 5 seconds, see if user input
+			# After processing pending messages
+			$self->parse_actions();
 		}
 	}
 }