summaryrefslogtreecommitdiffstats
path: root/scripts/mh_userstatus.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mh_userstatus.pl')
-rw-r--r--scripts/mh_userstatus.pl438
1 files changed, 438 insertions, 0 deletions
diff --git a/scripts/mh_userstatus.pl b/scripts/mh_userstatus.pl
new file mode 100644
index 0000000..4aedd7e
--- /dev/null
+++ b/scripts/mh_userstatus.pl
@@ -0,0 +1,438 @@
+##############################################################################
+#
+# mh_userstatus.pl v1.00 (20151129)
+#
+# Copyright (c) 2015 Michael Hansen
+#
+# Permission to use, copy, modify, and distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+##############################################################################
+#
+# Show in channels when users go away/back or oper/deoper
+#
+# Will periodically check the channels you are on for users changing their
+# away/oper status and print a line like:
+#
+# -!- <nick> [<userhost>] is now gone
+# -!- <nick> [<userhost>] is now here
+# -!- <nick> [<userhost>] is now oper
+# -!- <nick> [<userhost>] is now not oper
+#
+# You can also list the currently away or opered users with the commands /whoa
+# and /whoo respectively
+#
+# The following settings can finetune the scripts behavior:
+#
+# mh_userstatus_delay (default 5): aproximate delay between checking the
+# channel (in minutes). you can set this to 0 to disable running /who if you
+# use another script that already does a periodical /who on the channels you
+# are on
+#
+# mh_userstatus_lag_limit (default 5): amount of lag (in seconds) where we skip
+# checking the channel for status updates
+#
+# mh_userstatus_show_host (default ON): enable/disable showing userhosts
+#
+# history:
+# v1.00 (20151129)
+# initial release
+#
+
+use v5.14.2;
+
+use strict;
+
+##############################################################################
+#
+# irssi head
+#
+##############################################################################
+
+use Irssi 20100403;
+
+{ package Irssi::Nick }
+
+our $VERSION = '1.00';
+our %IRSSI =
+(
+ 'name' => 'mh_userstatus',
+ 'description' => 'Show in channels when users go away/back or oper/deoper',
+ 'license' => 'BSD',
+ 'authors' => 'Michael Hansen',
+ 'contact' => 'mh on IRCnet #help',
+ 'url' => 'http://scripts.irssi.org / https://github.com/mh-source/irssi-scripts',
+);
+
+##############################################################################
+#
+# global variables
+#
+##############################################################################
+
+our $userstatus_timeouts = undef;
+
+##############################################################################
+#
+# common support functions
+#
+##############################################################################
+
+sub trim_space
+{
+ my ($string) = @_;
+
+ if (defined($string))
+ {
+ $string =~ s/^\s+//g;
+ $string =~ s/\s+$//g;
+
+ } else {
+
+ $string = '';
+ }
+
+ return($string);
+}
+
+##############################################################################
+#
+# script functions
+#
+##############################################################################
+
+sub get_delay
+{
+ my $delay = Irssi::settings_get_int('mh_userstatus_delay');
+
+ if ($delay < 1)
+ {
+ $delay = 1;
+ }
+
+ $delay = $delay * 60000; # delay in minutes
+ $delay = $delay + (int(rand(30000)) + 1);
+
+ return($delay);
+}
+
+##############################################################################
+#
+# irssi timeouts
+#
+##############################################################################
+
+sub timeout_request_who
+{
+ my ($args) = @_;
+ my ($servertag, $channelname) = @{$args};
+
+ if (exists($userstatus_timeouts->{$servertag}))
+ {
+ if (exists($userstatus_timeouts->{$servertag}->{$channelname}))
+ {
+ delete($userstatus_timeouts->{$servertag}->{$channelname});
+ }
+ }
+
+ if (Irssi::settings_get_int('mh_userstatus_delay'))
+ {
+ my $server = Irssi::server_find_tag($servertag);
+
+ if ($server)
+ {
+ my $lag_limit = Irssi::settings_get_int('mh_userstatus_lag_limit');
+
+ if ($lag_limit)
+ {
+ $lag_limit = $lag_limit * 1000; # seconds to milliseconds
+ }
+
+ if ((not $lag_limit) or ($lag_limit > $server->{'lag'}))
+ {
+ my $channel = $server->channel_find($channelname);
+
+ if ($channel)
+ {
+ $server->redirect_event('who',
+ 1, # count
+ '', # arg
+ -1, # remote
+ '', # failure signal
+ { # signals
+ 'event 352' => 'silent event who', # RPL_WHOREPLY
+ '' => 'event empty',
+ }
+ );
+ $channel->command('WHO ' . $channelname);
+ }
+ }
+
+ my @args = ($servertag, $channelname);
+ $userstatus_timeouts->{$servertag}->{$channelname} = Irssi::timeout_add_once(get_delay(), 'timeout_request_who', \@args);
+ }
+ }
+}
+
+##############################################################################
+#
+# irssi signal handlers
+#
+##############################################################################
+
+sub signal_channel_sync_last
+{
+ my ($channel) = @_;
+
+ my $servertag = lc($channel->{'server'}->{'tag'});
+ my $channelname = lc($channel->{'name'});
+
+ if (exists($userstatus_timeouts->{$servertag}))
+ {
+ if (exists($userstatus_timeouts->{$servertag}->{$channelname}))
+ {
+ return(1);
+ }
+ }
+
+ if (Irssi::settings_get_int('mh_userstatus_delay'))
+ {
+ my @args = ($servertag, $channelname);
+ $userstatus_timeouts->{$servertag}->{$channelname} = Irssi::timeout_add_once(get_delay(), 'timeout_request_who', \@args);
+ }
+}
+
+sub signal_nicklist_gone_changed_last
+{
+ my ($channel, $nick) = @_;
+
+ if ($channel->{'synced'})
+ {
+ if ($nick->{'nick'} ne $channel->{'server'}->{'nick'})
+ {
+ my $format = '';
+
+ if (Irssi::settings_get_bool('mh_userstatus_show_host'))
+ {
+ $format = '_host'
+ }
+
+ if ($nick->{'gone'})
+ {
+ $channel->printformat(Irssi::MSGLEVEL_PARTS, 'mh_userstatus_gone' . $format, $nick->{'nick'}, $nick->{'host'});
+
+ } else {
+
+ $channel->printformat(Irssi::MSGLEVEL_JOINS, 'mh_userstatus_here' . $format, $nick->{'nick'}, $nick->{'host'});
+ }
+ }
+ }
+}
+
+sub signal_nicklist_serverop_changed_last
+{
+ my ($channel, $nick) = @_;
+
+ if ($channel->{'synced'})
+ {
+ if ($nick->{'nick'} ne $channel->{'server'}->{'nick'})
+ {
+ my $format = '';
+
+ if (Irssi::settings_get_bool('mh_userstatus_show_host'))
+ {
+ $format = '_host'
+ }
+
+ if ($nick->{'serverop'})
+ {
+ $channel->printformat(Irssi::MSGLEVEL_JOINS, 'mh_userstatus_oper' . $format, $nick->{'nick'}, $nick->{'host'});
+
+ } else {
+
+ $channel->printformat(Irssi::MSGLEVEL_PARTS, 'mh_userstatus_deop' . $format, $nick->{'nick'}, $nick->{'host'});
+ }
+ }
+ }
+}
+
+##############################################################################
+#
+# irssi command functions
+#
+##############################################################################
+
+sub command_whoa
+{
+ my ($data, $server, $windowitem) = @_;
+
+ if (ref($windowitem) ne 'Irssi::Irc::Channel')
+ {
+ Irssi::active_win->printformat(Irssi::MSGLEVEL_CRAP, 'mh_userstatus_error', 'Not a channel window');
+ return(0);
+ }
+
+ if (not $windowitem->{'synced'})
+ {
+ $windowitem->printformat(Irssi::MSGLEVEL_CRAP, 'mh_userstatus_error', 'Channel not synced, please wait');
+ return(0);
+ }
+
+ my $count = 0;
+
+ for my $nick (sort({ lc($a->{'nick'}) cmp lc($b->{'nick'}) } $windowitem->nicks()))
+ {
+ if ($nick->{'nick'} ne $windowitem->{'server'}->{'nick'})
+ {
+ my $format = '';
+
+ if (Irssi::settings_get_bool('mh_userstatus_show_host'))
+ {
+ $format = '_host'
+ }
+
+ if ($nick->{'gone'})
+ {
+ $count++;
+ $windowitem->printformat(Irssi::MSGLEVEL_PARTS, 'mh_userstatus_whoa_gone' . $format, $nick->{'nick'}, $nick->{'host'});
+ }
+ }
+ }
+
+ $windowitem->printformat(Irssi::MSGLEVEL_PARTS, 'mh_userstatus_whoa', $count);
+}
+
+sub command_whoo
+{
+ my ($data, $server, $windowitem) = @_;
+
+ if (ref($windowitem) ne 'Irssi::Irc::Channel')
+ {
+ Irssi::active_win->printformat(Irssi::MSGLEVEL_CRAP, 'mh_userstatus_error', 'Not a channel window');
+ return(0);
+ }
+
+ if (not $windowitem->{'synced'})
+ {
+ $windowitem->printformat(Irssi::MSGLEVEL_CRAP, 'mh_userstatus_error', 'Channel not synced, please wait');
+ return(0);
+ }
+
+ my $count = 0;
+
+ for my $nick (sort({ lc($a->{'nick'}) cmp lc($b->{'nick'}) } $windowitem->nicks()))
+ {
+ if ($nick->{'nick'} ne $windowitem->{'server'}->{'nick'})
+ {
+ my $format = '';
+
+ if (Irssi::settings_get_bool('mh_userstatus_show_host'))
+ {
+ $format = '_host'
+ }
+
+ if ($nick->{'serverop'})
+ {
+ $count++;
+ $windowitem->printformat(Irssi::MSGLEVEL_JOINS, 'mh_userstatus_whoo_oper' . $format, $nick->{'nick'}, $nick->{'host'});
+ }
+ }
+ }
+
+ $windowitem->printformat(Irssi::MSGLEVEL_JOINS, 'mh_userstatus_whoo', $count);
+}
+
+sub command_help
+{
+ my ($data, $server, $windowitem) = @_;
+
+ $data = lc(trim_space($data));
+
+ if ($data =~ m/^whoa$/)
+ {
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('WHOA', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('Shows all users in the current channel who are away.', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('See also: WHO, WHOO', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+
+ Irssi::signal_stop();
+
+ } elsif ($data =~ m/^whoo$/)
+ {
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('WHOO', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('Shows all users in the current channel who are opers.', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('See also: WHO, WHOA', Irssi::MSGLEVEL_CLIENTCRAP);
+ Irssi::print('', Irssi::MSGLEVEL_CLIENTCRAP);
+
+ Irssi::signal_stop();
+ }
+}
+
+##############################################################################
+#
+# script on load
+#
+##############################################################################
+
+Irssi::theme_register([
+ 'mh_userstatus_gone', '{channick $0} is now {hilight gone}',
+ 'mh_userstatus_here', '{channick_hilight $0} is now {hilight here}',
+ 'mh_userstatus_oper', '{channick_hilight $0} is now {hilight oper}',
+ 'mh_userstatus_deop', '{channick $0} is now {hilight not oper}',
+ 'mh_userstatus_gone_host', '{channick $0} {chanhost $1} is now {hilight gone}',
+ 'mh_userstatus_here_host', '{channick_hilight $0} {chanhost_hilight $1} is now {hilight here}',
+ 'mh_userstatus_oper_host', '{channick_hilight $0} {chanhost_hilight $1} is now {hilight oper}',
+ 'mh_userstatus_deop_host', '{channick $0} {chanhost $1} is now {hilight not oper}',
+ 'mh_userstatus_error', '{error $0}',
+ 'mh_userstatus_whoa', 'A total of $0 users are {hilight gone}',
+ 'mh_userstatus_whoo', 'A total of $0 users are {hilight oper}',
+ 'mh_userstatus_whoa_gone', '{channick $0} is {hilight gone}',
+ 'mh_userstatus_whoo_oper', '{channick_hilight $0} is {hilight oper}',
+ 'mh_userstatus_whoa_gone_host', '{channick $0} {chanhost $1} is {hilight gone}',
+ 'mh_userstatus_whoa_oper_host', '{channick_hilight $0} {chanhost_hilight $1} is {hilight oper}',
+]);
+
+Irssi::settings_add_int('mh_userstatus', 'mh_userstatus_delay', 5);
+Irssi::settings_add_int('mh_userstatus', 'mh_userstatus_lag_limit', 5);
+Irssi::settings_add_bool('mh_userstatus', 'mh_userstatus_show_host', 1);
+
+for my $channel (Irssi::channels())
+{
+ if ($channel->{'synced'})
+ {
+ signal_channel_sync_last($channel);
+ }
+}
+
+Irssi::signal_add_last('channel sync', 'signal_channel_sync_last');
+Irssi::signal_add_last('nicklist gone changed', 'signal_nicklist_gone_changed_last');
+Irssi::signal_add_last('nicklist serverop changed', 'signal_nicklist_serverop_changed_last');
+
+Irssi::command_bind('whoa', 'command_whoa', 'mh_userstatus');
+Irssi::command_bind('whoo', 'command_whoo', 'mh_userstatus');
+Irssi::command_bind('help', 'command_help');
+
+1;
+
+##############################################################################
+#
+# eof mh_userstatus.pl
+#
+##############################################################################