/** Handle /KICK */ CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User *user) { std::string reason; Channel* c = ServerInstance->FindChan(parameters[0]); User* u; if (CommandParser::LoopCall(user, this, parameters, 1)) return CMD_SUCCESS; if (IS_LOCAL(user)) u = ServerInstance->FindNickOnly(parameters[1]); else u = ServerInstance->FindNick(parameters[1]); if ((!u) || (!c) || (u->registered != REG_ALL)) { user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c ? parameters[1].c_str() : parameters[0].c_str()); return CMD_FAILURE; } Membership* srcmemb = NULL; if (IS_LOCAL(user)) { srcmemb = c->GetUser(user); if (!srcmemb) { user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", parameters[0].c_str()); return CMD_FAILURE; } if (u->server->IsULine()) { user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You may not kick a u-lined client", c->name.c_str()); return CMD_FAILURE; } } if (parameters.size() > 2) { reason.assign(parameters[2], 0, ServerInstance->Config->Limits.MaxKick); } else { reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick); } c->KickUser(user, u, reason, srcmemb); return CMD_SUCCESS; }
ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) override { if (target.type != MessageTarget::TYPE_CHANNEL || !IS_LOCAL(user)) return MOD_RES_PASSTHRU; Channel* chan = target.Get<Channel>(); ChannelSettings* settings = rm.ext.get(chan); if (!settings) return MOD_RES_PASSTHRU; Membership* memb = chan->GetUser(user); if (!memb) return MOD_RES_PASSTHRU; ModResult res = CheckExemption::Call(exemptionprov, user, chan, "repeat"); if (res == MOD_RES_ALLOW) return MOD_RES_PASSTHRU; if (rm.MatchLine(memb, settings, details.text)) { if (settings->Action == ChannelSettings::ACT_BLOCK) { user->WriteNotice("*** This line is too similar to one of your last lines."); return MOD_RES_DENY; } if (settings->Action == ChannelSettings::ACT_BAN) { Modes::ChangeList changelist; changelist.push_add(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->GetDisplayedHost()); ServerInstance->Modes.Process(ServerInstance->FakeClient, chan, NULL, changelist); } memb->chan->KickUser(ServerInstance->FakeClient, user, "Repeat flood"); return MOD_RES_DENY; } return MOD_RES_PASSTHRU; }
void User::DoHostCycle(const std::string &quitline) { char buffer[MAXBUF]; if (!ServerInstance->Config->CycleHosts) return; already_sent_t silent_id = ++LocalUser::already_sent_id; already_sent_t seen_id = ++LocalUser::already_sent_id; UserChanList include_c(chans); std::map<User*,bool> exceptions; FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions)); for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { LocalUser* u = IS_LOCAL(i->first); if (u && !u->quitting) { if (i->second) { u->already_sent = seen_id; u->Write(quitline); } else { u->already_sent = silent_id; } } } for (UCListIter v = include_c.begin(); v != include_c.end(); ++v) { Channel* c = *v; snprintf(buffer, MAXBUF, ":%s JOIN %s", GetFullHost().c_str(), c->name.c_str()); std::string joinline(buffer); Membership* memb = c->GetUser(this); std::string modeline = memb->modes; if (modeline.length() > 0) { for(unsigned int i=0; i < memb->modes.length(); i++) modeline.append(" ").append(nick); snprintf(buffer, MAXBUF, ":%s MODE %s +%s", ServerInstance->Config->CycleHostsFromUser ? GetFullHost().c_str() : ServerInstance->Config->ServerName.c_str(), c->name.c_str(), modeline.c_str()); modeline = buffer; } const UserMembList *ulist = c->GetUsers(); for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { LocalUser* u = IS_LOCAL(i->first); if (u == NULL || u == this) continue; if (u->already_sent == silent_id) continue; if (u->already_sent != seen_id) { u->Write(quitline); u->already_sent = seen_id; } u->Write(joinline); if (modeline.length() > 0) u->Write(modeline); } } }