#!/usr/bin/perl ############################################################################ # # xcafe.pl # sidekick services for xchat (http://xchat.org) # (c) Vladi Belperchinov-Shabanski "Cade" 2002-2003 # http://soul.datamax.bg/~cade # $Id: xcafe.pl,v 1.3 2004/08/05 08:21:55 cade Exp $ # ############################################################################ use strict; use Algorithm::FloodControl; use Mail::Sendmail; use Data::Dumper; ### CONFIG ################################################################### our $SEEMS_AWAY = 10*60; # in seconds ############################################################################## our $last_output_time = time(); our $last_input_time = time(); ############################################################################## my $start_time = time(); IRC::register( 'xcafe', '1.0', '', '' ); IRC::print( "*** xcafe ".'$Id: xcafe.pl,v 1.3 2004/08/05 08:21:55 cade Exp $' ); IRC::add_message_handler( $_, "h_input" ) for( qw( PRIVMSG NICK ) ); IRC::add_command_handler( '', "h_output" ); IRC::add_timeout_handler( 60*1000, "h_1min" ); ### GENERIC HANDLERS ######################################################### sub h_input { $last_input_time = time(); my $ev = irc_parse_event( @_ ); # IRC::print( "DEBUG: ---EVENT---\n" . Dumper( $ev ) . "\n---RAW---\n[$_[0]]\n---END---\n" ); if( $ev->{ 'TYPE' } eq 'PRIVMSG' ) { return h_ctcp_finger( $ev ) if $ev->{ 'TEXT' } eq "\001FINGER\001"; return h_inquire( $ev ) if $ev->{ 'TEXT' } =~ /^\s*!/; return h_private( $ev ) if $ev->{ 'PRIV' }; return h_public( $ev ); # else public } return h_nick( $ev ) if $ev->{ 'TYPE' } eq "NICK"; } sub h_output { $last_output_time = time(); # IRC::print( "OUTPUT: " . localtime($last_output_time) ); return 0; } sub h_1min { my $uptime = time() - $start_time; IRC::add_timeout_handler( 60*1000, "h_1min" ); return 1; } ### SPECIFIC/USERLEVEL HANDLERS ############################################## sub h_private { my $ev = shift; my $nick = $ev->{ 'NICK' }; # IRC::print( "PRIVATE: " . localtime($last_input_time) ); if( time() - $last_output_time > $SEEMS_AWAY and ! flood_check( 1, 300, "CTCP.AWAY.TO.$nick" ) ) { IRC::command( "/msg $nick I'm away since " . localtime( $last_output_time ) ); return; } } sub h_public { my $ev = shift; # IRC::print( "DEBUG: PUBLIC: " . localtime($last_input_time) ); return; } sub h_inquire { my $ev = shift; my $nick = $ev->{ 'NICK' }; my $text = $ev->{ 'TEXT' }; # IRC::command("/notice $nick *** unknown inquire"); } sub h_nick { my $ev = shift; } ### CTCP ##################################################################### our @finger; our $last_finger; sub h_ctcp_finger { my $ev = shift; my $nick = $ev->{ 'NICK' }; return 0 if flood_check( 1, 60, "CTCP.FINGER.FROM.*" ); return 0 if flood_check( 1, 60, "CTCP.FINGER.FROM.$nick" ); my %mail = ( To => 'XXXXXXXXXXXX@sms.mtel.net', From => 'z@bis.bg', Message => "CTCP FINGER: $nick" ); sendmail( %mail ); IRC::print("Received CTCP FINGER from $nick. Mail sent.\n"); return 1; } ### COMMANDS ################################################################# sub c_out { my $ev = shift; my $nick = $ev->{ 'NICK' }; my $pref; $pref = "/msg $nick " if $ev->{ 'PRIV' }; for my $a ( @_ ) { if( $ev->{ 'LOOP' } ) { IRC::print( $a ); } else { IRC::command( "$pref$_" ) for split /\n/, $a; }; } } sub c_outp { my $ev = shift; my $p = $ev->{'PRIV'}; $ev->{'PRIV'} = 1; c_out( $ev, @_ ); $ev->{'PRIV'} = $p; } ############################################################################## sub irc_parse_event { $_[0] =~ /^:?(([][}{\w\\\`^|\-]+?)!(.+)?\@)?(\S+)\s+([A-Za-z0-9]+)\s+([^:]+)?\s*:(.*)/o or return undef; my %res; $res{ 'NICK' } = $2; $res{ 'USER' } = $3; $res{ 'HOST' } = $4; $res{ 'TYPE' } = $5; $res{ 'RECV' } = [ split /\s+/, $6 ]; $res{ 'TEXT' } = $7; $res{ 'CHAN' } = IRC::get_info( 2 ); $res{ 'SERV' } = IRC::get_info( 3 ); for my $r ( @{ $res{ 'RECV' } } ) { $res{ 'LOOP' } = 1 if $res{ 'NICK' } eq IRC::get_info( 1 ); $res{ 'PRIV' } = 1 and last if $r eq IRC::get_info( 1 ); } return \%res; } ### FUNCTIONS ################################################################ ###eof########################################################################