summaryrefslogtreecommitdiff
path: root/src/modules/m_spanningtree
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/m_spanningtree')
-rw-r--r--src/modules/m_spanningtree/commandbuilder.h1
-rw-r--r--src/modules/m_spanningtree/main.cpp20
-rw-r--r--src/modules/m_spanningtree/main.h1
-rw-r--r--src/modules/m_spanningtree/netburst.cpp97
-rw-r--r--src/modules/m_spanningtree/treesocket.h4
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;