1# created for irssi 0.7.98, Copyright (c) 2000 Timo Sirainen
2
3# Are you ever tired of those people who keep changing their nicks?
4# Or maybe you just don't like someone's nick?
5# This script lets you see them with the real nick all the time no matter
6# what nick they're currently using.
7
8# Features:
9#  - when you first join to channel the nick is detected from real name
10#  - when the nick join to channel, it's detected from host mask
11#  - keeps track of parts/quits/nick changes
12#  - /find[realnick] command for seeing the current "fake nick"
13#  - all public messages coming from the nick are displayed as coming from
14#    the real nick.
15#  - all other people's replies to the fake nick are changed to show the
16#    real nick instead ("fakenick: hello" -> "realnick: hello")
17#  - if you reply to the real nick, it's automatically changed to the
18#    fake nick
19
20# TODO:
21#  - ability to detect always from either address or real name (send whois
22#    requests after join)
23#  - don't force the trackchannel
24#  - nick completion should complete to the real nick too (needs changes
25#    to irssi code, perl module doesn't recognize "completion word" signal)
26#  - support for runtime configuration + multiple nicks
27#  - support for /whois and some other commands? private messages?
28
29use strict;
30use Irssi;
31use Irssi::Irc;
32use vars qw($VERSION %IRSSI);
33$VERSION = "0.01";
34%IRSSI = (
35    authors     => "Timo Sirainen",
36    contact	=> "tss\@iki.fi",
37    name        => "track nick",
38    description => "Are you ever tired of those people who keep changing their nicks? Or maybe you just don't like someone's nick? This script lets you see them with the real nick all the time no matter what nick they're currently using.",
39    license	=> "Public Domain",
40    url		=> "http://irssi.org/",
41    changed	=> "2002-03-04T22:47+0100"
42);
43
44# change these to the values you want them to be
45# change these to the values you want them to be
46my $trackchannel = '#channel';
47my $realnick = 'nick';
48my $address_regexp = 'user@address.fi$';
49my $realname_regexp = 'first.*lastname';
50
51my $fakenick = '';
52
53sub event_nick {
54	my ($newnick, $server, $nick, $address) = @_;
55	$newnick = substr($newnick, 1) if ($newnick =~ /^:/);
56
57	$fakenick = $newnick if ($nick eq $fakenick)
58}
59
60sub event_join {
61	my ($data, $server, $nick, $address) = @_;
62
63	if (!$fakenick && $data eq $trackchannel &&
64	    $address =~ /$address_regexp/) {
65		$fakenick = $nick;
66	}
67}
68
69sub event_part {
70	my ($data, $server, $nick, $address) = @_;
71        my ($channel, $reason) = $data =~ /^(\S*)\s:(.*)/;
72
73	$fakenick = '' if ($fakenick eq $nick && $channel eq $trackchannel);
74}
75
76sub event_quit {
77	my ($data, $server, $nick, $address) = @_;
78
79	$fakenick = '' if ($fakenick eq $nick);
80}
81
82sub event_wholist {
83	my ($channel) = @_;
84
85	find_realnick($channel) if ($channel->{name} eq $trackchannel);
86}
87
88sub find_realnick {
89	my ($channel) = @_;
90
91	my @nicks = $channel->nicks();
92	$fakenick = '';
93	foreach my $nick (@nicks) {
94		my $realname = $nick->{realname};
95		if ($realname =~ /$realname_regexp/i) {
96			$fakenick = $nick->{nick};
97			last;
98		}
99	}
100}
101
102sub sig_public {
103	my ($server, $msg, $nick, $address, $target) = @_;
104
105	return if ($target ne $trackchannel || !$fakenick ||
106		   $fakenick eq $realnick);
107
108	if ($nick eq $fakenick) {
109		# text sent by fake nick - change it to real nick
110		send_real_public($server, $msg, $nick, $address, $target);
111		return;
112	}
113
114	if ($msg =~ /^$fakenick([:',].*)/) {
115		# someone's message starts with the fake nick,
116		# automatically change it to real nick
117		$msg = $realnick.$1;
118		Irssi::signal_emit("message public", $server, $msg,
119				   $nick, $address, $target);
120		Irssi::signal_stop();
121	}
122}
123
124sub send_real_public
125{
126	my ($server, $msg, $nick, $address, $target) = @_;
127
128	my $channel = $server->channel_find($target);
129	return if (!$channel);
130
131	my $nickrec = $channel->nick_find($nick);
132	return if (!$nickrec);
133
134	# create temporarily the nick to the nick list so that
135	# nick mode can be displayed correctly
136	my $newnick = $channel->nick_insert($realnick,
137		$nickrec->{op},
138		$nickrec->{voice}, 0);
139
140	Irssi::signal_emit("message public", $server, $msg,
141			   $realnick, $address, $target);
142	$channel->nick_remove($newnick);
143	Irssi::signal_stop();
144}
145
146sub sig_send_text {
147	my ($data, $server, $item) = @_;
148
149	return if (!$fakenick || !$item ||
150		   $item->{name} ne $trackchannel);
151
152	if ($fakenick ne $realnick && $data =~ /^$realnick([:',].*)/) {
153		# sending message to realnick, change it to fakenick
154		$data = $fakenick.$1;
155		Irssi::signal_emit("send text", $data, $server, $item);
156		Irssi::signal_stop();
157	}
158}
159
160sub cmd_realnick {
161	if ($fakenick) {
162		Irssi::print("$realnick is currently with nick: $fakenick");
163	} else {
164		Irssi::print("I can't find $realnick currently.");
165	}
166}
167
168my $channel = Irssi::channel_find($trackchannel);
169find_realnick($channel) if ($channel);
170
171Irssi::signal_add('event nick', 'event_nick');
172Irssi::signal_add('event join', 'event_join');
173Irssi::signal_add('event part', 'event_part');
174Irssi::signal_add('event quit', 'event_quit');
175Irssi::signal_add('message public', 'sig_public');
176Irssi::signal_add('send text', 'sig_send_text');
177Irssi::signal_add('channel wholist', 'event_wholist');
178
179Irssi::command_bind("find$realnick", 'cmd_realnick');
180