diff options
author | attilamolnar <attilamolnar@hush.com> | 2013-08-19 20:22:15 +0200 |
---|---|---|
committer | attilamolnar <attilamolnar@hush.com> | 2013-08-27 15:33:05 +0200 |
commit | 7e7e773d4d43e68c18c19e2ec712f4250e5f756d (patch) | |
tree | a446c63b439f3854ad2da6d8bd8d4dce9715b38a /src/modules/m_spanningtree | |
parent | 27ecc025acf7b01f51b2ecc32c28180dc49d793c (diff) |
m_spanningtree Introduce command builders
Diffstat (limited to 'src/modules/m_spanningtree')
21 files changed, 405 insertions, 278 deletions
diff --git a/src/modules/m_spanningtree/addline.cpp b/src/modules/m_spanningtree/addline.cpp index 2ee8401fa..d06317674 100644 --- a/src/modules/m_spanningtree/addline.cpp +++ b/src/modules/m_spanningtree/addline.cpp @@ -75,3 +75,13 @@ CmdResult CommandAddLine::Handle(User* usr, std::vector<std::string>& params) } } +CommandAddLine::Builder::Builder(XLine* xline, User* user) + : CmdBuilder(user, "ADDLINE") +{ + push(xline->type); + push(xline->Displayable()); + push(xline->source); + push_int(xline->set_time); + push_int(xline->duration); + push_last(xline->reason); +} diff --git a/src/modules/m_spanningtree/away.cpp b/src/modules/m_spanningtree/away.cpp index 7b151dfef..9c4ec5783 100644 --- a/src/modules/m_spanningtree/away.cpp +++ b/src/modules/m_spanningtree/away.cpp @@ -43,3 +43,16 @@ CmdResult CommandAway::HandleRemote(RemoteUser* u, std::vector<std::string>& par } return CMD_SUCCESS; } + +CommandAway::Builder::Builder(User* user) + : CmdBuilder(user, "AWAY") +{ + push_int(user->awaytime).push_last(user->awaymsg); +} + +CommandAway::Builder::Builder(User* user, const std::string& msg) + : CmdBuilder(user, "AWAY") +{ + if (!msg.empty()) + push_int(ServerInstance->Time()).push_last(msg); +} diff --git a/src/modules/m_spanningtree/commandbuilder.h b/src/modules/m_spanningtree/commandbuilder.h new file mode 100644 index 000000000..07f7c94d0 --- /dev/null +++ b/src/modules/m_spanningtree/commandbuilder.h @@ -0,0 +1,139 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com> + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#pragma once + +#include "utils.h" + +class TreeServer; + +class CmdBuilder +{ + std::string content; + + public: + CmdBuilder(const char* cmd) + : content(1, ':') + { + content.append(ServerInstance->Config->GetSID()); + push(cmd); + } + + CmdBuilder(const std::string& src, const char* cmd) + : content(1, ':') + { + content.append(src); + push(cmd); + } + + CmdBuilder(User* src, const char* cmd) + : content(1, ':') + { + content.append(src->uuid); + push(cmd); + } + + CmdBuilder& push_raw(const std::string& str) + { + content.append(str); + return *this; + } + + CmdBuilder& push_raw(const char* str) + { + content.append(str); + return *this; + } + + CmdBuilder& push_raw(char c) + { + content.push_back(c); + return *this; + } + + CmdBuilder& push(const std::string& str) + { + content.push_back(' '); + content.append(str); + return *this; + } + + CmdBuilder& push(const char* str) + { + content.push_back(' '); + content.append(str); + return *this; + } + + CmdBuilder& push(char c) + { + content.push_back(' '); + content.push_back(c); + return *this; + } + + template <typename T> + CmdBuilder& push_int(T i) + { + content.push_back(' '); + content.append(ConvToStr(i)); + return *this; + } + + CmdBuilder& push_last(const std::string& str) + { + content.push_back(' '); + content.push_back(':'); + content.append(str); + return *this; + } + + template<typename T> + CmdBuilder& insert(const T& cont) + { + for (typename T::const_iterator i = cont.begin(); i != cont.end(); ++i) + push(*i); + return *this; + } + + void push_back(const std::string& str) { push(str); } + + const std::string& str() const { return content; } + operator const std::string&() const { return str(); } + + void Broadcast() const + { + Utils->DoOneToMany(*this); + } + + void Forward(TreeServer* omit) const + { + Utils->DoOneToAllButSender(*this, omit); + } + + bool Unicast(const std::string& target) const + { + return Utils->DoOneToOne(*this, target); + } + + bool Unicast(User* target) const + { + return Unicast(target->server); + } +}; diff --git a/src/modules/m_spanningtree/commands.h b/src/modules/m_spanningtree/commands.h index 700176a16..007c0f2b0 100644 --- a/src/modules/m_spanningtree/commands.h +++ b/src/modules/m_spanningtree/commands.h @@ -20,6 +20,7 @@ #pragma once #include "main.h" +#include "commandbuilder.h" /** Handle /RCONNECT */ @@ -84,6 +85,14 @@ class CommandMetadata : public ServerCommand public: CommandMetadata(Module* Creator) : ServerCommand(Creator, "METADATA", 2) { } CmdResult Handle(User* user, std::vector<std::string>& params); + + class Builder : public CmdBuilder + { + public: + Builder(User* user, const std::string& key, const std::string& val); + Builder(Channel* chan, const std::string& key, const std::string& val); + Builder(const std::string& key, const std::string& val); + }; }; class CommandUID : public ServerOnlyServerCommand<CommandUID> @@ -91,6 +100,12 @@ class CommandUID : public ServerOnlyServerCommand<CommandUID> public: CommandUID(Module* Creator) : ServerOnlyServerCommand<CommandUID>(Creator, "UID", 10) { } CmdResult HandleServer(TreeServer* server, std::vector<std::string>& params); + + class Builder : public CmdBuilder + { + public: + Builder(User* user); + }; }; class CommandOpertype : public UserOnlyServerCommand<CommandOpertype> @@ -98,6 +113,12 @@ class CommandOpertype : public UserOnlyServerCommand<CommandOpertype> public: CommandOpertype(Module* Creator) : UserOnlyServerCommand<CommandOpertype>(Creator, "OPERTYPE", 1) { } CmdResult HandleRemote(RemoteUser* user, std::vector<std::string>& params); + + class Builder : public CmdBuilder + { + public: + Builder(User* user); + }; }; class TreeSocket; @@ -168,13 +189,27 @@ class CommandAway : public UserOnlyServerCommand<CommandAway> public: CommandAway(Module* Creator) : UserOnlyServerCommand<CommandAway>(Creator, "AWAY", 0, 2) { } CmdResult HandleRemote(RemoteUser* user, std::vector<std::string>& parameters); + + class Builder : public CmdBuilder + { + public: + Builder(User* user); + Builder(User* user, const std::string& msg); + }; }; +class XLine; class CommandAddLine : public ServerCommand { public: CommandAddLine(Module* Creator) : ServerCommand(Creator, "ADDLINE", 6, 6) { } CmdResult Handle(User* user, std::vector<std::string>& parameters); + + class Builder : public CmdBuilder + { + public: + Builder(XLine* xline, User* user = ServerInstance->FakeClient); + }; }; class CommandDelLine : public ServerCommand @@ -243,6 +278,12 @@ class CommandServer : public ServerOnlyServerCommand<CommandServer> public: CommandServer(Module* Creator) : ServerOnlyServerCommand<CommandServer>(Creator, "SERVER", 5) { } CmdResult HandleServer(TreeServer* server, std::vector<std::string>& parameters); + + class Builder : public CmdBuilder + { + public: + Builder(TreeServer* server); + }; }; class CommandSQuit : public ServerOnlyServerCommand<CommandSQuit> diff --git a/src/modules/m_spanningtree/idle.cpp b/src/modules/m_spanningtree/idle.cpp index 679948a51..d7c0cdf1b 100644 --- a/src/modules/m_spanningtree/idle.cpp +++ b/src/modules/m_spanningtree/idle.cpp @@ -59,11 +59,11 @@ CmdResult CommandIdle::HandleRemote(RemoteUser* issuer, std::vector<std::string> else idle = ((unsigned int) (ServerInstance->Time() - localtarget->idle_lastmsg)); - parameterlist reply; + CmdBuilder reply(params[0], "IDLE"); reply.push_back(issuer->uuid); reply.push_back(ConvToStr(target->signon)); reply.push_back(ConvToStr(idle)); - Utils->DoOneToOne(params[0], "IDLE", reply, issuer->server); + reply.Unicast(issuer); } return CMD_SUCCESS; diff --git a/src/modules/m_spanningtree/ijoin.cpp b/src/modules/m_spanningtree/ijoin.cpp index c549149b3..a579848c8 100644 --- a/src/modules/m_spanningtree/ijoin.cpp +++ b/src/modules/m_spanningtree/ijoin.cpp @@ -32,9 +32,7 @@ CmdResult CommandIJoin::HandleRemote(RemoteUser* user, std::vector<std::string>& // Ignore the join and send RESYNC, this will result in the remote server sending all channel data to us ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Received IJOIN for non-existant channel: " + params[0]); - parameterlist p; - p.push_back(params[0]); - Utils->DoOneToOne(ServerInstance->Config->GetSID(), "RESYNC", p, user->server); + CmdBuilder("RESYNC").push(params[0]).Unicast(user); return CMD_FAILURE; } diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 57fe2090c..f458c2d2f 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -408,11 +408,11 @@ void ModuleSpanningTree::OnUserInvite(User* source,User* dest,Channel* channel, { if (IS_LOCAL(source)) { - parameterlist params; + CmdBuilder params(source, "INVITE"); params.push_back(dest->uuid); params.push_back(channel->name); params.push_back(ConvToStr(expiry)); - Utils->DoOneToMany(source->uuid,"INVITE",params); + params.Broadcast(); } } @@ -422,10 +422,10 @@ void ModuleSpanningTree::OnPostTopicChange(User* user, Channel* chan, const std: if (!IS_LOCAL(user)) return; - parameterlist params; + CmdBuilder params(user->uuid, "TOPIC"); params.push_back(chan->name); - params.push_back(":"+topic); - Utils->DoOneToMany(user->uuid,"TOPIC",params); + params.push_last(topic); + params.Broadcast(); } void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, const std::string& text, char status, const CUList& exempt_list, MessageType msgtype) @@ -439,10 +439,10 @@ void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, User* d = (User*) dest; if (!IS_LOCAL(d)) { - parameterlist params; + CmdBuilder params(user, message_type); params.push_back(d->uuid); - params.push_back(":"+text); - Utils->DoOneToOne(user->uuid, message_type, params, d->server); + params.push_last(text); + params.Unicast(d); } } else if (target_type == TYPE_CHANNEL) @@ -452,10 +452,10 @@ void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, else if (target_type == TYPE_SERVER) { char* target = (char*) dest; - parameterlist par; + CmdBuilder par(user, message_type); par.push_back(target); - par.push_back(":"+text); - Utils->DoOneToMany(user->uuid, message_type, par); + par.push_last(text); + par.Broadcast(); } } @@ -471,26 +471,10 @@ void ModuleSpanningTree::OnUserConnect(LocalUser* user) if (user->quitting) return; - parameterlist params; - params.push_back(user->uuid); - params.push_back(ConvToStr(user->age)); - params.push_back(user->nick); - params.push_back(user->host); - params.push_back(user->dhost); - params.push_back(user->ident); - params.push_back(user->GetIPString()); - params.push_back(ConvToStr(user->signon)); - params.push_back("+"+std::string(user->FormatModes(true))); - params.push_back(":"+user->fullname); - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "UID", params); + CommandUID::Builder(user).Broadcast(); if (user->IsOper()) - { - params.clear(); - params.push_back(":"); - params[0].append(user->oper->name); - Utils->DoOneToMany(user->uuid,"OPERTYPE",params); - } + CommandOpertype::Builder(user).Broadcast(); for(Extensible::ExtensibleStore::const_iterator i = user->GetExtList().begin(); i != user->GetExtList().end(); i++) { @@ -506,26 +490,28 @@ void ModuleSpanningTree::OnUserConnect(LocalUser* user) void ModuleSpanningTree::OnUserJoin(Membership* memb, bool sync, bool created_by_local, CUList& excepts) { // Only do this for local users - if (IS_LOCAL(memb->user)) + if (!IS_LOCAL(memb->user)) + return; + + if (created_by_local) { - parameterlist params; + CmdBuilder params("FJOIN"); params.push_back(memb->chan->name); - if (created_by_local) + params.push_back(ConvToStr(memb->chan->age)); + params.push_raw(" +").push_raw(memb->chan->ChanModes(true)); + params.push(memb->modes).push_raw(',').push_raw(memb->user->uuid); + params.Broadcast(); + } + else + { + CmdBuilder params(memb->user, "IJOIN"); + params.push_back(memb->chan->name); + if (!memb->modes.empty()) { params.push_back(ConvToStr(memb->chan->age)); - params.push_back(std::string("+") + memb->chan->ChanModes(true)); - params.push_back(memb->modes+","+memb->user->uuid); - Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FJOIN",params); - } - else - { - if (!memb->modes.empty()) - { - params.push_back(ConvToStr(memb->chan->age)); - params.push_back(memb->modes); - } - Utils->DoOneToMany(memb->user->uuid, "IJOIN", params); + params.push_back(memb->modes); } + params.Broadcast(); } } @@ -534,9 +520,7 @@ void ModuleSpanningTree::OnChangeHost(User* user, const std::string &newhost) if (user->registered != REG_ALL || !IS_LOCAL(user)) return; - parameterlist params; - params.push_back(newhost); - Utils->DoOneToMany(user->uuid,"FHOST",params); + CmdBuilder(user, "FHOST").push(newhost).Broadcast(); } void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos) @@ -544,9 +528,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos) if (user->registered != REG_ALL || !IS_LOCAL(user)) return; - parameterlist params; - params.push_back(gecos); - Utils->DoOneToMany(user->uuid,"FNAME",params); + CmdBuilder(user, "FNAME").push(gecos).Broadcast(); } void ModuleSpanningTree::OnChangeIdent(User* user, const std::string &ident) @@ -554,20 +536,18 @@ void ModuleSpanningTree::OnChangeIdent(User* user, const std::string &ident) if ((user->registered != REG_ALL) || (!IS_LOCAL(user))) return; - parameterlist params; - params.push_back(ident); - Utils->DoOneToMany(user->uuid,"FIDENT",params); + CmdBuilder(user, "FIDENT").push(ident).Broadcast(); } void ModuleSpanningTree::OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts) { if (IS_LOCAL(memb->user)) { - parameterlist params; + CmdBuilder params(memb->user, "PART"); params.push_back(memb->chan->name); if (!partmessage.empty()) - params.push_back(":"+partmessage); - Utils->DoOneToMany(memb->user->uuid,"PART",params); + params.push_last(partmessage); + params.Broadcast(); } } @@ -575,13 +555,10 @@ void ModuleSpanningTree::OnUserQuit(User* user, const std::string &reason, const { if ((IS_LOCAL(user)) && (user->registered == REG_ALL)) { - parameterlist params; - if (oper_message != reason) ServerInstance->PI->SendMetaData(user, "operquit", oper_message); - params.push_back(":"+reason); - Utils->DoOneToMany(user->uuid,"QUIT",params); + CmdBuilder(user, "QUIT").push_last(reason).Broadcast(); } // Regardless, We need to modify the user Counts.. @@ -596,7 +573,7 @@ void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick) { if (IS_LOCAL(user)) { - parameterlist params; + CmdBuilder params(user, "NICK"); params.push_back(user->nick); /** IMPORTANT: We don't update the TS if the oldnick is just a case change of the newnick! @@ -605,31 +582,27 @@ void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick) user->age = ServerInstance->Time(); params.push_back(ConvToStr(user->age)); - Utils->DoOneToMany(user->uuid,"NICK",params); + params.Broadcast(); } else if (!loopCall && user->nick == user->uuid) { - parameterlist params; + CmdBuilder params("SAVE"); params.push_back(user->uuid); params.push_back(ConvToStr(user->age)); - Utils->DoOneToMany(ServerInstance->Config->GetSID(),"SAVE",params); + params.Broadcast(); } } void ModuleSpanningTree::OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts) { - parameterlist params; + if ((!IS_LOCAL(source) || source != ServerInstance->FakeClient)) + return; + + CmdBuilder params(source, "KICK"); params.push_back(memb->chan->name); params.push_back(memb->user->uuid); - params.push_back(":"+reason); - if (IS_LOCAL(source)) - { - Utils->DoOneToMany(source->uuid,"KICK",params); - } - else if (source == ServerInstance->FakeClient) - { - Utils->DoOneToMany(ServerInstance->Config->GetSID(),"KICK",params); - } + params.push_last(reason); + params.Broadcast(); } void ModuleSpanningTree::OnPreRehash(User* user, const std::string ¶meter) @@ -642,9 +615,9 @@ void ModuleSpanningTree::OnPreRehash(User* user, const std::string ¶meter) // Send out to other servers if (!parameter.empty() && parameter[0] != '-') { - parameterlist params; + CmdBuilder params((user ? user->uuid : ServerInstance->Config->GetSID()), "REHASH"); params.push_back(parameter); - Utils->DoOneToAllButSender(user ? user->uuid : ServerInstance->Config->GetSID(), "REHASH", params, user ? Utils->BestRouteTo(user->server) : NULL); + params.Forward(user ? Utils->BestRouteTo(user->server) : NULL); } } @@ -708,70 +681,38 @@ void ModuleSpanningTree::OnOper(User* user, const std::string &opertype) { if (user->registered != REG_ALL || !IS_LOCAL(user)) return; - parameterlist params; - params.push_back(":"); - params[0].append(opertype); - Utils->DoOneToMany(user->uuid,"OPERTYPE",params); + CommandOpertype::Builder(user).Broadcast(); } void ModuleSpanningTree::OnAddLine(User* user, XLine *x) { - if (!x->IsBurstable() || loopCall) + if (!x->IsBurstable() || loopCall || (user && !IS_LOCAL(user))) return; - parameterlist params; - params.push_back(x->type); - params.push_back(x->Displayable()); - params.push_back(ServerInstance->Config->ServerName); - params.push_back(ConvToStr(x->set_time)); - params.push_back(ConvToStr(x->duration)); - params.push_back(":" + x->reason); - if (!user) - { - /* Server-set lines */ - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ADDLINE", params); - } - else if (IS_LOCAL(user)) - { - /* User-set lines */ - Utils->DoOneToMany(user->uuid, "ADDLINE", params); - } + user = ServerInstance->FakeClient; + + CommandAddLine::Builder(x, user).Broadcast(); } void ModuleSpanningTree::OnDelLine(User* user, XLine *x) { - if (!x->IsBurstable() || loopCall) + if (!x->IsBurstable() || loopCall || (user && !IS_LOCAL(user))) return; - parameterlist params; + if (!user) + user = ServerInstance->FakeClient; + + CmdBuilder params(user, "DELLINE"); params.push_back(x->type); params.push_back(x->Displayable()); - - if (!user) - { - /* Server-unset lines */ - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "DELLINE", params); - } - else if (IS_LOCAL(user)) - { - /* User-unset lines */ - Utils->DoOneToMany(user->uuid, "DELLINE", params); - } + params.Broadcast(); } ModResult ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg) { if (IS_LOCAL(user)) - { - parameterlist params; - if (!awaymsg.empty()) - { - params.push_back(ConvToStr(user->awaytime)); - params.push_back(":" + awaymsg); - } - Utils->DoOneToMany(user->uuid, "AWAY", params); - } + CommandAway::Builder(user, awaymsg).Broadcast(); return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp index cf386cf21..5dea7ffae 100644 --- a/src/modules/m_spanningtree/metadata.cpp +++ b/src/modules/m_spanningtree/metadata.cpp @@ -73,3 +73,27 @@ CmdResult CommandMetadata::Handle(User* srcuser, std::vector<std::string>& param return CMD_SUCCESS; } +CommandMetadata::Builder::Builder(User* user, const std::string& key, const std::string& val) + : CmdBuilder("METADATA") +{ + push(user->uuid); + push(key); + push_last(val); +} + +CommandMetadata::Builder::Builder(Channel* chan, const std::string& key, const std::string& val) + : CmdBuilder("METADATA") +{ + push(chan->name); + push_int(chan->age); + push(key); + push_last(val); +} + +CommandMetadata::Builder::Builder(const std::string& key, const std::string& val) + : CmdBuilder("METADATA") +{ + push("*"); + push(key); + push_last(val); +} diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index 938585c84..2cd107972 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -26,6 +26,7 @@ #include "treesocket.h" #include "treeserver.h" #include "main.h" +#include "commands.h" /** 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 @@ -71,8 +72,7 @@ void TreeSocket::SendServers(TreeServer* Current, TreeServer* s) TreeServer* recursive_server = *i; if (recursive_server != s) { - this->WriteLine(InspIRCd::Format(":%s SERVER %s * 0 %s :%s", Current->GetID().c_str(), - recursive_server->GetName().c_str(), recursive_server->GetID().c_str(), recursive_server->GetDesc().c_str())); + this->WriteLine(CommandServer::Builder(recursive_server)); this->WriteLine(":" + recursive_server->GetID() + " VERSION :" + recursive_server->GetVersion()); /* down to next level */ this->SendServers(recursive_server, s); @@ -133,14 +133,7 @@ void TreeSocket::SendXLines() if (!i->second->IsBurstable()) break; - this->WriteLine(InspIRCd::Format(":%s ADDLINE %s %s %s %lu %lu :%s", - ServerInstance->Config->GetSID().c_str(), - it->c_str(), - i->second->Displayable().c_str(), - i->second->source.c_str(), - (unsigned long)i->second->set_time, - (unsigned long)i->second->duration, - i->second->reason.c_str())); + this->WriteLine(CommandAddLine::Builder(i->second)); } } } @@ -176,45 +169,28 @@ void TreeSocket::SendUsers() { for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++) { - if (u->second->registered == REG_ALL) - { - TreeServer* theirserver = Utils->FindServer(u->second->server); - if (theirserver) - { - this->WriteLine(InspIRCd::Format(":%s UID %s %lu %s %s %s %s %s %lu +%s :%s", - theirserver->GetID().c_str(), // Prefix: SID - u->second->uuid.c_str(), // 0: UUID - (unsigned long)u->second->age, // 1: TS - u->second->nick.c_str(), // 2: Nick - u->second->host.c_str(), // 3: Real host - u->second->dhost.c_str(), // 4: Display host - u->second->ident.c_str(), // 5: Ident - u->second->GetIPString().c_str(), // 6: IP address - (unsigned long)u->second->signon, // 7: Signon time - u->second->FormatModes(true), // 8...n: User modes and params - u->second->fullname.c_str())); // size-1: GECOS - - if (u->second->IsOper()) - { - this->WriteLine(InspIRCd::Format(":%s OPERTYPE :%s", u->second->uuid.c_str(), u->second->oper->name.c_str())); - } - if (u->second->IsAway()) - { - this->WriteLine(InspIRCd::Format(":%s AWAY %ld :%s", u->second->uuid.c_str(), (long)u->second->awaytime, - u->second->awaymsg.c_str())); - } - } + User* user = u->second; + if (user->registered != REG_ALL) + continue; - for(Extensible::ExtensibleStore::const_iterator i = u->second->GetExtList().begin(); i != u->second->GetExtList().end(); i++) - { - ExtensionItem* item = i->first; - std::string value = item->serialize(FORMAT_NETWORK, u->second, i->second); - if (!value.empty()) - Utils->Creator->ProtoSendMetaData(this, u->second, item->name, value); - } + this->WriteLine(CommandUID::Builder(user)); - FOREACH_MOD(OnSyncUser, (u->second,Utils->Creator,this)); + if (user->IsOper()) + this->WriteLine(CommandOpertype::Builder(user)); + + if (user->IsAway()) + this->WriteLine(CommandAway::Builder(user)); + + const Extensible::ExtensibleStore& exts = user->GetExtList(); + for (Extensible::ExtensibleStore::const_iterator i = exts.begin(); i != exts.end(); ++i) + { + ExtensionItem* item = i->first; + std::string value = item->serialize(FORMAT_NETWORK, u->second, i->second); + if (!value.empty()) + Utils->Creator->ProtoSendMetaData(this, u->second, item->name, value); } + + FOREACH_MOD(OnSyncUser, (user, Utils->Creator, this)); } } diff --git a/src/modules/m_spanningtree/nickcollide.cpp b/src/modules/m_spanningtree/nickcollide.cpp index e849c69ae..edc1ac6ff 100644 --- a/src/modules/m_spanningtree/nickcollide.cpp +++ b/src/modules/m_spanningtree/nickcollide.cpp @@ -23,6 +23,7 @@ #include "treesocket.h" #include "treeserver.h" #include "utils.h" +#include "commandbuilder.h" /* * Yes, this function looks a little ugly. @@ -105,10 +106,10 @@ int SpanningTreeUtilities::DoCollision(User* u, TreeServer* server, time_t remot * Local-side nick needs to change. Just in case we are hub, and * this "local" nick is actually behind us, send an SAVE out. */ - parameterlist params; + CmdBuilder params("SAVE"); params.push_back(u->uuid); params.push_back(ConvToStr(u->age)); - this->DoOneToMany(ServerInstance->Config->GetSID(),"SAVE",params); + params.Broadcast(); u->ForceNickChange(u->uuid); diff --git a/src/modules/m_spanningtree/opertype.cpp b/src/modules/m_spanningtree/opertype.cpp index 48f55356f..6e5d473aa 100644 --- a/src/modules/m_spanningtree/opertype.cpp +++ b/src/modules/m_spanningtree/opertype.cpp @@ -59,3 +59,8 @@ CmdResult CommandOpertype::HandleRemote(RemoteUser* u, std::vector<std::string>& return CMD_SUCCESS; } +CommandOpertype::Builder::Builder(User* user) + : CmdBuilder(user, "OPERTYPE") +{ + push_last(user->oper->name); +} diff --git a/src/modules/m_spanningtree/override_whois.cpp b/src/modules/m_spanningtree/override_whois.cpp index ec0ca9c5e..cb21f84b5 100644 --- a/src/modules/m_spanningtree/override_whois.cpp +++ b/src/modules/m_spanningtree/override_whois.cpp @@ -19,7 +19,7 @@ #include "inspircd.h" #include "main.h" -#include "utils.h" +#include "commandbuilder.h" ModResult ModuleSpanningTree::HandleRemoteWhois(const std::vector<std::string>& parameters, User* user) { @@ -28,9 +28,7 @@ ModResult ModuleSpanningTree::HandleRemoteWhois(const std::vector<std::string>& User* remote = ServerInstance->FindNickOnly(parameters[1]); if (remote && !IS_LOCAL(remote)) { - parameterlist params; - params.push_back(remote->uuid); - Utils->DoOneToOne(user->uuid,"IDLE",params,remote->server); + CmdBuilder(user, "IDLE").push(remote->uuid).Unicast(remote); return MOD_RES_DENY; } else if (!remote) diff --git a/src/modules/m_spanningtree/ping.cpp b/src/modules/m_spanningtree/ping.cpp index 537efe964..6d8893acf 100644 --- a/src/modules/m_spanningtree/ping.cpp +++ b/src/modules/m_spanningtree/ping.cpp @@ -29,13 +29,13 @@ CmdResult CommandPing::Handle(User* user, std::vector<std::string>& params) if (params[0] == ServerInstance->Config->GetSID()) { // PING for us, reply with a PONG - parameterlist reply; + CmdBuilder reply("PONG"); reply.push_back(user->uuid); if (params.size() >= 2) // If there is a second parameter, append it reply.push_back(params[1]); - Utils->DoOneToOne(params[0], "PONG", reply, user->server); + reply.Unicast(user); } return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/postcommand.cpp b/src/modules/m_spanningtree/postcommand.cpp index b36cfec20..57fbca6bc 100644 --- a/src/modules/m_spanningtree/postcommand.cpp +++ b/src/modules/m_spanningtree/postcommand.cpp @@ -22,6 +22,7 @@ #include "main.h" #include "utils.h" #include "treeserver.h" +#include "commandbuilder.h" void ModuleSpanningTree::OnPostCommand(Command* command, const std::vector<std::string>& parameters, LocalUser* user, CmdResult result, const std::string& original_line) { @@ -33,19 +34,16 @@ void SpanningTreeUtilities::RouteCommand(TreeServer* origin, CommandBase* thiscm { const std::string& command = thiscmd->name; RouteDescriptor routing = thiscmd->GetRouting(user, parameters); - - std::string sent_cmd = command; - parameterlist params; - if (routing.type == ROUTE_TYPE_LOCALONLY) - { return; - } - else if (routing.type == ROUTE_TYPE_OPT_BCAST) + + const bool encap = ((routing.type == ROUTE_TYPE_OPT_BCAST) || (routing.type == ROUTE_TYPE_OPT_UCAST)); + CmdBuilder params(user, encap ? "ENCAP" : command.c_str()); + + if (routing.type == ROUTE_TYPE_OPT_BCAST) { - params.push_back("*"); + params.push('*'); params.push_back(command); - sent_cmd = "ENCAP"; } else if (routing.type == ROUTE_TYPE_OPT_UCAST) { @@ -58,7 +56,6 @@ void SpanningTreeUtilities::RouteCommand(TreeServer* origin, CommandBase* thiscm } params.push_back(sdest->GetID()); params.push_back(command); - sent_cmd = "ENCAP"; } else { @@ -93,11 +90,11 @@ void SpanningTreeUtilities::RouteCommand(TreeServer* origin, CommandBase* thiscm return; // TODO OnBuildExemptList hook was here CUList exempts; - SendChannelMessage(user->uuid, c, parameters[1], pfx, exempts, sent_cmd.c_str(), origin ? origin->GetSocket() : NULL); + SendChannelMessage(user->uuid, c, parameters[1], pfx, exempts, command.c_str(), origin ? origin->GetSocket() : NULL); } else if (dest[0] == '$') { - DoOneToAllButSender(user->uuid, sent_cmd, params, origin); + params.Forward(origin); } else { @@ -109,17 +106,17 @@ void SpanningTreeUtilities::RouteCommand(TreeServer* origin, CommandBase* thiscm if (tsd == origin) // huh? no routing stuff around in a circle, please. return; - DoOneToOne(user->uuid, sent_cmd, params, d->server); + params.Unicast(d); } } else if (routing.type == ROUTE_TYPE_BROADCAST || routing.type == ROUTE_TYPE_OPT_BCAST) { - DoOneToAllButSender(user->uuid, sent_cmd, params, origin); + params.Forward(origin); } else if (routing.type == ROUTE_TYPE_UNICAST || routing.type == ROUTE_TYPE_OPT_UCAST) { if (origin && routing.serverdest == origin->GetName()) return; - DoOneToOne(user->uuid, sent_cmd, params, routing.serverdest); + params.Unicast(routing.serverdest); } } diff --git a/src/modules/m_spanningtree/protocolinterface.cpp b/src/modules/m_spanningtree/protocolinterface.cpp index 5fd598d1d..afd463360 100644 --- a/src/modules/m_spanningtree/protocolinterface.cpp +++ b/src/modules/m_spanningtree/protocolinterface.cpp @@ -22,6 +22,7 @@ #include "utils.h" #include "treeserver.h" #include "protocolinterface.h" +#include "commands.h" /* * For documentation on this class, see include/protocol.h. @@ -45,85 +46,71 @@ void SpanningTreeProtocolInterface::GetServerList(ServerList& sl) bool SpanningTreeProtocolInterface::SendEncapsulatedData(const parameterlist &encap) { + CmdBuilder params("ENCAP"); + params.insert(encap); if (encap[0].find_first_of("*?") != std::string::npos) { - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap); + params.Broadcast(); return true; } - return Utils->DoOneToOne(ServerInstance->Config->GetSID(), "ENCAP", encap, encap[0]); + return params.Unicast(encap[0]); } void SpanningTreeProtocolInterface::SendMetaData(Extensible* target, const std::string &key, const std::string &data) { - parameterlist params; - User* u = dynamic_cast<User*>(target); Channel* c = dynamic_cast<Channel*>(target); if (u) - params.push_back(u->uuid); + CommandMetadata::Builder(u, key, data).Broadcast(); else if (c) - { - params.push_back(c->name); - params.push_back(ConvToStr(c->age)); - } + CommandMetadata::Builder(c, key, data).Broadcast(); else - params.push_back("*"); - - params.push_back(key); - params.push_back(":" + data); - - Utils->DoOneToMany(ServerInstance->Config->GetSID(),"METADATA",params); + CommandMetadata::Builder(key, data).Broadcast(); } void SpanningTreeProtocolInterface::SendTopic(Channel* channel, std::string &topic) { - parameterlist params; + CmdBuilder params("FTOPIC"); params.push_back(channel->name); params.push_back(ConvToStr(channel->age)); params.push_back(ConvToStr(ServerInstance->Time())); params.push_back(ServerInstance->Config->ServerName); - params.push_back(":" + topic); + params.push_last(topic); - Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FTOPIC", params); + params.Broadcast(); } -void SpanningTreeProtocolInterface::SendMode(User* source, User* u, Channel* c, const parameterlist& modedata, const std::vector<TranslateType>& translate) +void SpanningTreeProtocolInterface::SendMode(User* source, User* u, Channel* c, const std::vector<std::string>& modedata, const std::vector<TranslateType>& translate) { - parameterlist params; - if (u) { if (u->registered != REG_ALL) return; + CmdBuilder params(source, "MODE"); params.push_back(u->uuid); - params.insert(params.end(), modedata.begin(), modedata.end()); - Utils->DoOneToMany(source->uuid, "MODE", params); + params.insert(modedata); + params.Broadcast(); } else { + CmdBuilder params(source, "FMODE"); params.push_back(c->name); params.push_back(ConvToStr(c->age)); params.push_back(CommandParser::TranslateUIDs(translate, modedata)); - Utils->DoOneToMany(source->uuid, "FMODE", params); + params.Broadcast(); } } void SpanningTreeProtocolInterface::SendSNONotice(const std::string &snomask, const std::string &text) { - parameterlist p; - p.push_back(snomask); - p.push_back(":" + text); - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "SNONOTICE", p); + CmdBuilder("SNONOTICE").push(snomask).push_last(text).Broadcast(); } void SpanningTreeProtocolInterface::PushToClient(User* target, const std::string &rawline) { - parameterlist p; - p.push_back(target->uuid); - p.push_back(":" + rawline); - Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", p, target->server); + CmdBuilder("PUSH").push(target->uuid).push_last(rawline).Unicast(target); } void SpanningTreeProtocolInterface::SendMessage(Channel* target, char status, const std::string& text, MessageType msgtype) @@ -135,9 +122,8 @@ void SpanningTreeProtocolInterface::SendMessage(Channel* target, char status, co void SpanningTreeProtocolInterface::SendMessage(User* target, const std::string& text, MessageType msgtype) { - const char* cmd = (msgtype == MSG_PRIVMSG ? "PRIVMSG" : "NOTICE"); - parameterlist p; + CmdBuilder p(msgtype == MSG_PRIVMSG ? "PRIVMSG" : "NOTICE"); p.push_back(target->uuid); - p.push_back(":" + text); - Utils->DoOneToOne(ServerInstance->Config->GetSID(), cmd, p, target->server); + p.push_last(text); + p.Unicast(target); } diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp index 807666f49..69cae001c 100644 --- a/src/modules/m_spanningtree/server.cpp +++ b/src/modules/m_spanningtree/server.cpp @@ -142,11 +142,8 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) Utils->TreeRoot->AddChild(MyRoot); this->DoBurst(MyRoot); - params[4] = ":" + params[4]; - - /* IMPORTANT: Take password/hmac hash OUT of here before we broadcast the introduction! */ - params[1] = "*"; - Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,MyRoot); + // This will send a * in place of the password/hmac + CommandServer::Builder(MyRoot).Forward(MyRoot); return true; } @@ -248,3 +245,11 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) return false; } +CommandServer::Builder::Builder(TreeServer* server) + : CmdBuilder(server->GetParent()->GetID(), "SERVER") +{ + push(server->GetName()); + push_raw(" * 0 "); + push_raw(server->GetID()); + push_last(server->GetDesc()); +} diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index 9376a5514..dc9bb5331 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -179,10 +179,10 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason) LocalSquit = true; if (Current->GetSocket()->Introduced()) { - parameterlist params; + CmdBuilder params("SQUIT"); params.push_back(Current->GetID()); - params.push_back(":"+reason); - Utils->DoOneToMany(Utils->TreeRoot->GetID(), "SQUIT", params); + params.push_last(reason); + params.Broadcast(); } } else diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index 5181dfeea..8d14ff5ff 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -29,6 +29,7 @@ #include "treeserver.h" #include "treesocket.h" #include "resolvers.h" +#include "commands.h" /* Handle ERROR command */ void TreeSocket::Error(parameterlist ¶ms) @@ -178,14 +179,8 @@ void TreeSocket::ProcessLine(std::string &line) MyRoot->bursting = true; this->DoBurst(MyRoot); - parameterlist sparams; - sparams.push_back(MyRoot->GetName()); - sparams.push_back("*"); - sparams.push_back("0"); - sparams.push_back(MyRoot->GetID()); - sparams.push_back(":" + MyRoot->GetDesc()); - Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(), "SERVER", sparams, MyRoot); - Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot); + CommandServer::Builder(MyRoot).Forward(MyRoot); + CmdBuilder(MyRoot->GetID(), "BURST").insert(params).Forward(MyRoot); } else if (command == "ERROR") { diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 55a6e3939..82d78124a 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -161,3 +161,17 @@ CmdResult CommandFName::HandleRemote(RemoteUser* src, std::vector<std::string>& return CMD_SUCCESS; } +CommandUID::Builder::Builder(User* user) + : CmdBuilder(user->uuid.substr(0, 3), "UID") +{ + push(user->uuid); + push_int(user->age); + push(user->nick); + push(user->host); + push(user->dhost); + push(user->ident); + push(user->GetIPString()); + push_int(user->signon); + push('+').push_raw(user->FormatModes(true)); + push_last(user->fullname); +} diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index f71a9f0d5..40db1339c 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -27,6 +27,7 @@ #include "treeserver.h" #include "treesocket.h" #include "resolvers.h" +#include "commandbuilder.h" SpanningTreeUtilities* Utils = NULL; @@ -189,22 +190,9 @@ void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeSocketSet return; } -std::string SpanningTreeUtilities::ConstructLine(const std::string& prefix, const std::string& command, const parameterlist& params) +void SpanningTreeUtilities::DoOneToAllButSender(const CmdBuilder& params, TreeServer* omitroute) { - std::string FullLine; - FullLine.reserve(1024); - FullLine = ":" + prefix + " " + command; - for (parameterlist::const_iterator x = params.begin(); x != params.end(); ++x) - { - FullLine.push_back(' '); - FullLine.append(*x); - } - return FullLine; -} - -void SpanningTreeUtilities::DoOneToAllButSender(const std::string& prefix, const std::string& command, const parameterlist& params, TreeServer* omitroute) -{ - std::string FullLine = ConstructLine(prefix, command, params); + const std::string& FullLine = params.str(); const TreeServer::ChildServers& children = TreeRoot->GetChildren(); for (TreeServer::ChildServers::const_iterator i = children.begin(); i != children.end(); ++i) @@ -218,13 +206,13 @@ void SpanningTreeUtilities::DoOneToAllButSender(const std::string& prefix, const } } -bool SpanningTreeUtilities::DoOneToOne(const std::string& prefix, const std::string& command, const parameterlist& params, const std::string& target) +bool SpanningTreeUtilities::DoOneToOne(const CmdBuilder& params, const std::string& target) { TreeServer* Route = this->BestRouteTo(target); if (!Route) return false; - Route->GetSocket()->WriteLine(ConstructLine(prefix, command, params)); + Route->GetSocket()->WriteLine(params); return true; } @@ -378,11 +366,10 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name) void SpanningTreeUtilities::SendChannelMessage(const std::string& prefix, Channel* target, const std::string& text, char status, const CUList& exempt_list, const char* message_type, TreeSocket* omit) { - std::string raw(":"); - raw.append(prefix).append(1, ' ').append(message_type).push_back(' '); - if (status) - raw.push_back(status); - raw.append(target->name).append(" :").append(text); + CmdBuilder msg(prefix, message_type); + if (status == 0) + status = ' '; + msg.push(status).push_raw(target->name).push_last(text); TreeSocketSet list; this->GetListOfServersForChannel(target, list, status, exempt_list); @@ -390,6 +377,6 @@ void SpanningTreeUtilities::SendChannelMessage(const std::string& prefix, Channe { TreeSocket* Sock = *i; if (Sock != omit) - Sock->WriteLine(raw); + Sock->WriteLine(msg); } } diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index 345b62b09..9e6f41852 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -32,6 +32,7 @@ class Link; class Autoconnect; class ModuleSpanningTree; class SpanningTreeUtilities; +class CmdBuilder; extern SpanningTreeUtilities* Utils; @@ -45,10 +46,6 @@ typedef TR1NS::unordered_map<std::string, TreeServer*, irc::insensitive, irc::St */ class SpanningTreeUtilities : public classbase { - /** Creates a line in the :<prefix> <command> [<params>] format - */ - std::string ConstructLine(const std::string& prefix, const std::string& command, const parameterlist& params); - CacheRefreshTimer RefreshTimer; public: @@ -130,15 +127,15 @@ class SpanningTreeUtilities : public classbase /** Send a message from this server to one other local or remote */ - bool DoOneToOne(const std::string& prefix, const std::string& command, const parameterlist& params, const std::string& target); + bool DoOneToOne(const CmdBuilder& params, const std::string& target); /** Send a message from this server to all but one other, local or remote */ - void DoOneToAllButSender(const std::string& prefix, const std::string& command, const parameterlist& params, TreeServer* omit); + void DoOneToAllButSender(const CmdBuilder& params, TreeServer* omit); /** Send a message from this server to all others */ - void DoOneToMany(const std::string &prefix, const std::string &command, const parameterlist ¶ms); + void DoOneToMany(const CmdBuilder& params); /** Read the spanningtree module's tags from the config file */ @@ -181,7 +178,7 @@ class SpanningTreeUtilities : public classbase void SendChannelMessage(const std::string& prefix, Channel* target, const std::string& text, char status, const CUList& exempt_list, const char* message_type, TreeSocket* omit = NULL); }; -inline void SpanningTreeUtilities::DoOneToMany(const std::string& prefix, const std::string& command, const parameterlist& params) +inline void SpanningTreeUtilities::DoOneToMany(const CmdBuilder& params) { - DoOneToAllButSender(prefix, command, params, NULL); + DoOneToAllButSender(params, NULL); } |