2 ### Process.pl: Kevin Lenzo 1997-1999
6 # process the incoming message
11 use vars qw($who $msgType $addressed $message $ident $user $host $chan
12 $learnok $talkok $force_public_reply $noreply $addrchar
13 $literal $addressedother $userHandle $lobotomized);
14 use vars qw(%channels %users %param %cache %chanconf %mask %orig %lang);
17 $learnok = 0; # Able to learn?
18 $talkok = 0; # Able to yap?
19 $force_public_reply = 0;
22 return 'X' if $who eq $ident; # self-message.
23 return 'addressedother set' if ($addressedother);
25 $talkok = ( $param{'addressing'} =~ /^OPTIONAL$/i or $addressed );
26 $learnok = 1 if ($addressed);
27 if ( $param{'learn'} =~ /^HUNGRY$/i ) {
35 # hack to support channel +o as '+o' in bot user file.
36 # requires +O in user file.
37 # is $who arg lowercase?
38 if ( exists $channels{$chan}{o}{ $orig{who} } && &IsFlag('O') eq 'O' ) {
39 &status("Gave $who/$chan +o (+O)\'ness");
40 $users{$userHandle}{FLAGS} .= 'o';
43 # check if we have our head intact.
45 if ( $addressed and IsFlag('o') eq 'o' ) {
46 my $delta_time = time() - ( $cache{lobotomy}{$who} || 0 );
47 &msg( $who, 'give me an unlobotomy.' ) if ( $delta_time > 60 * 60 );
48 $cache{lobotomy}{$who} = time();
50 return 'LOBOTOMY' unless IsFlag('A');
54 if ( $param{'talkMethod'} =~ /^PRIVATE$/i ) {
55 if ( $msgType =~ /public/ and $addressed ) {
57 "sorry. i'm in 'PRIVATE' talkMethod mode "
58 . "while you sent a message to me ${msgType}ly." );
64 # join, must be done before outsider checking.
65 if ( $message =~ /^join(\s+(.*))?\s*$/i ) {
66 return 'join: not addr' unless ($addressed);
68 $2 =~ /^($mask{chan})(\s+(\S+))?/;
69 my ( $joinchan, $key ) = ( lc $1, $3 );
71 if ( $joinchan eq '' ) {
76 if ( $joinchan !~ /^$mask{chan}$/ ) {
77 &msg( $who, "$joinchan is not a valid channel name." );
81 if ( &IsFlag('o') ne 'o' ) {
82 if ( !exists $chanconf{$joinchan} ) {
83 &msg( $who, "I am not allowed to join $joinchan." );
87 if ( &validChan($joinchan) ) {
89 "warn: I'm already on $joinchan, joining anyway..." );
92 $cache{join}{$joinchan} = $who; # used for on_join self.
94 &status("JOIN $joinchan $key <$who>");
95 &msg( $who, "joining $joinchan $key" );
96 &joinchan( $joinchan, $key );
97 &joinNextChan(); # hack.
103 if ( $msgType =~ /private/ and $message =~ s/^identify//i ) {
104 $message =~ s/^\s+|\s+$//g;
105 my @array = split / /, $message;
107 if ( $who =~ /^_default$/i ) {
108 &performStrictReply('you are too eleet.');
112 if ( !scalar @array or scalar @array > 2 ) {
117 my $do_nick = $array[1] || $who;
119 if ( !exists $users{$do_nick} ) {
120 &performStrictReply("nick $do_nick is not in user list.");
124 my $crypt = $users{$do_nick}{PASS};
125 if ( !defined $crypt ) {
126 &performStrictReply("user $do_nick has no passwd set.");
130 if ( !&ckpasswd( $array[0], $crypt ) ) {
131 &performStrictReply("invalid passwd for $do_nick.");
135 my $mask = "$who!$user@" . &makeHostMask($host);
136 ### TODO: prevent adding multiple dupe masks?
137 ### TODO: make &addHostMask() CMD?
138 &performStrictReply("Added $mask for $do_nick...");
139 $users{$do_nick}{HOSTS}{$mask} = 1;
145 if ( $msgType =~ /private/ and $message =~ s/^pass//i ) {
146 $message =~ s/^\s+|\s+$//g;
147 my @array = split ' ', $message;
149 if ( $who =~ /^_default$/i ) {
150 &performStrictReply('you are too eleet.');
154 if ( scalar @array != 1 ) {
159 # TODO: use &getUser()?
161 foreach ( keys %users ) {
162 if ( $users{$_}{FLAGS} =~ /n/ ) {
168 if ( !exists $users{$who} and !$first ) {
169 &performStrictReply("nick $who is not in user list.");
174 &performStrictReply('First time user... adding you as Master.');
175 $users{$who}{FLAGS} = 'aemnorst';
178 my $crypt = $users{$who}{PASS};
179 if ( defined $crypt ) {
180 &performStrictReply("user $who already has pass set.");
184 if ( !defined $host ) {
185 &WARN('pass: host == NULL.');
189 if ( !scalar keys %{ $users{$who}{HOSTS} } ) {
190 my $mask = "*!$user@" . &makeHostMask($host);
191 &performStrictReply("Added hostmask '\002$mask\002' to $who");
192 $users{$who}{HOSTS}{$mask} = 1;
195 $crypt = &mkcrypt( $array[0] );
196 $users{$who}{PASS} = $crypt;
197 &performStrictReply("new pass for $who, crypt $crypt.");
203 if ( &IsParam('disallowOutsiders') and $msgType =~ /private/i ) {
206 foreach ( keys %channels ) {
208 # don't test for $channel{_default} elsewhere !!!
209 next if ( /^\s*$/ || /^_?default$/ );
210 next unless ( &IsNickInChan( $who, $_ ) );
216 if ( !$found and scalar( keys %channels ) ) {
217 &status("OUTSIDER <$who> $message");
223 if ( $msgType =~ /public/ and $message =~ s/^\+// ) {
224 &status("Process: '+' flag detected; changing reply to public");
226 $who = $chan; # major hack to fix &msg().
227 $force_public_reply++;
229 # notice is still NOTICE but to whole channel => good.
232 # User Processing, for all users.
235 return 'SOMETHING parseCmdHook' if &parseCmdHook($message);
237 $retval = &userCommands();
238 return unless ( defined $retval );
239 return if ( $retval eq $noreply );
243 # once useless messages have been parsed out, we match them.
246 # confused? is this for infobot communications?
247 foreach ( keys %{ $lang{'confused'} } ) {
250 next unless ( $message =~ /^\Q$y\E\s*/ );
254 # hello. [took me a while to fix this. -xk]
255 if ( $orig{message} =~
256 /^(\Q$ident\E\S?[:, ]\S?)?\s*(h(ello|i( there)?|owdy|ey|ola))( \Q$ident\E)?\s*$/i
259 return '' unless ($talkok);
261 # 'mynick: hi' or 'hi mynick' or 'hi'.
262 &status('somebody said hello');
264 # 50% chance of replying to a random greeting when not addressed
265 if ( !defined $5 and $addressed == 0 and rand() < 0.5 ) {
266 &status('not returning unaddressed greeting');
270 # customized random message.
271 my $tmp = ( rand() < 0.5 ) ? ", $who" : '';
272 &performStrictReply( &getRandom( keys %{ $lang{'hello'} } ) . $tmp );
277 if ( $message =~ /how (the hell )?are (ya|you)( doin\'?g?)?\?*$/ ) {
279 &performReply( &getRandom( keys %{ $lang{'howareyou'} } ) );
284 if ( $message =~ /you (rock|rewl|rule|are so+ coo+l)/
285 || $message =~ /(good (bo(t|y)|g([ui]|r+)rl))|(bot( |\-)?snack)/i )
287 return 'praise: no addr' unless ($addressed);
289 &performReply( &getRandom( keys %{ $lang{'praise'} } ) );
294 if ( $message =~ /^than(ks?|x)( you)?( \S+)?/i ) {
295 return 'thank: no addr' unless ( $message =~ /$ident/ or $talkok );
297 &performReply( &getRandom( keys %{ $lang{'welcome'} } ) );
306 if ( $msgType =~ /public/i
307 && $message =~ /^(\S+)(--|\+\+)\s*$/
309 && &IsChanConfOrWarn('karma') )
312 # to request factoids such as 'g++' or 'libstdc++', append '?' to the query.
313 my ( $term, $inc ) = ( lc $1, $2 );
315 if ( lc $term eq lc $who ) {
316 &msg( $who, "please don't karma yourself" );
321 &sqlSelect( 'stats', 'counter', { nick => $term, type => 'karma' } )
323 if ( $inc eq '++' ) {
332 { 'nick' => $term, type => 'karma', channel => 'PRIVATE' },
342 # here's where the external routines get called.
343 # if they return anything but null, that's the 'answer'.
346 if ( !defined $er ) {
347 return 'SOMETHING 1';
350 # allow administration of bot via messages (default is DCC CHAT only)
351 if ( &IsFlag('A') ) {
352 &loadMyModule('UserDCC');
354 if ( !defined $er ) {
355 return 'SOMETHING 2';
359 if ( 0 and $addrchar ) {
361 "I don't trust people to use the core commands while addressing me in a short-cut way."
367 if ( &IsParam('factoids')
368 and $param{'DBType'} =~ /^(mysql|sqlite(2)?|pgsql)$/i )
372 elsif ( $param{'DBType'} =~ /^none$/i ) {
373 return 'NO FACTOIDS.';
376 &ERROR("INVALID FACTOID SUPPORT? ($param{'DBType'})");
384 # vim:ts=4:sw=4:expandtab:tw=80