diff options
Diffstat (limited to 'scripts/mlock.pl')
-rw-r--r-- | scripts/mlock.pl | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/scripts/mlock.pl b/scripts/mlock.pl new file mode 100644 index 0000000..bf2fd00 --- /dev/null +++ b/scripts/mlock.pl @@ -0,0 +1,135 @@ +# /MLOCK <channel> <mode> +# +# 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. +# You can remove the lock with /MODE #channel - + +use Irssi; +use Irssi::Irc; +use strict; +use vars qw($VERSION %IRSSI); + +$VERSION = "1.00"; +%IRSSI = ( + authors => 'Timo Sirainen', + name => 'mlock', + description => 'Channel mode locking', + license => 'Public Domain', + changed => 'Sun Mar 10 23:18 EET 2002' +); + +my %keep_channels; + +sub cmd_mlock { + my ($data, $server) = @_; + my ($channel, $mode) = split(/ /, $data, 2); + + if ($mode eq "-") { + # remove checking + delete $keep_channels{$channel}; + } else { + $keep_channels{$channel} = $mode; + mlock_check_mode($server, $channel); + } +} + +sub mlock_check_mode { + my ($server, $channame) = @_; + + my $channel = $server->channel_find($channame); + return if (!$channel || !$channel->{chanop}); + + my $keep_mode = $keep_channels{$channame}; + return if (!$keep_mode); + + # old channel mode + my ($oldmode, $oldkey, $oldlimit); + $oldmode = $channel->{mode}; + $oldmode =~ s/^([^ ]*).*/\1/; + $oldkey = $channel->{key}; + $oldlimit = $channel->{limit}; + + # get the new channel key/limit + my (@newmodes, $newkey, $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 + my %allmodes; + $keep_mode =~ s/^\+//; + for (my $n = 0; $n < length($keep_mode); $n++) { + my $modechar = substr($keep_mode, $n, 1); + $allmodes{$modechar} = '+'; + } + + for (my $n = 0; $n < length($oldmode); $n++) { + my $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 + my ($modecmd, $extracmd); + foreach my $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->{server}->command("/mode $channame $modecmd$extracmd"); + } +} + +sub mlock_mode_changed { + my ($server, $data) = @_; + my ($channel, $mode) = split(/ /, $data, 2); + + mlock_check_mode($server, $channel); +} + +sub mlock_synced { + my $channel = $_[0]; + + mlock_check_mode($channel->{server}, $channel->{name}); +} + +Irssi::command_bind('mlock', 'cmd_mlock'); +Irssi::signal_add_last("event mode", "mlock_mode_changed"); +Irssi::signal_add("channel synced", "mlock_synced"); |