InspIRCd  3.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(NULL)
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;
291  mutable SerializedList serlist;
292  bool sideeffect;
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  , msginit_done(false)
315  , sideeffect(false)
316  {
317  params.reserve(8);
318  serlist.reserve(8);
319  }
320 
328  Message(const char* cmd, const std::string& Sourcestr, User* Sourceuser = NULL)
329  : ClientProtocol::MessageSource(Sourcestr, Sourceuser)
330  , command(cmd ? cmd : std::string())
331  , msginit_done(false)
332  , sideeffect(false)
333  {
334  params.reserve(8);
335  serlist.reserve(8);
336  }
337 
341  const ParamList& GetParams() const { return params; }
342 
347  const TagMap& GetTags() const { return tags; }
348 
352  const char* GetCommand() const { return command.c_str(); }
353 
357  void PushParam(const char* str) { params.push_back(Param(0, str)); }
358 
362  void PushParam(const std::string& str) { params.push_back(Param(0, str)); }
363 
368  void PushParamRef(const std::string& str) { params.push_back(str); }
369 
373  void PushParamPlaceholder() { params.push_back(Param()); }
374 
379  void ReplaceParam(unsigned int index, const char* str) { params[index] = Param(0, str); }
380 
385  void ReplaceParam(unsigned int index, const std::string& str) { params[index] = Param(0, str); }
386 
392  void ReplaceParamRef(unsigned int index, const std::string& str) { params[index] = Param(str); }
393 
400  void AddTag(const std::string& tagname, MessageTagProvider* tagprov, const std::string& val, void* tagdata = NULL)
401  {
402  tags.insert(std::make_pair(tagname, MessageTagData(tagprov, val, tagdata)));
403  }
404 
408  void AddTags(const ClientProtocol::TagMap& newtags)
409  {
410  tags.insert(newtags.begin(), newtags.end());
411  }
412 
419  const SerializedMessage& GetSerialized(const SerializedInfo& serializeinfo) const;
420 
423  void ClearParams()
424  {
425  msginit_done = false;
426  params.clear();
427  tags.clear();
428  InvalidateCache();
429  }
430 
436  {
437  serlist.clear();
438  }
439 
440  void CopyAll()
441  {
442  size_t j = 0;
443  for (ParamList::iterator i = params.begin(); i != params.end(); ++i, j++)
444  {
445  Param& curr = *i;
446  if (!curr.IsOwned())
447  ReplaceParam(j, curr);
448  }
449  }
450 
451  void SetSideEffect(bool Sideeffect) { sideeffect = Sideeffect; }
452  bool IsSideEffect() const { return sideeffect; }
453 
454  friend class Serializer;
455 };
456 
465 {
466  EventProvider* event;
467  Message* initialmsg;
468  const MessageList* initialmsglist;
469  bool eventinit_done;
470 
471  public:
475  Event(EventProvider& protoeventprov)
476  : event(&protoeventprov)
477  , initialmsg(NULL)
478  , initialmsglist(NULL)
479  , eventinit_done(false)
480  {
481  }
482 
488  : event(&protoeventprov)
489  , initialmsg(&msg)
490  , initialmsglist(NULL)
491  , eventinit_done(false)
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:465
Event(EventProvider &protoeventprov)
Definition: clientprotocol.h:475
Event(EventProvider &protoeventprov, ClientProtocol::Message &msg)
Definition: clientprotocol.h:487
void SetMessageList(const MessageList &msglist)
Definition: clientprotocol.h:507
void GetMessagesForUser(LocalUser *user, MessageList &messagelist)
Definition: clientprotocol.cpp:87
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:373
void SetCommand(const char *cmd)
Definition: clientprotocol.h:298
void ReplaceParam(unsigned int index, const char *str)
Definition: clientprotocol.h:379
const TagMap & GetTags() const
Definition: clientprotocol.h:347
Message(const char *cmd, User *Sourceuser=NULL)
Definition: clientprotocol.h:311
void ReplaceParam(unsigned int index, const std::string &str)
Definition: clientprotocol.h:385
void PushParam(const char *str)
Definition: clientprotocol.h:357
void ClearParams()
Definition: clientprotocol.h:423
void AddTags(const ClientProtocol::TagMap &newtags)
Definition: clientprotocol.h:408
void ReplaceParamRef(unsigned int index, const std::string &str)
Definition: clientprotocol.h:392
void AddTag(const std::string &tagname, MessageTagProvider *tagprov, const std::string &val, void *tagdata=NULL)
Definition: clientprotocol.h:400
const char * GetCommand() const
Definition: clientprotocol.h:352
void PushParamRef(const std::string &str)
Definition: clientprotocol.h:368
void InvalidateCache()
Definition: clientprotocol.h:435
const SerializedMessage & GetSerialized(const SerializedInfo &serializeinfo) const
Definition: clientprotocol.cpp:72
const ParamList & GetParams() const
Definition: clientprotocol.h:341
void PushParam(const std::string &str)
Definition: clientprotocol.h:362
Message(const char *cmd, const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:328
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:222
Definition: event.h:124
ModuleEventListener(Module *mod, const std::string &eventid, unsigned int eventprio=DefaultPriority)
Definition: event.h:146
Definition: event.h:38
ModuleEventProvider(Module *mod, const std::string &eventid)
Definition: event.h:56
Definition: users.h:745
Definition: modules.h:72
Definition: modules.h:318
Definition: users.h:247
virtual const std::string & GetFullHost()
Definition: users.cpp:161
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