#!/usr/bin/perl # # by Szymon Sokol # ideas taken from BabelIRC by Stefan Tomanek # use strict; use locale; use utf8; use Irssi 20020324; use Irssi::TextUI; use POSIX; use Data::Dumper; use vars qw($VERSION %IRSSI %HELP %channels %translations); $VERSION = '2019071201'; %IRSSI = ( authors => 'Szymon Sokol', contact => '[email protected]', name => 'mangle', description => 'translates your messages into Morse code, rot13 and other sillinesses.', sbitems => 'mangle_sb', license => 'GPLv2', url => 'http://irssi.org/scripts/', changed => $VERSION, modules => 'Data::Dumper' ); # To work, this help requires scripthelp.pl by Maciek 'fahren' Freudenheim $HELP{"mangle add"} = "/mangle add [] Add a new translation entry for (default is current channel)"; $HELP{"mangle del"} = "/mangle del [] Removes the translation for (default is current channel)"; $HELP{"mangle say"} = "/mangle say Says something to the current channel using given translation"; $HELP{"mangle load"} = "/mangle load Loads translations from file"; $HELP{"mangle save"} = "/mangle save Saves active translations to file"; $HELP{"mangle show"} = "/mangle show Shows active translations"; $HELP{"mangle list"} = "/mangle list Lists available translations"; # the endless possibilities for extensions here %translations = ( # CChheecckk yyoouurr dduupplleexx sswwiittcchh "duplex" => sub { my ($text) = @_; $text =~ s/./$&$&/g; return $text; }, # TaLk LiKe ThIs - EvErY OtHeR LeTtEr Is UpPeRcAse "funky" => sub { my ($text) = @_; $text =~ s/(\w.)/\u$1/g; return $text; }, # TalkLikeThis-NoSpaces,WordBeginsWithUppercase "gnome" => sub { my ($text) = @_; $text =~ s/\b(\w)/\u$1/g; $text =~ s/\s+//g; return $text; }, # ds mangle by blap - double strike mathematical symbols "ds" => sub { my %ds = ( "A" => "𝔸", "B" => "𝔹", "C" => "â„‚", "D" => "𝔻", "E" => "𝔼", "F" => "𝔽", "G" => "𝔾", "H" => "ℍ", "I" => "𝕀", "J" => "𝕁", "K" => "𝕂", "L" => "𝕃", "M" => "𝕄", "N" => "â„•", "O" => "𝕆", "P" => "â„™", "Q" => "â„š", "R" => "ℝ", "S" => "𝕊", "T" => "𝕋", "U" => "𝕌", "V" => "𝕍", "W" => "𝕎", "X" => "𝕏", "Y" => "𝕐", "Z" => "ℤ", "a" => "𝕒", "b" => "𝕓", "c" => "𝕔", "d" => "𝕕", "e" => "𝕖", "f" => "𝕗", "g" => "𝕘", "h" => "𝕙", "i" => "𝕚", "j" => "𝕛", "k" => "𝕜", "l" => "𝕝", "m" => "𝕞", "n" => "𝕟", "o" => "𝕠", "p" => "𝕡", "q" => "𝕢", "r" => "𝕣", "s" => "𝕤", "t" => "𝕥", "u" => "𝕦", "v" => "𝕧", "w" => "𝕨", "x" => "𝕩", "y" => "𝕪", "z" => "𝕫", "0" => "𝟘", "1" => "𝟙", "2" => "𝟚", "3" => "𝟛", "4" => "𝟜", "5" => "𝟝", "6" => "𝟞", "7" => "𝟟", "8" => "𝟠", "9" => "𝟡" ); my ($text) = @_; $text =~ s/./defined $ds{$&} ? $ds{$&} : "$&"/eg; return $text; }, # curs cursive by blap - cursive (bold) script "curs" => sub { my %curs = ( "A" => "𝓐", "B" => "𝓑", "C" => "𝓒", "D" => "𝓓", "E" => "𝓔", "F" => "𝓕", "G" => "𝓖", "H" => "𝓗", "I" => "𝓘", "J" => "𝓙", "K" => "𝓚", "L" => "𝓛", "M" => "𝓜", "N" => "𝓝", "O" => "𝓞", "P" => "𝓟", "Q" => "𝓠", "R" => "𝓡", "S" => "𝓢", "T" => "𝓣", "U" => "𝓤", "V" => "𝓥", "W" => "𝓦", "X" => "𝓧", "Y" => "𝓨", "Z" => "𝓩", "a" => "𝓪", "b" => "𝓫", "c" => "𝓬", "d" => "𝓭", "e" => "𝓮", "f" => "𝓯", "g" => "𝓰", "h" => "𝓱", "i" => "𝓲", "j" => "𝓳", "k" => "𝓴", "l" => "𝓵", "m" => "𝓶", "n" => "𝓷", "o" => "𝓸", "p" => "𝓹", "q" => "𝓺", "r" => "𝓻", "s" => "𝓼", "t" => "𝓽", "u" => "𝓾", "v" => "𝓿", "w" => "𝔀", "x" => "𝔁", "y" => "𝔂", "z" => "𝔃" ); my ($text) = @_; $text =~ s/./defined $curs{$&} ? $curs{$&} : "$&"/eg; return $text; }, # vapor double-width by blap - 'vaporwave' script "vapor" => sub { my %vapor = ( " " => " ", "A" => "A", "B" => "ï¼¢", "C" => "ï¼£", "D" => "D", "E" => "ï¼¥", "F" => "F", "G" => "G", "H" => "H", "I" => "I", "J" => "J", "K" => "K", "L" => "L", "M" => "ï¼­", "N" => "ï¼®", "O" => "O", "P" => "ï¼°", "Q" => "ï¼±", "R" => "ï¼²", "S" => "ï¼³", "T" => "ï¼´", "U" => "ï¼µ", "V" => "V", "W" => "ï¼·", "X" => "X", "Y" => "ï¼¹", "Z" => "Z", "a" => "a", "b" => "b", "c" => "c", "d" => "d", "e" => "ï½…", "f" => "f", "g" => "g", "h" => "h", "i" => "i", "j" => "j", "k" => "k", "l" => "l", "m" => "m", "n" => "n", "o" => "o", "p" => "p", "q" => "q", "r" => "ï½’", "s" => "s", "t" => "ï½”", "u" => "u", "v" => "ï½–", "w" => "ï½—", "x" => "x", "y" => "ï½™", "z" => "z", "0" => "0", "1" => "1", "2" => "ï¼’", "3" => "3", "4" => "ï¼”", "5" => "5", "6" => "ï¼–", "7" => "ï¼—", "8" => "8", "9" => "ï¼™", '[' => 'ï¼»', ']' => 'ï¼½', '{' => 'ï½›', '}' => '}', '(' => '(', ')' => ')', '.' => '.', ',' => ',', '?' => '?', '!' => '!', '"' => chr(65282), '\'' => ''', '#' => '#', '$' => '$', '%' => 'ï¼…', '^' => 'ï¼¾', '&' => '&', '=' => '=', '\\' => 'ï¼¼', '/' => '/', '`' => 'ï½€' ); my ($text) = @_; $text =~ s/./defined $vapor{$&} ? $vapor{$&} : "$&"/eg; return $text; }, # blox cypher by blap "blox" => sub { my %blox = ( "a" => "â–ž", "b" => "▍", "c" => "â–Ž", "d" => "â–…", "e" => "â–ƒ", "f" => "â–š", "g" => "â—¼", "h" => "â–‡", "i" => "â–˜", "j" => "â–›", "k" => "┫", "l" => "â–‹", "m" => "â–†", "n" => "▝", "o" => "â–œ", "p" => "â–ˆ", "q" => "▁", "r" => "â–„", "s" => "â–œ", "t" => "â–€", "u" => "â–Œ", "v" => "â––", "w" => "â–™", "x" => "â–‚", "y" => "â–—", "z" => "â–Ÿ", "0" => "â–Š", "1" => "▐", "2" => "â–”", "3" => "â–’", "4" => "▏", "5" => "â–‘", "6" => "â–²", "7" => "┣", "8" => "â–“", "9" => "â–¼" ); my ($text) = @_; $text = lc($text); $text =~ s/./defined $blox{$&} ? $blox{$&} : "$&"/eg; return "╳".$text; }, "morse" => sub { my %morse = ( " " => "", "a" => ".-", "b" => "-...", "c" => "-.-.", "d" => "-..", "e" => ".", "f" => "..-.", "g" => "--.", "h" => "....", "i" => "..", "j" => ".---", "k" => "-.-", "l" => ".-..", "m" => "--", "n" => "-.", "o" => "---", "p" => ".--.", "q" => "--.-", "r" => ".-.", "s" => "...", "t" => "-", "u" => "..-", "v" => "...-", "w" => ".--", "x" => "-..-", "y" => "-.--", "z" => "--..", # notice: Polish and German diacritical characters have their own # Morse codes; the same probably stands true for other languages # using ISO-8859-2 - if you happen to know them, please send me e-mail "±" => ".-.-", "æ" => "-.-..", "ê" => "..-..", "³" => ".-..-", "ñ" => "--.-", "ó" => "---.". "¶" => "...-...", "¼" => "--..", "¿" => "--..-", 'ä'=>'.-.-', 'ö'=>'---.', 'ü'=>'..--', "0" => "-----", "1" => ".----", "2" => "..---", "3" => "...--", "4" => "....-", "5" => ".....", "6" => "-....", "7" => "--...", "8" => "---..", "9" => "----.", "'" => ".----.", '"' => ".-..-.", '.' => ".-.-.-", ',' => "--..--", '?' => "..--..", ':' => "---...", ';' => "-.-.-.", '-' => "-....-", '_' => "..--.-", '/' => "-..-.", '(' => "-.--.", ')' => "-.--.-", '@' => ".--.-.", # byFlorian Ernst '=' => "-...-" ); my ($text) = @_; $text = lc($text); $text =~ s/./defined $morse{$&} ? $morse{$&}." " : ""/eg; return $text.'[morse]'; }, # Fraktur font by blap "frakt" => sub { my %HoA = ( 'a' => ["𝖆"], 'b' => ["𝖇"], 'c' => ["𝖈"], 'd' => ["𝖉"], 'e' => ["𝖊"], 'f' => ["𝖋"], 'g' => ["𝖌"], 'h' => ["𝖍"], 'i' => ["𝖎"], 'j' => ["𝖏"], 'k' => ["𝖐"], 'l' => ["𝖑"], 'm' => ["𝖒"], 'n' => ["𝖓"], 'o' => ["𝖔"], 'p' => ["𝖕"], 'q' => ["𝖖"], 'r' => ["𝖗"], 's' => ["𝖘"], 't' => ["𝖙"], 'u' => ["𝖚"], 'v' => ["𝖛"], 'w' => ["𝖜"], 'x' => ["𝖝"], 'y' => ["𝖞"], 'z' => ["𝖟"], 'A' => ["𝕬"], 'B' => ["𝕭"], 'C' => ["𝕮"], 'D' => ["𝕯"], 'E' => ["𝕰"], 'F' => ["𝕱"], 'G' => ["𝕲"], 'H' => ["𝕳"], 'I' => ["𝕴"], 'J' => ["𝕵"], 'K' => ["𝕶"], 'L' => ["𝕷"], 'M' => ["𝕸"], 'N' => ["𝕹"], 'O' => ["𝕺"], 'P' => ["𝕻"], 'Q' => ["𝕼"], 'R' => ["𝕽"], 'S' => ["𝕾"], 'T' => ["𝕿"], 'U' => ["𝖀"], 'V' => ["𝖁"], 'W' => ["𝖂"], 'X' => ["𝖃"], 'Y' => ["𝖄"], 'Z' => ["𝖅"] ); my ($text) = @_; $text =~ s/./defined $HoA{$&} ? $HoA{$&}[rand(@{$HoA{$&}})] : "$&"/eg; return $text; }, # Unicode Obfusticator by blap "obfus" => sub { my %HoA = ( '0' => ["Ó¨","Ὀ","á»’","á»”","Θ","Ç‘","ÈŽ","Ï´","Ã’","Õ","Ô","Ǿ"], '1' => ["Ĭ","Ἰ","Ī","Ó€","Ί","Ι","І","Ї","Ῐ","á¿™","á¿š"], '2' => ["Æ»","ƨ"], '3' => ["Æ·","Ó ","Ò˜","Ò™","Óž","з","Õ…","З","ɝ"], '4' => ["Ч"], '5' => ["Ƽ"], '6' => ["ǝ","É™"], '7' => ["7"], '8' => ["Õ‘"], '9' => ["9"], 'a' => ["á¼…","ἁ","ẚ","Ó“","á½±","á¾·","ᾶ","á¾±","ÇŽ","ÇŸ","ά","É‘"], 'b' => ["ƃ","Æ…","þ","ḃ","ḅ","ḇ","ϸ","É“"], 'c' => ["Ä‹","ć","ƈ","â…½","Ï›","ç","Ï‚","ϲ"], 'd' => ["ÆŒ","ḑ","â…¾","ḋ","ḍ","ḏ","Õª","É—","É–"], 'e' => ["Ñ‘","Ä—","ệ","ѳ","ḕ","ḝ","è","ê","ϱ","È©","ε"], 'f' => ["Ò“","Æ’","Å¿","ẛ","ϝ","ḟ"], 'g' => ["ÄŸ","Ä£","É¡","Ç¥","ǧ","ց","Õ£","ǵ","ḡ","É•"], 'h' => ["Ä¥","Ò»","ẖ","ɧ","ɦ","Õ«","ḩ","ḫ","Õ°"], 'i' => ["Ä©","Ä«","á¼²","É©","¡","í","ì","ΐ","ί","ι","ḭ"], 'j' => ["ј","ĵ","ʝ","È·","Ç°","Õµ"], 'k' => ["ҝ","Æ™","ĸ","Ä·","к","ḱ","ḳ","κ"], 'l' => ["Å‚","Å€","Æš","ľ","ĺ","É«","Ç€","É­","ɬ","ḻ","ḽ"], 'm' => ["â‚¥","ṃ","ṁ","ɱ","ḿ"], 'n' => ["Æž","ἤ","á¹…","á½µ","ñ","É´","á¾—","ᾕ","á¾”","ῇ","Õ¼","Õ²"], 'o' => ["á»›","ở","ὁ","ŏ","ō","Æ¡","ὸ","á½¹","ó","ò","ʘ","È«"], 'p' => ["Ñ€","ҏ","á¹—","ṕ","ῤ","á¿¥","þ","Õ©"], 'q' => ["Ô›","Ê ","Õ¦","Õ£"], 'r' => ["Å—","Å•","Ñ“","Ó·","г","È‘","ɽ","ɼ"], 's' => ["ÅŸ","Å›","ṧ","á¹£","Ô‘","Å¡","Ê‚"], 't' => ["†","ṫ","Å¥","È›","Õ’","ȶ","ʈ"], 'u' => ["Æ°","á¹»","á¹³","ů","Å«","ụ","ủ","ù","µ","Çœ","Çš"], 'v' => ["ṿ","ὐ","á½—","á½”","á½»","ѵ","Ò¯","á¿ ","á¿¢","â…´","ΰ"], 'w' => ["ԝ","ẉ","ẃ","ẁ","ŵ","ẇ","ẅ"], 'x' => ["ẋ","Ò³","ẍ","Ï°"], 'y' => ["у","Æ´","Ó¯","Ñž","ỹ","ỵ","á»·","ẙ","ÿ"], 'z' => ["ƶ","ž","ż","ź","ẓ","ẑ","Ê‘"], 'A' => ["Ẩ","Ậ","Ä„","Ἆ","Ӑ","á¾»","á¾¹","Α","Ⱥ","Ã","ᾉ","ᾈ"], 'B' => ["Ɓ","Ḃ","Ḅ","Î’","Ð’"], 'C' => ["ÄŒ","Ĉ","Ć","₵","Òª","Ͼ","Ç"], 'D' => ["Đ","ÆŠ","Ɖ","Ḓ","Ḋ","Ḍ","Ḏ","Ð"], 'E' => ["Ẹ","Ę","Ẽ","Ä”","Ệ","Ɛ","Ԑ","Ḗ","Ḝ","Ὲ","Ȩ"], 'F' => ["Ò’","Æ‘","â‚£","ϝ","Ïœ"], 'G' => ["Äœ","Äž","Ä ","Ä¢","Ǥ","Ḡ","Ç´"], 'H' => ["Ĥ","Ó‡","Ò¤","Ò¢","Èž","Н","Ḥ","Ḫ"], 'I' => ["Ỉ","á¼¹","Ī","Ä°","Ȉ","ÈŠ","Ι","Í","Ḭ","á¿š","Ḯ"], 'J' => ["Ä´","ʆ","Ј"], 'K' => ["â‚­","Ƙ","Ķ","Κ","Ḱ","Ḳ","Ḵ","К","ÐŒ"], 'L' => ["Ł","Ľ","â…¬","Ḷ","Ḹ","Ḻ","â„’"], 'M' => ["Ӎ","Ṃ","á¹€","Îœ","Ðœ","Ḿ"], 'N' => ["Ň","Å…","Ń","₦","Ṋ","Ṉ","Ñ","Ǹ"], 'O' => ["Óª","Ờ","á»”","Ọ","Θ","Ø","Ã’","Õ","Ȭ","È®"], 'P' => ["Ƥ","ÒŽ","á¹–","á¹”","₱","Ῥ","Ρ"], 'Q' => ["Ôš"], 'R' => ["Ř","Å–","Å”","Ṟ","Ṙ","Ȑ"], 'S' => ["ÏŸ","Åž","Åœ","á¹ ","Å ","Ș","Տ"], 'T' => ["á¹°","á¹®","Ṫ","Æ®","Ŧ","Å¢","Т","Τ","á¿›"], 'U' => ["á»°","Ų","Ứ","Ử","Ũ","È”","È–","Ç•","Ç—","Ç›","Û","Ú"], 'V' => ["á¹¾","á¹¼","Ѷ","⋁","â…¤"], 'W' => ["Ôœ","Ẉ","Ẃ","Ẁ","Å´","Ẇ","Ẅ"], 'X' => ["Ẋ","Ò²","Ẍ","Ð¥","Χ"], 'Y' => ["Ỹ","Ẏ","Ò°","Ÿ","Ỳ","á»´","Â¥","Ï“","Ȳ","Î¥"], 'Z' => ["Ž","Å»","Ź","Ẓ","Ζ","Ȥ"], ); my ($text) = @_; $text =~ s/./defined $HoA{$&} ? $HoA{$&}[rand(@{$HoA{$&}})] : "$&"/eg; return $text; }, # convert text in Polish from ISO-8859-2 to 7-bit approximation # if you know how to do it for other languages using 8859-2, # please let me know "polskawe" => sub { my ($text) = @_; $text =~ y/¡ÆÊ£ÑÓ¦¯¬±æê³ñ󶿼/ACELNOSZZacelnoszz/; return $text; }, # Ouch, my eyes! "rainbow" => sub { my ($text) = @_; # colors list # 0 == white # 4 == light red # 8 == yellow # 9 == light green # 11 == light cyan # 12 == light blue # 13 == light magenta my @colors = ('00','04','08','09','11','12','13'); my $color; $text = join '', map { push @colors, $color = shift @colors; "\003" . $color . ($_ eq "," ? ",," : $_) } split(//,$text); return $text; }, # .drawkcab klaT "reverse" => sub { my ($text) = @_; $text = scalar reverse $text; return $text; }, # Gnyx va ebg13 rapbqvat. "rot13" => sub { my ($text) = @_; $text =~ y/N-ZA-Mn-za-m/A-Za-z/; return $text.' [rot13]'; }, # T-T-Talk l-l-like y-y-you h-h-have a s-s-stutter. "stutter" => sub { my ($text) = @_; $text =~ s/(\w)(\w+)/$1-$1-$1$2/g; return $text; }, # rmv vwls "vowels" => sub { my ($text) = @_; $text =~ y/aeiouy±ê//d; return $text; } ); sub add_channel ($$) { my ($channel,$code) = @_; $channels{$channel} = $code; } sub save_channels { my $filename = Irssi::settings_get_str('mangle_filename'); my $fo; open $fo, '>',$filename; my $data = Dumper(\%channels); print $fo $data; close $fo; print CLIENTCRAP "%R>>%n Mangle channels saved"; } sub load_channels { my $filename = Irssi::settings_get_str('mangle_filename'); return unless (-e $filename); my $fi; open $fi, '<',$filename; my $text; $text .= $_ foreach <$fi>; #no strict "vars"; my $VAR1; eval "$text"; %channels = %$VAR1; } sub mangle_show ($$) { my ($item, $get_size_only) = @_; my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active}; if (ref $win && ($win->{type} eq "CHANNEL" || $win->{type} eq "QUERY") && $channels{$win->{name}}) { my $code = $channels{$win->{name}}; $item->{min_size} = $item->{max_size} = length($code); $code = '%U%g'.$code.'%U%n'; my $format = "{sb ".$code."}"; $item->default_handler($get_size_only, $format, 0, 1); } else { $item->{min_size} = $item->{max_size} = 0; } } sub cmd_mangle ($$$) { my ($args, $server, $witem) = @_; my @arg = split(/ +/, $args); if ($arg[0] eq 'add' && defined $arg[1]) { my $code = $arg[1]; if(exists $translations{$code}) { if (defined $arg[2]) { add_channel($arg[2], $code); } elsif($witem) { add_channel($witem->{name}, $code); } } else { Irssi::print("There is no such translation as $code !"); } } elsif ($arg[0] eq 'del') { if(defined $arg[1]) { delete $channels{$arg[1]} if defined $channels{$arg[1]}; } elsif($witem) { delete $channels{$witem->{name}} if defined $channels{$witem->{name}}; } } elsif ($arg[0] eq 'say' && defined $arg[1]) { my $code = $arg[1]; if(exists $translations{$code}) { if($witem) { say($code, join(' ',@arg[2..$#arg]), $server, $witem); } } else { Irssi::print("There is no such translation as $code !"); } } elsif ($arg[0] eq 'save') { save_channels(); } elsif ($arg[0] eq 'load') { load_channels(); } elsif ($arg[0] eq 'list') { Irssi::print("mangle: available translations are: ". join(" ", sort keys %translations)); } elsif ($arg[0] eq 'show') { for (sort keys %channels) { Irssi::print("mangle: ".$_." set to ".$channels{$_}); } } else { Irssi::print("mangle v. $VERSION; use /help mangle for help (ensure you have scripthelp.pl loaded!)"); } Irssi::statusbar_items_redraw('mangle_sb'); } sub say ($$$$) { my ($code, $line, $server, $witem) = @_; my $target = ""; if ($line =~ s/^(\w+?: )//) { $target = $1; } $line = $translations{$code}->($line); $server->command('MSG '.$witem->{name}.' '.$target.$line); } sub event_send_text ($$$) { my ($line, $server, $witem) = @_; return unless ($witem && ($witem->{type} eq "CHANNEL" || $witem->{type} eq "QUERY") && $channels{$witem->{name}}); say($channels{$witem->{name}}, $line, $server, $witem); Irssi::signal_stop(); Irssi::statusbar_items_redraw('mangle_sb'); } # main Irssi::command_bind('mangle', \&cmd_mangle); foreach my $cmd ('add', 'del', 'save', 'load', 'say', 'list', 'show') { Irssi::command_bind('mangle '.$cmd => sub { cmd_mangle($cmd." ".$_[0], $_[1], $_[2]); }); } Irssi::statusbar_item_register('mangle_sb', 0, "mangle_show"); Irssi::signal_add('setup saved', 'save_channels'); Irssi::signal_add('send text', \&event_send_text); Irssi::signal_add('window changed', sub {Irssi::statusbar_items_redraw('mangle_sb');}); Irssi::settings_add_str($IRSSI{name}, 'mangle_filename', Irssi::get_irssi_dir()."/mangle_channels"); load_channels(); print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /help mangle for help'; # ;-)