1use strict; 2use Irssi 20020101.0250 (); 3use vars qw($VERSION %IRSSI); 4$VERSION = "2.1"; 5%IRSSI = ( 6 authors => "Timo Sirainen, Ian Peters, David Leadbeater, Bruno Cattáneo", 7 contact => "tss\@iki.fi", 8 name => "Nick Color", 9 description => "assign a different color for each nick", 10 license => "Public Domain", 11 url => "http://irssi.org/", 12 changed => "Mon 08 Jan 21:28:53 BST 2018", 13); 14 15# Settings: 16# nickcolor_colors: List of color codes to use. 17# e.g. /set nickcolor_colors 2 3 4 5 6 7 9 10 11 12 13 18# (avoid 8, as used for hilights in the default theme). 19# 20# nickcolor_enable_prefix: Enables prefix for same nick. 21# 22# nickcolor_enable_truncate: Enables nick truncation. 23# 24# nickcolor_prefix_text: Prefix text for succesive messages. 25# e.g. /set nickcolor_prefix_text - 26# 27# nickcolor_truncate_value: Truncate nick value. 28# e.g. /set nickcolor_truncate_value -7 29# This will truncate nicknames at 7 characters and make them right aligned 30 31my %saved_colors; 32my %session_colors = {}; 33my %saved_nicks; # To store each channel's last nickname 34 35sub load_colors { 36 open my $color_fh, "<", "$ENV{HOME}/.irssi/saved_colors"; 37 while (<$color_fh>) { 38 chomp; 39 my($nick, $color) = split ":"; 40 $saved_colors{$nick} = $color; 41 } 42} 43 44sub save_colors { 45 open COLORS, ">", "$ENV{HOME}/.irssi/saved_colors"; 46 47 foreach my $nick (keys %saved_colors) { 48 print COLORS "$nick:$saved_colors{$nick}\n"; 49 } 50 51 close COLORS; 52} 53 54# If someone we've colored (either through the saved colors, or the hash 55# function) changes their nick, we'd like to keep the same color associated 56# with them (but only in the session_colors, ie a temporary mapping). 57 58sub sig_nick { 59 my ($server, $newnick, $nick, $address) = @_; 60 my $color; 61 62 $newnick = substr ($newnick, 1) if ($newnick =~ /^:/); 63 64 if ($color = $saved_colors{$nick}) { 65 $session_colors{$newnick} = $color; 66 } elsif ($color = $session_colors{$nick}) { 67 $session_colors{$newnick} = $color; 68 } 69} 70 71# This gave reasonable distribution values when run across 72# /usr/share/dict/words 73 74sub simple_hash { 75 my ($string) = @_; 76 chomp $string; 77 my @chars = split //, $string; 78 my $counter; 79 80 foreach my $char (@chars) { 81 $counter += ord $char; 82 } 83 84 my @colors = split / /, Irssi::settings_get_str('nickcolor_colors'); 85 $counter = $colors[$counter % @colors]; 86 87 return $counter; 88} 89 90# process public (others) messages 91sub sig_public { 92 my ($server, $msg, $nick, $address, $target) = @_; 93 94 my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); 95 my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate'); 96 my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text'); 97 my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value'); 98 99 # Reference for server/channel 100 my $tagtarget = "$server->{tag}/$target"; 101 102 # Set default nick truncate value to 0 if option is disabled 103 $truncate_value = 0 if (!$enable_truncate); 104 105 # Has the user assigned this nick a color? 106 my $color = $saved_colors{$nick}; 107 108 # Have -we- already assigned this nick a color? 109 if (!$color) { 110 $color = $session_colors{$nick}; 111 } 112 113 # Let's assign this nick a color 114 if (!$color) { 115 $color = simple_hash $nick; 116 $session_colors{$nick} = $color; 117 } 118 119 $color = sprintf "\003%02d", $color; 120 121 # Optional: We check if it's the same nickname for current target 122 if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix) 123 { 124 # Grouped message 125 Irssi::command('/^format pubmsg ' . $prefix_text . '$1'); 126 } 127 else 128 { 129 # Normal message 130 Irssi::command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$[' . $truncate_value . ']0}}$1'); 131 132 # Save nickname for next message 133 $saved_nicks{$tagtarget} = $nick; 134 } 135 136} 137 138# process public (me) messages 139sub sig_me { 140 my ($server, $msg, $target) = @_; 141 my $nick = $server->{nick}; 142 143 my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); 144 my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate'); 145 my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text'); 146 my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value'); 147 148 # Reference for server/channel 149 my $tagtarget = "$server->{tag}/$target"; 150 151 # Set default nick truncate value to 0 if option is disabled 152 $truncate_value = 0 if (!$enable_truncate); 153 154 # Optional: We check if it's the same nickname for current target 155 if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix) 156 { 157 # Grouped message 158 Irssi::command('/^format own_msg ' . $prefix_text . '$1'); 159 } 160 else 161 { 162 # Normal message 163 Irssi::command('/^format own_msg {ownmsgnick $2 {ownnick $[' . $truncate_value . ']0}}$1'); 164 165 # Save nickname for next message 166 $saved_nicks{$tagtarget} = $nick; 167 } 168 169} 170 171# process public (others) actions 172sub sig_action_public { 173 my ($server, $msg, $nick, $address, $target) = @_; 174 175 my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); 176 177 # Reference for server/channel 178 my $tagtarget = "$server->{tag}/$target"; 179 180 # Empty current target nick if prefix option is enabled 181 $saved_nicks{$tagtarget} = '' if ($enable_prefix); 182 183} 184 185# process public (me) actions 186sub sig_action_me { 187 my ($server, $msg, $target) = @_; 188 my $nick = $server->{nick}; 189 190 my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); 191 192 # Reference for server/channel 193 my $tagtarget = "$server->{tag}/$target"; 194 195 # Empty current target nick if prefix option is enabled 196 $saved_nicks{$tagtarget} = '' if ($enable_prefix); 197 198} 199 200sub cmd_color { 201 my ($data, $server, $witem) = @_; 202 my ($op, $nick, $color) = split " ", $data; 203 204 $op = lc $op; 205 206 if (!$op) { 207 Irssi::print ("No operation given (save/set/clear/list/preview)"); 208 } elsif ($op eq "save") { 209 save_colors; 210 } elsif ($op eq "set") { 211 if (!$nick) { 212 Irssi::print ("Nick not given"); 213 } elsif (!$color) { 214 Irssi::print ("Color not given"); 215 } elsif ($color < 2 || $color > 14) { 216 Irssi::print ("Color must be between 2 and 14 inclusive"); 217 } else { 218 $saved_colors{$nick} = $color; 219 } 220 } elsif ($op eq "clear") { 221 if (!$nick) { 222 Irssi::print ("Nick not given"); 223 } else { 224 delete ($saved_colors{$nick}); 225 } 226 } elsif ($op eq "list") { 227 Irssi::print ("\nSaved Colors:"); 228 foreach my $nick (keys %saved_colors) { 229 Irssi::print (chr (3) . sprintf("%02d", $saved_colors{$nick}) . "$nick" . 230 chr (3) . "1 ($saved_colors{$nick})"); 231 } 232 } elsif ($op eq "preview") { 233 Irssi::print ("\nAvailable colors:"); 234 foreach my $i (2..14) { 235 Irssi::print (chr (3) . "$i" . "Color #$i"); 236 } 237 } 238} 239 240load_colors; 241 242Irssi::settings_add_str('misc', 'nickcolor_colors', '2 3 4 5 6 7 9 10 11 12 13'); 243Irssi::settings_add_bool('misc', 'nickcolor_enable_prefix', 0); 244Irssi::settings_add_bool('misc', 'nickcolor_enable_truncate', 0); 245Irssi::settings_add_str('misc', 'nickcolor_prefix_text' => '- '); 246Irssi::settings_add_int('misc', 'nickcolor_truncate_value' => 0); 247Irssi::command_bind('color', 'cmd_color'); 248 249Irssi::signal_add('message public', 'sig_public'); 250Irssi::signal_add('message own_public', 'sig_me'); 251Irssi::signal_add('message irc action', 'sig_action_public'); 252Irssi::signal_add('message irc own_action', 'sig_action_me'); 253Irssi::signal_add('event nick', 'sig_nick'); 254