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.
7 # You can remove the lock with /MODE #channel -
12 use vars qw($VERSION %IRSSI);
16 authors => 'Timo Sirainen',
18 description => 'Channel mode locking',
19 license => 'Public Domain',
20 changed => 'Sun Mar 10 23:18 EET 2002'
26 my ($data, $server) = @_;
27 my ($channel, $mode) = split(/ /, $data, 2);
31 delete $keep_channels{$channel};
33 $keep_channels{$channel} = $mode;
34 mlock_check_mode($server, $channel);
38 sub mlock_check_mode {
39 my ($server, $channame) = @_;
41 my $channel = $server->channel_find($channame);
42 return if (!$channel || !$channel->{chanop});
44 my $keep_mode = $keep_channels{$channame};
45 return if (!$keep_mode);
48 my ($oldmode, $oldkey, $oldlimit);
49 $oldmode = $channel->{mode};
50 $oldmode =~ s/^([^ ]*).*/\1/;
51 $oldkey = $channel->{key};
52 $oldlimit = $channel->{limit};
54 # get the new channel key/limit
55 my (@newmodes, $newkey, $limit);
56 @newmodes = split(/ /, $keep_mode); $keep_mode = $newmodes[0];
57 if ($keep_mode =~ /k/) {
58 if ($keep_mode =~ /k.*l/) {
59 $newkey = $newmodes[1];
60 $limit = $newmodes[2];
61 } elsif ($keep_mode =~ /l.*k/) {
62 $limit = $newmodes[1];
63 $newkey = $newmodes[2];
65 $newkey = $newmodes[1];
67 } elsif ($keep_mode =~ /l/) {
68 $limit = $newmodes[1];
71 # check the differences
73 $keep_mode =~ s/^\+//;
74 for (my $n = 0; $n < length($keep_mode); $n++) {
75 my $modechar = substr($keep_mode, $n, 1);
76 $allmodes{$modechar} = '+';
79 for (my $n = 0; $n < length($oldmode); $n++) {
80 my $modechar = substr($oldmode, $n, 1);
82 if ($allmodes{$modechar} eq '+') {
83 next if (($modechar eq "k" && $newkey ne $oldkey) ||
84 ($modechar eq "l" && $limit != $oldlimit));
85 delete $allmodes{$modechar};
87 $allmodes{$modechar} = '-';
91 # create the mode change string
92 my ($modecmd, $extracmd);
93 foreach my $mode (keys %allmodes) {
94 Irssi::print("key = '$mode':".$allmodes{$mode});
96 if ($allmodes{$mode} eq '+') {
97 next if ($newkey eq "");
99 # we need to get rid of old key too
101 $extracmd .= " $oldkey";
103 $extracmd .= " $newkey";
105 $extracmd .= " $oldkey";
108 if ($mode eq "l" && $allmodes{$mode} eq '+') {
109 next if ($limit <= 0);
110 $extracmd .= " $limit";
112 $modecmd .= $allmodes{$mode}.$mode;
115 if ($modecmd ne "") {
116 $channel->{server}->command("mode $channame $modecmd$extracmd");
120 sub mlock_mode_changed {
121 my ($server, $data) = @_;
122 my ($channel, $mode) = split(/ /, $data, 2);
124 mlock_check_mode($server, $channel);
130 mlock_check_mode($channel->{server}, $channel->{name});
133 Irssi::command_bind('mlock', 'cmd_mlock');
134 Irssi::signal_add_last("event mode", "mlock_mode_changed");
135 Irssi::signal_add("channel synced", "mlock_synced");