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  : owned(true)
243  {
244  new(str) std::string(s);
245  }
246 
247  Param(int, const std::string& s)
248  : owned(true)
249  {
250  new(str) std::string(s);
251  }
252 
253  Param(const Param& other)
254  {
255  InitFrom(other);
256  }
257 
258  ~Param()
259  {
260  using std::string;
261  if (owned)
262  str->~string();
263  }
264 
265  Param& operator=(const Param& other)
266  {
267  if (&other == this)
268  return *this;
269 
270  using std::string;
271  if (owned)
272  str->~string();
273  InitFrom(other);
274  return *this;
275  }
276 
277  bool IsOwned() const { return owned; }
278  };
279 
280  typedef std::vector<Param> ParamList;
281 
282  private:
283  typedef std::vector<std::pair<SerializedInfo, SerializedMessage> > SerializedList;
284 
285  ParamList params;
286  TagMap tags;
287  std::string command;
288  bool msginit_done;
289  mutable SerializedList serlist;
290  bool sideeffect;
291 
292  protected:
296  void SetCommand(const char* cmd)
297  {
298  command.clear();
299  if (cmd)
300  command = cmd;
301  }
302 
303  public:
309  Message(const char* cmd, User* Sourceuser = NULL)
310  : ClientProtocol::MessageSource(Sourceuser)
311  , command(cmd ? cmd : std::string())
312  , msginit_done(false)
313  , sideeffect(false)
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  , msginit_done(false)
330  , sideeffect(false)
331  {
332  params.reserve(8);
333  serlist.reserve(8);
334  }
335 
339  const ParamList& GetParams() const { return params; }
340 
345  const TagMap& GetTags() const { return tags; }
346 
350  const char* GetCommand() const { return command.c_str(); }
351 
355  void PushParam(const char* str) { params.push_back(Param(0, str)); }
356 
360  void PushParam(const std::string& str) { params.push_back(Param(0, str)); }
361 
366  void PushParamRef(const std::string& str) { params.push_back(str); }
367 
371  void PushParamPlaceholder() { params.push_back(Param()); }
372 
377  void ReplaceParam(unsigned int index, const char* str) { params[index] = Param(0, str); }
378 
383  void ReplaceParam(unsigned int index, const std::string& str) { params[index] = Param(0, str); }
384 
390  void ReplaceParamRef(unsigned int index, const std::string& str) { params[index] = Param(str); }
391 
398  void AddTag(const std::string& tagname, MessageTagProvider* tagprov, const std::string& val, void* tagdata = NULL)
399  {
400  tags.insert(std::make_pair(tagname, MessageTagData(tagprov, val, tagdata)));
401  }
402 
406  void AddTags(const ClientProtocol::TagMap& newtags)
407  {
408  tags.insert(newtags.begin(), newtags.end());
409  }
410 
417  const SerializedMessage& GetSerialized(const SerializedInfo& serializeinfo) const;
418 
421  void ClearParams()
422  {
423  msginit_done = false;
424  params.clear();
425  tags.clear();
426  InvalidateCache();
427  }
428 
434  {
435  serlist.clear();
436  }
437 
438  void CopyAll()
439  {
440  size_t j = 0;
441  for (ParamList::iterator i = params.begin(); i != params.end(); ++i, j++)
442  {
443  Param& curr = *i;
444  if (!curr.IsOwned())
445  ReplaceParam(j, curr);
446  }
447  }
448 
449  void SetSideEffect(bool Sideeffect) { sideeffect = Sideeffect; }
450  bool IsSideEffect() const { return sideeffect; }
451 
452  friend class Serializer;
453 };
454 
463 {
464  EventProvider* event;
465  Message* initialmsg;
466  const MessageList* initialmsglist;
467  bool eventinit_done;
468 
469  public:
473  Event(EventProvider& protoeventprov)
474  : event(&protoeventprov)
475  , initialmsg(NULL)
476  , initialmsglist(NULL)
477  , eventinit_done(false)
478  {
479  }
480 
486  : event(&protoeventprov)
487  , initialmsg(&msg)
488  , initialmsglist(NULL)
489  , eventinit_done(false)
490  {
491  }
492 
496  void SetMessage(Message* msg)
497  {
498  initialmsg = msg;
499  initialmsglist = NULL;
500  }
501 
505  void SetMessageList(const MessageList& msglist)
506  {
507  initialmsg = NULL;
508  initialmsglist = &msglist;
509  }
510 
516  void GetMessagesForUser(LocalUser* user, MessageList& messagelist);
517 };
518 
521 {
522  public:
523  MessageTagEvent(Module* mod)
524  : ModuleEventProvider(mod, "event/messagetag")
525  {
526  }
527 };
528 
535 {
536  public:
541  : Events::ModuleEventListener(mod, "event/messagetag")
542  {
543  }
544 
552  {
553  }
554 
563  virtual ModResult OnProcessTag(User* user, const std::string& tagname, std::string& tagvalue)
564  {
565  return MOD_RES_PASSTHRU;
566  }
567 
574  virtual bool ShouldSendTag(LocalUser* user, const MessageTagData& tagdata) = 0;
575 };
576 
582 {
583  public:
584  static std::string GetEventName(const std::string& name)
585  {
586  return "event/protoevent_" + name;
587  }
588 
595  EventHook(Module* mod, const std::string& name, unsigned int priority = Events::ModuleEventListener::DefaultPriority)
596  : Events::ModuleEventListener(mod, GetEventName(name), priority)
597  {
598  }
599 
604  virtual void OnEventInit(const ClientProtocol::Event& ev)
605  {
606  }
607 
618  virtual ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) = 0;
619 };
620 
626 {
627  public:
633  EventProvider(Module* Mod, const std::string& eventname)
634  : Events::ModuleEventProvider(Mod, ClientProtocol::EventHook::GetEventName(eventname))
635  {
636  }
637 };
638 
643 {
644  EventProvider numeric;
645  EventProvider join;
646  EventProvider part;
647  EventProvider kick;
648  EventProvider quit;
649  EventProvider nick;
650  EventProvider mode;
651  EventProvider topic;
652  EventProvider privmsg;
653  EventProvider invite;
654  EventProvider ping;
655  EventProvider pong;
656  EventProvider error;
657 
658  RFCEvents()
659  : numeric(NULL, "NUMERIC")
660  , join(NULL, "JOIN")
661  , part(NULL, "PART")
662  , kick(NULL, "KICK")
663  , quit(NULL, "QUIT")
664  , nick(NULL, "NICK")
665  , mode(NULL, "MODE")
666  , topic(NULL, "TOPIC")
667  , privmsg(NULL, "PRIVMSG")
668  , invite(NULL, "INVITE")
669  , ping(NULL, "PING")
670  , pong(NULL, "PONG")
671  , error(NULL, "ERROR")
672  {
673  }
674 };
675 
679 class CoreExport ClientProtocol::Serializer : public DataProvider
680 {
681  private:
683 
689  TagSelection MakeTagWhitelist(LocalUser* user, const TagMap& tagmap) const;
690 
691  public:
696  Serializer(Module* mod, const char* Name);
697 
705  bool HandleTag(LocalUser* user, const std::string& tagname, std::string& tagvalue, TagMap& tags) const;
706 
714  const SerializedMessage& SerializeForUser(LocalUser* user, Message& msg);
715 
722  virtual std::string Serialize(const Message& msg, const TagSelection& tagwl) const = 0;
723 
730  virtual bool Parse(LocalUser* user, const std::string& line, ParseOutput& parseoutput) = 0;
731 };
732 
733 inline ClientProtocol::MessageTagData::MessageTagData(MessageTagProvider* prov, const std::string& val, void* data)
734  : tagprov(prov)
735  , value(val)
736  , provdata(data)
737 {
738 }
ClientProtocol::Event::SetMessage
void SetMessage(Message *msg)
Definition: clientprotocol.h:496
ClientProtocol::Message::SerializedInfo
Definition: clientprotocol.h:186
ClientProtocol::EventProvider
Definition: clientprotocol.h:625
ClientProtocol::Event::SetMessageList
void SetMessageList(const MessageList &msglist)
Definition: clientprotocol.h:505
ClientProtocol::Message::PushParam
void PushParam(const std::string &str)
Definition: clientprotocol.h:360
ClientProtocol::Serializer::HandleTag
bool HandleTag(LocalUser *user, const std::string &tagname, std::string &tagvalue, TagMap &tags) const
Definition: clientprotocol.cpp:29
insp::aligned_storage< std::string >
ClientProtocol::MessageTagEvent
Definition: clientprotocol.h:519
ClientProtocol::TagSelection::IsSelected
bool IsSelected(const TagMap &tags, TagMap::const_iterator it) const
Definition: clientprotocol.h:65
ClientProtocol::Serializer::Serialize
virtual std::string Serialize(const Message &msg, const TagSelection &tagwl) const =0
Events::ModuleEventListener::ModuleEventListener
ModuleEventListener(Module *mod, const std::string &eventid, unsigned int eventprio=DefaultPriority)
Definition: event.h:141
ClientProtocol::Message::ReplaceParam
void ReplaceParam(unsigned int index, const char *str)
Definition: clientprotocol.h:377
ClientProtocol::Event
Definition: clientprotocol.h:462
ClientProtocol::Message::ClearParams
void ClearParams()
Definition: clientprotocol.h:421
insp::flat_map< std::string, MessageTagData, std::greater< std::string > >
ClientProtocol::TagSelection::Select
void Select(const TagMap &tags, TagMap::const_iterator it)
Definition: clientprotocol.h:76
ClientProtocol::ParseOutput::params
ClientProtocol::ParamList params
Definition: clientprotocol.h:45
ClientProtocol::Message::PushParamPlaceholder
void PushParamPlaceholder()
Definition: clientprotocol.h:371
ClientProtocol::MessageSource::SetSourceUser
void SetSourceUser(User *Sourceuser)
Definition: clientprotocol.h:144
ClientProtocol::MessageSource::GetSource
const std::string * GetSource() const
Definition: clientprotocol.h:124
DataProvider
Definition: modules.h:207
ClientProtocol::Message::AddTag
void AddTag(const std::string &tagname, MessageTagProvider *tagprov, const std::string &val, void *tagdata=NULL)
Definition: clientprotocol.h:398
ClientProtocol::MessageSource::SetSource
void SetSource(const MessageSource &other)
Definition: clientprotocol.h:165
ClientProtocol::Event::GetMessagesForUser
void GetMessagesForUser(LocalUser *user, MessageList &messagelist)
Definition: clientprotocol.cpp:87
ModResult
Definition: modules.h:70
ClientProtocol::Message::AddTags
void AddTags(const ClientProtocol::TagMap &newtags)
Definition: clientprotocol.h:406
ClientProtocol::Event::Event
Event(EventProvider &protoeventprov)
Definition: clientprotocol.h:473
ClientProtocol::Message::ReplaceParamRef
void ReplaceParamRef(unsigned int index, const std::string &str)
Definition: clientprotocol.h:390
User::GetFullHost
virtual const std::string & GetFullHost()
Definition: users.cpp:161
ClientProtocol::Message::SerializedInfo::operator==
bool operator==(const SerializedInfo &other) const
Definition: clientprotocol.h:205
ClientProtocol::MessageTagProvider::MessageTagProvider
MessageTagProvider(Module *mod)
Definition: clientprotocol.h:540
ClientProtocol::Message::ReplaceParam
void ReplaceParam(unsigned int index, const std::string &str)
Definition: clientprotocol.h:383
ClientProtocol::MessageTagProvider::ShouldSendTag
virtual bool ShouldSendTag(LocalUser *user, const MessageTagData &tagdata)=0
ClientProtocol::ParseOutput
Definition: clientprotocol.h:37
ClientProtocol::MessageSource::MessageSource
MessageSource(const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:116
ClientProtocol::RFCEvents
Definition: clientprotocol.h:642
ClientProtocol::Message::PushParam
void PushParam(const char *str)
Definition: clientprotocol.h:355
ClientProtocol::TagSelection
Definition: clientprotocol.h:54
ClientProtocol::ParseOutput::cmd
std::string cmd
Definition: clientprotocol.h:41
ClientProtocol::EventHook::OnPreEventSend
virtual ModResult OnPreEventSend(LocalUser *user, const ClientProtocol::Event &ev, ClientProtocol::MessageList &messagelist)=0
ClientProtocol::Message::SetCommand
void SetCommand(const char *cmd)
Definition: clientprotocol.h:296
ClientProtocol::EventProvider::EventProvider
EventProvider(Module *Mod, const std::string &eventname)
Definition: clientprotocol.h:633
ClientProtocol::Message::InvalidateCache
void InvalidateCache()
Definition: clientprotocol.h:433
ClientProtocol::Message::Message
Message(const char *cmd, User *Sourceuser=NULL)
Definition: clientprotocol.h:309
ClientProtocol::TagSelection::operator==
bool operator==(const TagSelection &other) const
Definition: clientprotocol.h:87
ClientProtocol::Message::GetSerialized
const SerializedMessage & GetSerialized(const SerializedInfo &serializeinfo) const
Definition: clientprotocol.cpp:72
ClientProtocol::Message::GetParams
const ParamList & GetParams() const
Definition: clientprotocol.h:339
ClientProtocol::Message::SerializedInfo::SerializedInfo
SerializedInfo(const Serializer *Ser, const TagSelection &Tagwl)
Definition: clientprotocol.h:195
ClientProtocol::Message::Param
Definition: clientprotocol.h:211
Events::ModuleEventProvider
Definition: event.h:35
ClientProtocol::ParseOutput::tags
ClientProtocol::TagMap tags
Definition: clientprotocol.h:49
ClientProtocol::Event::Event
Event(EventProvider &protoeventprov, ClientProtocol::Message &msg)
Definition: clientprotocol.h:485
ClientProtocol::Message::Message
Message(const char *cmd, const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:326
Events::ModuleEventListener
Definition: event.h:118
ClientProtocol::Message::GetCommand
const char * GetCommand() const
Definition: clientprotocol.h:350
ClientProtocol::Message::PushParamRef
void PushParamRef(const std::string &str)
Definition: clientprotocol.h:366
Module
Definition: modules.h:247
User
Definition: users.h:233
ClientProtocol::Serializer::Parse
virtual bool Parse(LocalUser *user, const std::string &line, ParseOutput &parseoutput)=0
ClientProtocol::MessageSource::MessageSource
MessageSource(User *Sourceuser=NULL)
Definition: clientprotocol.h:104
ClientProtocol::Serializer::SerializeForUser
const SerializedMessage & SerializeForUser(LocalUser *user, Message &msg)
Definition: clientprotocol.cpp:62
ClientProtocol::Message
Definition: clientprotocol.h:181
ClientProtocol::MessageTagProvider::OnPopulateTags
virtual void OnPopulateTags(ClientProtocol::Message &msg)
Definition: clientprotocol.h:551
ClientProtocol::Serializer::Serializer
Serializer(Module *mod, const char *Name)
Definition: clientprotocol.cpp:23
ClientProtocol::EventHook
Definition: clientprotocol.h:581
ClientProtocol::EventHook::OnEventInit
virtual void OnEventInit(const ClientProtocol::Event &ev)
Definition: clientprotocol.h:604
ClientProtocol::MessageSource::SetSource
void SetSource(const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:156
ClientProtocol::MessageTagProvider
Definition: clientprotocol.h:534
ClientProtocol::MessageTagData
Definition: typedefs.h:68
ClientProtocol::EventHook::EventHook
EventHook(Module *mod, const std::string &name, unsigned int priority=Events::ModuleEventListener::DefaultPriority)
Definition: clientprotocol.h:595
ClientProtocol::MessageTagProvider::OnProcessTag
virtual ModResult OnProcessTag(User *user, const std::string &tagname, std::string &tagvalue)
Definition: clientprotocol.h:563
Events::ModuleEventProvider::ModuleEventProvider
ModuleEventProvider(Module *mod, const std::string &eventid)
Definition: event.h:54
ClientProtocol::MessageSource::GetSourceUser
User * GetSourceUser() const
Definition: clientprotocol.h:138
ClientProtocol::Serializer
Definition: clientprotocol.h:679
ClientProtocol::Message::GetTags
const TagMap & GetTags() const
Definition: clientprotocol.h:345
ClientProtocol::MessageSource
Definition: clientprotocol.h:93
LocalUser
Definition: users.h:727