gloox  1.0.27
mucroom.cpp
1 /*
2  Copyright (c) 2006-2023 by Jakob Schröter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 
15 #include "mucroom.h"
16 #include "clientbase.h"
17 #include "dataform.h"
18 #include "presence.h"
19 #include "disco.h"
20 #include "mucmessagesession.h"
21 #include "message.h"
22 #include "error.h"
23 #include "util.h"
24 #include "tag.h"
25 
26 namespace gloox
27 {
28 
29  // ---- MUCRoom::MUCAdmin ----
30  /* Error type values */
31  static const char* affiliationValues [] = {
32  "none",
33  "outcast",
34  "member",
35  "owner",
36  "admin"
37  };
38 
39  /* Stanza error values */
40  static const char* roleValues [] = {
41  "none",
42  "visitor",
43  "participant",
44  "moderator",
45  };
46 
48  const char* historyTypeValues[] =
49  {
50  "maxchars", "maxstanzas", "seconds", "since"
51  };
52 
53  static inline MUCRoomAffiliation affiliationType( const std::string& type )
54  {
55  return static_cast<MUCRoomAffiliation>( util::lookup( type, affiliationValues ) );
56  }
57 
58  static inline MUCRoomRole roleType( const std::string& type )
59  {
60  return static_cast<MUCRoomRole>( util::lookup( type, roleValues ) );
61  }
62 
63  MUCRoom::MUCAdmin::MUCAdmin( MUCRoomRole role, const std::string& nick,
64  const std::string& reason )
65  : StanzaExtension( ExtMUCAdmin ), m_affiliation( AffiliationInvalid ), m_role( role )
66  {
67  m_list.push_back( MUCListItem( nick, role, reason ) );
68  }
69 
70  MUCRoom::MUCAdmin::MUCAdmin( MUCRoomAffiliation affiliation, const std::string& nick,
71  const std::string& reason )
72  : StanzaExtension( ExtMUCAdmin ), m_affiliation( affiliation ), m_role( RoleInvalid )
73  {
74  m_list.push_back( MUCListItem( nick, affiliation, reason ) );
75  }
76 
77  MUCRoom::MUCAdmin::MUCAdmin( MUCOperation operation, const MUCListItemList& jids )
78  : StanzaExtension( ExtMUCAdmin ), m_list( jids ), m_affiliation( AffiliationInvalid ),
79  m_role( RoleInvalid )
80  {
81  switch( operation )
82  {
83  case StoreVoiceList:
84  case RequestVoiceList:
85  m_role = RoleParticipant;
86  break;
87  case StoreModeratorList:
89  m_role = RoleModerator;
90  break;
91  case StoreBanList:
92  case RequestBanList:
93  m_affiliation = AffiliationOutcast;
94  break;
95  case StoreMemberList:
96  case RequestMemberList:
97  m_affiliation = AffiliationMember;
98  break;
99  case StoreOwnerList:
100  case RequestOwnerList:
101  m_affiliation = AffiliationOwner;
102  break;
103  case StoreAdminList:
104  case RequestAdminList:
105  m_affiliation = AffiliationAdmin;
106  break;
107  default:
108  return;
109  break;
110  }
111 
112  if( m_list.empty() )
113  m_list.push_back( MUCListItem( JID() ) );
114  }
115 
116  MUCRoom::MUCAdmin::MUCAdmin( const Tag* tag )
117  : StanzaExtension( ExtMUCAdmin ), m_affiliation( AffiliationInvalid ), m_role( RoleInvalid )
118  {
119  if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_MUC_ADMIN )
120  return;
121 
122  const TagList& items = tag->findChildren( "item" );
123  TagList::const_iterator it = items.begin();
124  for( ; it != items.end(); ++it )
125  {
126  m_list.push_back( MUCListItem( JID( (*it)->findAttribute( "jid" ) ),
127  roleType( (*it)->findAttribute( "role" ) ),
128  affiliationType( (*it)->findAttribute( "affiliation" ) ),
129  (*it)->findAttribute( "nick" ) ) );
130  if( m_role == RoleInvalid )
131  m_role = roleType( (*it)->findAttribute( "role" ) );
132  if( m_affiliation == AffiliationInvalid )
133  m_affiliation = affiliationType( (*it)->findAttribute( "affiliation" ) );
134  }
135  }
136 
137  MUCRoom::MUCAdmin::~MUCAdmin()
138  {
139  }
140 
141  const std::string& MUCRoom::MUCAdmin::filterString() const
142  {
143  static const std::string filter = "/iq/query[@xmlns='" + XMLNS_MUC_ADMIN + "']";
144  return filter;
145  }
146 
147  Tag* MUCRoom::MUCAdmin::tag() const
148  {
149  Tag* t = new Tag( "query" );
150  t->setXmlns( XMLNS_MUC_ADMIN );
151 
152  if( m_list.empty() || ( m_affiliation == AffiliationInvalid && m_role == RoleInvalid ) )
153  return t;
154 
155  MUCListItemList::const_iterator it = m_list.begin();
156  for( ; it != m_list.end(); ++it )
157  {
158  Tag* i = new Tag( t, "item" );
159  if( (*it).jid() )
160  i->addAttribute( "jid", (*it).jid().bare() );
161  if( !(*it).nick().empty() )
162  i->addAttribute( "nick", (*it).nick() );
163 
164  MUCRoomRole rol = RoleInvalid;
165  if( (*it).role() != RoleInvalid )
166  rol = (*it).role();
167  else if( m_role != RoleInvalid )
168  rol = m_role;
169  if( rol != RoleInvalid )
170  i->addAttribute( "role", util::lookup( rol, roleValues ) );
171 
173  if( (*it).affiliation() != AffiliationInvalid )
174  aff = (*it).affiliation();
175  else if( m_affiliation != AffiliationInvalid )
176  aff = m_affiliation;
177  if( aff != AffiliationInvalid )
178  i->addAttribute( "affiliation", util::lookup( aff, affiliationValues ) );
179  if( !(*it).reason().empty() )
180  new Tag( i, "reason", (*it).reason() );
181  }
182 
183  return t;
184  }
185  // ---- ~MUCRoom::MUCAdmin ----
186 
187  // ---- MUCRoom::MUCOwner ----
188  MUCRoom::MUCOwner::MUCOwner( QueryType type, DataForm* form )
189  : StanzaExtension( ExtMUCOwner ), m_type( type ), m_form( form )
190  {
191  m_valid = true;
192 
193  if( m_form )
194  return;
195 
196  switch( type )
197  {
198  case TypeCancelConfig:
199  m_form = new DataForm( TypeCancel );
200  break;
201  case TypeInstantRoom:
202  m_form = new DataForm( TypeSubmit );
203  break;
204  default:
205  break;
206  }
207  }
208 
209  MUCRoom::MUCOwner::MUCOwner( const JID& alternate, const std::string& reason,
210  const std::string& password )
211  : StanzaExtension( ExtMUCOwner ), m_type( TypeDestroy ), m_jid( alternate ),
212  m_reason( reason ), m_pwd( password ), m_form( 0 )
213  {
214  m_valid = true;
215  }
216 
217  MUCRoom::MUCOwner::MUCOwner( const Tag* tag )
218  : StanzaExtension( ExtMUCOwner ), m_type( TypeIncomingTag ), m_form( 0 )
219  {
220  if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_MUC_OWNER )
221  return;
222 
223  const TagList& l = tag->children();
224  TagList::const_iterator it = l.begin();
225  for( ; it != l.end(); ++it )
226  {
227  const std::string& name = (*it)->name();
228  if( name == "x" && (*it)->xmlns() == XMLNS_X_DATA )
229  {
230  m_form = new DataForm( (*it) );
231  break;
232  }
233  else if( name == "destroy" )
234  {
235  m_type = TypeDestroy;
236  m_jid = (*it)->findAttribute( "jid" );
237  m_pwd = (*it)->findCData( "/query/destroy/password" );
238  m_reason = (*it)->findCData( "/query/destroy/reason" );
239  break;
240  }
241  }
242  m_valid = true;
243  }
244 
245  MUCRoom::MUCOwner::~MUCOwner()
246  {
247  delete m_form;
248  }
249 
250  const std::string& MUCRoom::MUCOwner::filterString() const
251  {
252  static const std::string filter = "/iq/query[@xmlns='" + XMLNS_MUC_OWNER + "']";
253  return filter;
254  }
255 
256  Tag* MUCRoom::MUCOwner::tag() const
257  {
258  if( !m_valid )
259  return 0;
260 
261  Tag* t = new Tag( "query" );
262  t->setXmlns( XMLNS_MUC_OWNER );
263 
264  switch( m_type )
265  {
266  case TypeInstantRoom:
267  case TypeSendConfig:
268  case TypeCancelConfig:
269  case TypeIncomingTag:
270  if( m_form )
271  t->addChild( m_form->tag() );
272  break;
273  case TypeDestroy:
274  {
275  Tag* d = new Tag( t, "destroy" );
276  if( m_jid )
277  d->addAttribute( "jid", m_jid.bare() );
278 
279  if( !m_reason.empty() )
280  new Tag( d, "reason", m_reason );
281 
282  if( !m_pwd.empty() )
283  new Tag( d, "password", m_pwd );
284 
285  break;
286  }
287  case TypeRequestConfig:
288  case TypeCreate:
289  default:
290  break;
291  }
292 
293  return t;
294  }
295  // ---- ~MUCRoom::MUCOwner ----
296 
297  // ---- MUCRoom::MUCUser ----
298  MUCRoom::MUCUser::MUCUser( MUCUserOperation operation, const std::string& to,
299  const std::string& reason, const std::string& thread )
300  : StanzaExtension( ExtMUCUser ), m_affiliation( AffiliationInvalid ), m_role( RoleInvalid ),
301  m_jid( new std::string( to ) ), m_actor( 0 ),
302  m_thread( thread.empty() ? 0 : new std::string( thread ) ),
303  m_reason( new std::string( reason ) ), m_newNick( 0 ), m_password( 0 ), m_alternate( 0 ),
304  m_operation( operation ),
305  m_flags( 0 ), m_del( false ), m_continue( !thread.empty() )
306  {
307  }
308 
310  : StanzaExtension( ExtMUCUser ), m_affiliation( AffiliationInvalid ), m_role( RoleInvalid ),
311  m_jid( 0 ), m_actor( 0 ), m_thread( 0 ), m_reason( 0 ), m_newNick( 0 ),
312  m_password( 0 ), m_alternate( 0 ), m_operation( OpNone ),
313  m_flags( 0 ), m_del( false ), m_continue( false )
314  {
315  if( !tag || tag->name() != "x" || tag->xmlns() != XMLNS_MUC_USER )
316  return;
317 
318  const Tag* t = 0;
319  const TagList& l = tag->children();
320  TagList::const_iterator it = l.begin();
321  for( ; it != l.end(); ++it )
322  {
323  if( (*it)->name() == "item" )
324  {
325  m_affiliation = getEnumAffiliation( (*it)->findAttribute( "affiliation" ) );
326  m_role = getEnumRole( (*it)->findAttribute( "role" ) );
327 
328  if( (*it)->hasAttribute( "jid" ) )
329  m_jid = new std::string( (*it)->findAttribute( "jid" ) );
330 
331  if( ( t = (*it)->findChild( "actor" ) ) )
332  m_actor = new std::string( t->findAttribute( "jid" ) );
333 
334  if( ( t = (*it)->findChild( "reason" ) ) )
335  m_reason = new std::string( t->cdata() );
336 
337  if( (*it)->hasAttribute( "nick" ) )
338  m_newNick = new std::string( (*it)->findAttribute( "nick" ) );
339  }
340  else if( (*it)->name() == "status" )
341  {
342  const std::string& code = (*it)->findAttribute( "code" );
343  if( code == "100" )
344  m_flags |= FlagNonAnonymous;
345  else if( code == "101" )
346  m_flags |= UserAffiliationChangedWNR;
347  else if( code == "110" )
348  m_flags |= UserSelf;
349  else if( code == "170" )
350  m_flags |= FlagPublicLogging;
351  else if( code == "201" )
352  m_flags |= UserNewRoom;
353  else if( code == "210" )
354  m_flags |= UserNickAssigned;
355  else if( code == "301" )
356  m_flags |= UserBanned;
357  else if( code == "303" )
358  m_flags |= UserNickChanged;
359  else if( code == "307" )
360  m_flags |= UserKicked;
361  else if( code == "321" )
362  m_flags |= UserAffiliationChanged;
363  else if( code == "322" )
364  m_flags |= UserMembershipRequired;
365  else if( code == "332" )
366  m_flags |= UserRoomShutdown;
367  }
368  else if( (*it)->name() == "destroy" )
369  {
370  m_del = true;
371  if( (*it)->hasAttribute( "jid" ) )
372  m_alternate = new std::string( (*it)->findAttribute( "jid" ) );
373 
374  if( ( t = (*it)->findChild( "reason" ) ) )
375  m_reason = new std::string( t->cdata() );
376 
377  m_flags |= UserRoomDestroyed;
378  }
379  else if( (*it)->name() == "invite" )
380  {
381  m_operation = OpInviteFrom;
382  m_jid = new std::string( (*it)->findAttribute( "from" ) );
383  if( m_jid->empty() )
384  {
385  m_operation = OpInviteTo;
386  m_jid->assign( (*it)->findAttribute( "to" ) );
387  }
388  if( (*it)->hasChild( "reason" ) )
389  m_reason = new std::string( (*it)->findChild( "reason" )->cdata() );
390  if( (*it)->hasChild( "continue" ) )
391  {
392  m_continue = true;
393  m_thread = new std::string( (*it)->findChild( "continue" )->findAttribute( "thread" ) );
394  }
395  }
396  else if( (*it)->name() == "decline" )
397  {
398  m_operation = OpDeclineFrom;
399  m_jid = new std::string( (*it)->findAttribute( "from" ) );
400  if( m_jid->empty() )
401  {
402  m_operation = OpDeclineTo;
403  m_jid->assign( (*it)->findAttribute( "from" ) );
404  }
405  if( (*it)->hasChild( "reason" ) )
406  m_reason = new std::string( (*it)->findChild( "reason" )->cdata() );
407  }
408  else if( (*it)->name() == "password" )
409  {
410  m_password = new std::string( (*it)->cdata() );
411  }
412  }
413  }
414 
416  {
417  delete m_jid;
418  delete m_actor;
419  delete m_thread;
420  delete m_reason;
421  delete m_newNick;
422  delete m_password;
423  delete m_alternate;
424  }
425 
426  MUCRoomRole MUCRoom::MUCUser::getEnumRole( const std::string& role )
427  {
428  if( role == "moderator" )
429  return RoleModerator;
430  if( role == "participant" )
431  return RoleParticipant;
432  if( role == "visitor" )
433  return RoleVisitor;
434  return RoleNone;
435  }
436 
437  MUCRoomAffiliation MUCRoom::MUCUser::getEnumAffiliation( const std::string& affiliation )
438  {
439  if( affiliation == "owner" )
440  return AffiliationOwner;
441  if( affiliation == "admin" )
442  return AffiliationAdmin;
443  if( affiliation == "member" )
444  return AffiliationMember;
445  if( affiliation == "outcast" )
446  return AffiliationOutcast;
447  return AffiliationNone;
448  }
449 
450  const std::string& MUCRoom::MUCUser::filterString() const
451  {
452  static const std::string filter = "/presence/x[@xmlns='" + XMLNS_MUC_USER + "']"
453  "|/message/x[@xmlns='" + XMLNS_MUC_USER + "']";
454  return filter;
455  }
456 
458  {
459  Tag* t = new Tag( "x" );
460  t->setXmlns( XMLNS_MUC_USER );
461 
462  if( m_affiliation != AffiliationInvalid || m_role != RoleInvalid )
463  {
464  Tag* i = new Tag( t, "item" );
465  if( m_jid )
466  i->addAttribute( "jid", *m_jid );
467  if( m_role != RoleInvalid )
468  i->addAttribute( "role", util::lookup( m_role, roleValues ) );
469  if( m_affiliation != AffiliationInvalid )
470  i->addAttribute( "affiliation", util::lookup( m_affiliation, affiliationValues ) );
471 
472  if( m_actor )
473  new Tag( i, "actor", "jid", *m_actor );
474 
475  if( m_reason )
476  new Tag( i, "reason", *m_reason );
477 
478  if( m_flags & FlagNonAnonymous )
479  new Tag( t, "status", "code", "100" );
480  if( m_flags & UserAffiliationChangedWNR )
481  new Tag( t, "status", "code", "101" );
482  if( m_flags & UserSelf )
483  new Tag( t, "status", "code", "110" );
484  if( m_flags & FlagPublicLogging )
485  new Tag( t, "status", "code", "170" );
486  if( m_flags & UserNewRoom )
487  new Tag( t, "status", "code", "201" );
488  if( m_flags & UserNickAssigned )
489  new Tag( t, "status", "code", "210" );
490  if( m_flags & UserBanned )
491  new Tag( t, "status", "code", "301" );
492  if( m_flags & UserNickChanged )
493  new Tag( t, "status", "code", "303" );
494  if( m_flags & UserKicked )
495  new Tag( t, "status", "code", "307" );
496  if( m_flags & UserAffiliationChanged )
497  new Tag( t, "status", "code", "321" );
498  if( m_flags & UserMembershipRequired )
499  new Tag( t, "status", "code", "322" );
500  if( m_flags & UserRoomShutdown )
501  new Tag( t, "status", "code", "332" );
502  }
503  else if( m_del )
504  {
505  Tag* d = new Tag( t, "destroy" );
506  if( m_alternate )
507  d->addAttribute( "jid", *m_alternate );
508  if( m_reason )
509  new Tag( d, "reason", *m_reason );
510  }
511  else if( m_operation != OpNone && m_jid )
512  {
513  Tag* d = 0;
514  if( m_operation == OpInviteTo )
515  d = new Tag( t, "invite", "to", *m_jid );
516  else if( m_operation == OpInviteFrom )
517  d = new Tag( t, "invite", "from", *m_jid );
518  else if( m_operation == OpDeclineTo )
519  d = new Tag( t, "decline", "to", *m_jid );
520  else if( m_operation == OpDeclineFrom )
521  d = new Tag( t, "decline", "from", *m_jid );
522 
523  if( m_reason )
524  new Tag( d, "reason", *m_reason );
525 
526  if( m_continue )
527  {
528  Tag* c = new Tag( d, "continue" );
529  if( m_thread )
530  c->addAttribute( "thread", *m_thread );
531  }
532 
533  if( m_password )
534  new Tag( t, "password", *m_password );
535 
536  }
537 
538  return t;
539  }
540  // ---- ~MUCRoom::MUCUser ----
541 
542  // ---- MUCRoom::MUC ----
543  MUCRoom::MUC::MUC( const std::string& password,
544  MUCRoom::HistoryRequestType historyType,
545  const std::string& historySince,
546  int historyValue )
547  : StanzaExtension( ExtMUC ),
548  m_password( password.empty() ? 0 : new std::string( password ) ),
549  m_historySince( new std::string( historySince ) ),
550  m_historyType( historyType ), m_historyValue( historyValue )
551  {
552  }
553 
554  MUCRoom::MUC::MUC( const Tag* tag )
555  : StanzaExtension( ExtMUC ),
556  m_password( 0 ), m_historySince( 0 ),
557  m_historyType( HistoryUnknown ), m_historyValue( 0 )
558  {
559  if( !tag || tag->name() != "x" || tag->xmlns() != XMLNS_MUC_USER )
560  return;
561 
562  const TagList& l = tag->children();
563  TagList::const_iterator it = l.begin();
564  for( ; it != l.end(); ++it )
565  {
566  if( (*it)->name() == "history" )
567  {
568  if( (*it)->hasAttribute( "seconds" ) )
569  m_historyValue = atoi( (*it)->findAttribute( "seconds" ).c_str() );
570  else if( (*it)->hasAttribute( "maxstanzas" ) )
571  m_historyValue = atoi( (*it)->findAttribute( "maxstanzas" ).c_str() );
572  else if( (*it)->hasAttribute( "maxchars" ) )
573  m_historyValue = atoi( (*it)->findAttribute( "maxchars" ).c_str() );
574  else if( (*it)->hasAttribute( "since" ) )
575  m_historySince = new std::string( (*it)->findAttribute( "since" ) );
576  }
577  else if( (*it)->name() == "password" )
578  {
579  m_password = new std::string( (*it)->cdata() );
580  }
581  }
582  }
583 
585  {
586  delete m_password;
587  delete m_historySince;
588  }
589 
590  const std::string& MUCRoom::MUC::filterString() const
591  {
592  static const std::string filter = "/presence/x[@xmlns='" + XMLNS_MUC + "']";
593  return filter;
594  }
595 
597  {
598  Tag* t = new Tag( "x" );
599  t->setXmlns( XMLNS_MUC );
600 
601  if( m_historyType != HistoryUnknown )
602  {
603  const std::string& histStr = util::lookup( m_historyType, historyTypeValues );
604  Tag* h = new Tag( t, "history" );
605  if( m_historyType == HistorySince && m_historySince )
606  h->addAttribute( histStr, *m_historySince );
607  else
608  h->addAttribute( histStr, m_historyValue );
609  }
610 
611  if( m_password )
612  new Tag( t, "password", *m_password );
613 
614  return t;
615  }
616  // ---- ~MUCRoom::MUC ----
617 
618  // --- MUCRoom ----
620  MUCRoomConfigHandler* mrch )
621  : m_parent( parent ), m_nick( nick ), m_joined( false ), m_roomHandler( mrh ),
622  m_roomConfigHandler( mrch ), m_session( 0 ), m_affiliation( AffiliationNone ),
623  m_role( RoleNone ), m_historyType( HistoryUnknown ), m_historyValue( 0 ),
624  m_flags( 0 ), m_creationInProgress( false ), m_configChanged( false ),
625  m_publishNick( false ), m_publish( false ), m_unique( false )
626  {
627  if( m_parent )
628  {
629  m_parent->registerStanzaExtension( new MUCAdmin() );
630  m_parent->registerStanzaExtension( new MUCOwner() );
631  m_parent->registerStanzaExtension( new MUCUser() );
632  m_parent->registerStanzaExtension( new MUC() );
633  m_parent->registerStanzaExtension( new DelayedDelivery() );
634  }
635  }
636 
638  {
639  if( m_joined )
640  leave();
641 
642  if( m_parent )
643  {
644  if( m_publish )
645  m_parent->disco()->removeNodeHandler( this, XMLNS_MUC_ROOMS );
646 
647  m_parent->removeIDHandler( this );
648 // m_parent->removeStanzaExtension( ExtMUCAdmin ); // don't remove, other rooms might need it
649 // m_parent->removeStanzaExtension( ExtMUCOwner );
650  m_parent->removePresenceHandler( m_nick.bareJID(), this );
651  m_parent->disco()->removeDiscoHandler( this );
652  }
653  }
654 
655  void MUCRoom::join( Presence::PresenceType type, const std::string& status, int priority )
656  {
657  if( m_joined || !m_parent )
658  return;
659 
660  m_parent->registerPresenceHandler( m_nick.bareJID(), this );
661 
662  m_session = new MUCMessageSession( m_parent, m_nick.bareJID() );
663  m_session->registerMessageHandler( this );
664 
665  Presence pres( type, m_nick.full(), status, priority );
666  pres.addExtension( new MUC( m_password, m_historyType, m_historySince, m_historyValue ) );
667  m_joined = true;
668  m_parent->send( pres );
669  }
670 
671  void MUCRoom::leave( const std::string& msg )
672  {
673  if( !m_joined )
674  return;
675 
676  if( m_parent )
677  {
678  Presence pres( Presence::Unavailable, m_nick.full(), msg );
679  m_parent->send( pres );
680  m_parent->removePresenceHandler( m_nick.bareJID(), this );
681  m_parent->disposeMessageSession( m_session );
682  }
683 
684  m_session = 0;
685  m_joined = false;
686  }
687 
688  void MUCRoom::destroy( const std::string& reason, const JID& alternate, const std::string& password )
689  {
690  if( !m_parent )
691  return;
692 
693  const std::string& id = m_parent->getID();
694  IQ iq( IQ::Set, m_nick.bareJID(), id );
695  iq.addExtension( new MUCOwner( alternate, reason, password ) );
696  m_parent->send( iq, this, DestroyRoom );
697  }
698 
699  void MUCRoom::send( const std::string& message )
700  {
701  if( m_session && m_joined )
702  m_session->send( message );
703  }
704 
705  void MUCRoom::send( const std::string& message, const std::string& subject, const StanzaExtensionList& sel )
706  {
707  if( m_session && m_joined )
708  m_session->send( message, subject, sel );
709  }
710 
711  void MUCRoom::setSubject( const std::string& subject )
712  {
713  if( m_session && m_joined )
714  m_session->setSubject( subject );
715  }
716 
717  void MUCRoom::setNick( const std::string& nick )
718  {
719  if( m_parent && m_joined )
720  {
721  m_newNick = nick;
722 
723  Presence p( Presence::Available, m_nick.bare() + "/" + m_newNick );
724  m_parent->send( p );
725  }
726  else
727  m_nick.setResource( nick );
728  }
729 
731  {
732  if( m_parent )
733  m_parent->disco()->getDiscoInfo( m_nick.bare(), EmptyString, this, GetRoomInfo );
734  }
735 
737  {
738  if( m_parent )
739  m_parent->disco()->getDiscoItems( m_nick.bare(), EmptyString, this, GetRoomItems );
740  }
741 
742  void MUCRoom::setPresence( Presence::PresenceType presence, const std::string& msg )
743  {
744  if( m_parent && presence != Presence::Unavailable && m_joined )
745  {
746  Presence p( presence, m_nick.full(), msg );
747  m_parent->send( p );
748  }
749  }
750 
751  void MUCRoom::invite( const JID& invitee, const std::string& reason, const std::string& thread )
752  {
753  if( !m_parent || !m_joined )
754  return;
755 
756  Message msg( Message::Normal, m_nick.bareJID() );
757  msg.addExtension( new MUCUser( OpInviteTo, invitee.bare(), reason, thread ) );
758  m_parent->send( msg );
759  }
760 
761  Message* MUCRoom::declineInvitation( const JID& room, const JID& invitor, const std::string& reason )
762  {
763  Message* msg = new Message( Message::Normal, room.bare() );
764  msg->addExtension( new MUCUser( OpDeclineTo, invitor.bare(), reason ) );
765  return msg;
766  }
767 
768  void MUCRoom::setPublish( bool publish, bool publishNick )
769  {
770  m_publish = publish;
771  m_publishNick = publishNick;
772 
773  if( !m_parent )
774  return;
775 
776  if( m_publish )
777  m_parent->disco()->registerNodeHandler( this, XMLNS_MUC_ROOMS );
778  else
779  m_parent->disco()->removeNodeHandler( this, XMLNS_MUC_ROOMS );
780  }
781 
782  void MUCRoom::addHistory( const std::string& message, const JID& from, const std::string& stamp )
783  {
784  if( !m_joined || !m_parent )
785  return;
786 
787  Message m( Message::Groupchat, m_nick.bareJID(), message );
788  m.addExtension( new DelayedDelivery( from, stamp ) );
789  m_parent->send( m );
790  }
791 
793  {
794  m_historyType = type;
795  m_historySince = EmptyString;
796  m_historyValue = value;
797  }
798 
799  void MUCRoom::setRequestHistory( const std::string& since )
800  {
801  m_historyType = HistorySince;
802  m_historySince = since;
803  m_historyValue = 0;
804  }
805 
806  Message* MUCRoom::createDataForm( const JID& room, const DataForm* df )
807  {
808  Message* m = new Message( Message::Normal, room.bare() );
809  m->addExtension( df );
810  return m;
811  }
812 
814  {
815  if( !m_parent || !m_joined )
816  return;
817 
818  DataForm* df = new DataForm( TypeSubmit );
820  df->addField( DataFormField::TypeTextSingle, "muc#role", "participant", "Requested role" );
821 
822  Message m( Message::Normal, m_nick.bare() );
823  m.addExtension( df );
824 
825  m_parent->send( m );
826  }
827 
828  void MUCRoom::setRole( const std::string& nick, MUCRoomRole role,
829  const std::string& reason )
830  {
831  if( !m_parent || !m_joined || nick.empty() || role == RoleInvalid )
832  return;
833 
835  switch( role )
836  {
837  case RoleNone:
838  action = SetRNone;
839  break;
840  case RoleVisitor:
841  action = SetVisitor;
842  break;
843  case RoleParticipant:
844  action = SetParticipant;
845  break;
846  case RoleModerator:
847  action = SetModerator;
848  break;
849  default:
850  break;
851  }
852 
853  IQ iq( IQ::Set, m_nick.bareJID() );
854  iq.addExtension( new MUCAdmin( role, nick, reason ) );
855 
856  m_parent->send( iq, this, action );
857  }
858 
859  void MUCRoom::setAffiliation( const std::string& nick, MUCRoomAffiliation affiliation,
860  const std::string& reason )
861  {
862  if( !m_parent || !m_joined || nick.empty() || affiliation == AffiliationInvalid )
863  return;
864 
866  switch( affiliation )
867  {
868  case AffiliationOutcast:
869  action = SetOutcast;
870  break;
871  case AffiliationNone:
872  action = SetANone;
873  break;
874  case AffiliationMember:
875  action = SetMember;
876  break;
877  case AffiliationAdmin:
878  action = SetAdmin;
879  break;
880  case AffiliationOwner:
881  action = SetOwner;
882  break;
883  default:
884  break;
885  }
886 
887  IQ iq( IQ::Set, m_nick.bareJID() );
888  iq.addExtension( new MUCAdmin( affiliation, nick, reason ) );
889 
890  m_parent->send( iq, this, action );
891  }
892 
894  {
895  if( !m_parent || !m_joined || !m_roomConfigHandler )
896  return;
897 
898  IQ iq( IQ::Get, m_nick.bareJID() );
899  iq.addExtension( new MUCAdmin( operation ) );
900  m_parent->send( iq, this, operation );
901  }
902 
903  void MUCRoom::storeList( const MUCListItemList items, MUCOperation operation )
904  {
905  if( !m_parent || !m_joined )
906  return;
907 
908  IQ iq( IQ::Set, m_nick.bareJID() );
909  iq.addExtension( new MUCAdmin( operation , items ) );
910  m_parent->send( iq, this, operation );
911  }
912 
913  void MUCRoom::handlePresence( const Presence& presence )
914  {
915  if( ( presence.from().bare() != m_nick.bare() ) || !m_roomHandler )
916  return;
917 
918  if( presence.subtype() == Presence::Error )
919  {
920  if( m_newNick.empty() )
921  {
922  m_parent->removePresenceHandler( m_nick.bareJID(), this );
923  m_parent->disposeMessageSession( m_session );
924  m_joined = false;
925  m_session = 0;
926  }
927  else
928  m_newNick = "";
929 
930  m_roomHandler->handleMUCError( this, presence.error()
931  ? presence.error()->error()
933  }
934  else
935  {
936  const MUCUser* mu = presence.findExtension<MUCUser>( ExtMUCUser );
937  if( !mu )
938  return;
939 
940  MUCRoomParticipant party;
941  party.nick = new JID( presence.from() );
942  party.status = presence.status();
943  party.affiliation = mu->affiliation();
944  party.role = mu->role();
945  party.jid = mu->jid() ? new JID( *(mu->jid()) ) : 0;
946  party.actor = mu->actor() ? new JID( *(mu->actor()) ) : 0;
947  party.reason = mu->reason() ? *(mu->reason()) : EmptyString;
948  party.newNick = mu->newNick() ? *(mu->newNick()) : EmptyString;
949  party.alternate = mu->alternate() ? new JID( *(mu->alternate()) ) : 0;
950  party.flags = mu->flags();
951 
952  if( party.flags & FlagNonAnonymous )
953  setNonAnonymous();
954 
955  if( party.flags & UserSelf )
956  {
957  m_role = party.role;
958  m_affiliation = party.affiliation;
959  }
960  if( party.flags & UserNewRoom )
961  {
962  m_creationInProgress = true;
963  if( instantRoomHook() || m_roomHandler->handleMUCRoomCreation( this ) )
965  }
966  if( party.flags & UserNickAssigned )
967  m_nick.setResource( presence.from().resource() );
968 
969  if( party.flags & UserNickChanged && !party.newNick.empty()
970  && m_nick.resource() == presence.from().resource()
971  && party.newNick == m_newNick )
972  party.flags |= UserSelf;
973 
974  if( party.flags & UserNickChanged && party.flags & UserSelf && !party.newNick.empty() )
975  m_nick.setResource( party.newNick );
976 
977  if( m_roomHandler )
978  m_roomHandler->handleMUCParticipantPresence( this, party, presence );
979 
980  delete party.nick;
981  delete party.jid;
982  delete party.actor;
983  delete party.alternate;
984  }
985  }
986 
987  void MUCRoom::instantRoom( int context )
988  {
989  if( !m_creationInProgress || !m_parent || !m_joined )
990  return;
991 
992  IQ iq( IQ::Set, m_nick.bareJID() );
993  iq.addExtension( new MUCOwner( context == CreateInstantRoom
994  ? MUCOwner::TypeInstantRoom : MUCOwner::TypeCancelConfig ) );
995 
996  m_parent->send( iq, this, context );
997 
998  m_creationInProgress = false;
999  }
1000 
1002  {
1003  if( !m_parent || !m_joined )
1004  return;
1005 
1006  IQ iq( IQ::Get, m_nick.bareJID() );
1007  iq.addExtension( new MUCOwner( MUCOwner::TypeRequestConfig ) );
1008 
1009  m_parent->send( iq, this, RequestRoomConfig );
1010 
1011  if( m_creationInProgress )
1012  m_creationInProgress = false;
1013  }
1014 
1016  {
1017  if( !m_parent || !m_joined )
1018  return;
1019 
1020  IQ iq( IQ::Set, m_nick.bareJID() );
1021  iq.addExtension( new MUCOwner( MUCOwner::TypeSendConfig, form ) );
1022 
1023  m_parent->send( iq, this, SendRoomConfig );
1024  }
1025 
1026  void MUCRoom::setNonAnonymous()
1027  {
1028  m_flags |= FlagNonAnonymous;
1029  m_flags &= ~( FlagSemiAnonymous | FlagFullyAnonymous );
1030  }
1031 
1032  void MUCRoom::setSemiAnonymous()
1033  {
1034  m_flags &= ~( FlagNonAnonymous | FlagFullyAnonymous );
1035  m_flags |= FlagSemiAnonymous;
1036  }
1037 
1038  void MUCRoom::setFullyAnonymous()
1039  {
1040  m_flags &= ~( FlagNonAnonymous | FlagSemiAnonymous );
1041  m_flags |= FlagFullyAnonymous;
1042  }
1043 
1044  void MUCRoom::handleMessage( const Message& msg, MessageSession* /*session*/ )
1045  {
1046  if( !m_roomHandler )
1047  return;
1048 
1049  if( msg.subtype() == Message::Error )
1050  {
1051  m_roomHandler->handleMUCError( this, msg.error() ? msg.error()->error() : StanzaErrorUndefined );
1052  }
1053  else
1054  {
1055  const MUCUser* mu = msg.findExtension<MUCUser>( ExtMUCUser );
1056  if( mu )
1057  {
1058  const int flags = mu->flags();
1059  if( flags & FlagNonAnonymous )
1060  setNonAnonymous();
1061  if( flags & FlagPublicLogging )
1062  {
1063  m_flags &= ~FlagPublicLoggingOff;
1064  m_flags |= FlagPublicLogging;
1065  }
1066  if( flags & FlagPublicLoggingOff )
1067  {
1068  m_flags &= ~FlagPublicLogging;
1069  m_flags |= FlagPublicLoggingOff;
1070  }
1071  if( flags & FlagSemiAnonymous )
1072  setSemiAnonymous();
1073  if( flags & FlagFullyAnonymous )
1074  setFullyAnonymous();
1075 
1076  if( mu->operation() == OpDeclineFrom && mu->jid() )
1077  m_roomHandler->handleMUCInviteDecline( this, JID( *(mu->jid()) ),
1078  mu->reason() ? *(mu->reason()) : EmptyString );
1079  }
1080 
1081  const DataForm* df = msg.findExtension<DataForm>( ExtDataForm );
1082  if( m_roomConfigHandler && df )
1083  {
1084  m_roomConfigHandler->handleMUCRequest( this, *df );
1085  return;
1086  }
1087 
1088  if( !msg.subject().empty() )
1089  {
1090  m_roomHandler->handleMUCSubject( this, msg.from().resource(), msg.subject() );
1091  }
1092  else if( !msg.body().empty() || !msg.extensions().empty() )
1093  {
1094  std::string when;
1095  bool privMsg = false;
1096  if( msg.when() )
1097  when = msg.when()->stamp();
1098 
1099  if( msg.subtype() & ( Message::Chat | Message::Normal ) )
1100  privMsg = true;
1101 
1102  m_roomHandler->handleMUCMessage( this, msg, privMsg );
1103  }
1104  }
1105  }
1106 
1107  void MUCRoom::handleIqID( const IQ& iq, int context )
1108  {
1109  if( !m_roomConfigHandler )
1110  return;
1111 
1112  switch( iq.subtype() )
1113  {
1114  case IQ::Result:
1115  handleIqResult( iq, context );
1116  break;
1117  case IQ::Error:
1118  handleIqError( iq, context );
1119  break;
1120  default:
1121  break;
1122  }
1123  }
1124 
1125  void MUCRoom::handleIqResult( const IQ& iq, int context )
1126  {
1127  switch( context )
1128  {
1129  case SetRNone:
1130  case SetVisitor:
1131  case SetParticipant:
1132  case SetModerator:
1133  case SetANone:
1134  case SetOutcast:
1135  case SetMember:
1136  case SetAdmin:
1137  case SetOwner:
1138  case CreateInstantRoom:
1139  case CancelRoomCreation:
1140  case SendRoomConfig:
1141  case DestroyRoom:
1142  case StoreVoiceList:
1143  case StoreBanList:
1144  case StoreMemberList:
1145  case StoreModeratorList:
1146  case StoreAdminList:
1147  m_roomConfigHandler->handleMUCConfigResult( this, true, static_cast<MUCOperation>( context ) );
1148  break;
1149  case RequestRoomConfig:
1150  {
1151  const MUCOwner* mo = iq.findExtension<MUCOwner>( ExtMUCOwner );
1152  if( !mo )
1153  break;
1154 
1155  if( mo->form() )
1156  m_roomConfigHandler->handleMUCConfigForm( this, *(mo->form()) );
1157  break;
1158  }
1159  case RequestVoiceList:
1160  case RequestBanList:
1161  case RequestMemberList:
1162  case RequestModeratorList:
1163  case RequestOwnerList:
1164  case RequestAdminList:
1165  {
1166  const MUCAdmin* ma = iq.findExtension<MUCAdmin>( ExtMUCAdmin );
1167  if( !ma )
1168  break;
1169 
1170  m_roomConfigHandler->handleMUCConfigList( this, ma->list(), static_cast<MUCOperation>( context ) );
1171  break;
1172  }
1173  default:
1174  break;
1175  }
1176  }
1177 
1178  void MUCRoom::handleIqError( const IQ& /*iq*/, int context )
1179  {
1180  switch( context )
1181  {
1182  case SetRNone:
1183  case SetVisitor:
1184  case SetParticipant:
1185  case SetModerator:
1186  case SetANone:
1187  case SetOutcast:
1188  case SetMember:
1189  case SetAdmin:
1190  case SetOwner:
1191  case CreateInstantRoom:
1192  case CancelRoomCreation:
1193  case RequestRoomConfig:
1194  case SendRoomConfig:
1195  case DestroyRoom:
1196  case RequestVoiceList:
1197  case StoreVoiceList:
1198  case RequestBanList:
1199  case StoreBanList:
1200  case RequestMemberList:
1201  case StoreMemberList:
1202  case RequestModeratorList:
1203  case StoreModeratorList:
1204  case RequestOwnerList:
1205  case StoreOwnerList:
1206  case RequestAdminList:
1207  case StoreAdminList:
1208  m_roomConfigHandler->handleMUCConfigResult( this, false, static_cast<MUCOperation>( context ) );
1209  break;
1210  }
1211  }
1212 
1213  void MUCRoom::handleDiscoInfo( const JID& /*from*/, const Disco::Info& info, int context )
1214  {
1215  switch( context )
1216  {
1217  case GetRoomInfo:
1218  {
1219  int oldflags = m_flags;
1220  m_flags = 0;
1221  if( oldflags & FlagPublicLogging )
1222  m_flags |= FlagPublicLogging;
1223 
1224  std::string name;
1225  const StringList& l = info.features();
1226  StringList::const_iterator it = l.begin();
1227  for( ; it != l.end(); ++it )
1228  {
1229  if( (*it) == "muc_hidden" )
1230  m_flags |= FlagHidden;
1231  else if( (*it) == "muc_membersonly" )
1232  m_flags |= FlagMembersOnly;
1233  else if( (*it) == "muc_moderated" )
1234  m_flags |= FlagModerated;
1235  else if( (*it) == "muc_nonanonymous" )
1236  setNonAnonymous();
1237  else if( (*it) == "muc_open" )
1238  m_flags |= FlagOpen;
1239  else if( (*it) == "muc_passwordprotected" )
1240  m_flags |= FlagPasswordProtected;
1241  else if( (*it) == "muc_persistent" )
1242  m_flags |= FlagPersistent;
1243  else if( (*it) == "muc_public" )
1244  m_flags |= FlagPublic;
1245  else if( (*it) == "muc_semianonymous" )
1246  setSemiAnonymous();
1247  else if( (*it) == "muc_temporary" )
1248  m_flags |= FlagTemporary;
1249  else if( (*it) == "muc_fullyanonymous" )
1250  setFullyAnonymous();
1251  else if( (*it) == "muc_unmoderated" )
1252  m_flags |= FlagUnmoderated;
1253  else if( (*it) == "muc_unsecured" )
1254  m_flags |= FlagUnsecured;
1255  }
1256 
1257  const Disco::IdentityList& il = info.identities();
1258  if( il.size() )
1259  name = il.front()->name();
1260 
1261  if( m_roomHandler )
1262  m_roomHandler->handleMUCInfo( this, m_flags, name, info.form() );
1263  break;
1264  }
1265  default:
1266  break;
1267  }
1268  }
1269 
1270  void MUCRoom::handleDiscoItems( const JID& /*from*/, const Disco::Items& items, int context )
1271  {
1272  if( !m_roomHandler )
1273  return;
1274 
1275  switch( context )
1276  {
1277  case GetRoomItems:
1278  {
1279  m_roomHandler->handleMUCItems( this, items.items() );
1280  break;
1281  }
1282  default:
1283  break;
1284  }
1285  }
1286 
1287  void MUCRoom::handleDiscoError( const JID& /*from*/, const Error* /*error*/, int context )
1288  {
1289  if( !m_roomHandler )
1290  return;
1291 
1292  switch( context )
1293  {
1294  case GetRoomInfo:
1295  m_roomHandler->handleMUCInfo( this, 0, EmptyString, 0 );
1296  break;
1297  case GetRoomItems:
1298  m_roomHandler->handleMUCItems( this, Disco::ItemList() );
1299  break;
1300  default:
1301  break;
1302  }
1303  }
1304 
1305  StringList MUCRoom::handleDiscoNodeFeatures( const JID& /*from*/, const std::string& /*node*/ )
1306  {
1307  return StringList();
1308  }
1309 
1311  const std::string& /*node*/ )
1312  {
1313  return Disco::IdentityList();
1314  }
1315 
1316  Disco::ItemList MUCRoom::handleDiscoNodeItems( const JID& /*from*/, const JID& /*to*/,
1317  const std::string& node )
1318  {
1319  Disco::ItemList l;
1320  if( node == XMLNS_MUC_ROOMS && m_publish )
1321  {
1322  l.push_back( new Disco::Item( m_nick.bareJID(), EmptyString,
1323  m_publishNick ? m_nick.resource() : EmptyString ) );
1324  }
1325  return l;
1326  }
1327 
1328 }
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
Definition: clientbase.h:79
const std::string getID()
void registerPresenceHandler(PresenceHandler *ph)
virtual Disco * disco() const
Definition: clientbase.h:233
void removeIDHandler(IqHandler *ih)
void send(Tag *tag)
void disposeMessageSession(MessageSession *session)
void registerStanzaExtension(StanzaExtension *ext)
void removePresenceHandler(PresenceHandler *ph)
virtual void addField(DataFormField *field)
An abstraction of a XEP-0004 Data Form.
Definition: dataform.h:57
This is an implementation of XEP-0203 (Delayed Delivery).
const std::string & stamp() const
An abstraction of a Disco Info element (from Service Discovery, XEP-0030) as a StanzaExtension.
Definition: disco.h:66
const StringList & features() const
Definition: disco.h:80
const DataForm * form() const
Definition: disco.h:99
const IdentityList & identities() const
Definition: disco.h:93
An abstraction of a Disco item (Service Discovery, XEP-0030).
Definition: disco.h:353
An abstraction of a Disco query element (from Service Discovery, XEP-0030) in the disco::items namesp...
Definition: disco.h:276
const ItemList & items() const
Definition: disco.h:311
void removeDiscoHandler(DiscoHandler *dh)
Definition: disco.cpp:481
void removeNodeHandler(DiscoNodeHandler *nh, const std::string &node)
Definition: disco.cpp:502
void getDiscoInfo(const JID &to, const std::string &node, DiscoHandler *dh, int context, const std::string &tid=EmptyString)
Definition: disco.h:451
void registerNodeHandler(DiscoNodeHandler *nh, const std::string &node)
Definition: disco.cpp:497
std::list< Identity * > IdentityList
Definition: disco.h:51
void getDiscoItems(const JID &to, const std::string &node, DiscoHandler *dh, int context, const std::string &tid=EmptyString)
Definition: disco.h:466
std::list< Item * > ItemList
Definition: disco.h:261
A stanza error abstraction implemented as a StanzaExtension.
Definition: error.h:35
StanzaError error() const
Definition: error.h:75
An abstraction of an IQ stanza.
Definition: iq.h:34
IqType subtype() const
Definition: iq.h:74
@ Set
Definition: iq.h:46
@ Error
Definition: iq.h:49
@ Result
Definition: iq.h:48
@ Get
Definition: iq.h:45
An abstraction of a JID.
Definition: jid.h:31
const std::string & resource() const
Definition: jid.h:116
const std::string & full() const
Definition: jid.h:61
const std::string & bare() const
Definition: jid.h:67
bool setResource(const std::string &resource)
Definition: jid.cpp:64
JID bareJID() const
Definition: jid.h:74
This is a MessageSession, adapted to be used in a MUC context.
virtual void send(const std::string &message)
virtual void setSubject(const std::string &subject)
An abstract interface that can be implemented for MUC room configuration.
virtual void handleMUCConfigResult(MUCRoom *room, bool success, MUCOperation operation)=0
virtual void handleMUCConfigList(MUCRoom *room, const MUCListItemList &items, MUCOperation operation)=0
virtual void handleMUCRequest(MUCRoom *room, const DataForm &form)=0
virtual void handleMUCConfigForm(MUCRoom *room, const DataForm &form)=0
This interface enables inheriting classes to be notified about certain events in a MUC room.
virtual void handleMUCParticipantPresence(MUCRoom *room, const MUCRoomParticipant participant, const Presence &presence)=0
virtual void handleMUCInfo(MUCRoom *room, int features, const std::string &name, const DataForm *infoForm)=0
virtual void handleMUCMessage(MUCRoom *room, const Message &msg, bool priv)=0
virtual void handleMUCSubject(MUCRoom *room, const std::string &nick, const std::string &subject)=0
virtual void handleMUCInviteDecline(MUCRoom *room, const JID &invitee, const std::string &reason)=0
virtual void handleMUCError(MUCRoom *room, StanzaError error)=0
virtual void handleMUCItems(MUCRoom *room, const Disco::ItemList &items)=0
virtual bool handleMUCRoomCreation(MUCRoom *room)=0
An abstraction of a MUC user query.
Definition: mucroom.h:202
MUCRoomAffiliation affiliation() const
Definition: mucroom.h:237
MUCUser(MUCUserOperation operation, const std::string &to, const std::string &reason, const std::string &thread=EmptyString)
Definition: mucroom.cpp:298
virtual const std::string & filterString() const
Definition: mucroom.cpp:450
int flags() const
Definition: mucroom.h:231
const std::string * alternate() const
Definition: mucroom.h:279
MUCUserOperation operation() const
Definition: mucroom.h:291
MUCRoomRole role() const
Definition: mucroom.h:243
virtual Tag * tag() const
Definition: mucroom.cpp:457
An abstraction of a MUC query.
Definition: mucroom.h:128
virtual const std::string & filterString() const
Definition: mucroom.cpp:590
MUC(const std::string &password, HistoryRequestType historyType=HistoryUnknown, const std::string &historySince=EmptyString, int historyValue=0)
Definition: mucroom.cpp:543
virtual Tag * tag() const
Definition: mucroom.cpp:596
void setPublish(bool publish, bool publishNick)
Definition: mucroom.cpp:768
MUCRoomAffiliation affiliation() const
Definition: mucroom.h:435
virtual bool instantRoomHook() const
Definition: mucroom.h:786
void requestVoice()
Definition: mucroom.cpp:813
MUCRoom(ClientBase *parent, const JID &nick, MUCRoomHandler *mrh, MUCRoomConfigHandler *mrch=0)
Definition: mucroom.cpp:619
void setPresence(Presence::PresenceType presence, const std::string &msg=EmptyString)
Definition: mucroom.cpp:742
virtual void handleIqID(const IQ &iq, int context)
Definition: mucroom.cpp:1107
void send(const std::string &message)
Definition: mucroom.cpp:699
void requestRoomConfig()
Definition: mucroom.cpp:1001
void setRequestHistory(int value, HistoryRequestType type)
Definition: mucroom.cpp:792
virtual void handleDiscoInfo(const JID &from, const Disco::Info &info, int context)
Definition: mucroom.cpp:1213
void acknowledgeInstantRoom()
Definition: mucroom.h:673
void requestList(MUCOperation operation)
Definition: mucroom.cpp:893
void setRoomConfig(DataForm *form)
Definition: mucroom.cpp:1015
void getRoomItems()
Definition: mucroom.cpp:736
virtual void handlePresence(const Presence &presence)
Definition: mucroom.cpp:913
void setAffiliation(const std::string &nick, MUCRoomAffiliation affiliation, const std::string &reason)
Definition: mucroom.cpp:859
static Message * declineInvitation(const JID &room, const JID &invitor, const std::string &reason=EmptyString)
Definition: mucroom.cpp:761
virtual void join(Presence::PresenceType type=Presence::Available, const std::string &status=EmptyString, int priority=0)
Definition: mucroom.cpp:655
virtual void handleDiscoError(const JID &from, const Error *error, int context)
Definition: mucroom.cpp:1287
virtual ~MUCRoom()
Definition: mucroom.cpp:637
virtual Disco::ItemList handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node=EmptyString)
Definition: mucroom.cpp:1316
int flags() const
Definition: mucroom.h:740
virtual void handleDiscoItems(const JID &from, const Disco::Items &items, int context)
Definition: mucroom.cpp:1270
void addHistory(const std::string &message, const JID &from, const std::string &stamp)
Definition: mucroom.cpp:782
void destroy(const std::string &reason=EmptyString, const JID &alternate=JID(), const std::string &password=EmptyString)
Definition: mucroom.cpp:688
static Message * createDataForm(const JID &room, const DataForm *df)
Definition: mucroom.cpp:806
void leave(const std::string &msg=EmptyString)
Definition: mucroom.cpp:671
virtual Disco::IdentityList handleDiscoNodeIdentities(const JID &from, const std::string &node)
Definition: mucroom.cpp:1310
MUCRoomRole role() const
Definition: mucroom.h:441
void setSubject(const std::string &subject)
Definition: mucroom.cpp:711
virtual StringList handleDiscoNodeFeatures(const JID &from, const std::string &node)
Definition: mucroom.cpp:1305
void getRoomInfo()
Definition: mucroom.cpp:730
void setRole(const std::string &nick, MUCRoomRole role, const std::string &reason=EmptyString)
Definition: mucroom.cpp:828
void storeList(const MUCListItemList items, MUCOperation operation)
Definition: mucroom.cpp:903
void invite(const JID &invitee, const std::string &reason, const std::string &thread=EmptyString)
Definition: mucroom.cpp:751
virtual void handleMessage(const Message &msg, MessageSession *session=0)
Definition: mucroom.cpp:1044
const std::string name() const
Definition: mucroom.h:376
const std::string nick() const
Definition: mucroom.h:389
void setNick(const std::string &nick)
Definition: mucroom.cpp:717
An abstraction of a message session between any two entities.
void registerMessageHandler(MessageHandler *mh)
An abstraction of a message stanza.
Definition: message.h:34
const std::string subject(const std::string &lang="default") const
Definition: message.h:101
const std::string body(const std::string &lang="default") const
Definition: message.h:87
MessageType subtype() const
Definition: message.h:76
const DelayedDelivery * when() const
Definition: message.h:131
An abstraction of a presence stanza.
Definition: presence.h:33
PresenceType subtype() const
Definition: presence.h:76
const std::string status(const std::string &lang="default") const
Definition: presence.h:106
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
void addExtension(const StanzaExtension *se)
Definition: stanza.cpp:52
const Error * error() const
Definition: stanza.cpp:47
const StanzaExtensionList & extensions() const
Definition: stanza.h:113
const JID & from() const
Definition: stanza.h:51
const StanzaExtension * findExtension(int type) const
Definition: stanza.cpp:57
This is an abstraction of an XML element.
Definition: tag.h:47
Tag * findChild(const std::string &name) const
Definition: tag.cpp:624
const std::string xmlns() const
Definition: tag.cpp:543
bool addAttribute(Attribute *attr)
Definition: tag.cpp:354
const std::string cdata() const
Definition: tag.cpp:497
const std::string & findAttribute(const std::string &name) const
Definition: tag.cpp:589
const std::string & name() const
Definition: tag.h:394
const TagList & children() const
Definition: tag.cpp:510
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition: tag.cpp:522
The namespace for the gloox library.
Definition: adhoc.cpp:28
std::list< Tag * > TagList
Definition: tag.h:26
const std::string XMLNS_MUC_OWNER
Definition: gloox.cpp:72
std::list< const StanzaExtension * > StanzaExtensionList
Definition: gloox.h:1268
MUCRoomRole
Definition: gloox.h:1164
@ RoleParticipant
Definition: gloox.h:1167
@ RoleInvalid
Definition: gloox.h:1169
@ RoleModerator
Definition: gloox.h:1168
@ RoleVisitor
Definition: gloox.h:1166
@ RoleNone
Definition: gloox.h:1165
std::list< std::string > StringList
Definition: gloox.h:1251
const std::string XMLNS_MUC_REQUEST
Definition: gloox.cpp:75
const char * historyTypeValues[]
Definition: mucroom.cpp:48
const std::string XMLNS_X_DATA
Definition: gloox.cpp:49
@ UserBanned
Definition: gloox.h:1204
@ UserNewRoom
Definition: gloox.h:1210
@ UserRoomDestroyed
Definition: gloox.h:1207
@ UserRoomShutdown
Definition: gloox.h:1214
@ UserSelf
Definition: gloox.h:1201
@ UserNickChanged
Definition: gloox.h:1202
@ UserNickAssigned
Definition: gloox.h:1208
@ UserKicked
Definition: gloox.h:1203
@ UserAffiliationChangedWNR
Definition: gloox.h:1216
@ UserMembershipRequired
Definition: gloox.h:1211
@ UserAffiliationChanged
Definition: gloox.h:1205
std::list< MUCListItem > MUCListItemList
const std::string EmptyString
Definition: gloox.cpp:124
@ StanzaErrorUndefined
Definition: gloox.h:952
const std::string XMLNS_MUC_USER
Definition: gloox.cpp:68
const std::string XMLNS_MUC_ADMIN
Definition: gloox.cpp:69
MUCRoomAffiliation
Definition: gloox.h:1151
@ AffiliationInvalid
Definition: gloox.h:1157
@ AffiliationOwner
Definition: gloox.h:1155
@ AffiliationMember
Definition: gloox.h:1154
@ AffiliationNone
Definition: gloox.h:1152
@ AffiliationAdmin
Definition: gloox.h:1156
@ AffiliationOutcast
Definition: gloox.h:1153
@ TypeSubmit
Definition: dataform.h:37
@ TypeCancel
Definition: dataform.h:39
const std::string XMLNS_MUC_ROOMS
Definition: gloox.cpp:74
@ FlagPublicLoggingOff
Definition: gloox.h:1179
@ FlagHidden
Definition: gloox.h:1180
@ FlagMembersOnly
Definition: gloox.h:1181
@ FlagTemporary
Definition: gloox.h:1188
@ FlagPersistent
Definition: gloox.h:1185
@ FlagModerated
Definition: gloox.h:1182
@ FlagOpen
Definition: gloox.h:1184
@ FlagPublicLogging
Definition: gloox.h:1178
@ FlagNonAnonymous
Definition: gloox.h:1183
@ FlagPasswordProtected
Definition: gloox.h:1177
@ FlagSemiAnonymous
Definition: gloox.h:1187
@ FlagUnmoderated
Definition: gloox.h:1189
@ FlagFullyAnonymous
Definition: gloox.h:1191
@ FlagUnsecured
Definition: gloox.h:1190
@ FlagPublic
Definition: gloox.h:1186
const std::string XMLNS_MUC
Definition: gloox.cpp:67
MUCRoomAffiliation affiliation