diff options
Diffstat (limited to 'src/modules/m_spanningtree')
-rw-r--r-- | src/modules/m_spanningtree/commandbuilder.h | 1 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 20 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.h | 1 | ||||
-rw-r--r-- | src/modules/m_spanningtree/netburst.cpp | 97 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket.h | 4 |
5 files changed, 99 insertions, 24 deletions
diff --git a/src/modules/m_spanningtree/commandbuilder.h b/src/modules/m_spanningtree/commandbuilder.h index 597b22751..aa4778fa9 100644 --- a/src/modules/m_spanningtree/commandbuilder.h +++ b/src/modules/m_spanningtree/commandbuilder.h @@ -25,6 +25,7 @@ class TreeServer; class CmdBuilder { + protected: std::string content; public: diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index f264f9a7a..6e992c02d 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -718,26 +718,6 @@ ModResult ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg) return MOD_RES_PASSTHRU; } -void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const parameterlist &modeline, const std::vector<TranslateType> &translate) -{ - TreeSocket* s = (TreeSocket*)opaque; - std::string output_text = CommandParser::TranslateUIDs(translate, modeline); - - if (target) - { - if (target_type == TYPE_USER) - { - User* u = (User*)target; - s->WriteLine(":"+ServerInstance->Config->GetSID()+" MODE "+u->uuid+" "+output_text); - } - else if (target_type == TYPE_CHANNEL) - { - Channel* c = (Channel*)target; - s->WriteLine(":"+ServerInstance->Config->GetSID()+" FMODE "+c->name+" "+ConvToStr(c->age)+" "+output_text); - } - } -} - void ModuleSpanningTree::ProtoSendMetaData(void* opaque, Extensible* target, const std::string &extname, const std::string &extdata) { TreeSocket* s = static_cast<TreeSocket*>(opaque); diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 8a13c7814..737b7d576 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -158,7 +158,6 @@ class ModuleSpanningTree : public Module void OnDelLine(User *u, XLine *x) CXX11_OVERRIDE; ModResult OnStats(char statschar, User* user, string_list &results) CXX11_OVERRIDE; ModResult OnSetAway(User* user, const std::string &awaymsg) CXX11_OVERRIDE; - void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::vector<std::string> &modeline, const std::vector<TranslateType> &translate); void ProtoSendMetaData(void* opaque, Extensible* target, const std::string &extname, const std::string &extdata); void OnLoadModule(Module* mod) CXX11_OVERRIDE; void OnUnloadModule(Module* mod) CXX11_OVERRIDE; diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index d4669442a..9ca5b04d4 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -28,6 +28,67 @@ #include "main.h" #include "commands.h" +/** + * Creates FMODE messages, used only when syncing channels + */ +class FModeBuilder : public CmdBuilder +{ + static const size_t maxline = 480; + std::string params; + unsigned int modes; + std::string::size_type startpos; + + public: + FModeBuilder(Channel* chan) + : CmdBuilder("FMODE"), modes(0) + { + push(chan->name).push_int(chan->age).push_raw(" +"); + startpos = str().size(); + } + + /** Add a mode to the message + */ + void push_mode(const char modeletter, const std::string& mask) + { + push_raw(modeletter); + params.push_back(' '); + params.append(mask); + modes++; + } + + /** Remove all modes from the message + */ + void clear() + { + content.erase(startpos); + params.clear(); + modes = 0; + } + + /** Prepare the message for sending, next mode can only be added after clear() + */ + const std::string& finalize() + { + return push_raw(params); + } + + /** Returns true if the given mask can be added to the message, false if the message + * has no room for the mask + */ + bool has_room(const std::string& mask) const + { + return ((str().size() + params.size() + mask.size() + 2 <= maxline) && + (modes < ServerInstance->Config->Limits.MaxModes)); + } + + /** Returns true if this message is empty (has no modes) + */ + bool empty() const + { + return (modes == 0); + } +}; + /** This function is called when we want to send a netburst to a local * server. There is a set order we must do this, because for example * users require their servers to exist, and channels require their @@ -107,9 +168,6 @@ void TreeSocket::SendFJoins(Channel* c) line.append(modestr).append(1, ',').append(i->first->uuid).push_back(' '); } this->WriteLine(line); - - ChanModeReference ban(NULL, "ban"); - static_cast<ListModeBase*>(*ban)->DoSyncChannel(c, Utils->Creator, this); } /** Send all XLines we know about */ @@ -139,6 +197,37 @@ void TreeSocket::SendXLines() } } +void TreeSocket::SendListModes(Channel* chan) +{ + FModeBuilder fmode(chan); + const ModeParser::ListModeList& listmodes = ServerInstance->Modes->GetListModes(); + for (ModeParser::ListModeList::const_iterator i = listmodes.begin(); i != listmodes.end(); ++i) + { + ListModeBase* mh = *i; + ListModeBase::ModeList* list = mh->GetList(chan); + if (!list) + continue; + + // Add all items on the list to the FMODE, send it whenever it becomes too long + const char modeletter = mh->GetModeChar(); + for (ListModeBase::ModeList::const_iterator j = list->begin(); j != list->end(); ++j) + { + const std::string& mask = j->mask; + if (!fmode.has_room(mask)) + { + // No room for this mask, send the current line as-is then add the mask to a + // new, empty FMODE message + this->WriteLine(fmode.finalize()); + fmode.clear(); + } + fmode.push_mode(modeletter, mask); + } + } + + if (!fmode.empty()) + this->WriteLine(fmode.finalize()); +} + /** Send channel topic, modes and metadata */ void TreeSocket::SyncChannel(Channel* chan) { @@ -149,6 +238,8 @@ void TreeSocket::SyncChannel(Channel* chan) if (chan->topicset != 0) this->WriteLine(CommandFTopic::Builder(chan)); + SendListModes(chan); + for (Extensible::ExtensibleStore::const_iterator i = chan->GetExtList().begin(); i != chan->GetExtList().end(); i++) { ExtensionItem* item = i->first; diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index 6d79711cc..8c87c4df6 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -102,6 +102,10 @@ class TreeSocket : public BufferedSocket */ bool CheckDuplicate(const std::string& servername, const std::string& sid); + /** Send all ListModeBase modes set on the channel + */ + void SendListModes(Channel* chan); + public: const time_t age; |