]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/channels.cpp
Replace the deprecated MAXBANS token with MAXLIST.
[user/henk/code/inspircd.git] / src / channels.cpp
index 6e3bc5e04e4cbe6f21dcbb4104ed9af9e581c588..bc23c680a07b309a83de482bc29ef7c1ed18dd93 100644 (file)
@@ -46,12 +46,20 @@ void Channel::SetMode(ModeHandler* mh, bool on)
        modes[mh->GetId()] = on;
 }
 
-void Channel::SetTopic(User* u, const std::string& ntopic)
+void Channel::SetTopic(User* u, const std::string& ntopic, time_t topicts, const std::string* setter)
 {
-       this->topic.assign(ntopic, 0, ServerInstance->Config->Limits.MaxTopic);
-       this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128);
-       this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str());
-       this->topicset = ServerInstance->Time();
+       // Send a TOPIC message to the channel only if the new topic text differs
+       if (this->topic != ntopic)
+       {
+               this->topic = ntopic;
+               this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str());
+       }
+
+       // Always update setter and set time
+       if (!setter)
+               setter = ServerInstance->Config->FullHostInTopic ? &u->GetFullHost() : &u->nick;
+       this->setby.assign(*setter, 0, ServerInstance->Config->Limits.GetMaxMask());
+       this->topicset = topicts;
 
        FOREACH_MOD(OnPostTopicChange, (u, this, this->topic));
 }
@@ -130,7 +138,7 @@ void Channel::SetDefaultModes()
                        if (mode->IsPrefixMode())
                                continue;
 
-                       if (mode->GetNumParams(true))
+                       if (mode->NeedsParam(true))
                        {
                                list.GetToken(parameter);
                                // If the parameter begins with a ':' then it's invalid
@@ -140,7 +148,7 @@ void Channel::SetDefaultModes()
                        else
                                parameter.clear();
 
-                       if ((mode->GetNumParams(true)) && (parameter.empty()))
+                       if ((mode->NeedsParam(true)) && (parameter.empty()))
                                continue;
 
                        mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, this, parameter, true);
@@ -173,14 +181,14 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co
                {
                        unsigned int opermaxchans = ConvToInt(user->oper->getConfig("maxchans"));
                        // If not set, use 2.0's <channels:opers>, if that's not set either, use limit from CC
-                       if (!opermaxchans)
+                       if (!opermaxchans && user->HasPrivPermission("channels/high-join-limit"))
                                opermaxchans = ServerInstance->Config->OperMaxChans;
                        if (opermaxchans)
                                maxchans = opermaxchans;
                }
                if (user->chans.size() >= maxchans)
                {
-                       user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str());
+                       user->WriteNumeric(ERR_TOOMANYCHANNELS, cname, "You are on too many channels");
                        return NULL;
                }
        }
@@ -240,7 +248,7 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co
                                        if (!MOD_RESULT.check(InspIRCd::TimingSafeCompare(ckey, key)))
                                        {
                                                // If no key provided, or key is not the right one, and can't bypass +k (not invited or option not enabled)
-                                               user->WriteNumeric(ERR_BADCHANNELKEY, "%s :Cannot join channel (Incorrect channel key)", chan->name.c_str());
+                                               user->WriteNumeric(ERR_BADCHANNELKEY, chan->name, "Cannot join channel (Incorrect channel key)");
                                                return NULL;
                                        }
                                }
@@ -250,7 +258,7 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co
                                        FIRST_MOD_RESULT(OnCheckInvite, MOD_RESULT, (user, chan));
                                        if (MOD_RESULT != MOD_RES_ALLOW)
                                        {
-                                               user->WriteNumeric(ERR_INVITEONLYCHAN, "%s :Cannot join channel (Invite only)", chan->name.c_str());
+                                               user->WriteNumeric(ERR_INVITEONLYCHAN, chan->name, "Cannot join channel (Invite only)");
                                                return NULL;
                                        }
                                }
@@ -261,14 +269,14 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co
                                        FIRST_MOD_RESULT(OnCheckLimit, MOD_RESULT, (user, chan));
                                        if (!MOD_RESULT.check((chan->GetUserCounter() < atol(limit.c_str()))))
                                        {
-                                               user->WriteNumeric(ERR_CHANNELISFULL, "%s :Cannot join channel (Channel is full)", chan->name.c_str());
+                                               user->WriteNumeric(ERR_CHANNELISFULL, chan->name, "Cannot join channel (Channel is full)");
                                                return NULL;
                                        }
                                }
 
                                if (chan->IsBanned(user))
                                {
-                                       user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s :Cannot join channel (You're banned)", chan->name.c_str());
+                                       user->WriteNumeric(ERR_BANNEDFROMCHAN, chan->name, "Cannot join channel (You're banned)");
                                        return NULL;
                                }
                        }
@@ -405,23 +413,25 @@ ModResult Channel::GetExtBanStatus(User *user, char type)
  * Remove a channel from a users record, remove the reference to the Membership object
  * from the channel and destroy it.
  */
-void Channel::PartUser(User *user, std::string &reason)
+bool Channel::PartUser(User* user, std::string& reason)
 {
        MemberMap::iterator membiter = userlist.find(user);
 
-       if (membiter != userlist.end())
-       {
-               Membership* memb = membiter->second;
-               CUList except_list;
-               FOREACH_MOD(OnUserPart, (memb, reason, except_list));
+       if (membiter == userlist.end())
+               return false;
+
+       Membership* memb = membiter->second;
+       CUList except_list;
+       FOREACH_MOD(OnUserPart, (memb, reason, except_list));
 
-               WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
+       WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
 
-               // Remove this channel from the user's chanlist
-               user->chans.erase(memb);
-               // Remove the Membership from this channel's userlist and destroy it
-               this->DelUser(membiter);
-       }
+       // Remove this channel from the user's chanlist
+       user->chans.erase(memb);
+       // Remove the Membership from this channel's userlist and destroy it
+       this->DelUser(membiter);
+
+       return true;
 }
 
 void Channel::KickUser(User* src, const MemberMap::iterator& victimiter, const std::string& reason)
@@ -560,6 +570,13 @@ const char* Channel::ChanModes(bool showkey)
        return scratch.c_str();
 }
 
+void Channel::WriteNotice(const std::string& text)
+{
+       std::string rawmsg = "NOTICE ";
+       rawmsg.append(this->name).append(" :").append(text);
+       WriteChannelWithServ(ServerInstance->Config->ServerName, rawmsg);
+}
+
 /* returns the status character for a given user on a channel, e.g. @ for op,
  * % for halfop etc. If the user has several modes set, the highest mode
  * the user has must be returned.
@@ -594,20 +611,17 @@ unsigned int Membership::getRank()
        return rv;
 }
 
-const char* Membership::GetAllPrefixChars() const
+std::string Membership::GetAllPrefixChars() const
 {
-       static char prefix[64];
-       int ctr = 0;
-
+       std::string ret;
        for (std::string::const_iterator i = modes.begin(); i != modes.end(); ++i)
        {
                PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(*i);
                if (mh && mh->GetPrefix())
-                       prefix[ctr++] = mh->GetPrefix();
+                       ret.push_back(mh->GetPrefix());
        }
-       prefix[ctr] = 0;
 
-       return prefix;
+       return ret;
 }
 
 unsigned int Channel::GetPrefixValue(User* user)