From: erry Date: Fri, 2 Sep 2011 16:54:45 +0000 (+0000) Subject: /cs set noclones; prevents clones from joining channels. Appears to work. Help files... X-Git-Url: https://jfr.im/git/irc/SurrealServices/srsv.git/commitdiff_plain/0b380dbc163653e55670fba629c7183cf1eeb9ed /cs set noclones; prevents clones from joining channels. Appears to work. Help files included. git-svn-id: http://svn.tabris.net/repos/srsv@3560 70d4eda1-72e9-0310-a436-91e5bd24443c --- diff --git a/branches/0.4.3/SrSv/ChanReg/Flags.pm b/branches/0.4.3/SrSv/ChanReg/Flags.pm index fbc331b3..e42bfbfd 100644 --- a/branches/0.4.3/SrSv/ChanReg/Flags.pm +++ b/branches/0.4.3/SrSv/ChanReg/Flags.pm @@ -42,6 +42,7 @@ BEGIN { CRF_AUTOVOICE => 1024, CRF_WELCOMEINCHAN => 2048, CRF_NEVEROP => 4096, + CRF_NOCLONES => 8192, ); our @EXPORT = (qw(cr_chk_flag cr_set_flag), keys(%constants)); diff --git a/branches/0.4.3/help/chanserv/set.txt b/branches/0.4.3/help/chanserv/set.txt index 5a424df9..480a6682 100644 --- a/branches/0.4.3/help/chanserv/set.txt +++ b/branches/0.4.3/help/chanserv/set.txt @@ -17,7 +17,7 @@ Settings: AUTOVOICE Voices everyone who joins the channel. BANTYPE Selects the ban-type to be used for KICKBAN and AKICKs TOPICLOCK Restricts who can change the topic in the channel. - + NOCLONES Bans people who bring clones into the channel. Oper only flags: HOLD Prevent channel from expiring FREEZE Suspend access in this channel diff --git a/branches/0.4.3/help/chanserv/set/noclones.txt b/branches/0.4.3/help/chanserv/set/noclones.txt new file mode 100644 index 00000000..0a757437 --- /dev/null +++ b/branches/0.4.3/help/chanserv/set/noclones.txt @@ -0,0 +1,4 @@ +%BChanServ SET NOCLONES%B Kicks and bans users who bring clones (multiple connections) to a channel. +Users in the channel's access lists are excempt. + +Syntax: %BSET%B %U#channel%U %BNOCLONES%B <%UON/OFF%U> diff --git a/branches/0.4.3/modules/serviceslibs/chanserv.pm b/branches/0.4.3/modules/serviceslibs/chanserv.pm index cde9d58a..fba111cf 100644 --- a/branches/0.4.3/modules/serviceslibs/chanserv.pm +++ b/branches/0.4.3/modules/serviceslibs/chanserv.pm @@ -148,7 +148,7 @@ our ($cur_lock, $cnt_lock); our ( $get_joinpart_lock, $get_modelock_lock, $get_update_modes_lock, - $chanjoin, $chanpart, $chop, $chdeop, $get_op, $get_user_chans, $get_user_chans_recent, + $chanjoin, $chanpart, $chanpart2, $chop, $chdeop, $get_op, $get_user_chans, $get_user_chans_recent, $get_all_closed_chans, $get_user_count, $is_in_chan, @@ -212,6 +212,8 @@ our ( $set_bantype, $get_bantype, $drop_chantext, $drop_nicktext, + $get_host, + $get_host_inchan, ); sub init() { @@ -223,6 +225,7 @@ sub init() { $chanjoin = $dbh->prepare("REPLACE INTO chanuser (seq,nickid,chan,op,joined) VALUES (?, ?, ?, ?, 1)"); $chanpart = $dbh->prepare("UPDATE chanuser SET joined=0, seq=? WHERE nickid=? AND chan=? AND (seq <= ? OR seq > ?)"); + $chanpart2 = $dbh->prepare("UPDATE chanuser SET joined=0 WHERE nickid=? AND chan=?"); #$chop = $dbh->prepare("UPDATE chanuser SET op=op+? WHERE nickid=? AND chan=?"); $chop = $dbh->prepare("UPDATE chanuser SET op=IF(op & ?, op, op ^ ?) WHERE nickid=? AND chan=?"); $chdeop = $dbh->prepare("UPDATE chanuser SET op=IF(op & ?, op ^ ?, op) WHERE nickid=? AND chan=?"); @@ -510,6 +513,8 @@ sub init() { $drop_chantext = $dbh->prepare("DELETE FROM chantext WHERE chan=?"); $drop_nicktext = $dbh->prepare("DELETE nicktext.* FROM nicktext WHERE nicktext.chan=?"); + $get_host = $dbh->prepare ("SELECT user.host from user where user.nick=?"); + $get_host_inchan = $dbh->prepare ("select user.nick from user left join chanuser on (user.id=chanuser.nickid) where user.host=? and chanuser.joined=1 and chanuser.chan=? and user.nick<>?"); } use SrSv::MySQL::Stub { @@ -537,6 +542,22 @@ our %high_priority_cmds = ( down => 1, ); +sub clones_exist ($$) { + my ($user, $chan) = @_; + my $cn = $chan->{CHAN}; + unless(cr_chk_flag($chan, CRF_NOCLONES)) { + return; + } + my $nick = $user->{NICK}; + $get_host->execute($nick); + my ($host) = $get_host->fetchrow_array; + $get_host_inchan -> execute ($host,$cn,$nick); + my ($joined) = $get_host_inchan->fetchrow_array; + if ($joined) { + return $joined; + } + return 0; +} sub dispatch($$$) { my ($src, $dst, $msg) = @_; @@ -1750,6 +1771,7 @@ sub cs_set_pre($$$$) { 'autovoice' => 1, 'avoice' => 1, 'neverop' => 1, 'noop' => 1, + 'noclones' => 1, ); my %override_set = ( 'hold' => 'SERVOP', 'noexpire' => 'SERVOP', 'no-expire' => 'SERVOP', @@ -1926,7 +1948,20 @@ sub cs_set($$$;$) { notice($user, "Please say \002on\002 or \002off\002."); return; } - + if ($set =~ /^(?:noclones)$/i) { + cr_set_flag($chan, CRF_NOCLONES, $val); + if($val) { + notice($user, + "Noclones is now \002ON\002.", + "Clones will be kicked out of \002$cn\002." + ); + } else { + notice($user, + "Noclones is now \002OFF\002.", + "People are allowed to bring clones in \002$cn\002." + ); + } + } if($set =~ /^(?:opguard|secureops)$/i) { cr_set_flag($chan, CRF_OPGUARD, $val); @@ -3700,7 +3735,14 @@ sub do_status($$;$) { return 0; } my ($acc, $root) = get_best_acc($user, $chan, 2); - if(!can_do($chan, 'JOIN', $user, { ACC => $acc, NOREPLY => 1 })) { + my ($accnick, $override) = can_do($chan, 'JOIN', $user, { ACC => $acc, NOREPLY => 1 }); + unless ($acc > 0 || $override) { + if (clones_exist ($user, $chan)) { + kickban($chan, $user, undef, 'No clones allowed in this channel.') + } + } + + if(!$accnick && !$override) { kickban($chan, $user, undef, 'This is a private channel.') unless $check_only; return 0; @@ -4608,6 +4650,7 @@ sub user_join_multi($$) { foreach my $user (@$users) { $user->{__ID} = get_user_id($user); + unless (defined($user->{__ID})) { # This does happen occasionally. it's a BUG. # At least we have a diagnostic for it now.