]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_spanningtree/commandbuilder.h
Fix some regressions in sending tags between servers.
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / commandbuilder.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #pragma once
21
22 #include "utils.h"
23
24 class TreeServer;
25
26 class CmdBuilder
27 {
28  protected:
29         /** The raw message contents. */
30         std::string content;
31
32         /** Tags which have been added to this message. */
33         ClientProtocol::TagMap tags;
34
35         /** The size of tags within the contents. */
36         size_t tagsize;
37
38         /** Fires the ServerProtocol::MessageEventListener::OnBuildMessage event for a server target. */
39         void FireEvent(Server* target, const char* cmd, ClientProtocol::TagMap& taglist);
40
41         /** Fires the ServerProtocol::MessageEventListener::OnBuildMessage event for a user target. */
42         void FireEvent(User* target, const char* cmd, ClientProtocol::TagMap& taglist);
43
44         /** Updates the tag string within the buffer. */
45         void UpdateTags();
46
47  public:
48         CmdBuilder(const char* cmd)
49                 : content(1, ':')
50                 , tagsize(0)
51         {
52                 content.append(ServerInstance->Config->GetSID());
53                 push(cmd);
54                 FireEvent(ServerInstance->FakeClient->server, cmd, tags);
55         }
56
57         CmdBuilder(TreeServer* src, const char* cmd)
58                 : content(1, ':')
59                 , tagsize(0)
60         {
61                 content.append(src->GetID());
62                 push(cmd);
63                 FireEvent(src, cmd, tags);
64         }
65
66         CmdBuilder(User* src, const char* cmd)
67                 : content(1, ':')
68                 , tagsize(0)
69         {
70                 content.append(src->uuid);
71                 push(cmd);
72                 if (InspIRCd::IsSID(src->uuid))
73                         FireEvent(src->server, cmd, tags);
74                 else
75                         FireEvent(src, cmd, tags);
76         }
77
78         CmdBuilder& push_raw(const std::string& s)
79         {
80                 content.append(s);
81                 return *this;
82         }
83
84         CmdBuilder& push_raw(const char* s)
85         {
86                 content.append(s);
87                 return *this;
88         }
89
90         CmdBuilder& push_raw(char c)
91         {
92                 content.push_back(c);
93                 return *this;
94         }
95
96         template <typename T>
97         CmdBuilder& push_raw_int(T i)
98         {
99                 content.append(ConvToStr(i));
100                 return *this;
101         }
102
103         template <typename InputIterator>
104         CmdBuilder& push_raw(InputIterator first, InputIterator last)
105         {
106                 content.append(first, last);
107                 return *this;
108         }
109
110         CmdBuilder& push(const std::string& s)
111         {
112                 content.push_back(' ');
113                 content.append(s);
114                 return *this;
115         }
116
117         CmdBuilder& push(const char* s)
118         {
119                 content.push_back(' ');
120                 content.append(s);
121                 return *this;
122         }
123
124         CmdBuilder& push(char c)
125         {
126                 content.push_back(' ');
127                 content.push_back(c);
128                 return *this;
129         }
130
131         template <typename T>
132         CmdBuilder& push_int(T i)
133         {
134                 content.push_back(' ');
135                 content.append(ConvToStr(i));
136                 return *this;
137         }
138
139         CmdBuilder& push_last(const std::string& s)
140         {
141                 content.push_back(' ');
142                 content.push_back(':');
143                 content.append(s);
144                 return *this;
145         }
146
147         CmdBuilder& push_tags(ClientProtocol::TagMap newtags)
148         {
149                 // It has to be this way around so new tags get priority.
150                 newtags.insert(tags.begin(), tags.end());
151                 std::swap(tags, newtags);
152                 UpdateTags();
153                 return *this;
154         }
155
156         template<typename T>
157         CmdBuilder& insert(const T& cont)
158         {
159                 for (typename T::const_iterator i = cont.begin(); i != cont.end(); ++i)
160                         push(*i);
161                 return *this;
162         }
163
164         const std::string& str() const { return content; }
165         operator const std::string&() const { return str(); }
166
167         void Broadcast() const
168         {
169                 Utils->DoOneToMany(*this);
170         }
171
172         void Forward(TreeServer* omit) const
173         {
174                 Utils->DoOneToAllButSender(*this, omit);
175         }
176
177         void Unicast(User* target) const
178         {
179                 Utils->DoOneToOne(*this, target->server);
180         }
181 };