InspIRCd  4.0
clientprotocol.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2018-2020 Sadie Powell <[email protected]>
5  * Copyright (C) 2018 Attila Molnar <[email protected]>
6  *
7  * This file is part of InspIRCd. InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #pragma once
22 
23 #include "event.h"
24 
25 namespace ClientProtocol
26 {
27  class EventHook;
28  class MessageSource;
29  struct RFCEvents;
30  struct ParseOutput;
31  class TagSelection;
32 }
33 
38 {
41  std::string cmd;
42 
45  ClientProtocol::ParamList params;
46 
50 };
51 
55 {
56  std::bitset<64> selection;
57 
58  public:
65  bool IsSelected(const TagMap& tags, TagMap::const_iterator it) const
66  {
67  const size_t index = std::distance(tags.begin(), it);
68  return ((index < selection.size()) && (selection[index]));
69  }
70 
76  void Select(const TagMap& tags, TagMap::const_iterator it)
77  {
78  const size_t index = std::distance(tags.begin(), it);
79  if (index < selection.size())
80  selection[index] = true;
81  }
82 
87  bool operator==(const TagSelection& other) const
88  {
89  return (this->selection == other.selection);
90  }
91 };
92 
94 {
95  User* sourceuser;
96  const std::string* sourcestr;
97 
98  public:
104  MessageSource(User* Sourceuser = NULL)
105  {
106  SetSourceUser(Sourceuser);
107  }
108 
116  MessageSource(const std::string& Sourcestr, User* Sourceuser = NULL)
117  {
118  SetSource(Sourcestr, Sourceuser);
119  }
120 
124  const std::string* GetSource() const
125  {
126  // Return string if there's one explicitly set
127  if (sourcestr)
128  return sourcestr;
129  if (sourceuser)
130  return &sourceuser->GetFullHost();
131  return NULL;
132  }
133 
138  User* GetSourceUser() const { return sourceuser; }
139 
144  void SetSourceUser(User* Sourceuser)
145  {
146  sourceuser = Sourceuser;
147  sourcestr = NULL;
148  }
149 
156  void SetSource(const std::string& Sourcestr, User* Sourceuser = NULL)
157  {
158  sourcestr = &Sourcestr;
159  sourceuser = Sourceuser;
160  }
161 
165  void SetSource(const MessageSource& other)
166  {
167  sourcestr = other.sourcestr;
168  sourceuser = other.sourceuser;
169  }
170 };
171 
182 {
183  public:
187  {
188  const Serializer* serializer;
189  TagSelection tagwl;
190 
195  SerializedInfo(const Serializer* Ser, const TagSelection& Tagwl)
196  : serializer(Ser)
197  , tagwl(Tagwl)
198  {
199  }
200 
205  bool operator==(const SerializedInfo& other) const
206  {
207  return ((serializer == other.serializer) && (tagwl == other.tagwl));
208  }
209  };
210 
211  class Param
212  {
213  const std::string* ptr;
215  bool owned;
216 
217  void InitFrom(const Param& other)
218  {
219  owned = other.owned;
220  if (owned)
221  new(str) std::string(*other.str);
222  else
223  ptr = other.ptr;
224  }
225 
226  public:
227  operator const std::string&() const { return (owned ? *str : *ptr); }
228 
229  Param()
230  : ptr(nullptr)
231  , owned(false)
232  {
233  }
234 
235  Param(const std::string& s)
236  : ptr(&s)
237  , owned(false)
238  {
239  }
240 
241  Param(int, const char* s)
242  : ptr(NULL)
243  , owned(true)
244  {
245  new(str) std::string(s);
246  }
247 
248  Param(int, const std::string& s)
249  : ptr(NULL)
250  , owned(true)
251  {
252  new(str) std::string(s);
253  }
254 
255  Param(const Param& other)
256  {
257  InitFrom(other);
258  }
259 
260  ~Param()
261  {
262  using std::string;
263  if (owned)
264  str->~string();
265  }
266 
267  Param& operator=(const Param& other)
268  {
269  if (&other == this)
270  return *this;
271 
272  using std::string;
273  if (owned)
274  str->~string();
275  InitFrom(other);
276  return *this;
277  }
278 
279  bool IsOwned() const { return owned; }
280  };
281 
282  typedef std::vector<Param> ParamList;
283 
284  private:
285  typedef std::vector<std::pair<SerializedInfo, SerializedMessage> > SerializedList;
286 
287  ParamList params;
288  TagMap tags;
289  std::string command;
290  bool msginit_done = false;
291  mutable SerializedList serlist;
292  bool sideeffect = false;
293 
294  protected:
298  void SetCommand(const char* cmd)
299  {
300  command.clear();
301  if (cmd)
302  command = cmd;
303  }
304 
305  public:
311  Message(const char* cmd, User* Sourceuser = NULL)
312  : ClientProtocol::MessageSource(Sourceuser)
313  , command(cmd ? cmd : std::string())
314  {
315  params.reserve(8);
316  serlist.reserve(8);
317  }
318 
326  Message(const char* cmd, const std::string& Sourcestr, User* Sourceuser = NULL)
327  : ClientProtocol::MessageSource(Sourcestr, Sourceuser)
328  , command(cmd ? cmd : std::string())
329  {
330  params.reserve(8);
331  serlist.reserve(8);
332  }
333 
337  const ParamList& GetParams() const { return params; }
338 
343  const TagMap& GetTags() const { return tags; }
344 
348  const char* GetCommand() const { return command.c_str(); }
349 
353  void PushParam(const char* str) { params.emplace_back(0, str); }
354 
358  void PushParam(const std::string& str) { params.emplace_back(0, str); }
359 
363  template <typename... Args>
364  void PushParam(const Args&... args)
365  {
366  (PushParam(ConvToStr(args)), ...);
367  }
368 
373  void PushParamRef(const std::string& str) { params.push_back(str); }
374 
378  void PushParamPlaceholder() { params.emplace_back(); }
379 
384  void ReplaceParam(size_t index, const char* str) { params[index] = Param(0, str); }
385 
390  void ReplaceParam(size_t index, const std::string& str) { params[index] = Param(0, str); }
391 
397  void ReplaceParamRef(size_t index, const std::string& str) { params[index] = Param(str); }
398 
405  void AddTag(const std::string& tagname, MessageTagProvider* tagprov, const std::string& val, void* tagdata = NULL)
406  {
407  tags.emplace(tagname, MessageTagData(tagprov, val, tagdata));
408  }
409 
413  void AddTags(const ClientProtocol::TagMap& newtags)
414  {
415  tags.insert(newtags.begin(), newtags.end());
416  }
417 
424  const SerializedMessage& GetSerialized(const SerializedInfo& serializeinfo) const;
425 
428  void ClearParams()
429  {
430  msginit_done = false;
431  params.clear();
432  tags.clear();
433  InvalidateCache();
434  }
435 
441  {
442  serlist.clear();
443  }
444 
445  void CopyAll()
446  {
447  size_t idx = 0;
448  for (const auto& param : params)
449  {
450  if (!param.IsOwned())
451  ReplaceParam(idx, param);
452  idx++;
453  }
454  }
455 
456  void SetSideEffect(bool Sideeffect) { sideeffect = Sideeffect; }
457  bool IsSideEffect() const { return sideeffect; }
458 
459  friend class Serializer;
460 };
461 
470 {
471  EventProvider* event;
472  Message* initialmsg = nullptr;
473  const MessageList* initialmsglist = nullptr;
474  bool eventinit_done = false;
475 
476  public:
480  Event(EventProvider& protoeventprov)
481  : event(&protoeventprov)
482  {
483  }
484 
490  : event(&protoeventprov)
491  , initialmsg(&msg)
492  {
493  }
494 
498  void SetMessage(Message* msg)
499  {
500  initialmsg = msg;
501  initialmsglist = NULL;
502  }
503 
507  void SetMessageList(const MessageList& msglist)
508  {
509  initialmsg = NULL;
510  initialmsglist = &msglist;
511  }
512 
518  void GetMessagesForUser(LocalUser* user, MessageList& messagelist);
519 };
520 
523 {
524  public:
525  MessageTagEvent(Module* mod)
526  : ModuleEventProvider(mod, "event/messagetag")
527  {
528  }
529 };
530 
537 {
538  public:
543  : Events::ModuleEventListener(mod, "event/messagetag")
544  {
545  }
546 
554  {
555  }
556 
565  virtual ModResult OnProcessTag(User* user, const std::string& tagname, std::string& tagvalue)
566  {
567  return MOD_RES_PASSTHRU;
568  }
569 
576  virtual bool ShouldSendTag(LocalUser* user, const MessageTagData& tagdata) = 0;
577 };
578 
584 {
585  public:
586  static std::string GetEventName(const std::string& name)
587  {
588  return "event/protoevent_" + name;
589  }
590 
597  EventHook(Module* mod, const std::string& name, unsigned int priority = Events::ModuleEventListener::DefaultPriority)
598  : Events::ModuleEventListener(mod, GetEventName(name), priority)
599  {
600  }
601 
606  virtual void OnEventInit(const ClientProtocol::Event& ev)
607  {
608  }
609 
620  virtual ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) = 0;
621 };
622 
628 {
629  public:
635  EventProvider(Module* Mod, const std::string& eventname)
636  : Events::ModuleEventProvider(Mod, ClientProtocol::EventHook::GetEventName(eventname))
637  {
638  }
639 };
640 
645 {
646  EventProvider numeric;
647  EventProvider join;
648  EventProvider part;
649  EventProvider kick;
650  EventProvider quit;
651  EventProvider nick;
652  EventProvider mode;
653  EventProvider topic;
654  EventProvider privmsg;
655  EventProvider invite;
656  EventProvider ping;
657  EventProvider pong;
658  EventProvider error;
659 
660  RFCEvents()
661  : numeric(NULL, "NUMERIC")
662  , join(NULL, "JOIN")
663  , part(NULL, "PART")
664  , kick(NULL, "KICK")
665  , quit(NULL, "QUIT")
666  , nick(NULL, "NICK")
667  , mode(NULL, "MODE")
668  , topic(NULL, "TOPIC")
669  , privmsg(NULL, "PRIVMSG")
670  , invite(NULL, "INVITE")
671  , ping(NULL, "PING")
672  , pong(NULL, "PONG")
673  , error(NULL, "ERROR")
674  {
675  }
676 };
677 
681 class CoreExport ClientProtocol::Serializer : public DataProvider
682 {
683  private:
685 
691  TagSelection MakeTagWhitelist(LocalUser* user, const TagMap& tagmap) const;
692 
693  public:
698  Serializer(Module* mod, const char* Name);
699 
707  bool HandleTag(LocalUser* user, const std::string& tagname, std::string& tagvalue, TagMap& tags) const;
708 
716  const SerializedMessage& SerializeForUser(LocalUser* user, Message& msg);
717 
724  virtual std::string Serialize(const Message& msg, const TagSelection& tagwl) const = 0;
725 
732  virtual bool Parse(LocalUser* user, const std::string& line, ParseOutput& parseoutput) = 0;
733 };
734 
735 inline ClientProtocol::MessageTagData::MessageTagData(MessageTagProvider* prov, const std::string& val, void* data)
736  : tagprov(prov)
737  , value(val)
738  , provdata(data)
739 {
740 }
Definition: clientprotocol.h:584
virtual ModResult OnPreEventSend(LocalUser *user, const ClientProtocol::Event &ev, ClientProtocol::MessageList &messagelist)=0
virtual void OnEventInit(const ClientProtocol::Event &ev)
Definition: clientprotocol.h:606
EventHook(Module *mod, const std::string &name, unsigned int priority=Events::ModuleEventListener::DefaultPriority)
Definition: clientprotocol.h:597
Definition: clientprotocol.h:470
Event(EventProvider &protoeventprov)
Definition: clientprotocol.h:480
Event(EventProvider &protoeventprov, ClientProtocol::Message &msg)
Definition: clientprotocol.h:489
void SetMessageList(const MessageList &msglist)
Definition: clientprotocol.h:507
void GetMessagesForUser(LocalUser *user, MessageList &messagelist)
Definition: clientprotocol.cpp:86
void SetMessage(Message *msg)
Definition: clientprotocol.h:498
Definition: clientprotocol.h:628
EventProvider(Module *Mod, const std::string &eventname)
Definition: clientprotocol.h:635
Definition: clientprotocol.h:212
Definition: clientprotocol.h:182
void PushParamPlaceholder()
Definition: clientprotocol.h:378
void SetCommand(const char *cmd)
Definition: clientprotocol.h:298
void ReplaceParamRef(size_t index, const std::string &str)
Definition: clientprotocol.h:397
void PushParam(const Args &... args)
Definition: clientprotocol.h:364
const TagMap & GetTags() const
Definition: clientprotocol.h:343
Message(const char *cmd, User *Sourceuser=NULL)
Definition: clientprotocol.h:311
void PushParam(const char *str)
Definition: clientprotocol.h:353
void ReplaceParam(size_t index, const std::string &str)
Definition: clientprotocol.h:390
void ClearParams()
Definition: clientprotocol.h:428
void ReplaceParam(size_t index, const char *str)
Definition: clientprotocol.h:384
void AddTags(const ClientProtocol::TagMap &newtags)
Definition: clientprotocol.h:413
void AddTag(const std::string &tagname, MessageTagProvider *tagprov, const std::string &val, void *tagdata=NULL)
Definition: clientprotocol.h:405
const char * GetCommand() const
Definition: clientprotocol.h:348
void PushParamRef(const std::string &str)
Definition: clientprotocol.h:373
void InvalidateCache()
Definition: clientprotocol.h:440
const SerializedMessage & GetSerialized(const SerializedInfo &serializeinfo) const
Definition: clientprotocol.cpp:72
const ParamList & GetParams() const
Definition: clientprotocol.h:337
void PushParam(const std::string &str)
Definition: clientprotocol.h:358
Message(const char *cmd, const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:326
Definition: clientprotocol.h:94
void SetSource(const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:156
MessageSource(const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:116
const std::string * GetSource() const
Definition: clientprotocol.h:124
void SetSource(const MessageSource &other)
Definition: clientprotocol.h:165
MessageSource(User *Sourceuser=NULL)
Definition: clientprotocol.h:104
void SetSourceUser(User *Sourceuser)
Definition: clientprotocol.h:144
User * GetSourceUser() const
Definition: clientprotocol.h:138
Definition: clientprotocol.h:523
Definition: clientprotocol.h:537
virtual void OnPopulateTags(ClientProtocol::Message &msg)
Definition: clientprotocol.h:553
virtual ModResult OnProcessTag(User *user, const std::string &tagname, std::string &tagvalue)
Definition: clientprotocol.h:565
MessageTagProvider(Module *mod)
Definition: clientprotocol.h:542
virtual bool ShouldSendTag(LocalUser *user, const MessageTagData &tagdata)=0
Definition: clientprotocol.h:682
Serializer(Module *mod, const char *Name)
Definition: clientprotocol.cpp:23
bool HandleTag(LocalUser *user, const std::string &tagname, std::string &tagvalue, TagMap &tags) const
Definition: clientprotocol.cpp:29
virtual bool Parse(LocalUser *user, const std::string &line, ParseOutput &parseoutput)=0
const SerializedMessage & SerializeForUser(LocalUser *user, Message &msg)
Definition: clientprotocol.cpp:62
virtual std::string Serialize(const Message &msg, const TagSelection &tagwl) const =0
Definition: clientprotocol.h:55
void Select(const TagMap &tags, TagMap::const_iterator it)
Definition: clientprotocol.h:76
bool operator==(const TagSelection &other) const
Definition: clientprotocol.h:87
bool IsSelected(const TagMap &tags, TagMap::const_iterator it) const
Definition: clientprotocol.h:65
Definition: modules.h:194
Definition: event.h:137
ModuleEventListener(Module *mod, const std::string &eventid, unsigned int eventprio=DefaultPriority)
Definition: event.h:159
Definition: event.h:40
ModuleEventProvider(Module *mod, const std::string &eventid)
Definition: event.h:58
Definition: users.h:658
Definition: modules.h:72
Definition: modules.h:286
Definition: users.h:238
virtual const std::string & GetFullHost()
Definition: users.cpp:145
Definition: clientprotocol.h:187
SerializedInfo(const Serializer *Ser, const TagSelection &Tagwl)
Definition: clientprotocol.h:195
bool operator==(const SerializedInfo &other) const
Definition: clientprotocol.h:205
Definition: typedefs.h:69
Definition: clientprotocol.h:38
std::string cmd
Definition: clientprotocol.h:41
ClientProtocol::ParamList params
Definition: clientprotocol.h:45
ClientProtocol::TagMap tags
Definition: clientprotocol.h:49
Definition: clientprotocol.h:645