]> git.donarmstrong.com Git - infobot.git/blob - src/Factoids/Reply.pl
- Remaining files that were changed due to removal of $noreply or
[infobot.git] / src / Factoids / Reply.pl
1 ###
2 ### Reply.pl: Kevin Lenzo   (c) 1997
3 ###
4
5 ##
6 # x is y === $lhs $mhs $rhs
7 #
8 #   lhs - factoid.
9 #   mhs - verb.
10 #   rhs - factoid message.
11 ##
12
13 if (&IsParam("useStrict")) { use strict; }
14
15 use vars qw($msgType $uh $lastWho $ident);
16 use vars qw(%lang %lastWho);
17
18 sub getReply {
19     my($message) = @_;
20     my($lhs,$mhs,$rhs);
21     my($result,$reply);
22     my $literal = 0;
23     $orig{message} = $message;
24
25     if (!defined $message or $message =~ /^\s*$/) {
26         &WARN("getR: message == NULL.");
27         return '';
28     }
29
30     $message =~ tr/A-Z/a-z/;
31
32     if ($result = &getFactoid($message)) {
33         $lhs = $message;
34         $mhs = "is";
35         $rhs = $result;
36     } else {
37         return '';
38     }
39
40     # if there was a head...
41     my(@poss) = split '\|\|', $result;
42     $poss[0] =~ s/^\s//;
43     $poss[$#poss] =~ s/\s$//;
44
45     if ((@poss > 1) && ($msgType =~ /public/)) {
46         $result = &getRandom(@poss);
47         $result =~ s/^\s*//;
48     }
49
50     my $fauthor = &dbGet("factoids", "factoid_key", $message, "created_by");
51     ### we need non-evaluating regex like in factoid sar.
52     if ($msgType =~ /^private$/) {
53         if (defined $fauthor and $fauthor =~ /^\Q$who\E\!/i) {
54             &status("Reply.pl: author requested own factoid in private; literal!");
55             $literal = 1;
56         }
57     } else {
58         my $done = 0;
59
60         # (blah1|blah2)?
61         while ($result =~ /\((.*?)\)\?/) {
62             my $str = $1;
63             if (rand() > 0.5) {         # fix.
64                 &status("Factoid transform: keeping '$str'.");
65                 $result =~ s/\(\Q$str\E\)\?/$str/;
66             } else {                    # remove
67                 &status("Factoid transform: removing '$str'.");
68                 $result =~ s/\(\Q$str\E\)\?\s?//;
69             }
70             $done++;
71             last if ($done >= 10);      # just in case.
72         }
73         $done = 0;
74
75         # EG: (0-32768) => 6325
76         ### TODO: (1-10,20-30,40) => 24
77         while ($result =~ /\((\d+)-(\d+)\)/) {
78             my ($lower,$upper) = ($1,$2);
79             my $new = int(rand $upper-$lower) + $lower;
80
81             &status("Reply.pl: SARing '$&' to '$new'.");
82             $result =~ s/$&/$new/;
83             $done++;
84             last if ($done >= 10);      # just in case.
85         }
86         $done = 0;
87
88         # EG: (blah1|blah2|blah3|) => blah1
89         while ($result =~ /.*\((.*\|.*?)\).*/) {
90             $result = &smart_replace($result);
91
92             $done++;
93             last if ($done >= 10);      # just in case.
94         }
95         &status("Reply.pl: $done SARs done.") if ($done);
96     }
97
98     $reply = $result;
99     if ($result ne "") {
100         ### AT LAST, REPEAT PREVENTION CODE REMOVED IN FAVOUR OF GLOBAL
101         ### FLOOD REPETION AND PROTECTION. -20000124
102
103         # stats code.
104         &setFactInfo($lhs,"requested_by", $nuh);
105         &setFactInfo($lhs,"requested_time", time());
106         ### FIXME: old mysql doesn't support
107         ###     "requested_count=requested_count+1".
108         my $count = &getFactInfo($lhs,"requested_count") || 0;
109         $count++;
110         &setFactInfo($lhs,"requested_count", $count);
111
112         my $real   = 0;
113         my $author = &getFactInfo($lhs,"created_by") || '';
114
115         $real++ if ($author =~ /^\Q$who\E\!/);
116         $real++ if (&IsFlag("n"));
117         $real = 0 if ($msgType =~ /public/);
118
119         ### fix up the reply.
120         # only remove '<reply>'
121         if (!$real and $reply =~ s/^\s*<reply>\s*//i) {
122             # 'are' fix.
123             if ($reply =~ s/^are /$lhs are /i) {
124                 &DEBUG("Reply.pl: el-cheapo 'are' fix executed.");
125                 $mhs = "are";   # what's this for?
126             }
127
128         } elsif (!$real and $reply =~ s/^\s*<action>\s*(.*)/\cAACTION $1\cA/i) {
129             # only remove '<action>' and make it an action.
130         } else {                # not a short reply
131
132             ### bot->bot reply.
133             if (exists $bots{$nuh} and $rhs !~ /^\s*$/) {
134                 return "$lhs $mhs $rhs";
135             }
136
137             ### bot->person reply.
138             # result is random if separated by '||'.
139             # rhs is full factoid with '||'.
140             if ($mhs eq "is") {
141                 $reply = &getRandom(keys %{$lang{'factoid'}});
142                 $reply =~ s/##KEY/$lhs/;
143                 $reply =~ s/##VALUE/$result/;
144             } else {
145                 $reply = "$lhs $mhs $result";
146             }
147
148             if ($reply =~ s/^\Q$who\E is/you are/i) {
149                 # fix the person.
150             } else {
151                 if ($reply =~ /^you are / or $reply =~ / you are /) {
152                     return if ($addressed);
153                 }
154             }
155         }
156     }
157
158     return $reply if ($literal);
159
160     # remove excessive beginning and end whitespaces.
161     $reply      =~ s/^\s+|\s+$//g;
162
163     if ($reply =~ /^\s+$/) {
164         &DEBUG("Reply: Null factoid ($message)");
165         return '';
166     }
167
168     return $reply unless ($reply =~ /\$/);
169
170     ###
171     ### $ SUBSTITUTION.
172     ###
173     
174     # $date, $time.
175     my $date    =  scalar(localtime());
176     $date       =~ s/\:\d+(\s+\w+)\s+\d+$/$1/;
177     $reply      =~ s/\$date/$date/gi;
178     $date       =~ s/\w+\s+\w+\s+\d+\s+//;
179     $reply      =~ s/\$time/$date/gi;
180
181     # dollar variables.
182     $reply      =~ s/\$nick/$who/g;
183     $reply      =~ s/\$who/$who/g;      # backward compat.
184     if ($reply =~ /\$(user(name)?|host)/) {
185         my ($username, $hostname) = split /\@/, $uh;
186         $reply  =~ s/\$user(name)?/$username/g;
187         $reply  =~ s/\$host(name)?/$hostname/g;
188     }
189     $reply      =~ s/\$chan(nel)?/$talkchannel/g;
190     if ($msgType =~ /public/) {
191         $reply  =~ s/\$lastspeaker/$lastWho{$talkchannel}/g;
192     } else {
193         $reply  =~ s/\$lastspeaker/$lastWho/g;
194     }
195
196     if ($reply =~ /\$rand/) {
197         my $rand  = rand();
198         my $randp = int($rand*100);
199         $reply =~ s/\$randpercentage/$randp/g;  # ???
200         # randnick.
201         if ($reply =~ /\$randnick/) {
202             my @nicks = keys %{$channels{$chan}{''}};
203             my $randnick = $nicks[ int($rand*$#nicks) ];
204             s/\$randnick/$randnick/;
205         }
206
207         ### TODO: number of digits. 'x.y'
208         if ($reply =~ /\$rand(\d+)/) {
209             # will this work as it does in C?
210             $rand = sprintf("%*f", $1, $rand);
211         }
212         $reply =~ s/\$rand/$rand/g;
213     }
214
215     $reply      =~ s/\$factoid/$lhs/g;
216     $reply      =~ s/\$ident/$ident/g;
217
218     if ($reply =~ /\$startTime/) {
219         my $time = scalar(localtime $^T);
220         $reply =~ s/\$startTime/$time/;
221     }
222
223     if ($reply =~ /\$uptime/) {
224         my $uptime = &Time2String(time() - $^T);
225         $reply =~ s/\$uptime/$uptime/;
226     }
227
228     if ($reply =~ /\$factoids/) {
229         my $count = &countKeys("factoids");
230         $reply =~ s/\$factoids/$factoids/;
231     }
232
233     if ($reply =~ /\$Fupdate/) {
234         my $x = "\002$count{'Update'}\002 ".
235                 &fixPlural("modification", $count{'Update'});
236         $reply =~ s/\$Fupdate/$x/;
237     }
238
239     if ($reply =~ /\$Fquestion/) {
240         my $x = "\002$count{'Question'}\002 ".
241                 &fixPlural("question", $count{'Question'});
242         $reply =~ s/\$Fquestion/$x/;
243     }
244
245     if ($reply =~ /\$Fdunno/) {
246         my $x = "\002$count{'Dunno'}\002 ".
247                 &fixPlural("dunno", $count{'Dunno'});
248         $reply =~ s/\$Fdunno/$x/;
249     }
250
251     $reply      =~ s/\$memusage/$memusage/;
252
253     $reply;
254 }
255
256 sub smart_replace {
257     my ($string) = @_;
258     my ($l,$r) = (0,0);         # l = left,  r = right.
259     my ($s,$t) = (0,0);         # s = start, t = marker.
260     my $i = 0;
261     my @rand;
262     my $old = $string;
263
264     foreach (split //, $string) {
265
266         if ($_ eq "(") {
267 ###         print "( l=>$l, r=>$r\n";
268
269             if (!$l and !$r) {
270 #               print "STARTING at $i\n";
271                 $s = $i;
272                 $t = $i;
273             }
274
275             $l++;
276             $r--;
277         }
278
279         if ($_ eq ")") {
280 ###         print ") l=>$l, r=>$r\n";
281
282             $r++;
283             $l--;
284
285             if (!$l and !$r) {
286                 my $substr = substr($old,$s,$i-$s+1);
287 #               print "STOP at $i $substr\n";
288                 push(@rand, substr($old,$t+1,$i-$t-1) );
289
290                 my $rand = $rand[rand @rand];
291                 &status("Reply.pl: SARing '$substr' to '$rand'.");
292                 $string =~ s/\Q$substr\E/$rand/;
293                 undef @rand;
294             }
295         }
296
297         if ($_ eq "|" and $l+$r== 0 and $l==1) {
298 #           print "| at $i (l=>$l,r=>$r)\n";
299             push(@rand, substr($old,$t+1,$i-$t-1) );
300             $t = $i;
301         }
302
303         $i++;
304     }
305
306     if ($old eq $string) {
307         &WARN("smart_replace: no subst made.");
308     }
309
310     return $string;
311 }
312
313
314 1;