]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/channels.cpp
Allow static build of inspircd without module support
[user/henk/code/inspircd.git] / src / channels.cpp
index b250368b37f3c4605cde91999d17ee0b174ea347..3f0fc4a36271077bc78b15f056b86a109210c6c7 100644 (file)
@@ -125,17 +125,32 @@ Membership* Channel::AddUser(User* user)
        return memb;
 }
 
-unsigned long Channel::DelUser(User* user)
+void Channel::DelUser(User* user)
 {
        UserMembIter a = userlist.find(user);
 
        if (a != userlist.end())
        {
+               a->second->cull();
                delete a->second;
                userlist.erase(a);
        }
 
-       return userlist.size();
+       if (userlist.empty())
+       {
+               ModResult res;
+               FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
+               if (res == MOD_RES_DENY)
+                       return;
+               chan_hash::iterator iter = ServerInstance->chanlist->find(this->name);
+               /* kill the record */
+               if (iter != ServerInstance->chanlist->end())
+               {
+                       FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this));
+                       ServerInstance->chanlist->erase(iter);
+               }
+               ServerInstance->GlobalCulls.AddItem(this);
+       }
 }
 
 bool Channel::HasUser(User* user)
@@ -158,7 +173,8 @@ const UserMembList* Channel::GetUsers()
 
 void Channel::SetDefaultModes()
 {
-       ServerInstance->Logs->Log("CHANNELS", DEBUG, "SetDefaultModes %s", ServerInstance->Config->DefaultModes);
+       ServerInstance->Logs->Log("CHANNELS", DEBUG, "SetDefaultModes %s",
+               ServerInstance->Config->DefaultModes.c_str());
        irc::spacesepstream list(ServerInstance->Config->DefaultModes);
        std::string modeseq;
        std::string parameter;
@@ -202,24 +218,23 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char
         */
        if (IS_LOCAL(user) && !override)
        {
-               // Checking MyClass exists because we *may* get here with NULL, not 100% sure.
-               if (user->MyClass && user->MyClass->maxchans)
+               if (user->HasPrivPermission("channels/high-join-limit"))
                {
-                       if (user->HasPrivPermission("channels/high-join-limit"))
+                       if (user->chans.size() >= ServerInstance->Config->OperMaxChans)
                        {
-                               if (user->chans.size() >= ServerInstance->Config->OperMaxChans)
-                               {
-                                       user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
-                                       return NULL;
-                               }
+                               user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
+                               return NULL;
                        }
-                       else
+               }
+               else
+               {
+                       unsigned int maxchans = user->GetClass()->maxchans;
+                       if (!maxchans)
+                               maxchans = ServerInstance->Config->MaxChans;
+                       if (user->chans.size() >= maxchans)
                        {
-                               if (user->chans.size() >= user->MyClass->maxchans)
-                               {
-                                       user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
-                                       return NULL;
-                               }
+                               user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
+                               return NULL;
                        }
                }
        }
@@ -275,7 +290,7 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char
                        else if (MOD_RESULT == MOD_RES_PASSTHRU)
                        {
                                std::string ckey = Ptr->GetModeParameter('k');
-                               bool invited = user->IsInvited(Ptr->name.c_str());
+                               bool invited = IS_LOCAL(user)->IsInvited(Ptr->name.c_str());
                                bool can_bypass = ServerInstance->Config->InvBypassModes && invited;
 
                                if (!ckey.empty())
@@ -322,7 +337,7 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char
                                 */
                                if (invited)
                                {
-                                       user->RemoveInvite(Ptr->name.c_str());
+                                       IS_LOCAL(user)->RemoveInvite(Ptr->name.c_str());
                                }
                        }
                }
@@ -362,7 +377,9 @@ Channel* Channel::ForceChan(Channel* Ptr, User* user, const std::string &privs,
        Ptr->WriteAllExcept(user, false, 0, except_list, "JOIN :%s", Ptr->name.c_str());
 
        /* Theyre not the first ones in here, make sure everyone else sees the modes we gave the user */
-       std::string ms = ServerInstance->Modes->ModeString(user, Ptr);
+       std::string ms = memb->modes;
+       for(unsigned int i=0; i < memb->modes.length(); i++)
+               ms.append(" ").append(user->nick);
        if ((Ptr->GetUserCounter() > 1) && (ms.length()))
                Ptr->WriteAllExceptSender(user, true, 0, "MODE %s +%s", Ptr->name.c_str(), ms.c_str());
 
@@ -447,10 +464,10 @@ ModResult Channel::GetExtBanStatus(User *user, char type)
  * remove a channel from a users record, and return the number of users left.
  * Therefore, if this function returns 0 the caller should delete the Channel.
  */
-long Channel::PartUser(User *user, std::string &reason)
+void Channel::PartUser(User *user, std::string &reason)
 {
        if (!user)
-               return this->GetUserCounter();
+               return;
 
        Membership* memb = GetUser(user);
 
@@ -465,38 +482,13 @@ long Channel::PartUser(User *user, std::string &reason)
                this->RemoveAllPrefixes(user);
        }
 
-       if (!this->DelUser(user)) /* if there are no users left on the channel... */
-       {
-               chan_hash::iterator iter = ServerInstance->chanlist->find(this->name);
-               /* kill the record */
-               if (iter != ServerInstance->chanlist->end())
-               {
-                       ModResult res;
-                       FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
-                       if (res == MOD_RES_DENY)
-                               return 1; // delete halted by module
-                       FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this));
-                       ServerInstance->chanlist->erase(iter);
-               }
-               return 0;
-       }
-
-       return this->GetUserCounter();
+       this->DelUser(user);
 }
 
-long Channel::ServerKickUser(User* user, const char* reason, const char* servername)
-{
-       if (servername == NULL || *ServerInstance->Config->HideWhoisServer)
-               servername = ServerInstance->Config->ServerName;
-
-       ServerInstance->FakeClient->server = servername;
-       return this->KickUser(ServerInstance->FakeClient, user, reason);
-}
-
-long Channel::KickUser(User *src, User *user, const char* reason)
+void Channel::KickUser(User *src, User *user, const char* reason)
 {
        if (!src || !user || !reason)
-               return this->GetUserCounter();
+               return;
 
        Membership* memb = GetUser(user);
        if (IS_LOCAL(src))
@@ -504,12 +496,12 @@ long Channel::KickUser(User *src, User *user, const char* reason)
                if (!memb)
                {
                        src->WriteNumeric(ERR_USERNOTINCHANNEL, "%s %s %s :They are not on that channel",src->nick.c_str(), user->nick.c_str(), this->name.c_str());
-                       return this->GetUserCounter();
+                       return;
                }
                if ((ServerInstance->ULine(user->server)) && (!ServerInstance->ULine(src->server)))
                {
                        src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only a u-line may kick a u-line from a channel.",src->nick.c_str(), this->name.c_str());
-                       return this->GetUserCounter();
+                       return;
                }
 
                ModResult res;
@@ -519,7 +511,7 @@ long Channel::KickUser(User *src, User *user, const char* reason)
                        FIRST_MOD_RESULT(OnUserPreKick, res, (src,memb,reason));
 
                if (res == MOD_RES_DENY)
-                       return this->GetUserCounter();
+                       return;
 
                if (res == MOD_RES_PASSTHRU)
                {
@@ -528,7 +520,7 @@ long Channel::KickUser(User *src, User *user, const char* reason)
                        if ((them < HALFOP_VALUE) || (them < us))
                        {
                                src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",src->nick.c_str(), this->name.c_str(), them >= HALFOP_VALUE ? "" : "half-");
-                               return this->GetUserCounter();
+                               return;
                        }
                }
        }
@@ -544,25 +536,7 @@ long Channel::KickUser(User *src, User *user, const char* reason)
                this->RemoveAllPrefixes(user);
        }
 
-       if (!this->DelUser(user))
-       /* if there are no users left on the channel */
-       {
-               chan_hash::iterator iter = ServerInstance->chanlist->find(this->name.c_str());
-
-               /* kill the record */
-               if (iter != ServerInstance->chanlist->end())
-               {
-                       ModResult res;
-                       FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
-                       if (res == MOD_RES_DENY)
-                               return 1; // delete halted by module
-                       FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this));
-                       ServerInstance->chanlist->erase(iter);
-               }
-               return 0;
-       }
-
-       return this->GetUserCounter();
+       this->DelUser(user);
 }
 
 void Channel::WriteChannel(User* user, const char* text, ...)
@@ -597,7 +571,7 @@ void Channel::WriteChannel(User* user, const std::string &text)
        }
 }
 
-void Channel::WriteChannelWithServ(const char* ServName, const char* text, ...)
+void Channel::WriteChannelWithServ(const std::string& ServName, const char* text, ...)
 {
        char textbuffer[MAXBUF];
        va_list argsPtr;
@@ -612,11 +586,11 @@ void Channel::WriteChannelWithServ(const char* ServName, const char* text, ...)
        this->WriteChannelWithServ(ServName, std::string(textbuffer));
 }
 
-void Channel::WriteChannelWithServ(const char* ServName, const std::string &text)
+void Channel::WriteChannelWithServ(const std::string& ServName, const std::string &text)
 {
        char tb[MAXBUF];
 
-       snprintf(tb,MAXBUF,":%s %s", ServName ? ServName : ServerInstance->Config->ServerName, text.c_str());
+       snprintf(tb,MAXBUF,":%s %s", ServName.empty() ? ServerInstance->Config->ServerName.c_str() : ServName.c_str(), text.c_str());
        std::string out = tb;
 
        for (UserMembIter i = userlist.begin(); i != userlist.end(); i++)
@@ -664,7 +638,7 @@ void Channel::WriteAllExcept(User* user, bool serversource, char status, CUList
 {
        char tb[MAXBUF];
 
-       snprintf(tb,MAXBUF,":%s %s", serversource ? ServerInstance->Config->ServerName : user->GetFullHost().c_str(), text.c_str());
+       snprintf(tb,MAXBUF,":%s %s", serversource ? ServerInstance->Config->ServerName.c_str() : user->GetFullHost().c_str(), text.c_str());
        std::string out = tb;
 
        this->RawWriteAllExcept(user, serversource, status, except_list, std::string(tb));
@@ -672,19 +646,19 @@ void Channel::WriteAllExcept(User* user, bool serversource, char status, CUList
 
 void Channel::RawWriteAllExcept(User* user, bool serversource, char status, CUList &except_list, const std::string &out)
 {
-       char statmode = 0;
+       unsigned int minrank = 0;
        if (status)
        {
                ModeHandler* mh = ServerInstance->Modes->FindPrefix(status);
                if (mh)
-                       statmode = mh->GetModeChar();
+                       minrank = mh->GetPrefixRank();
        }
        for (UserMembIter i = userlist.begin(); i != userlist.end(); i++)
        {
-               if ((IS_LOCAL(i->first)) && (except_list.find(i->first) == except_list.end()))
+               if (IS_LOCAL(i->first) && (except_list.find(i->first) == except_list.end()))
                {
-                       /* User doesnt have the status we're after */
-                       if (statmode && !i->second->hasMode(statmode))
+                       /* User doesn't have the status we're after */
+                       if (minrank && i->second->getRank() < minrank)
                                continue;
 
                        i->first->Write(out);