1 # /MLOCK <channel> <mode>
3 # Locks the channel mode to <mode>, if someone else tries to change the mode
4 # Irssi will automatically change it back. +k and +l are a bit special since
5 # they require the parameter. If you omit the parameter, like setting the
6 # mode to "+ntlk", Irssi will allow all +k and +l (or -lk) mode changes.
15 my ($data, $server) = @_;
16 my ($channel, $mode) = split(/ /, $data, 2);
18 $keep_channels{$channel} = $mode;
19 mlock_check_mode($server, $channel);
22 sub mlock_check_mode {
23 my ($server, $channame) = @_;
25 my $channel = $server->channel_find($channame);
26 return if (!$channel || !$channel->{chanop});
28 my $keep_mode = $keep_channels{$channame};
29 return if (!$keep_mode);
32 my ($oldmode, $oldkey, $oldlimit);
33 $oldmode = $channel->{mode};
34 $oldmode =~ s/^([^ ]*).*/\1/;
35 $oldkey = $channel->{key};
36 $oldlimit = $channel->{limit};
38 # get the new channel key/limit
39 my (@newmodes, $newkey, $limit);
40 @newmodes = split(/ /, $keep_mode); $keep_mode = $newmodes[0];
41 if ($keep_mode =~ /k/) {
42 if ($keep_mode =~ /k.*l/) {
43 $newkey = $newmodes[1];
44 $limit = $newmodes[2];
45 } elsif ($keep_mode =~ /l.*k/) {
46 $limit = $newmodes[1];
47 $newkey = $newmodes[2];
49 $newkey = $newmodes[1];
51 } elsif ($keep_mode =~ /l/) {
52 $limit = $newmodes[1];
55 # check the differences
57 $keep_mode =~ s/^\+//;
58 for (my $n = 0; $n < length($keep_mode); $n++) {
59 my $modechar = substr($keep_mode, $n, 1);
60 $allmodes{$modechar} = '+';
63 for (my $n = 0; $n < length($oldmode); $n++) {
64 my $modechar = substr($oldmode, $n, 1);
66 if ($allmodes{$modechar} eq '+') {
67 next if (($modechar eq "k" && $newkey ne $oldkey) ||
68 ($modechar eq "l" && $limit != $oldlimit));
69 delete $allmodes{$modechar};
71 $allmodes{$modechar} = '-';
75 # create the mode change string
76 my ($modecmd, $extracmd);
77 foreach my $mode (keys %allmodes) {
78 Irssi::print("key = '$mode':".$allmodes{$mode});
80 if ($allmodes{$mode} eq '+') {
81 next if ($newkey eq "");
83 # we need to get rid of old key too
85 $extracmd .= " $oldkey";
87 $extracmd .= " $newkey";
89 $extracmd .= " $oldkey";
92 if ($mode eq "l" && $allmodes{$mode} eq '+') {
93 next if ($limit <= 0);
94 $extracmd .= " $limit";
96 $modecmd .= $allmodes{$mode}.$mode;
100 $channel->{server}->command("/mode $channame $modecmd$extracmd");
104 sub mlock_mode_changed {
105 my ($server, $data) = @_;
106 my ($channel, $mode) = split(/ /, $data, 2);
108 mlock_check_mode($server, $channel);
114 mlock_check_mode($channel->{server}, $channel->{name});
117 Irssi::command_bind('mlock', 'cmd_mlock');
118 Irssi::signal_add_last("event mode", "mlock_mode_changed");
119 Irssi::signal_add("channel synced", "mlock_synced");