InspIRCd  3.0
clientprotocol.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2016 Attila Molnar <[email protected]>
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 "event.h"
23 
24 namespace ClientProtocol
25 {
26  class EventHook;
27  class MessageSource;
28  struct RFCEvents;
29  struct ParseOutput;
30  class TagSelection;
31 }
32 
37 {
40  std::string cmd;
41 
44  ClientProtocol::ParamList params;
45 
49 };
50 
54 {
55  std::bitset<64> selection;
56 
57  public:
64  bool IsSelected(const TagMap& tags, TagMap::const_iterator it) const
65  {
66  const size_t index = std::distance(tags.begin(), it);
67  return ((index < selection.size()) && (selection[index]));
68  }
69 
75  void Select(const TagMap& tags, TagMap::const_iterator it)
76  {
77  const size_t index = std::distance(tags.begin(), it);
78  if (index < selection.size())
79  selection[index] = true;
80  }
81 
86  bool operator==(const TagSelection& other) const
87  {
88  return (this->selection == other.selection);
89  }
90 };
91 
93 {
94  User* sourceuser;
95  const std::string* sourcestr;
96 
97  public:
103  MessageSource(User* Sourceuser = NULL)
104  {
105  SetSourceUser(Sourceuser);
106  }
107 
115  MessageSource(const std::string& Sourcestr, User* Sourceuser = NULL)
116  {
117  SetSource(Sourcestr, Sourceuser);
118  }
119 
123  const std::string* GetSource() const
124  {
125  // Return string if there's one explicitly set
126  if (sourcestr)
127  return sourcestr;
128  if (sourceuser)
129  return &sourceuser->GetFullHost();
130  return NULL;
131  }
132 
137  User* GetSourceUser() const { return sourceuser; }
138 
143  void SetSourceUser(User* Sourceuser)
144  {
145  sourceuser = Sourceuser;
146  sourcestr = NULL;
147  }
148 
155  void SetSource(const std::string& Sourcestr, User* Sourceuser = NULL)
156  {
157  sourcestr = &Sourcestr;
158  sourceuser = Sourceuser;
159  }
160 
164  void SetSource(const MessageSource& other)
165  {
166  sourcestr = other.sourcestr;
167  sourceuser = other.sourceuser;
168  }
169 };
170 
181 {
182  public:
186  {
187  const Serializer* serializer;
188  TagSelection tagwl;
189 
194  SerializedInfo(const Serializer* Ser, const TagSelection& Tagwl)
195  : serializer(Ser)
196  , tagwl(Tagwl)
197  {
198  }
199 
204  bool operator==(const SerializedInfo& other) const
205  {
206  return ((serializer == other.serializer) && (tagwl == other.tagwl));
207  }
208  };
209 
210  class Param
211  {
212  const std::string* ptr;
214  bool owned;
215 
216  void InitFrom(const Param& other)
217  {
218  owned = other.owned;
219  if (owned)
220  new(str) std::string(*other.str);
221  else
222  ptr = other.ptr;
223  }
224 
225  public:
226  operator const std::string&() const { return (owned ? *str : *ptr); }
227 
228  Param()
229  : ptr(NULL)
230  , owned(false)
231  {
232  }
233 
234  Param(const std::string& s)
235  : ptr(&s)
236  , owned(false)
237  {
238  }
239 
240  Param(int, const char* s)
241  : owned(true)
242  {
243  new(str) std::string(s);
244  }
245 
246  Param(int, const std::string& s)
247  : owned(true)
248  {
249  new(str) std::string(s);
250  }
251 
252  Param(const Param& other)
253  {
254  InitFrom(other);
255  }
256 
257  ~Param()
258  {
259  using std::string;
260  if (owned)
261  str->~string();
262  }
263 
264  Param& operator=(const Param& other)
265  {
266  if (&other == this)
267  return *this;
268 
269  using std::string;
270  if (owned)
271  str->~string();
272  InitFrom(other);
273  return *this;
274  }
275 
276  bool IsOwned() const { return owned; }
277  };
278 
279  typedef std::vector<Param> ParamList;
280 
281  private:
282  typedef std::vector<std::pair<SerializedInfo, SerializedMessage> > SerializedList;
283 
284  ParamList params;
285  TagMap tags;
286  std::string command;
287  bool msginit_done;
288  mutable SerializedList serlist;
289  bool sideeffect;
290 
291  protected:
295  void SetCommand(const char* cmd)
296  {
297  command.clear();
298  if (cmd)
299  command = cmd;
300  }
301 
302  public:
308  Message(const char* cmd, User* Sourceuser = NULL)
309  : ClientProtocol::MessageSource(Sourceuser)
310  , command(cmd ? cmd : std::string())
311  , msginit_done(false)
312  , sideeffect(false)
313  {
314  params.reserve(8);
315  serlist.reserve(8);
316  }
317 
325  Message(const char* cmd, const std::string& Sourcestr, User* Sourceuser = NULL)
326  : ClientProtocol::MessageSource(Sourcestr, Sourceuser)
327  , command(cmd ? cmd : std::string())
328  , msginit_done(false)
329  , sideeffect(false)
330  {
331  params.reserve(8);
332  serlist.reserve(8);
333  }
334 
338  const ParamList& GetParams() const { return params; }
339 
344  const TagMap& GetTags() const { return tags; }
345 
349  const char* GetCommand() const { return command.c_str(); }
350 
354  void PushParam(const char* str) { params.push_back(Param(0, str)); }
355 
359  void PushParam(const std::string& str) { params.push_back(Param(0, str)); }
360 
365  void PushParamRef(const std::string& str) { params.push_back(str); }
366 
370  void PushParamPlaceholder() { params.push_back(Param()); }
371 
376  void ReplaceParam(unsigned int index, const char* str) { params[index] = Param(0, str); }
377 
382  void ReplaceParam(unsigned int index, const std::string& str) { params[index] = Param(0, str); }
383 
389  void ReplaceParamRef(unsigned int index, const std::string& str) { params[index] = Param(str); }
390 
397  void AddTag(const std::string& tagname, MessageTagProvider* tagprov, const std::string& val, void* tagdata = NULL)
398  {
399  tags.insert(std::make_pair(tagname, MessageTagData(tagprov, val, tagdata)));
400  }
401 
405  void AddTags(const ClientProtocol::TagMap& newtags)
406  {
407  tags.insert(newtags.begin(), newtags.end());
408  }
409 
416  const SerializedMessage& GetSerialized(const SerializedInfo& serializeinfo) const;
417 
420  void ClearParams()
421  {
422  msginit_done = false;
423  params.clear();
424  tags.clear();
425  InvalidateCache();
426  }
427 
433  {
434  serlist.clear();
435  }
436 
437  void CopyAll()
438  {
439  size_t j = 0;
440  for (ParamList::iterator i = params.begin(); i != params.end(); ++i, j++)
441  {
442  Param& curr = *i;
443  if (!curr.IsOwned())
444  ReplaceParam(j, curr);
445  }
446  }
447 
448  void SetSideEffect(bool Sideeffect) { sideeffect = Sideeffect; }
449  bool IsSideEffect() const { return sideeffect; }
450 
451  friend class Serializer;
452 };
453 
462 {
463  EventProvider* event;
464  Message* initialmsg;
465  const MessageList* initialmsglist;
466  bool eventinit_done;
467 
468  public:
472  Event(EventProvider& protoeventprov)
473  : event(&protoeventprov)
474  , initialmsg(NULL)
475  , initialmsglist(NULL)
476  , eventinit_done(false)
477  {
478  }
479 
485  : event(&protoeventprov)
486  , initialmsg(&msg)
487  , initialmsglist(NULL)
488  , eventinit_done(false)
489  {
490  }
491 
495  void SetMessage(Message* msg)
496  {
497  initialmsg = msg;
498  initialmsglist = NULL;
499  }
500 
504  void SetMessageList(const MessageList& msglist)
505  {
506  initialmsg = NULL;
507  initialmsglist = &msglist;
508  }
509 
515  void GetMessagesForUser(LocalUser* user, MessageList& messagelist);
516 };
517 
524 {
525  public:
530  : Events::ModuleEventListener(mod, "event/messagetag")
531  {
532  }
533 
541  {
542  }
543 
552  virtual ModResult OnProcessTag(User* user, const std::string& tagname, std::string& tagvalue)
553  {
554  return MOD_RES_PASSTHRU;
555  }
556 
563  virtual bool ShouldSendTag(LocalUser* user, const MessageTagData& tagdata) = 0;
564 };
565 
571 {
572  public:
573  static std::string GetEventName(const std::string& name)
574  {
575  return "event/protoevent_" + name;
576  }
577 
584  EventHook(Module* mod, const std::string& name, unsigned int priority = Events::ModuleEventListener::DefaultPriority)
585  : Events::ModuleEventListener(mod, GetEventName(name), priority)
586  {
587  }
588 
593  virtual void OnEventInit(const ClientProtocol::Event& ev)
594  {
595  }
596 
607  virtual ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) = 0;
608 };
609 
615 {
616  public:
622  EventProvider(Module* Mod, const std::string& eventname)
623  : Events::ModuleEventProvider(Mod, ClientProtocol::EventHook::GetEventName(eventname))
624  {
625  }
626 };
627 
632 {
633  EventProvider numeric;
634  EventProvider join;
635  EventProvider part;
636  EventProvider kick;
637  EventProvider quit;
638  EventProvider nick;
639  EventProvider mode;
640  EventProvider topic;
641  EventProvider privmsg;
642  EventProvider invite;
643  EventProvider ping;
644  EventProvider pong;
645  EventProvider error;
646 
647  RFCEvents()
648  : numeric(NULL, "NUMERIC")
649  , join(NULL, "JOIN")
650  , part(NULL, "PART")
651  , kick(NULL, "KICK")
652  , quit(NULL, "QUIT")
653  , nick(NULL, "NICK")
654  , mode(NULL, "MODE")
655  , topic(NULL, "TOPIC")
656  , privmsg(NULL, "PRIVMSG")
657  , invite(NULL, "INVITE")
658  , ping(NULL, "PING")
659  , pong(NULL, "PONG")
660  , error(NULL, "ERROR")
661  {
662  }
663 };
664 
668 class CoreExport ClientProtocol::Serializer : public DataProvider
669 {
671 
677  TagSelection MakeTagWhitelist(LocalUser* user, const TagMap& tagmap) const;
678 
679  public:
684  Serializer(Module* mod, const char* Name);
685 
693  bool HandleTag(LocalUser* user, const std::string& tagname, std::string& tagvalue, TagMap& tags) const;
694 
702  const SerializedMessage& SerializeForUser(LocalUser* user, Message& msg);
703 
710  virtual std::string Serialize(const Message& msg, const TagSelection& tagwl) const = 0;
711 
718  virtual bool Parse(LocalUser* user, const std::string& line, ParseOutput& parseoutput) = 0;
719 };
720 
721 inline ClientProtocol::MessageTagData::MessageTagData(MessageTagProvider* prov, const std::string& val, void* data)
722  : tagprov(prov)
723  , value(val)
724  , provdata(data)
725 {
726 }
ClientProtocol::Event::SetMessage
void SetMessage(Message *msg)
Definition: clientprotocol.h:495
ClientProtocol::Message::SerializedInfo
Definition: clientprotocol.h:185
ClientProtocol::EventProvider
Definition: clientprotocol.h:614
ClientProtocol::Event::SetMessageList
void SetMessageList(const MessageList &msglist)
Definition: clientprotocol.h:504
ClientProtocol::Message::PushParam
void PushParam(const std::string &str)
Definition: clientprotocol.h:359
ClientProtocol::Serializer::HandleTag
bool HandleTag(LocalUser *user, const std::string &tagname, std::string &tagvalue, TagMap &tags) const
Definition: clientprotocol.cpp:28
insp::aligned_storage< std::string >
ClientProtocol::TagSelection::IsSelected
bool IsSelected(const TagMap &tags, TagMap::const_iterator it) const
Definition: clientprotocol.h:64
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:135
ClientProtocol::Message::ReplaceParam
void ReplaceParam(unsigned int index, const char *str)
Definition: clientprotocol.h:376
ClientProtocol::Event
Definition: clientprotocol.h:461
ClientProtocol::Message::ClearParams
void ClearParams()
Definition: clientprotocol.h:420
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:75
ClientProtocol::ParseOutput::params
ClientProtocol::ParamList params
Definition: clientprotocol.h:44
ClientProtocol::Message::PushParamPlaceholder
void PushParamPlaceholder()
Definition: clientprotocol.h:370
ClientProtocol::MessageSource::SetSourceUser
void SetSourceUser(User *Sourceuser)
Definition: clientprotocol.h:143
ClientProtocol::MessageSource::GetSource
const std::string * GetSource() const
Definition: clientprotocol.h:123
DataProvider
Definition: modules.h:202
ClientProtocol::Message::AddTag
void AddTag(const std::string &tagname, MessageTagProvider *tagprov, const std::string &val, void *tagdata=NULL)
Definition: clientprotocol.h:397
ClientProtocol::MessageSource::SetSource
void SetSource(const MessageSource &other)
Definition: clientprotocol.h:164
ClientProtocol::Event::GetMessagesForUser
void GetMessagesForUser(LocalUser *user, MessageList &messagelist)
Definition: clientprotocol.cpp:86
ModResult
Definition: modules.h:65
ClientProtocol::Message::AddTags
void AddTags(const ClientProtocol::TagMap &newtags)
Definition: clientprotocol.h:405
ClientProtocol::Event::Event
Event(EventProvider &protoeventprov)
Definition: clientprotocol.h:472
ClientProtocol::Message::ReplaceParamRef
void ReplaceParamRef(unsigned int index, const std::string &str)
Definition: clientprotocol.h:389
User::GetFullHost
virtual const std::string & GetFullHost()
Definition: users.cpp:146
ClientProtocol::Message::SerializedInfo::operator==
bool operator==(const SerializedInfo &other) const
Definition: clientprotocol.h:204
ClientProtocol::MessageTagProvider::MessageTagProvider
MessageTagProvider(Module *mod)
Definition: clientprotocol.h:529
ClientProtocol::Message::ReplaceParam
void ReplaceParam(unsigned int index, const std::string &str)
Definition: clientprotocol.h:382
ClientProtocol::MessageTagProvider::ShouldSendTag
virtual bool ShouldSendTag(LocalUser *user, const MessageTagData &tagdata)=0
ClientProtocol::ParseOutput
Definition: clientprotocol.h:36
ClientProtocol::MessageSource::MessageSource
MessageSource(const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:115
ClientProtocol::RFCEvents
Definition: clientprotocol.h:631
ClientProtocol::Message::PushParam
void PushParam(const char *str)
Definition: clientprotocol.h:354
ClientProtocol::TagSelection
Definition: clientprotocol.h:53
ClientProtocol::ParseOutput::cmd
std::string cmd
Definition: clientprotocol.h:40
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:295
ClientProtocol::EventProvider::EventProvider
EventProvider(Module *Mod, const std::string &eventname)
Definition: clientprotocol.h:622
ClientProtocol::Message::InvalidateCache
void InvalidateCache()
Definition: clientprotocol.h:432
ClientProtocol::Message::Message
Message(const char *cmd, User *Sourceuser=NULL)
Definition: clientprotocol.h:308
ClientProtocol::TagSelection::operator==
bool operator==(const TagSelection &other) const
Definition: clientprotocol.h:86
ClientProtocol::Message::GetSerialized
const SerializedMessage & GetSerialized(const SerializedInfo &serializeinfo) const
Definition: clientprotocol.cpp:71
ClientProtocol::Message::GetParams
const ParamList & GetParams() const
Definition: clientprotocol.h:338
ClientProtocol::Message::SerializedInfo::SerializedInfo
SerializedInfo(const Serializer *Ser, const TagSelection &Tagwl)
Definition: clientprotocol.h:194
ClientProtocol::Message::Param
Definition: clientprotocol.h:210
Events::ModuleEventProvider
Definition: event.h:34
ClientProtocol::ParseOutput::tags
ClientProtocol::TagMap tags
Definition: clientprotocol.h:48
ClientProtocol::Event::Event
Event(EventProvider &protoeventprov, ClientProtocol::Message &msg)
Definition: clientprotocol.h:484
ClientProtocol::Message::Message
Message(const char *cmd, const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:325
Events::ModuleEventListener
Definition: event.h:112
ClientProtocol::Message::GetCommand
const char * GetCommand() const
Definition: clientprotocol.h:349
ClientProtocol::Message::PushParamRef
void PushParamRef(const std::string &str)
Definition: clientprotocol.h:365
Module
Definition: modules.h:242
User
Definition: users.h:224
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:103
ClientProtocol::Serializer::SerializeForUser
const SerializedMessage & SerializeForUser(LocalUser *user, Message &msg)
Definition: clientprotocol.cpp:61
ClientProtocol::Message
Definition: clientprotocol.h:180
ClientProtocol::MessageTagProvider::OnPopulateTags
virtual void OnPopulateTags(ClientProtocol::Message &msg)
Definition: clientprotocol.h:540
ClientProtocol::Serializer::Serializer
Serializer(Module *mod, const char *Name)
Definition: clientprotocol.cpp:22
ClientProtocol::EventHook
Definition: clientprotocol.h:570
ClientProtocol::EventHook::OnEventInit
virtual void OnEventInit(const ClientProtocol::Event &ev)
Definition: clientprotocol.h:593
ClientProtocol::MessageSource::SetSource
void SetSource(const std::string &Sourcestr, User *Sourceuser=NULL)
Definition: clientprotocol.h:155
ClientProtocol::MessageTagProvider
Definition: clientprotocol.h:523
ClientProtocol::MessageTagData
Definition: typedefs.h:64
ClientProtocol::EventHook::EventHook
EventHook(Module *mod, const std::string &name, unsigned int priority=Events::ModuleEventListener::DefaultPriority)
Definition: clientprotocol.h:584
ClientProtocol::MessageTagProvider::OnProcessTag
virtual ModResult OnProcessTag(User *user, const std::string &tagname, std::string &tagvalue)
Definition: clientprotocol.h:552
Events::ModuleEventProvider::ModuleEventProvider
ModuleEventProvider(Module *mod, const std::string &eventid)
Definition: event.h:48
ClientProtocol::MessageSource::GetSourceUser
User * GetSourceUser() const
Definition: clientprotocol.h:137
ClientProtocol::Serializer
Definition: clientprotocol.h:668
ClientProtocol::Message::GetTags
const TagMap & GetTags() const
Definition: clientprotocol.h:344
ClientProtocol::MessageSource
Definition: clientprotocol.h:92
LocalUser
Definition: users.h:718