X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fchannels.cpp;h=f49d359cd27f778c4a599948e51265ee05a7d0ea;hb=173bc63cb59bbf19e73d1b823e3e9423c9f79860;hp=5954d8ded3fdfc93c307c1e0f276359fc3a6b8c8;hpb=b4a7847bb8f39b466161c5fde7e58d41e81275d7;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/channels.cpp b/src/channels.cpp index 5954d8ded..f49d359cd 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -25,8 +25,6 @@ #include "inspircd.h" #include "listmode.h" -#include -#include "mode.h" namespace { @@ -161,30 +159,26 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co /* * We don't restrict the number of channels that remote users or users that are override-joining may be in. - * We restrict local users to MaxChans channels. - * We restrict local operators to OperMaxChans channels. + * We restrict local users to channels. + * We restrict local operators to channels. * This is a lot more logical than how it was formerly. -- w00t */ if (!override) { - if (user->HasPrivPermission("channels/high-join-limit")) + unsigned int maxchans = user->GetClass()->maxchans; + if (user->IsOper()) { - if (user->chans.size() >= ServerInstance->Config->OperMaxChans) - { - user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str()); - return NULL; - } + unsigned int opermaxchans = ConvToInt(user->oper->getConfig("maxchans")); + // If not set, use 2.0's , if that's not set either, use limit from CC + if (!opermaxchans) + opermaxchans = ServerInstance->Config->OperMaxChans; + if (opermaxchans) + maxchans = opermaxchans; } - else + if (user->chans.size() >= maxchans) { - unsigned int maxchans = user->GetClass()->maxchans; - if (!maxchans) - maxchans = ServerInstance->Config->MaxChans; - if (user->chans.size() >= maxchans) - { - user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str()); - return NULL; - } + user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str()); + return NULL; } } @@ -296,17 +290,17 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co return chan; } -void Channel::ForceJoin(User* user, const std::string* privs, bool bursting, bool created_by_local) +Membership* Channel::ForceJoin(User* user, const std::string* privs, bool bursting, bool created_by_local) { if (IS_SERVER(user)) { ServerInstance->Logs->Log("CHANNELS", LOG_DEBUG, "Attempted to join server user " + user->uuid + " to channel " + this->name); - return; + return NULL; } Membership* memb = this->AddUser(user); if (!memb) - return; // Already on the channel + return NULL; // Already on the channel user->chans.push_front(memb); @@ -354,6 +348,7 @@ void Channel::ForceJoin(User* user, const std::string* privs, bool bursting, boo } FOREACH_MOD(OnPostJoin, (memb)); + return memb; } bool Channel::IsBanned(User* user) @@ -448,52 +443,13 @@ void Channel::PartUser(User *user, std::string &reason) } } -void Channel::KickUser(User* src, User* victim, const std::string& reason, Membership* srcmemb) +void Channel::KickUser(User* src, const UserMembIter& victimiter, const std::string& reason) { - UserMembIter victimiter = userlist.find(victim); - Membership* memb = ((victimiter != userlist.end()) ? victimiter->second : NULL); - - if (!memb) - { - src->WriteNumeric(ERR_USERNOTINCHANNEL, "%s %s :They are not on that channel", victim->nick.c_str(), this->name.c_str()); - return; - } - - // Do the following checks only if the KICK is done by a local user; - // each server enforces its own rules. - if (IS_LOCAL(src)) - { - // Modules are allowed to explicitly allow or deny kicks done by local users - ModResult res; - FIRST_MOD_RESULT(OnUserPreKick, res, (src,memb,reason)); - if (res == MOD_RES_DENY) - return; - - if (res == MOD_RES_PASSTHRU) - { - if (!srcmemb) - srcmemb = GetUser(src); - unsigned int them = srcmemb ? srcmemb->getRank() : 0; - unsigned int req = HALFOP_VALUE; - for (std::string::size_type i = 0; i < memb->modes.length(); i++) - { - ModeHandler* mh = ServerInstance->Modes->FindMode(memb->modes[i], MODETYPE_CHANNEL); - if (mh && mh->GetLevelRequired() > req) - req = mh->GetLevelRequired(); - } - - if (them < req) - { - src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You must be a channel %soperator", - this->name.c_str(), req > HALFOP_VALUE ? "" : "half-"); - return; - } - } - } - + Membership* memb = victimiter->second; CUList except_list; FOREACH_MOD(OnUserKick, (src, memb, reason, except_list)); + User* victim = memb->user; WriteAllExcept(src, false, 0, except_list, "KICK %s %s :%s", name.c_str(), victim->nick.c_str(), reason.c_str()); victim->chans.erase(memb); @@ -626,26 +582,15 @@ const char* Channel::ChanModes(bool showkey) /* compile a userlist of a channel into a string, each nick seperated by * spaces and op, voice etc status shown as @ and +, and send it to 'user' */ -void Channel::UserList(User *user) +void Channel::UserList(User* user, bool has_user) { bool has_privs = user->HasPrivPermission("channels/auspex"); - if (this->IsModeSet(secretmode) && !this->HasUser(user) && !has_privs) - { - user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", this->name.c_str()); - return; - } - std::string list; list.push_back(this->IsModeSet(secretmode) ? '@' : this->IsModeSet(privatemode) ? '*' : '='); list.push_back(' '); list.append(this->name).append(" :"); std::string::size_type pos = list.size(); - /* Improvement by Brain - this doesnt change in value, so why was it inside - * the loop? - */ - bool has_user = this->HasUser(user); - const size_t maxlen = ServerInstance->Config->Limits.MaxLine - 10 - ServerInstance->Config->ServerName.size(); std::string prefixlist; std::string nick; @@ -668,10 +613,11 @@ void Channel::UserList(User *user) prefixlist.push_back(prefix); nick = i->first->nick; - FOREACH_MOD(OnNamesListItem, (user, memb, prefixlist, nick)); + ModResult res; + FIRST_MOD_RESULT(OnNamesListItem, res, (user, memb, prefixlist, nick)); - /* Nick was nuked, a module wants us to skip it */ - if (nick.empty()) + // See if a module wants us to exclude this user from NAMES + if (res == MOD_RES_DENY) continue; if (list.size() + prefixlist.length() + nick.length() + 1 > maxlen) @@ -799,8 +745,6 @@ void Invitation::Create(Channel* c, LocalUser* u, time_t timeout) Invitation* Invitation::Find(Channel* c, LocalUser* u, bool check_expired) { ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Find chan=%s user=%s check_expired=%d", c ? c->name.c_str() : "NULL", u ? u->uuid.c_str() : "NULL", check_expired); - if (!u || u->invites.empty()) - return NULL; Invitation* result = NULL; for (InviteList::iterator i = u->invites.begin(); i != u->invites.end(); )