1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# /MLOCK <channel> <mode> - for Irssi 0.7.96 and above
#
# Locks the channel mode to <mode>, if someone else tries to change the mode
# Irssi will automatically change it back. +k and +l are a bit special since
# they require the parameter. If you omit the parameter, like setting the
# mode to "+ntlk", Irssi will allow all +k and +l (or -lk) mode changes.
use Irssi;
use Irssi::Irc;
sub cmd_mlock {
my ($data, $server) = @_;
my ($channel, $mode) = split(/ /, $data, 2);
$keep_channels{$channel} = $mode;
mlock_check_mode($server, $channel);
return 1;
}
sub mlock_check_mode {
my ($server, $channame) = @_;
$channel = $server->channel_find($channame);
return if (!channel || !$channel->values()->{'chanop'});
$keep_mode = $keep_channels{$channame};
return if (!$keep_mode);
# old channel mode
$oldmode = $channel->values()->{'mode'};
$oldmode =~ s/^([^ ]*).*/\1/;
$oldkey = $channel->values()->{'key'};
$oldlimit = $channel->values()->{'limit'};
# get the new channel key/limit
@newmodes = split(/ /, $keep_mode); $keep_mode = $newmodes[0];
if ($keep_mode =~ /k/) {
if ($keep_mode =~ /k.*l/) {
$newkey = $newmodes[1];
$limit = $newmodes[2];
} elsif ($keep_mode =~ /l.*k/) {
$limit = $newmodes[1];
$newkey = $newmodes[2];
} else {
$newkey = $newmodes[1];
}
} elsif ($keep_mode =~ /l/) {
$limit = $newmodes[1];
}
# check the differences
undef %allmodes;
$keep_mode =~ s/^\+//;
for ($n = 0; $n < length($keep_mode); $n++) {
$modechar = substr($keep_mode, $n, 1);
$allmodes{$modechar} = '+';
}
for ($n = 0; $n < length($oldmode); $n++) {
$modechar = substr($oldmode, $n, 1);
if ($allmodes{$modechar} eq '+') {
next if (($modechar eq "k" && $newkey ne $oldkey) ||
($modechar eq "l" && $limit != $oldlimit));
delete $allmodes{$modechar};
} else {
$allmodes{$modechar} = '-';
}
}
# create the mode change string
$modecmd = ""; $extracmd = "";
foreach $mode (keys %allmodes) {
Irssi::print("key = '$mode':".$allmodes{$mode});
if ($mode eq "k") {
if ($allmodes{$mode} eq '+') {
next if ($newkey eq "");
if ($oldkey ne "") {
# we need to get rid of old key too
$modecmd .= "-k";
$extracmd .= " $oldkey";
}
$extracmd .= " $newkey";
} else {
$extracmd .= " $oldkey";
}
}
if ($mode eq "l" && $allmodes{$mode} eq '+') {
next if ($limit <= 0);
$extracmd .= " $limit";
}
$modecmd .= $allmodes{$mode}.$mode;
}
if ($modecmd ne "") {
$channel->values()->{'server'}->command("/mode $channame $modecmd$extracmd");
}
}
sub mlock_mode_changed {
my ($data, $server) = @_;
my ($channel, $mode) = split(/ /, $data, 2);
mlock_check_mode($server, $channel);
}
sub mlock_synced {
my $channel = $_[0];
mlock_check_mode($channel->values()->{'server'}, $channel->values()->{'name'});
}
Irssi::command_bind('mlock', '', 'cmd_mlock');
Irssi::signal_add_last("event mode", "mlock_mode_changed");
Irssi::signal_add("channel synced", "mlock_synced");
|