+
+ # don't evaluate if it has factoid arguments.
+ # if ($message =~ /^cmd:/i) {
+ # &status("Reply: not doing substVars (eval dollar vars)");
+ # } else {
+ $reply = &substVars( $reply, 1 );
+
+ # }
+
+ $reply;
+}
+
+sub smart_replace {
+ my ($string) = @_;
+ my ( $l, $r ) = ( 0, 0 ); # l = left, r = right.
+ my ( $s, $t ) = ( 0, 0 ); # s = start, t = marker.
+ my $i = 0;
+ my $old = $string;
+ my @rand;
+
+ foreach ( split //, $string ) {
+
+ if ( $_ eq "(" ) {
+ if ( !$l and !$r ) {
+ $s = $i;
+ $t = $i;
+ }
+
+ $l++;
+ $r--;
+ }
+
+ if ( $_ eq ")" ) {
+ $r++;
+ $l--;
+
+ if ( !$l and !$r ) {
+ my $substr = substr( $old, $s, $i - $s + 1 );
+ push( @rand, substr( $old, $t + 1, $i - $t - 1 ) );
+
+ my $rand = $rand[ rand @rand ];
+
+ # &status("SARing '$substr' to '$rand'.");
+ $string =~ s/\Q$substr\E/$rand/;
+ undef @rand;
+ }
+ }
+
+ if ( $_ eq "|" and $l + $r == 0 and $l == 1 ) {
+ push( @rand, substr( $old, $t + 1, $i - $t - 1 ) );
+ $t = $i;
+ }
+
+ $i++;
+ }
+
+ if ( $old eq $string ) {
+ &WARN("smart_replace: no subst made. (string => $string)");
+ }
+
+ return $string;
+}
+
+sub SARit {
+ my ($txt) = @_;
+ my $done = 0;
+
+ # (blah1|blah2)?
+ while ( $txt =~ /\((.*?)\)\?/ ) {
+ my $str = $1;
+ if ( rand() > 0.5 ) { # fix.
+ &status("Factoid transform: keeping '$str'.");
+ $txt =~ s/\(\Q$str\E\)\?/$str/;
+ }
+ else { # remove
+ &status("Factoid transform: removing '$str'.");
+ $txt =~ s/\(\Q$str\E\)\?\s?//;
+ }
+ $done++;
+ last if ( $done >= 10 ); # just in case.
+ }
+ $done = 0;
+
+ # EG: (0-32768) => 6325
+ ### TODO: (1-10,20-30,40) => 24
+ while ( $txt =~ /\((\d+)-(\d+)\)/ ) {
+ my ( $lower, $upper ) = ( $1, $2 );
+ my $new = int( rand $upper - $lower ) + $lower;
+
+ &status("SARing '$&' to '$new' (2).");
+ $txt =~ s/$&/$new/;
+ $done++;
+ last if ( $done >= 10 ); # just in case.
+ }
+ $done = 0;
+
+ # EG: (blah1|blah2|blah3|) => blah1
+ while ( $txt =~ /.*\((.*\|.*?)\).*/ ) {
+ $txt = &smart_replace($txt);
+
+ $done++;
+ last if ( $done >= 10 ); # just in case.
+ }
+ &status("Reply.pl: $done SARs done.") if ($done);
+
+ # <URL></URL> type
+ #
+ while ( $txt =~ /<URL>(.*)<\/URL>/ ) {
+ &status("we have to norm this <URL></URL> stuff, SARing");
+ my $foobar = $1;
+ if ( $foobar =~ m/(http:\/\/[^?]+)\?(.*)/ ) {
+ my ( $pig1, $pig2 ) = ( $1, $2 );
+ &status("SARing using URLencode");
+ $pig2 =~ s/([^\w])/sprintf("%%%02x",ord($1))/gie;
+ $foobar = $pig1 . "?" . $pig2;
+ }
+ $txt =~ s/<URL>(.*)<\/URL>/$foobar/;
+ }
+ return $txt;
+}
+
+sub substVars {
+ my ( $reply, $flag ) = @_;
+
+ # $date, $time, $day.
+ # TODO: support localtime.
+ my $date = strftime( "%Y.%m.%d", gmtime() );
+ $reply =~ s/\$date/$date/gi;
+ my $time = strftime( "%k:%M:%S", gmtime() );
+ $reply =~ s/\$time/$time/gi;
+ my $day = strftime( "%A", gmtime() );
+ $reply =~ s/\$day/$day/gi;
+
+ # support $ident when I have multiple nicks
+ my $mynick = $conn->nick() if $conn;