]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/netburst.cpp
m_spanningtree Remove unneeded #includes
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / netburst.cpp
index 5248ea897e3a33dcc4ba5f4be58ba062cd2d2d68..566224c7a6c8b1f5e7057e5453abbee3e3dd9890 100644 (file)
 
 #include "inspircd.h"
 #include "xline.h"
+#include "listmode.h"
 
 #include "treesocket.h"
 #include "treeserver.h"
-#include "utils.h"
 #include "main.h"
 
 /** This function is called when we want to send a netburst to a local
@@ -47,8 +47,10 @@ void TreeSocket::DoBurst(TreeServer* s)
        this->SendServers(Utils->TreeRoot,s,1);
        /* Send users and their oper status */
        this->SendUsers();
-       /* Send everything else (channel modes, xlines etc) */
-       this->SendChannelModes();
+
+       for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); ++i)
+               SyncChannel(i->second);
+
        this->SendXLines();
        FOREACH_MOD(I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this));
        this->WriteLine(":" + ServerInstance->Config->GetSID() + " ENDBURST");
@@ -87,101 +89,49 @@ void TreeSocket::SendServers(TreeServer* Current, TreeServer* s, int hops)
 /** Send one or more FJOINs for a channel of users.
  * If the length of a single line is more than 480-NICKMAX
  * in length, it is split over multiple lines.
+ * Send one or more FMODEs for a channel with the
+ * channel bans, if there's any.
  */
 void TreeSocket::SendFJoins(Channel* c)
 {
-       std::string buffer;
-       char list[MAXBUF];
-
-       size_t curlen, headlen;
-       curlen = headlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu +%s :",
-               ServerInstance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true));
-       int numusers = 0;
-       char* ptr = list + curlen;
-       bool looped_once = false;
+       std::string line(":");
+       line.append(ServerInstance->Config->GetSID()).append(" FJOIN ").append(c->name).append(1, ' ').append(ConvToStr(c->age)).append(" +");
+       std::string::size_type erase_from = line.length();
+       line.append(c->ChanModes(true)).append(" :");
 
        const UserMembList *ulist = c->GetUsers();
-       std::string modes;
-       std::string params;
 
-       for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++)
+       for (UserMembCIter i = ulist->begin(); i != ulist->end(); ++i)
        {
-               size_t ptrlen = 0;
-               std::string modestr = i->second->modes;
-
-               if ((curlen + modestr.length() + i->first->uuid.length() + 4) > 480)
+               const std::string& modestr = i->second->modes;
+               if ((line.length() + modestr.length() + (UUID_LENGTH-1) + 2) > 480)
                {
-                       // remove the final space
-                       if (ptr[-1] == ' ')
-                               ptr[-1] = '\0';
-                       buffer.append(list).append("\r\n");
-                       curlen = headlen;
-                       ptr = list + headlen;
-                       numusers = 0;
+                       this->WriteLine(line);
+                       line.erase(erase_from);
+                       line.append(" :");
                }
-
-               ptrlen = snprintf(ptr, MAXBUF-curlen, "%s,%s ", modestr.c_str(), i->first->uuid.c_str());
-
-               looped_once = true;
-
-               curlen += ptrlen;
-               ptr += ptrlen;
-
-               numusers++;
+               line.append(modestr).append(1, ',').append(i->first->uuid).push_back(' ');
        }
+       this->WriteLine(line);
 
-       // Okay, permanent channels will (of course) need this \r\n anyway, numusers check is if there
-       // actually were people in the channel (looped_once == true)
-       if (!looped_once || numusers > 0)
-       {
-               // remove the final space
-               if (ptr[-1] == ' ')
-                       ptr[-1] = '\0';
-               buffer.append(list).append("\r\n");
-       }
-
-       int linesize = 1;
-       for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++)
-       {
-               int size = b->data.length() + 2;
-               int currsize = linesize + size;
-               if (currsize <= 350)
-               {
-                       modes.append("b");
-                       params.append(" ").append(b->data);
-                       linesize += size;
-               }
-               if ((modes.length() >= ServerInstance->Config->Limits.MaxModes) || (currsize > 350))
-               {
-                       /* Wrap at MAXMODES */
-                       buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n");
-                       modes.clear();
-                       params.clear();
-                       linesize = 1;
-               }
-       }
-
-       /* Only send these if there are any */
-       if (!modes.empty())
-               buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params);
-
-       this->WriteLine(buffer);
+       ModeReference ban(NULL, "ban");
+       static_cast<ListModeBase*>(*ban)->DoSyncChannel(c, Utils->Creator, this);
 }
 
 /** Send all XLines we know about */
 void TreeSocket::SendXLines()
 {
        char data[MAXBUF];
-       std::string n = ServerInstance->Config->GetSID();
-       const char* sn = n.c_str();
+       const char* sn = ServerInstance->Config->GetSID().c_str();
 
        std::vector<std::string> types = ServerInstance->XLines->GetAllTypes();
-       time_t current = ServerInstance->Time();
 
-       for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); ++it)
+       for (std::vector<std::string>::const_iterator it = types.begin(); it != types.end(); ++it)
        {
+               /* Expired lines are removed in XLineManager::GetAll() */
                XLineLookup* lookup = ServerInstance->XLines->GetAll(*it);
 
+               /* lookup cannot be NULL in this case but a check won't hurt */
                if (lookup)
                {
                        for (LookupIter i = lookup->begin(); i != lookup->end(); ++i)
@@ -192,11 +142,6 @@ void TreeSocket::SendXLines()
                                if (!i->second->IsBurstable())
                                        break;
 
-                               /* If it's expired, don't bother to burst it
-                                */
-                               if (i->second->duration && current > i->second->expiry)
-                                       continue;
-
                                snprintf(data,MAXBUF,":%s ADDLINE %s %s %s %lu %lu :%s",sn, it->c_str(), i->second->Displayable(),
                                                i->second->source.c_str(),
                                                (unsigned long)i->second->set_time,
@@ -209,31 +154,26 @@ void TreeSocket::SendXLines()
 }
 
 /** Send channel topic, modes and metadata */
-void TreeSocket::SendChannelModes()
+void TreeSocket::SyncChannel(Channel* chan)
 {
        char data[MAXBUF];
-       std::string n = ServerInstance->Config->GetSID();
-       const char* sn = n.c_str();
 
-       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
+       SendFJoins(chan);
+       if (!chan->topic.empty())
        {
-               SendFJoins(c->second);
-               if (!c->second->topic.empty())
-               {
-                       snprintf(data,MAXBUF,":%s FTOPIC %s %lu %s :%s", sn, c->second->name.c_str(), (unsigned long)c->second->topicset, c->second->setby.c_str(), c->second->topic.c_str());
-                       this->WriteLine(data);
-               }
-
-               for(Extensible::ExtensibleStore::const_iterator i = c->second->GetExtList().begin(); i != c->second->GetExtList().end(); i++)
-               {
-                       ExtensionItem* item = i->first;
-                       std::string value = item->serialize(FORMAT_NETWORK, c->second, i->second);
-                       if (!value.empty())
-                               Utils->Creator->ProtoSendMetaData(this, c->second, item->name, value);
-               }
+               snprintf(data,MAXBUF,":%s FTOPIC %s %lu %s :%s", ServerInstance->Config->GetSID().c_str(), chan->name.c_str(), (unsigned long)chan->topicset, chan->setby.c_str(), chan->topic.c_str());
+               this->WriteLine(data);
+       }
 
-               FOREACH_MOD(I_OnSyncChannel,OnSyncChannel(c->second,Utils->Creator,this));
+       for (Extensible::ExtensibleStore::const_iterator i = chan->GetExtList().begin(); i != chan->GetExtList().end(); i++)
+       {
+               ExtensionItem* item = i->first;
+               std::string value = item->serialize(FORMAT_NETWORK, chan, i->second);
+               if (!value.empty())
+                       Utils->Creator->ProtoSendMetaData(this, chan, item->name, value);
        }
+
+       FOREACH_MOD(I_OnSyncChannel,OnSyncChannel(chan, Utils->Creator, this));
 }
 
 /** send all users and their oper state/modes */
@@ -256,17 +196,17 @@ void TreeSocket::SendUsers()
                                                u->second->host.c_str(),        /* 3: Displayed Host */
                                                u->second->dhost.c_str(),       /* 4: Real host */
                                                u->second->ident.c_str(),       /* 5: Ident */
-                                               u->second->GetIPString(),       /* 6: IP string */
+                                               u->second->GetIPString().c_str(),       /* 6: IP string */
                                                (unsigned long)u->second->signon, /* 7: Signon time for WHOWAS */
                                                u->second->FormatModes(true),   /* 8...n: Modes and params */
                                                u->second->fullname.c_str());   /* size-1: GECOS */
                                this->WriteLine(data);
-                               if (IS_OPER(u->second))
+                               if (u->second->IsOper())
                                {
                                        snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->uuid.c_str(), u->second->oper->name.c_str());
                                        this->WriteLine(data);
                                }
-                               if (IS_AWAY(u->second))
+                               if (u->second->IsAway())
                                {
                                        snprintf(data,MAXBUF,":%s AWAY %ld :%s", u->second->uuid.c_str(), (long)u->second->awaytime, u->second->awaymsg.c_str());
                                        this->WriteLine(data);