InspIRCd  3.0
clientprotocolmsg.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2018, 2020-2021 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() : ServerInstance->FakeClient->server)->GetName())
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() : ServerInstance->FakeClient->server)->GetName())
86  {
87  PushParamRef(target);
88  InitFromNumeric(num);
89  }
90 
94  Numeric(unsigned int num)
95  : ClientProtocol::Message(NULL, ServerInstance->Config->GetServerName())
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 
493  Privmsg(const std::string& source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
494  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
495  {
496  if (status)
497  {
498  std::string rawtarget(1, status);
499  rawtarget.append(target);
500  PushParam(rawtarget);
501  }
502  else
503  {
504  PushParam(target);
505  }
506  PushParam(text);
507  }
508 
516  Privmsg(const std::string& source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
517  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
518  {
519  PushTargetChan(status, targetchan);
520  PushParam(text);
521  }
522 
529  Privmsg(const std::string& source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
530  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
531  {
532  PushTargetUser(targetuser);
533  PushParam(text);
534  }
535 
542  Privmsg(NoCopy, User* source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG)
543  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
544  {
545  PushParam(target);
546  PushParamRef(text);
547  }
548 
556  Privmsg(NoCopy, User* source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
557  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
558  {
559  PushTargetChan(status, targetchan);
560  PushParamRef(text);
561  }
562 
569  Privmsg(NoCopy, User* source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
570  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
571  {
572  PushTargetUser(targetuser);
573  PushParamRef(text);
574  }
575 
582  Privmsg(NoCopy, const std::string& source, const std::string& target, const std::string& text, MessageType mt = MSG_PRIVMSG)
583  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
584  {
585  PushParam(target);
586  PushParamRef(text);
587  }
588 
596  Privmsg(NoCopy, const std::string& source, const Channel* targetchan, const std::string& text, MessageType mt = MSG_PRIVMSG, char status = 0)
597  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
598  {
599  PushTargetChan(status, targetchan);
600  PushParamRef(text);
601  }
602 
609  Privmsg(NoCopy, const std::string& source, const User* targetuser, const std::string& text, MessageType mt = MSG_PRIVMSG)
610  : ClientProtocol::Message(CommandStrFromMsgType(mt), source)
611  {
612  PushTargetUser(targetuser);
613  PushParamRef(text);
614  }
615 };
616 
621 {
627  Invite(User* source, User* target, Channel* chan)
628  : ClientProtocol::Message("INVITE", source)
629  {
630  PushParamRef(target->nick);
631  PushParamRef(chan->name);
632  }
633 };
634 
639 {
644  : ClientProtocol::Message("PING")
645  {
646  PushParamRef(ServerInstance->Config->GetServerName());
647  }
648 
652  Ping(const std::string& cookie)
653  : ClientProtocol::Message("PING")
654  {
655  PushParamRef(cookie);
656  }
657 };
658 
663 {
668  Pong(const std::string& cookie, const std::string& server = "")
669  : ClientProtocol::Message("PONG", ServerInstance->Config->GetServerName())
670  {
671  if (server.empty())
672  PushParamRef(ServerInstance->Config->GetServerName());
673  else
674  PushParam(server);
675  PushParamRef(cookie);
676  }
677 };
678 
683 {
687  Error(const std::string& text)
688  : ClientProtocol::Message("ERROR")
689  {
690  PushParam(text);
691  }
692 };
Definition: channels.h:41
std::string name
Definition: channels.h:88
Definition: clientprotocol.h:182
void SetCommand(const char *cmd)
Definition: clientprotocol.h:298
void PushParam(const char *str)
Definition: clientprotocol.h:357
void ClearParams()
Definition: clientprotocol.h:423
void PushParamRef(const std::string &str)
Definition: clientprotocol.h:368
Definition: clientprotocolmsg.h:106
Membership * GetMember() const
Definition: clientprotocolmsg.h:149
Join(Membership *Memb)
Definition: clientprotocolmsg.h:121
Join(Membership *Memb, const std::string &sourcestrref)
Definition: clientprotocolmsg.h:131
void SetParams(Membership *Memb)
Definition: clientprotocolmsg.h:140
Join()
Definition: clientprotocolmsg.h:112
Definition: clientprotocolmsg.h:226
User * GetUserTarget() const
Definition: clientprotocolmsg.h:381
Mode()
Definition: clientprotocolmsg.h:336
Mode(User *source, Channel *Chantarget, User *Usertarget, const Modes::ChangeList &changelist)
Definition: clientprotocolmsg.h:322
static std::string ToModeLetters(const Modes::ChangeList &changelist)
Definition: clientprotocolmsg.h:291
Modes::ChangeList::List::const_iterator GetEndIterator() const
Definition: clientprotocolmsg.h:369
Channel * GetChanTarget() const
Definition: clientprotocolmsg.h:386
void SetParams(Channel *Chantarget, User *Usertarget, const Modes::ChangeList &changelist)
Definition: clientprotocolmsg.h:348
Mode(User *source, Channel *Chantarget, User *Usertarget, const Modes::ChangeList &changelist, Modes::ChangeList::List::const_iterator beginiter)
Definition: clientprotocolmsg.h:305
Modes::ChangeList::List::const_iterator GetBeginIterator() const
Definition: clientprotocolmsg.h:364
const std::string & GetStrTarget() const
Definition: clientprotocolmsg.h:376
Definition: clientprotocolmsg.h:49
Numeric(unsigned int num)
Definition: clientprotocolmsg.h:94
Numeric(const ::Numeric::Numeric &num, User *user)
Definition: clientprotocolmsg.h:70
Numeric(const ::Numeric::Numeric &num, const std::string &target)
Definition: clientprotocolmsg.h:84
Definition: clientprotocolmsg.h:409
NoCopy
Definition: clientprotocolmsg.h:435
Privmsg(const std::string &source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:516
static const char * CommandStrFromMsgType(MessageType mt)
Definition: clientprotocolmsg.h:441
Privmsg(NoCopy, const std::string &source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:596
Privmsg(NoCopy, const std::string &source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:582
Privmsg(const std::string &source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:493
Privmsg(User *source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:466
Privmsg(NoCopy, const std::string &source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:609
Privmsg(User *source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:452
Privmsg(User *source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:479
Privmsg(NoCopy, User *source, const Channel *targetchan, const std::string &text, MessageType mt=MSG_PRIVMSG, char status=0)
Definition: clientprotocolmsg.h:556
Privmsg(NoCopy, User *source, const std::string &target, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:542
Privmsg(const std::string &source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:529
Privmsg(NoCopy, User *source, const User *targetuser, const std::string &text, MessageType mt=MSG_PRIVMSG)
Definition: clientprotocolmsg.h:569
ServerConfig * Config
Definition: inspircd.h:273
Definition: membership.h:36
Channel *const chan
Definition: membership.h:48
User *const user
Definition: membership.h:44
char GetModeChar() const
Definition: mode.h:243
Definition: modechange.h:53
const List & getlist() const
Definition: modechange.h:119
const std::string & GetServerName() const
Definition: configreader.h:453
Definition: users.h:244
std::string nick
Definition: users.h:321
unsigned int registered
Definition: users.h:364
Definition: clientprotocolmsg.h:683
Error(const std::string &text)
Definition: clientprotocolmsg.h:687
Definition: clientprotocolmsg.h:621
Invite(User *source, User *target, Channel *chan)
Definition: clientprotocolmsg.h:627
Definition: clientprotocolmsg.h:174
Kick(User *source, Membership *memb, const std::string &reason)
Definition: clientprotocolmsg.h:180
Definition: clientprotocolmsg.h:210
Nick(User *source, const std::string &newnick)
Definition: clientprotocolmsg.h:215
Definition: clientprotocolmsg.h:156
Part(Membership *memb, const std::string &reason)
Definition: clientprotocolmsg.h:161
Definition: clientprotocolmsg.h:639
Ping()
Definition: clientprotocolmsg.h:643
Ping(const std::string &cookie)
Definition: clientprotocolmsg.h:652
Definition: clientprotocolmsg.h:663
Pong(const std::string &cookie, const std::string &server="")
Definition: clientprotocolmsg.h:668
Definition: clientprotocolmsg.h:193
Quit(User *source, const std::string &reason)
Definition: clientprotocolmsg.h:198
Definition: clientprotocolmsg.h:392
Topic(User *source, const Channel *chan, const std::string &newtopic)
Definition: clientprotocolmsg.h:398
Definition: modechange.h:32