2 ### Reply.pl: Kevin Lenzo (c) 1997
6 # x is y === $lhs $mhs $rhs
10 # rhs - factoid message.
15 use vars qw($msgType $uh $lastWho $ident);
16 use vars qw(%lang %lastWho);
21 my($reply, $count, $fauthor, $result, $factoid, $search, @searches);
22 $orig{message} = $message;
24 if (!defined $message or $message =~ /^\s*$/) {
25 &WARN("getR: message == NULL.");
29 $message =~ tr/A-Z/a-z/;
30 $message =~ s/^cmd:/CMD:/;
32 if (!$literal and &IsChanConf("factoidSearch")) {
33 @searches = split(/\s+/, &getChanConf("factoidSearch"));
35 @searches = ('_default');
38 # check for factoids with each prefix
39 foreach $search (@searches) {
40 if ($search eq '_default') {
43 $factoid = "$search $message";
45 ($count, $fauthor, $result) = &sqlSelect("factoids",
46 "requested_count,created_by,factoid_value",
47 { factoid_key => $factoid }
57 return "\"$factoid\" $mhs \"$rhs\"" if ($literal);
62 # if there was a head...
63 my(@poss) = split '\|\|', $result;
65 $poss[$#poss] =~ s/\s$//;
68 $result = &getRandom(@poss);
72 $result = &SARit($result);
76 ### AT LAST, REPEAT PREVENTION CODE REMOVED IN FAVOUR OF GLOBAL
77 ### FLOOD REPETION AND PROTECTION. -20000124
80 ### FIXME: old mysql doesn't support
81 ### "requested_count=requested_count+1".
83 &sqlSet("factoids", {'factoid_key' => $factoid}, {
85 requested_time => time(),
86 requested_count => $count
89 # TODO: rename $real to something else!
91 # my $author = &getFactInfo($lhs,"created_by") || '';
92 # $real++ if ($author =~ /^\Q$who\E\!/);
93 # $real++ if (&IsFlag("n"));
94 $real = 0 if ($msgType =~ /public/);
97 # only remove '<reply>'
98 if (!$real and $reply =~ s/^\s*<reply>\s*//i) {
100 if ($reply =~ s/^are /$lhs are /i) {
101 &VERB("Reply.pl: el-cheapo 'are' fix executed.",2);
104 } elsif (!$real and $reply =~ s/^\s*<action>\s*(.*)/\cAACTION $1\cA/i) {
105 # only remove '<action>' and make it an action.
106 } else { # not a short reply
109 if (exists $bots{$nuh} and $rhs !~ /^\s*$/) {
110 return "$lhs $mhs $rhs";
113 ### bot->person reply.
114 # result is random if separated by '||'.
115 # rhs is full factoid with '||'.
117 $reply = &getRandom(keys %{ $lang{'factoid'} });
118 $reply =~ s/##KEY/$lhs/;
119 $reply =~ s/##VALUE/$result/;
121 $reply = "$lhs $mhs $result";
124 if ($reply =~ s/^\Q$who\E is/you are/i) {
127 if ($reply =~ /^you are / or $reply =~ / you are /) {
128 return if ($addressed);
134 return $reply if ($literal);
136 # remove excessive beginning and end whitespaces.
137 $reply =~ s/^\s+|\s+$//g;
139 if ($reply =~ /^\s+$/) {
140 &DEBUG("Reply: Null factoid ($message)");
144 return $reply unless ($reply =~ /\$/);
150 # don't evaluate if it has factoid arguments.
151 if ($message =~ /^CMD:/i) {
152 &status("Reply: not doing substVars (eval dollar vars)");
154 $reply = &substVars($reply,1);
162 my ($l,$r) = (0,0); # l = left, r = right.
163 my ($s,$t) = (0,0); # s = start, t = marker.
168 foreach (split //, $string) {
185 my $substr = substr($old,$s,$i-$s+1);
186 push(@rand, substr($old,$t+1,$i-$t-1) );
188 my $rand = $rand[rand @rand];
189 # &status("SARing '$substr' to '$rand'.");
190 $string =~ s/\Q$substr\E/$rand/;
195 if ($_ eq "|" and $l+$r== 0 and $l==1) {
196 push(@rand, substr($old,$t+1,$i-$t-1) );
203 if ($old eq $string) {
204 &WARN("smart_replace: no subst made. (string => $string)");
215 while ($txt =~ /\((.*?)\)\?/) {
217 if (rand() > 0.5) { # fix.
218 &status("Factoid transform: keeping '$str'.");
219 $txt =~ s/\(\Q$str\E\)\?/$str/;
221 &status("Factoid transform: removing '$str'.");
222 $txt =~ s/\(\Q$str\E\)\?\s?//;
225 last if ($done >= 10); # just in case.
229 # EG: (0-32768) => 6325
230 ### TODO: (1-10,20-30,40) => 24
231 while ($txt =~ /\((\d+)-(\d+)\)/) {
232 my ($lower,$upper) = ($1,$2);
233 my $new = int(rand $upper-$lower) + $lower;
235 &status("SARing '$&' to '$new' (2).");
238 last if ($done >= 10); # just in case.
242 # EG: (blah1|blah2|blah3|) => blah1
243 while ($txt =~ /.*\((.*\|.*?)\).*/) {
244 $txt = &smart_replace($txt);
247 last if ($done >= 10); # just in case.
249 &status("Reply.pl: $done SARs done.") if ($done);
255 my($reply,$flag) = @_;
258 # TODO: support localtime.
259 my $date = scalar(gmtime());
260 $date =~ s/\:\d+(\s+\w+)\s+\d+$/$1/;
261 $reply =~ s/\$date/$date/gi;
262 $date =~ s/\w+\s+\w+\s+\d+\s+//;
263 $reply =~ s/\$time/$date/gi;
267 $reply =~ s/\$nick/$who/g;
268 $reply =~ s/\$who/$who/g; # backward compat.
271 if ($reply =~ /\$(user(name)?|host)/) {
272 my ($username, $hostname) = split /\@/, $uh;
273 $reply =~ s/\$user(name)?/$username/g;
274 $reply =~ s/\$host(name)?/$hostname/g;
276 $reply =~ s/\$chan(nel)?/$talkchannel/g;
277 if ($msgType =~ /public/) {
278 $reply =~ s/\$lastspeaker/$lastWho{$talkchannel}/g;
280 $reply =~ s/\$lastspeaker/$lastWho/g;
283 if ($reply =~ /\$rand/) {
287 if ($reply =~ /\$randnick/) {
288 my @nicks = keys %{ $channels{$chan}{''} };
289 my $randnick = $nicks[ int($rand*$#nicks) ];
290 $reply =~ s/\$randnick/$randnick/g;
294 if ($reply =~ /\$rand(\d+)(\.(\d+))?/) {
298 #&DEBUG("dot => $dot, max => $max, rand=>$rand");
299 $rand = sprintf("%.*f", $dot, $rand*$max);
301 &DEBUG("swapping $orig to $rand");
302 $reply =~ s/\Q$orig\E/$rand/eg;
304 $reply =~ s/\$rand/$rand/g;
308 $reply =~ s/\$ident/$ident/g;
310 if ($reply =~ /\$startTime/) {
311 my $time = scalar(gmtime $^T);
312 $reply =~ s/\$startTime/$time/;
315 if ($reply =~ /\$uptime/) {
316 my $uptime = &Time2String(time() - $^T);
317 $reply =~ s/\$uptime/$uptime/;
320 if ($reply =~ /\$factoids/) {
321 my $factoids = &countKeys("factoids");
322 $reply =~ s/\$factoids/$factoids/;
325 if ($reply =~ /\$Fupdate/) {
326 my $x = "\002$count{'Update'}\002 ".
327 &fixPlural("modification", $count{'Update'});
328 $reply =~ s/\$Fupdate/$x/;
331 if ($reply =~ /\$Fquestion/) {
332 my $x = "\002$count{'Question'}\002 ".
333 &fixPlural("question", $count{'Question'});
334 $reply =~ s/\$Fquestion/$x/;
337 if ($reply =~ /\$Fdunno/) {
338 my $x = "\002$count{'Dunno'}\002 ".
339 &fixPlural("dunno", $count{'Dunno'});
340 $reply =~ s/\$Fdunno/$x/;
343 $reply =~ s/\$memusage/$memusage/;