Mercurial > hg > lolscript
view teh-lol.pl @ 35:cf9c8bd9a51b draft default tip @
update copyright year
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Fri, 14 Jul 2017 13:55:54 -0400 |
parents | c2e67df94367 |
children |
line wrap: on
line source
#Copyright © 2009 - 2017 Jordi Gutiérrez Hermoso <jordigh@octave.org> # #teh-lol.pl is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation, either version 3 of the License, or #(at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program. If not, see <http://www.gnu.org/licenses/>. use strict; Xchat::register('teh lol', '1.0.0', 'lols back'); #Check if it's time to relol Xchat::hook_print('Channel Message', \&check_lol); Xchat::hook_print('Your Message', \&update_tstamp); #Report lol combos Xchat::hook_print('Channel Message', \&check_combo); Xchat::hook_print('Channel Msg Hilight', \&check_combo); Xchat::hook_print('Your Message', \&check_combo); my %timestamp; sub update_tstamp{ my @xchat_args = @{$_[0]}; my $msg = $xchat_args[1]; if( $msg =~ /^lol/ ){ my $chan = Xchat::get_info("channel"); $timestamp{$chan} = time; } return Xchat::EAT_NONE; } my @no_lol_list; if (open FILE, $ENV{"HOME"}."/.xchat2/no-lol") { while (<FILE>) { chomp; push @no_lol_list, $_; } close(FILE); } ## Advanced lollists have attempted alternative lols, so let's catch ## those too. my $l = "[lI1|]"; my $o = "[oо0]"; # | counts as a word boundary, so now we need generalised word # boundaries to exclude | my $b = "(?:\b|\|)"; sub check_lol { my @xchat_args = @{$_[0]}; my $chatter = $xchat_args[0]; my $msg = $xchat_args[1]; my $chan = Xchat::get_info("channel"); my $timesince_lasttalk = time - Xchat::user_info -> {'lasttalk'}; ## Chatter name without possible colour codes $chatter = Xchat::strip_code($chatter); ## Match stuff like "lol", "loool" and "lololol". Also mimic ## punctuation. if ($msg =~ /$b( ## Starting l, capture it in $1 $l ## either a single "o" or an "o" followed by a bunch ## of "lolo", capture it in $2 ((?:$o|(?<!$l)$l$o)+) ## closing l $l) ## Final punctuation or word boundary, capture it in $3 ([\.!?]+|$b) /ix #Two minutes of not saying anything in the channel counts as #idling, so don't pester when idling. and $timesince_lasttalk < 120 #Enemies of the lols are abusing the lol, no lols for them. and not grep(/$chatter/, @no_lol_list) ) { my $lol = $1; my $midlol = $2; my $endlol = $3; my $relol; #Mimic long lols, with same punctuation and capitalisation if (length $lol > 3) { ## Why can't I just plain index Perl strings like in Python? ## Gotta turn them into arrays first. :-( my @lol = split(//, $lol); my @midlol = split(//, $midlol); ## For maximum lolitude, randomly exaggerate long lols my $repeat_mid = int rand(3)+1; $relol = $lol[0].$midlol[0]; for(my $i = 0; $i < $repeat_mid; $i++) { $relol .= join("", @midlol[1..$#midlol]); } $relol .= $lol[$#lol].$endlol; } else { $relol = $lol.$endlol; } #Don't lol more than once in 30 minutes. if ( time - $timestamp{$chan} > 1800 or not defined $timestamp{$chan} ) { #Delay the response a little, for maximum annoyance. #( theoros's algorithm from #not-math ) my $delay = 1.8; if (length($relol) > 3){ $delay += ((length $relol) - 3 + rand(5)) * 0.069; } #Convert to milliseconds. $delay *= 1e3; Xchat::hook_timer($delay, sub { Xchat::command("say $relol"); return Xchat::REMOVE; } ); } $timestamp{$chan} = time; } return Xchat::EAT_NONE; } my $prev_msg = ""; my %combo_count; my %prev_loller; sub check_combo { my $chan = Xchat::get_info("channel"); my $loller = $_[0][0]; my $msg = $_[0][1]; my $nick = Xchat::get_info("nick"); ## Allow "lol stuff" and e.g. "JordiGH: lol stuff" to be part of a ## lolcombo my $islol = $msg =~ /^\s*($nick.?\s*)?$l(($o|(?<!$l)$l$o)+)$l$b/i; if(not $islol) { my $combo = $combo_count{$chan}; # We have a combo to report! if($combo > 2) { my $qualifier; if($combo == 3) { $qualifier = "Good"; } elsif ($combo > 3 and $combo <= 5) { $qualifier = "Great"; } elsif ($combo > 5 and $combo <= 10) { $qualifier = "Marvelous"; } else { $qualifier = "M-M-M-MONSTER COMBO!"; } my $report = "$combo-lol combo! $qualifier!"; my $delay = (rand(3) + 1)*1e3; Xchat::hook_timer($delay, sub { Xchat::command("say $report"); return Xchat::REMOVE; } ); } $combo_count{$chan} = 0; $prev_loller{$chan} = ""; } else { #A loller trying to cheat ruins the combo for everyone if( $loller eq $prev_loller{$chan}) { $combo_count{$chan} = 0; } else { $combo_count{$chan}++; } $prev_loller{$chan} = $loller; } return Xchat::EAT_NONE; } # lolololol # lol # loooooooool