Skip to content

Commit

Permalink
10.73: NAMES without a parameter is currently not supported. instead …
Browse files Browse the repository at this point in the history
…of sending ERR_NEEDMOREPARAMS, use RPL_LOAD2HI and RPL_ENDOFNAMES. fixed issue where show_in_whois was fired twice, each time with different arguments. added show_in_names which allows modules to hide users from NAMES. added names_character which allows modules to change the '=' char in NAMREPLYs. Channel::Secret now hides users in private or secret channels from NAMES. #34             Channel::Secret now appropriately sets the NAMREPLY character to '@' or '*' for secret and private channels respectively.
  • Loading branch information
cooper committed Jun 25, 2016
1 parent 6667e68 commit 3049e4c
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 30 deletions.
8 changes: 8 additions & 0 deletions INDEV
Expand Up @@ -3089,3 +3089,11 @@ CHANGES:
added handler for JELP PARTALL.

72. working on adding channel private (+p) to the Channel::Secret module. #34

73. NAMES without a parameter is currently not supported.
instead of sending ERR_NEEDMOREPARAMS, use RPL_LOAD2HI and RPL_ENDOFNAMES.
fixed issue where show_in_whois was fired twice, each time with different arguments.
added show_in_names which allows modules to hide users from NAMES.
added names_character which allows modules to change the '=' char in NAMREPLYs.
Channel::Secret now hides users in private or secret channels from NAMES. #34
Channel::Secret now appropriately sets the NAMREPLY character to '@' or '*' for secret and private channels respectively.
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
10.72
10.73
2 changes: 1 addition & 1 deletion modules/Channel/Secret.module/Secret.json
Expand Up @@ -12,5 +12,5 @@
"description" : "allows a channel to be marked secret or private",
"name" : "Channel::Secret",
"package" : "M::Channel::Secret",
"version" : "1.4"
"version" : "1.8"
}
59 changes: 47 additions & 12 deletions modules/Channel/Secret.module/Secret.pm
Expand Up @@ -26,20 +26,20 @@ our ($api, $mod, $pool);

sub init {

# register secret mode block.
# register secret mode block
$mod->register_channel_mode_block(
name => 'secret',
code => \&M::Core::ChannelModes::cmode_normal
) or return;

# register private mode block.
# register private mode block
$mod->register_channel_mode_block(
name => 'secret',
code => \&M::Core::ChannelModes::cmode_normal
) or return;

# Hook on the show_in_list and show_in_whois events to prevent secret
# channels from showing in list or WHOIS
# Hook on the show_in_list, show_in_whois, and show_in_names events to
# prevent secret or private channels from showing
$pool->on('channel.show_in_list' => \&show_in_list,
with_eo => 1,
name => 'channel.secret.show_in_list'
Expand All @@ -49,6 +49,13 @@ sub init {
name => 'channel.secret.show_in_whois'
);

# names_character allows us to change the "=" in NAMES to "@" or "*"
# for secret and private channels respectively
$pool->on('channel.names_character' => \&names_character,
with_eo => 1,
name => 'channel.secret.names_character'
);

return 1;
}

Expand All @@ -58,12 +65,12 @@ sub show_in_list {
my ($channel, $event, $user) = @_;

# if it's neither secret not private, we are not concerned with this.
return $SHOW_IT if
!$channel->is_mode('secret') && !$channel->is_mode('private');
return $SHOW_IT
if !$channel->is_mode('secret') && !$channel->is_mode('private');

# if the user asking has super powers, show it.
return $SHOW_IT if
$user->has_flag('see_secret');
return $SHOW_IT
if $user->has_flag('see_secret');

# if it is secret or private, but this guy's in there, show it.
return $SHOW_IT
Expand All @@ -73,7 +80,10 @@ sub show_in_list {
}

sub show_in_whois {
my ($channel, $event, $user) = @_;
my ($channel, $event, $quser, $ruser) = @_;

# $quser = the one being queried
# $ruser = the one requesting the info

# if it's not secret, we are not concerned with this
# because private channels show up in WHOIS.
Expand All @@ -82,13 +92,38 @@ sub show_in_whois {

# if the user asking has super powers, show it.
return $SHOW_IT
if $user->has_flag('see_secret');
if $ruser->has_flag('see_secret');

# if it is secret, but this guy's in there, show it.
# if it is secret, but the one requesting it is in there, show it.
return $SHOW_IT
if $channel->has_user($user);
if $channel->has_user($ruser);

$event->stop;
}

sub show_in_names {
my ($channel, $event, $quser, $ruser) = @_;

# $quser = the one being queried
# $ruser = the one requesting the info

# if it's neither secret not private, we are not concerned with this.
return $SHOW_IT
if !$channel->is_mode('secret') && !$channel->is_mode('private');

# if it is secret or private, but this guy's in there, show it.
return $SHOW_IT
if $channel->has_user($ruser);

$event->stop;
}

# override the character in NAMES
sub names_character {
my ($channel, $event, $c) = @_;
# $c is a string reference with the current character
$$c = "*" if $channel->is_mode('private');
$$c = "@" if $channel->is_mode('secret'); # more important than private
}

$mod
2 changes: 1 addition & 1 deletion modules/Core/UserCommands.module/UserCommands.json
Expand Up @@ -12,5 +12,5 @@
"description" : "the core set of user commands",
"name" : "Core::UserCommands",
"package" : "M::Core::UserCommands",
"version" : "10.72"
"version" : "10.73"
}
24 changes: 14 additions & 10 deletions modules/Core/UserCommands.module/UserCommands.pm
Expand Up @@ -119,7 +119,7 @@ our %user_commands = (
code => \&names,
desc => 'view the user list of a channel',
fntsy => 1,
params => '*'
params => '*(opt)'
},
OPER => {
code => \&oper,
Expand Down Expand Up @@ -549,13 +549,22 @@ sub _cjoin {

sub names {
my ($user, $event, $given) = @_;

# we aren't currently supporting NAMES without a parameter
if (!defined $given) {
$user->numeric(RPL_LOAD2HI => 'NAMES');
$user->numeric(RPL_ENDOFNAMES => '*');
return;
}

foreach my $chname (split ',', $given) {
# nonexistent channels return no error,
# and RPL_ENDOFNAMES is sent no matter what
my $channel = $pool->lookup_channel($chname);
$channel->names($user, 1) if $channel;
$user->numeric(RPL_ENDOFNAMES => $channel ? $channel->name : $chname);
}

return 1;
}

Expand Down Expand Up @@ -652,6 +661,9 @@ sub add_whois_callbacks {
my $show_channels = sub {
my ($quser, $ruser) = @_;

# $quser = the one being queried
# $ruser = the one requesting the info

# some channels may be skipped using event stopper.
my @channels;
foreach my $channel ($quser->channels) {
Expand All @@ -668,15 +680,7 @@ sub add_whois_callbacks {
my $channels_list = sub {
my ($quser, $ruser) = @_;
my @all_chans = @{ delete $channels{$quser} || [] };
my @show_chans;

# show it? assuming same logic as /LIST.
foreach my $channel (@all_chans) {
next if $channel->fire_event(show_in_whois => $ruser)->stopper;
push @show_chans, $channel;
}

return join ' ', map $_->{name}, @show_chans;
return join ' ', map $_->{name}, @all_chans;
};

# server information.
Expand Down
2 changes: 1 addition & 1 deletion modules/Core/UserNumerics.module/UserNumerics.json
Expand Up @@ -9,5 +9,5 @@
"description" : "the core set of user numerics",
"name" : "Core::UserNumerics",
"package" : "M::Core::UserNumerics",
"version" : "10.7"
"version" : "10.73"
}
1 change: 1 addition & 0 deletions modules/Core/UserNumerics.module/UserNumerics.pm
Expand Up @@ -47,6 +47,7 @@ our %user_numerics = (
RPL_ADMINLOC1 => [257, ':%s' ],
RPL_ADMINLOC2 => [258, ':%s' ],
RPL_ADMINEMAIL => [259, ':%s' ],
RPL_LOAD2HI => [263, '%s :Command dropped' ],
RPL_LOCALUSERS => [265, '%d %d :Current local users %d, max %d' ],
RPL_GLOBALUSERS => [266, '%d %d :Current global users %d, max %d' ],
RPL_AWAY => [301, '%s :%s' ],
Expand Down
2 changes: 1 addition & 1 deletion modules/ircd.module/channel.module/channel.json
Expand Up @@ -8,5 +8,5 @@
"no_bless" : 1,
"package" : "channel",
"preserve_sym" : 1,
"version" : "10.71"
"version" : "10.73"
}
24 changes: 21 additions & 3 deletions modules/ircd.module/channel.module/channel.pm
Expand Up @@ -527,24 +527,42 @@ sub localjoin {
# send NAMES.
sub names {
my ($channel, $user, $no_endof) = @_;

my $in_channel = $channel->has_user($user);
my $prefixes = $user->has_cap('multi-prefix') ? 'prefixes' : 'prefix';

my @str;
my $curr = 0;
foreach my $usr ($channel->users) {

# some extension said not to show this user.
# the first user is the one being considered;
# the second is the one which initiated the NAMES.
next if $channel->fire_event(show_in_names => $usr, $user)->stopper;

# if this user is invisible, do not show him unless the querier is in a common
# channel or has the see_invisible flag.
if ($usr->is_mode('invisible')) {
next if !$channel->has_user($user) && !$user->has_flag('see_invisible');
next if !$in_channel && !$user->has_flag('see_invisible');
}

# add him.
my $prefixes = $user->has_cap('multi-prefix') ? 'prefixes' : 'prefix';
$str[$curr] .= $channel->$prefixes($usr).$usr->{nick}.q( );

# if the current string is over 500 chars, start a new one.
$curr++ if length $str[$curr] > 500;

}
$user->numeric(RPL_NAMREPLY => '=', $channel->name, $_) foreach @str;

# fire an event which allows modules to change the character.
my $c = \'=';
$channel->fire_event(names_character => $c);

# send out the NAMREPLYs, if any. if no users matched, none will be sent.
# then, send out ENDOFNAMES unless told not to by the caller.
$user->numeric(RPL_NAMREPLY => $$c, $channel->name, $_) foreach @str;
$user->numeric(RPL_ENDOFNAMES => $channel->name ) unless $no_endof;

}

# send mode information.
Expand Down

0 comments on commit 3049e4c

Please sign in to comment.