diff --git a/PBot/ChanOpCommands.pm b/PBot/ChanOpCommands.pm index 6bf8852f..0015b7a1 100644 --- a/PBot/ChanOpCommands.pm +++ b/PBot/ChanOpCommands.pm @@ -37,6 +37,8 @@ sub initialize { $pbot->{commands}->register(sub { return $self->ban_user(@_) }, "ban", 10); $pbot->{commands}->register(sub { return $self->unban_user(@_) }, "unban", 10); + $pbot->{commands}->register(sub { return $self->mute_user(@_) }, "mute", 10); + $pbot->{commands}->register(sub { return $self->unmute_user(@_) }, "unmute", 10); $pbot->{commands}->register(sub { return $self->kick_user(@_) }, "kick", 10); } @@ -50,10 +52,15 @@ sub ban_user { return ""; } + if ($channel !~ m/^#/) { + $length = "$channel $length"; + $channel = $from; + } + $channel = $from if not defined $channel; if(not defined $target) { - return "/msg $nick Usage: ban [channel [timeout (default: 24 hours)]]"; + return "/msg $nick Usage: ban [channel [timeout (default: 24 hours)]]"; } if(not defined $length) { @@ -101,6 +108,72 @@ sub unban_user { return "/msg $nick $target has been unbanned from $channel."; } +sub mute_user { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my ($target, $channel, $length) = split(/\s+/, $arguments, 3); + + if(not defined $from) { + $self->{pbot}->{logger}->log("Command missing ~from parameter!\n"); + return ""; + } + + if ($channel !~ m/^#/) { + $length = "$channel $length"; + $channel = $from; + } + + $channel = $from if not defined $channel; + + if(not defined $target) { + return "/msg $nick Usage: mute [channel [timeout (default: 24 hours)]]"; + } + + if(not defined $length) { + $length = 60 * 60 * 24; # 24 hours + } else { + my $error; + ($length, $error) = parsedate($length); + return $error if defined $error; + } + + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); + return "I don't think so." if $target =~ /^\Q$botnick\E!/i; + + $self->{pbot}->{chanops}->mute_user_timed($target, $channel, $length); + + if ($length > 0) { + $length = duration($length); + } else { + $length = 'all eternity'; + } + + return "/msg $nick $target muted in $channel for $length"; +} + +sub unmute_user { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + + if(not defined $from) { + $self->{pbot}->{logger}->log("Command missing ~from parameter!\n"); + return ""; + } + + my ($target, $channel) = split / /, $arguments; + + if(not defined $target) { + return "/msg $nick Usage: unmute [channel]"; + } + + $channel = $from if not defined $channel; + + return "/msg $nick Usage for /msg: unmute $target " if $channel !~ /^#/; + + $self->{pbot}->{chanops}->unmute_user($target, $channel); + return "/msg $nick $target has been unmuted in $channel."; +} + sub kick_user { my $self = shift; my ($from, $nick, $user, $host, $arguments) = @_; diff --git a/PBot/ChanOps.pm b/PBot/ChanOps.pm index 2c5e8292..849495cd 100644 --- a/PBot/ChanOps.pm +++ b/PBot/ChanOps.pm @@ -35,6 +35,14 @@ sub initialize { $self->{unban_timeout}->load; + $self->{unmute_timeout} = PBot::DualIndexHashObject->new( + pbot => $self->{pbot}, + name => 'Unmute Timeouts', + filename => $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/unmute_timeouts' + ); + + $self->{unmute_timeout}->load; + $self->{op_commands} = {}; $self->{is_opped} = {}; $self->{op_requested} = {}; @@ -43,8 +51,9 @@ sub initialize { $self->{pbot}->{registry}->add_default('text', 'general', 'deop_timeout', $conf{'deop_timeout'} // 300); - $self->{pbot}->{timer}->register(sub { $self->check_opped_timeouts }, 10); - $self->{pbot}->{timer}->register(sub { $self->check_unban_timeouts }, 10); + $self->{pbot}->{timer}->register(sub { $self->check_opped_timeouts }, 10); + $self->{pbot}->{timer}->register(sub { $self->check_unban_timeouts }, 10); + $self->{pbot}->{timer}->register(sub { $self->check_unmute_timeouts }, 10); } sub gain_ops { @@ -124,6 +133,38 @@ sub ban_user_timed { } } +sub mute_user { + my $self = shift; + my ($mask, $channel) = @_; + + $self->add_op_command($channel, "mode $channel +q $mask"); + $self->gain_ops($channel); +} + +sub unmute_user { + my $self = shift; + my ($mask, $channel) = @_; + $self->{pbot}->{logger}->log("Unmuting $channel $mask\n"); + if($self->{unmute_timeout}->find_index($channel, $mask)) { + $self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + 7200; # try again in 2 hours if unmute doesn't immediately succeed + $self->{unmute_timeout}->save; + } + $self->add_op_command($channel, "mode $channel -q $mask"); + $self->gain_ops($channel); +} + +sub mute_user_timed { + my $self = shift; + my ($mask, $channel, $length) = @_; + + $mask .= '!*@*' if $mask !~ m/[\$!@]/; + $self->mute_user($mask, $channel); + if ($length > 0) { + $self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + $length; + $self->{unmute_timeout}->save; + } +} + sub join_channel { my ($self, $channel) = @_; @@ -166,6 +207,22 @@ sub check_unban_timeouts { } } +sub check_unmute_timeouts { + my $self = shift; + + return if not $self->{pbot}->{joined_channels}; + + my $now = gettimeofday(); + + foreach my $channel (keys %{ $self->{unmute_timeout}->hash }) { + foreach my $mask (keys %{ $self->{unmute_timeout}->hash->{$channel} }) { + if($self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} < $now) { + $self->unmute_user($mask, $channel); + } + } + } +} + sub check_opped_timeouts { my $self = shift; my $now = gettimeofday();