InspIRCd  3.0
clientprotocolmsg.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2018 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 namespace ClientProtocol
24 {
25  namespace Messages
26  {
27  class Numeric;
28  class Join;
29  struct Part;
30  struct Kick;
31  struct Quit;
32  struct Nick;
33  class Mode;
34  struct Topic;
35  class Privmsg;
36  struct Invite;
37  struct Ping;
38  struct Pong;
39  struct Error;
40  }
41 }
42 
49 {
50  char numericstr[4];
51 
52  void InitCommand(unsigned int number)
53  {
54  snprintf(numericstr, sizeof(numericstr), "%03u", number);
55  SetCommand(numericstr);
56  }
57 
58  void InitFromNumeric(const ::Numeric::Numeric& numeric)
59  {
60  InitCommand(numeric.GetNumeric());
61  for (std::vector<std::string>::const_iterator i = numeric.GetParams().begin(); i != numeric.GetParams().end(); ++i)
62  PushParamRef(*i);
63  }
64 
65  public:
70  Numeric(const ::Numeric::Numeric& num, User* user)
71  : ClientProtocol::Message(NULL, (num.GetServer() ? num.GetServer()->GetName() : ServerInstance->Config->ServerName))
72  {
73  if (user->registered & REG_NICK)
74  PushParamRef(user->nick);
75  else
76  PushParam("*");
77  InitFromNumeric(num);
78  }
79 
84  Numeric(const ::Numeric::Numeric& num, const std::string& target)
85  : ClientProtocol::Message(NULL, (num.GetServer() ? num.GetServer()->GetName() : ServerInstance->Config->ServerName))
86  {
87  PushParamRef(target);
88  InitFromNumeric(num);
89  }
90 
94  Numeric(unsigned int num)
95  : ClientProtocol::Message(NULL, ServerInstance->Config->ServerName)
96  {
97  InitCommand(num);
98  PushParam("*");
99  }
100 };
101 
106 {
107  Membership* memb;
108 
109  public:
113  : ClientProtocol::Message("JOIN")
114  , memb(NULL)
115  {
116  }
117 
122  : ClientProtocol::Message("JOIN", Memb->user)
123  {
124  SetParams(Memb);
125  }
126 
131  Join(Membership* Memb, const std::string& sourcestrref)
132  : ClientProtocol::Message("JOIN", sourcestrref, Memb->user)
133  {
134  SetParams(Memb);
135  }
136 
140  void SetParams(Membership* Memb)
141  {
142  memb = Memb;
143  PushParamRef(memb->chan->name);
144  }
145 
149  Membership* GetMember() const { return memb; }
150 };
151 
156 {
161  Part(Membership* memb, const std::string& reason)
162  : ClientProtocol::Message("PART", memb->user)
163  {
164  PushParamRef(memb->chan->name);
165  if (!reason.empty())
166  PushParamRef(reason);
167  }
168 };
169 
174 {
180  Kick(User* source, Membership* memb, const std::string& reason)
181  : ClientProtocol::Message("KICK", source)
182  {
183  PushParamRef(memb->chan->name);
184  PushParamRef(memb->user->nick);
185  PushParamRef(reason);
186  }
187 };
188 
193 {
198  Quit(User* source, const std::string& reason)
199  : ClientProtocol::Message("QUIT", source)
200  {
201  if (!reason.empty())
202  PushParamRef(reason);
203  }
204 };
205 
210 {
215  Nick(User* source, const std::string& newnick)
216  : ClientProtocol::Message("NICK", source)
217  {
218  PushParamRef(newnick);
219  }
220 };
221 
226 {
227  Channel* chantarget;
228  User* usertarget;
229  Modes::ChangeList::List::const_iterator beginit;
230  Modes::ChangeList::List::const_iterator lastit;
231 
238  static std::string ToModeLetters(const Modes::ChangeList::List& list, std::string::size_type maxlinelen, Modes::ChangeList::List::const_iterator beginit, Modes::ChangeList::List::const_iterator& lastit)
239  {
240  std::string ret;
241  std::string::size_type paramlength = 0;
242  char output_pm = '\0'; // current output state, '+' or '-'
243 
244  Modes::ChangeList::List::const_iterator i;
245  for (i = beginit; i != list.end(); ++i)
246  {
247  const Modes::Change& item = *i;
248 
249  const char needed_pm = (item.adding ? '+' : '-');
250  if (needed_pm != output_pm)
251  {
252  output_pm = needed_pm;
253  ret.push_back(output_pm);
254  }
255 
256  if (!item.param.empty())
257  paramlength += item.param.length() + 1;
258  if (ret.length() + 1 + paramlength > maxlinelen)
259  {
260  // Mode sequence is getting too long
261  const char c = *ret.rbegin();
262  if ((c == '+') || (c == '-'))
263  ret.erase(ret.size()-1);
264  break;
265  }
266 
267  ret.push_back(item.mh->GetModeChar());
268  }
269 
270  lastit = i;
271  return ret;
272  }
273 
276  void PushModeParams()
277  {
278  for (Modes::ChangeList::List::const_iterator i = beginit; i != lastit; ++i)
279  {
280  const Modes::Change& item = *i;
281  if (!item.param.empty())
282  PushParamRef(item.param);
283  }
284  }
285 
286  public:
291  static std::string ToModeLetters(const Modes::ChangeList& changelist)
292  {
293  // TODO: This assumes that std::string::max_size() >= UINT_MAX
294  Modes::ChangeList::List::const_iterator dummy;
295  return ToModeLetters(changelist.getlist(), UINT_MAX, changelist.getlist().begin(), dummy);
296  }
297 
305  Mode(User* source, Channel* Chantarget, User* Usertarget, const Modes::ChangeList& changelist, Modes::ChangeList::List::const_iterator beginiter)
306  : ClientProtocol::Message("MODE", source)
307  , chantarget(Chantarget)
308  , usertarget(Usertarget)
309  , beginit(beginiter)
310  {
312  PushParam(ToModeLetters(changelist.getlist(), 450, beginit, lastit));
313  PushModeParams();
314  }
315 
322  Mode(User* source, Channel* Chantarget, User* Usertarget, const Modes::ChangeList& changelist)
323  : ClientProtocol::Message("MODE", source)
324  , chantarget(Chantarget)
325  , usertarget(Usertarget)
326  , beginit(changelist.getlist().begin())
327  {
329  PushParam(ToModeLetters(changelist.getlist(), 450, beginit, lastit));
330  PushModeParams();
331  }
332 
337  : ClientProtocol::Message("MODE", ServerInstance->FakeClient)
338  , chantarget(NULL)
339  , usertarget(NULL)
340  {
341  }
342 
348  void SetParams(Channel* Chantarget, User* Usertarget, const Modes::ChangeList& changelist)
349  {
350  ClearParams();
351 
352  chantarget = Chantarget;
353  usertarget = Usertarget;
354  beginit = changelist.getlist().begin();
355 
357  PushParam(ToModeLetters(changelist.getlist(), 450, beginit, lastit));
358  PushModeParams();
359  }
360 
364  Modes::ChangeList::List::const_iterator GetBeginIterator() const { return beginit; }
365 
369  Modes::ChangeList::List::const_iterator GetEndIterator() const { return lastit; }
370 
376  const std::string& GetStrTarget() const { return (chantarget ? chantarget->name : usertarget->nick); }
377 
381  User* GetUserTarget() const { return usertarget; }
382 
386  Channel* GetChanTarget() const { return chantarget; }
387 };
388 
392 {
398  Topic(User* source, const Channel* chan, const std::string& newtopic)
399  : ClientProtocol::Message("TOPIC", source)
400  {
401  PushParamRef(chan->name);
402  PushParamRef(newtopic);
403  }
404 };
405 
409 {
410  void PushTargetChan(char status, const Channel* targetchan)
411  {
412  if (status)
413  {
414  std::string rawtarget(1, status);
415  rawtarget.append(targetchan->name);
416  PushParam(rawtarget);
417  }
418  else
419  {
420  PushParamRef(targetchan->name);
421  }
422  }
423 
424  void PushTargetUser(const User* targetuser)
425  {
426  if (targetuser->registered & REG_NICK)
427  PushParamRef(targetuser->nick);
428  else
429  PushParam("*");
430  }
431 
432  public:
435  enum NoCopy { nocopy };
436 
441  static const char* CommandStrFromMsgType(MessageType mt)
442  {
443  return ((mt == MSG_PRIVMSG) ? "PRIVMSG" : "NOTICE");
444  }
445 
452  Privmsg(User* source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG)
453  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
454  {
455  PushParam(target);
456  PushParam(text);
457  }
458 
466  Privmsg(User* source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
467  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
468  {
469  PushTargetChan(status, targetchan);
470  PushParam(text);
471  }
472 
479  Privmsg(User* source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
480  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
481  {
482  PushTargetUser(targetuser);
483  PushParam(text);
484  }
485 
492  Privmsg(const std::string& source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG)
493  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
494  {
495  PushParam(target);
496  PushParam(text);
497  }
498 
506  Privmsg(const std::string& source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
507  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
508  {
509  PushTargetChan(status, targetchan);
510  PushParam(text);
511  }
512 
519  Privmsg(const std::string& source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
520  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
521  {
522  PushTargetUser(targetuser);
523  PushParam(text);
524  }
525 
532  Privmsg(NoCopy, User* source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG)
533  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
534  {
535  PushParam(target);
536  PushParamRef(text);
537  }
538 
546  Privmsg(NoCopy, User* source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
547  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
548  {
549  PushTargetChan(status, targetchan);
550  PushParamRef(text);
551  }
552 
559  Privmsg(NoCopy, User* source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
560  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
561  {
562  PushTargetUser(targetuser);
563  PushParamRef(text);
564  }
565 
572  Privmsg(NoCopy, const std::string& source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG)
573  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
574  {
575  PushParam(target);
576  PushParamRef(text);
577  }
578 
586  Privmsg(NoCopy, const std::string& source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
587  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
588  {
589  PushTargetChan(status, targetchan);
590  PushParamRef(text);
591  }
592 
599  Privmsg(NoCopy, const std::string& source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
600  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
601  {
602  PushTargetUser(targetuser);
603  PushParamRef(text);
604  }
605 };
606 
611 {
617  Invite(User* source, User* target, Channel* chan)
618  : ClientProtocol::Message("INVITE", source)
619  {
620  PushParamRef(target->nick);
621  PushParamRef(chan->name);
622  }
623 };
624 
629 {
634  : ClientProtocol::Message("PING")
635  {
636  PushParamRef(ServerInstance->Config->ServerName);
637  }
638 
642  Ping(const std::string& cookie)
643  : ClientProtocol::Message("PING")
644  {
645  PushParamRef(cookie);
646  }
647 };
648 
653 {
657  Pong(const std::string& cookie)
658  : ClientProtocol::Message("PONG", ServerInstance->Config->ServerName)
659  {
660  PushParamRef(ServerInstance->Config->ServerName);
661  PushParamRef(cookie);
662  }
663 };
664 
669 {
673  Error(const std::string& text)
674  : ClientProtocol::Message("ERROR")
675  {
676  PushParam(text);
677  }
678 };
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(const std::string &source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:519
Modes::ChangeList::getlist
const List & getlist() const
Definition: modechange.h:119
ClientProtocol::Messages::Mode
Definition: clientprotocolmsg.h:225
ClientProtocol::Messages::Join::Join
Join()
Definition: clientprotocolmsg.h:112
Modes::ChangeList
Definition: modechange.h:52
Channel::name
std::string name
Definition: channels.h:88
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(User *source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:479
ClientProtocol::Messages::Part
Definition: clientprotocolmsg.h:155
ClientProtocol::Messages::Privmsg
Definition: clientprotocolmsg.h:408
ClientProtocol::Messages::Nick::Nick
Nick(User *source, const std::string &newnick)
Definition: clientprotocolmsg.h:215
ClientProtocol::Messages::Mode::GetChanTarget
Channel * GetChanTarget() const
Definition: clientprotocolmsg.h:386
ClientProtocol::Messages::Join::Join
Join(Membership *Memb)
Definition: clientprotocolmsg.h:121
ClientProtocol::Messages::Pong::Pong
Pong(const std::string &cookie)
Definition: clientprotocolmsg.h:657
ClientProtocol::Message::ClearParams
void ClearParams()
Definition: clientprotocol.h:421
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(NoCopy, User *source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:559
ClientProtocol::Messages::Numeric::Numeric
Numeric(unsigned int num)
Definition: clientprotocolmsg.h:94
ClientProtocol::Messages::Mode::SetParams
void SetParams(Channel *Chantarget, User *Usertarget, const Modes::ChangeList &changelist)
Definition: clientprotocolmsg.h:348
ClientProtocol::Messages::Mode::GetStrTarget
const std::string & GetStrTarget() const
Definition: clientprotocolmsg.h:376
ClientProtocol::Messages::Topic::Topic
Topic(User *source, const Channel *chan, const std::string &newtopic)
Definition: clientprotocolmsg.h:398
Modes::Change
Definition: modechange.h:31
ClientProtocol::Messages::Topic
Definition: clientprotocolmsg.h:391
ClientProtocol::Messages::Mode::Mode
Mode(User *source, Channel *Chantarget, User *Usertarget, const Modes::ChangeList &changelist, Modes::ChangeList::List::const_iterator beginiter)
Definition: clientprotocolmsg.h:305
ClientProtocol::Messages::Mode::GetEndIterator
Modes::ChangeList::List::const_iterator GetEndIterator() const
Definition: clientprotocolmsg.h:369
ClientProtocol::Messages::Ping::Ping
Ping(const std::string &cookie)
Definition: clientprotocolmsg.h:642
ClientProtocol::Messages::Invite::Invite
Invite(User *source, User *target, Channel *chan)
Definition: clientprotocolmsg.h:617
ClientProtocol::Messages::Join::SetParams
void SetParams(Membership *Memb)
Definition: clientprotocolmsg.h:140
ClientProtocol::Messages::Quit
Definition: clientprotocolmsg.h:192
ClientProtocol::Messages::Error
Definition: clientprotocolmsg.h:668
ClientProtocol::Messages::Privmsg::NoCopy
NoCopy
Definition: clientprotocolmsg.h:435
ClientProtocol::Messages::Mode::Mode
Mode()
Definition: clientprotocolmsg.h:336
ClientProtocol::Messages::Quit::Quit
Quit(User *source, const std::string &reason)
Definition: clientprotocolmsg.h:198
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(NoCopy, User *source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:532
ClientProtocol::Messages::Mode::Mode
Mode(User *source, Channel *Chantarget, User *Usertarget, const Modes::ChangeList &changelist)
Definition: clientprotocolmsg.h:322
ClientProtocol::Messages::Kick
Definition: clientprotocolmsg.h:173
ClientProtocol::Messages::Pong
Definition: clientprotocolmsg.h:652
ModeHandler::GetModeChar
char GetModeChar() const
Definition: mode.h:243
ServerConfig::ServerName
std::string ServerName
Definition: configreader.h:325
ClientProtocol::Messages::Privmsg::CommandStrFromMsgType
static const char * CommandStrFromMsgType(MessageType mt)
Definition: clientprotocolmsg.h:441
ClientProtocol::Messages::Numeric::Numeric
Numeric(const ::Numeric::Numeric &num, const std::string &target)
Definition: clientprotocolmsg.h:84
ClientProtocol::Messages::Mode::GetBeginIterator
Modes::ChangeList::List::const_iterator GetBeginIterator() const
Definition: clientprotocolmsg.h:364
Channel
Definition: channels.h:40
ClientProtocol::Messages::Mode::ToModeLetters
static std::string ToModeLetters(const Modes::ChangeList &changelist)
Definition: clientprotocolmsg.h:291
ClientProtocol::Messages::Kick::Kick
Kick(User *source, Membership *memb, const std::string &reason)
Definition: clientprotocolmsg.h:180
ClientProtocol::Message::PushParam
void PushParam(const char *str)
Definition: clientprotocol.h:355
ClientProtocol::Message::SetCommand
void SetCommand(const char *cmd)
Definition: clientprotocol.h:296
ClientProtocol::Messages::Nick
Definition: clientprotocolmsg.h:209
User::nick
std::string nick
Definition: users.h:311
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(NoCopy, const std::string &source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:586
Membership::user
User *const user
Definition: membership.h:44
Membership::chan
Channel *const chan
Definition: membership.h:48
ClientProtocol::Messages::Ping::Ping
Ping()
Definition: clientprotocolmsg.h:633
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(const std::string &source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:506
ClientProtocol::Messages::Ping
Definition: clientprotocolmsg.h:628
ClientProtocol::Message::PushParamRef
void PushParamRef(const std::string &str)
Definition: clientprotocol.h:366
User
Definition: users.h:233
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(User *source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:452
ClientProtocol::Message
Definition: clientprotocol.h:181
ClientProtocol::Messages::Join::GetMember
Membership * GetMember() const
Definition: clientprotocolmsg.h:149
InspIRCd::Config
ServerConfig * Config
Definition: inspircd.h:273
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(NoCopy, const std::string &source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:572
ClientProtocol::Messages::Mode::GetUserTarget
User * GetUserTarget() const
Definition: clientprotocolmsg.h:381
ClientProtocol::Messages::Invite
Definition: clientprotocolmsg.h:610
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(const std::string &source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:492
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(NoCopy, User *source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:546
ClientProtocol::Messages::Join::Join
Join(Membership *Memb, const std::string &sourcestrref)
Definition: clientprotocolmsg.h:131
ClientProtocol::Messages::Numeric
Definition: clientprotocolmsg.h:48
Membership
Definition: membership.h:35
ClientProtocol::Messages::Part::Part
Part(Membership *memb, const std::string &reason)
Definition: clientprotocolmsg.h:161
ClientProtocol::Messages::Error::Error
Error(const std::string &text)
Definition: clientprotocolmsg.h:673
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(NoCopy, const std::string &source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:599
User::registered
unsigned int registered
Definition: users.h:354
ClientProtocol::Messages::Privmsg::Privmsg
Privmsg(User *source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:466
ClientProtocol::Messages::Numeric::Numeric
Numeric(const ::Numeric::Numeric &num, User *user)
Definition: clientprotocolmsg.h:70
ClientProtocol::Messages::Join
Definition: clientprotocolmsg.h:105