Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
132 lines (122 sloc) 4.62 KB
use strict;
use Irssi ();
use vars qw(%IRSSI $VERSION);
$VERSION = '0.1';
%IRSSI = (
authors => 'Nei',
contact => 'Nei @ anti@conference.jabber.teamidiot.de',
url => "http://anti.teamidiot.de/",
name => 'dccrelay',
description => 'Relays DCC messages. Originally written by greeny & mute for NoNameScript.',
license => 'GNU GPLv2 or later',
);
use constant NET => 0;
use constant NICK => 1;
use constant RESUME => 2;
sub lc1459 ($) {
my $x = shift;
$x =~ y/A-Z][\\^/a-z}{|~/;
$x
}
my ($r_net, $r_nick) = ('', '');
my %relaying = ();
Irssi::settings_add_str('dccrel', 'dccrel_on', '');
Irssi::settings_add_bool('dccrel', 'dccrel_auto_on', 0);
Irssi::theme_register([
relay_dcc_send => '{dcc DCC Relay SEND from {nick $0} [$1 port $2]: $3 [$4] {dcc to {nick $5/$6}}}',
relay_dcc_rejected => '{dcc DCC Relay REJECT SEND from {nick $0} [$1] {dcc to {nick $2/$3}}}'
]);
Irssi::signal_add({
'ctcp msg' => sub {
my ($server, $data, $from, $host, $to) = @_;
length($data) > 250 and return;
my ($self, $network) = ($server->{'nick'}, $server->{'tag'});
#Irssi::print(join '>>', @_);
if (lc1459($to) eq lc1459($self) and $data =~ /^dcc ([^ ]+) /i) { # mss me & dcc
my $func = lc $1;
if ('send' eq $func) { # S -> R
if (my ($file, $ip, $port, $size) = $data =~ /^dcc send (".*"|[^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)(?: |$)/i) {
if (my $r_ser = Irssi::server_find_tag($r_net)) {
$relaying{$file} = $relaying{$port} =[ $network => $from => 0];
$r_ser->send_raw("PRIVMSG $r_nick :\001$data\001");
my $h_ip = ($ip =~ /:/ ? "[$ip]" : inet_ntoa(inet_aton($ip)));
#$server->print('', "DCC Relay SEND from $from [$h_ip port $port]: $file [$size] to $r_net/$r_nick", Irssi::MSGLEVEL_DCC);
$server->printformat('', Irssi::MSGLEVEL_DCC, 'relay_dcc_send', $from, $h_ip, $port, $file, $size, $r_net, $r_nick);
#Irssi::print(Dumper(\%relaying));
Irssi::signal_stop();
}
}
}
elsif ('resume' eq $func) { # R -> S
if (my ($fake, $port, $pos) = $data =~ /^dcc resume (".*"|[^ ]+) ([^ ]+) ([^ ]+)(?: |$)/i) {
if (lc $network eq lc $r_net and lc1459($from) eq lc1459($r_nick)) {
if (my $info = $relaying{$port}) { if (my $s_ser = Irssi::server_find_tag($info->[NET])) { # saw this
my ($s_nick, $s_net) = ($info->[NICK], $info->[NET]);
$info->[RESUME] = 1;
$s_ser->send_raw("PRIVMSG $s_nick :\001$data\001");
#$server->print('', "DCC Relay RESUME from $from [$pos] to $s_net/$s_nick", Irssi::MSGLEVEL_DCC);
Irssi::signal_stop();
} }
}
}
}
elsif ('accept' eq $func) { # S -> R
if (my ($fake, $port, $pos) = $data =~ /^dcc accept (".*"|[^ ]+) ([^ ]+) ([^ ]+)(?: |$)/i) {
if (my $info = $relaying{$port} and my $r_ser = Irssi::server_find_tag($r_net)) {
if (lc $network eq lc $info->[NET] and lc1459($from) eq lc1459($info->[NICK]) and $info->[RESUME]) {
$r_ser->send_raw("PRIVMSG $r_nick :\001$data\001");
#$server->print('', "DCC Relay ACCEPT from $from [$pos] to $r_net/$r_nick", Irssi::MSGLEVEL_DCC);
Irssi::signal_stop();
}
}
}
}
}
},
'ctcp reply' => sub {
my ($server, $data, $from, $host, $to) = @_;
length($data) > 250 and return;
my ($self, $network) = ($server->{'nick'}, $server->{'tag'});
if (lc1459($to) eq lc1459($self) and $data =~ /^dcc ([^ ]+) /i) { # mss me & dcc
my $func = lc $1;
if ('reject' eq $func) { # R -> S
if (my ($file) = $data =~ /^dcc reject send (".*"|[^ ]+)(?: |$)/i) {
if (lc $network eq lc $r_net and lc1459($from) eq lc1459($r_nick)) {
if (my $info = $relaying{$file}) { if (my $s_ser = Irssi::server_find_tag($info->[NET])) { # this too
my ($s_nick, $s_net) = ($info->[NICK], $info->[NET]);
@$info = ();
$s_ser->send_raw("NOTICE $s_nick :\001$data\001");
#$server->print('', "DCC Relay REJECT SEND from $from to $s_net/$s_nick", Irssi::MSGLEVEL_DCC);
$server->printformat('', Irssi::MSGLEVEL_DCC, 'relay_dcc_rejected', $from, $file, $s_net, $s_nick);
Irssi::signal_stop();
} }
}
}
}
}
}
});
Irssi::command_bind(
dccrel => sub {
my ($data) = @_;
my ($state, $value) = split / /, $data, 2;
if ($state =~ /^(?:on|off)$/i) {
if ($value) {
Irssi::command("SET dccrel_on $value");
}
if (lc $state eq 'off') {
($r_net, $r_nick) = ('', '');
}
elsif (lc $state eq 'on') {
my $settings = Irssi::settings_get_str('dccrel_on');
($r_net, $r_nick) = split '/', $settings, 2;
}
}
#else {
Irssi::print("DCC Relay status: $r_net/$r_nick");
#}
}
);
if (Irssi::settings_get_bool('dccrel_auto_on')) {
Irssi::command('DCCREL on');
}