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,
$set_bantype, $get_bantype,
$drop_chantext, $drop_nicktext,
+ $get_host,
+ $get_host_inchan,
);
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=?");
$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 {
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) = @_;
'autovoice' => 1, 'avoice' => 1,
'neverop' => 1, 'noop' => 1,
+ 'noclones' => 1,
);
my %override_set = (
'hold' => 'SERVOP', 'noexpire' => 'SERVOP', 'no-expire' => 'SERVOP',
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);
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;
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.