]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/channels.cpp
Fix this so it works, passes test case. Provide a method to query for a bit and to...
[user/henk/code/inspircd.git] / src / channels.cpp
index 5e2ef907c866da549c550019daf48e093f830979..948b49a0bf5556edc3f7b606ca679b7b92c8d413 100644 (file)
@@ -30,6 +30,7 @@ chanrec::chanrec(InspIRCd* Instance) : ServerInstance(Instance)
        created = topicset = limit = 0;
        internal_userlist.clear();
        memset(&modes,0,64);
+       age = ServerInstance->Time(true);
 }
 
 void chanrec::SetMode(char mode,bool mode_on)
@@ -225,7 +226,11 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo
                Instance->chanlist[cname] = Ptr;
 
                strlcpy(Ptr->name, cname,CHANMAX);
-               Ptr->modes[CM_TOPICLOCK] = Ptr->modes[CM_NOEXTERNAL] = 1;
+
+               /* As spotted by jilles, dont bother to set this on remote users */
+               if (IS_LOCAL(user))
+                       Ptr->modes[CM_TOPICLOCK] = Ptr->modes[CM_NOEXTERNAL] = 1;
+
                Ptr->created = Instance->Time();
                *Ptr->topic = 0;
                *Ptr->setby = 0;
@@ -301,8 +306,6 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo
                                }
                                if (Ptr->bans.size())
                                {
-                                       char mask[MAXBUF];
-                                       snprintf(mask, MAXBUF, "%s!%s@%s",user->nick, user->ident, user->GetIPString());
                                        if (Ptr->IsBanned(user))
                                        {
                                                user->WriteServ("474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name);
@@ -387,33 +390,30 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo
 
 chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* user, const std::string &privs)
 {
+       userrec* dummyuser = new userrec(Instance);
+       std::string nick = user->nick;
+
        a->uc_modes = 0;
+       dummyuser->SetFd(FD_MAGIC_NUMBER);
+
+       a->channel = Ptr;
+       Ptr->AddUser(user);
+       user->ModChannelCount(1);
 
        for (std::string::const_iterator x = privs.begin(); x != privs.end(); x++)
        {
                const char status = *x;
-               switch (status)
-               {
-                       case '@':
-                               a->uc_modes |= UCMODE_OP;
-                       break;
-                       case '%':
-                               a->uc_modes |= UCMODE_HOP;
-                       break;
-                       case '+':
-                               a->uc_modes |= UCMODE_VOICE;
-                       break;
-               }
                ModeHandler* mh = Instance->Modes->FindPrefix(status);
                if (mh)
                {
                        Ptr->SetPrefix(user, status, mh->GetPrefixRank(), true);
+                       /* Make sure that the mode handler knows this mode was now set */
+                       mh->OnModeChange(dummyuser, dummyuser, Ptr, nick, true);
                }
        }
 
-       a->channel = Ptr;
-       Ptr->AddUser(user);
-       user->ModChannelCount(1);
+       delete dummyuser;
+
        Ptr->WriteChannel(user,"JOIN :%s",Ptr->name);
 
        /* Theyre not the first ones in here, make sure everyone else sees the modes we gave the user */
@@ -432,6 +432,7 @@ chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* u
                Ptr->UserList(user);
        }
        FOREACH_MOD_I(Instance,I_OnUserJoin,OnUserJoin(user,Ptr));
+       FOREACH_MOD_I(Instance,I_OnPostJoin,OnPostJoin(user,Ptr));
        return Ptr;
 }
 
@@ -892,6 +893,11 @@ const char* chanrec::GetPrefixChar(userrec *user)
        {
                if (n->second.size())
                {
+                       /* If the user has any prefixes, their highest prefix
+                        * will always be at the head of the list, as the list is
+                        * sorted in rank order highest first (see SetPrefix()
+                        * for reasons why)
+                        */
                        *pf = n->second.begin()->first;
                        return pf;
                }
@@ -973,11 +979,6 @@ int chanrec::GetStatus(userrec *user)
        return STATUS_NORMAL;
 }
 
-/*bool ModeParser::PrefixComparison(const prefixtype one, const prefixtype two)
-{       
-        return one.second > two.second;
-}*/
-
 void chanrec::SetPrefix(userrec* user, char prefix, unsigned int prefix_value, bool adding)
 {
        prefixlist::iterator n = prefixes.find(user);
@@ -989,6 +990,11 @@ void chanrec::SetPrefix(userrec* user, char prefix, unsigned int prefix_value, b
                        if (std::find(n->second.begin(), n->second.end(), pfx) == n->second.end())
                        {
                                n->second.push_back(pfx);
+                               /* We must keep prefixes in rank order, largest first.
+                                * This is for two reasons, firstly because x-chat *ass-u-me's* this
+                                * state, and secondly it turns out to be a benefit to us later.
+                                * See above in GetPrefix().
+                                */
                                std::sort(n->second.begin(), n->second.end(), ModeParser::PrefixComparison);
                        }
                }
@@ -1008,12 +1014,16 @@ void chanrec::SetPrefix(userrec* user, char prefix, unsigned int prefix_value, b
                                n->second.erase(x);
                }
        }
+       ServerInstance->Log(DEBUG,"Added prefix %c to %s for %s, prefixlist size is now %d", prefix, this->name, user->nick, prefixes.size());
 }
 
 void chanrec::RemoveAllPrefixes(userrec* user)
 {
        prefixlist::iterator n = prefixes.find(user);
        if (n != prefixes.end())
+       {
+               ServerInstance->Log(DEBUG,"Removed prefixes from %s for %s, prefixlist size is now %d", this->name, user->nick, prefixes.size());
                prefixes.erase(n);
+       }
 }