gloox  1.0.23
mucroom.cpp
1 /*
2  Copyright (c) 2006-2019 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" );
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" );
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 ----
619  MUCRoom::MUCRoom( ClientBase* parent, const JID& nick, MUCRoomHandler* mrh,
620  MUCRoomConfigHandler* mrch )
621  : m_parent( parent ), m_nick( nick ), m_joined( false ), m_roomHandler( mrh ),
622  m_roomConfigHandler( mrch ), m_affiliation( AffiliationNone ), m_role( RoleNone ),
623  m_historyType( HistoryUnknown ), m_historyValue( 0 ), m_flags( 0 ),
624  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::setSubject( const std::string& subject )
706  {
707  if( m_session && m_joined )
708  m_session->setSubject( subject );
709  }
710 
711  void MUCRoom::setNick( const std::string& nick )
712  {
713  if( m_parent && m_joined )
714  {
715  m_newNick = nick;
716 
717  Presence p( Presence::Available, m_nick.bare() + "/" + m_newNick );
718  m_parent->send( p );
719  }
720  else
721  m_nick.setResource( nick );
722  }
723 
725  {
726  if( m_parent )
727  m_parent->disco()->getDiscoInfo( m_nick.bare(), EmptyString, this, GetRoomInfo );
728  }
729 
731  {
732  if( m_parent )
733  m_parent->disco()->getDiscoItems( m_nick.bare(), EmptyString, this, GetRoomItems );
734  }
735 
736  void MUCRoom::setPresence( Presence::PresenceType presence, const std::string& msg )
737  {
738  if( m_parent && presence != Presence::Unavailable && m_joined )
739  {
740  Presence p( presence, m_nick.full(), msg );
741  m_parent->send( p );
742  }
743  }
744 
745  void MUCRoom::invite( const JID& invitee, const std::string& reason, const std::string& thread )
746  {
747  if( !m_parent || !m_joined )
748  return;
749 
750  Message msg( Message::Normal, m_nick.bareJID() );
751  msg.addExtension( new MUCUser( OpInviteTo, invitee.bare(), reason, thread ) );
752  m_parent->send( msg );
753  }
754 
755  Message* MUCRoom::declineInvitation( const JID& room, const JID& invitor, const std::string& reason )
756  {
757  Message* msg = new Message( Message::Normal, room.bare() );
758  msg->addExtension( new MUCUser( OpDeclineTo, invitor.bare(), reason ) );
759  return msg;
760  }
761 
762  void MUCRoom::setPublish( bool publish, bool publishNick )
763  {
764  m_publish = publish;
765  m_publishNick = publishNick;
766 
767  if( !m_parent )
768  return;
769 
770  if( m_publish )
771  m_parent->disco()->registerNodeHandler( this, XMLNS_MUC_ROOMS );
772  else
773  m_parent->disco()->removeNodeHandler( this, XMLNS_MUC_ROOMS );
774  }
775 
776  void MUCRoom::addHistory( const std::string& message, const JID& from, const std::string& stamp )
777  {
778  if( !m_joined || !m_parent )
779  return;
780 
781  Message m( Message::Groupchat, m_nick.bareJID(), message );
782  m.addExtension( new DelayedDelivery( from, stamp ) );
783  m_parent->send( m );
784  }
785 
787  {
788  m_historyType = type;
789  m_historySince = EmptyString;
790  m_historyValue = value;
791  }
792 
793  void MUCRoom::setRequestHistory( const std::string& since )
794  {
795  m_historyType = HistorySince;
796  m_historySince = since;
797  m_historyValue = 0;
798  }
799 
800  Message* MUCRoom::createDataForm( const JID& room, const DataForm* df )
801  {
802  Message* m = new Message( Message::Normal, room.bare() );
803  m->addExtension( df );
804  return m;
805  }
806 
808  {
809  if( !m_parent || !m_joined )
810  return;
811 
812  DataForm* df = new DataForm( TypeSubmit );
814  df->addField( DataFormField::TypeTextSingle, "muc#role", "participant", "Requested role" );
815 
816  Message m( Message::Normal, m_nick.bare() );
817  m.addExtension( df );
818 
819  m_parent->send( m );
820  }
821 
822  void MUCRoom::setRole( const std::string& nick, MUCRoomRole role,
823  const std::string& reason )
824  {
825  if( !m_parent || !m_joined || nick.empty() || role == RoleInvalid )
826  return;
827 
829  switch( role )
830  {
831  case RoleNone:
832  action = SetRNone;
833  break;
834  case RoleVisitor:
835  action = SetVisitor;
836  break;
837  case RoleParticipant:
838  action = SetParticipant;
839  break;
840  case RoleModerator:
841  action = SetModerator;
842  break;
843  default:
844  break;
845  }
846 
847  IQ iq( IQ::Set, m_nick.bareJID() );
848  iq.addExtension( new MUCAdmin( role, nick, reason ) );
849 
850  m_parent->send( iq, this, action );
851  }
852 
853  void MUCRoom::setAffiliation( const std::string& nick, MUCRoomAffiliation affiliation,
854  const std::string& reason )
855  {
856  if( !m_parent || !m_joined || nick.empty() || affiliation == AffiliationInvalid )
857  return;
858 
860  switch( affiliation )
861  {
862  case AffiliationOutcast:
863  action = SetOutcast;
864  break;
865  case AffiliationNone:
866  action = SetANone;
867  break;
868  case AffiliationMember:
869  action = SetMember;
870  break;
871  case AffiliationAdmin:
872  action = SetAdmin;
873  break;
874  case AffiliationOwner:
875  action = SetOwner;
876  break;
877  default:
878  break;
879  }
880 
881  IQ iq( IQ::Set, m_nick.bareJID() );
882  iq.addExtension( new MUCAdmin( affiliation, nick, reason ) );
883 
884  m_parent->send( iq, this, action );
885  }
886 
888  {
889  if( !m_parent || !m_joined || !m_roomConfigHandler )
890  return;
891 
892  IQ iq( IQ::Get, m_nick.bareJID() );
893  iq.addExtension( new MUCAdmin( operation ) );
894  m_parent->send( iq, this, operation );
895  }
896 
897  void MUCRoom::storeList( const MUCListItemList items, MUCOperation operation )
898  {
899  if( !m_parent || !m_joined )
900  return;
901 
902  IQ iq( IQ::Set, m_nick.bareJID() );
903  iq.addExtension( new MUCAdmin( operation , items ) );
904  m_parent->send( iq, this, operation );
905  }
906 
907  void MUCRoom::handlePresence( const Presence& presence )
908  {
909  if( ( presence.from().bare() != m_nick.bare() ) || !m_roomHandler )
910  return;
911 
912  if( presence.subtype() == Presence::Error )
913  {
914  if( m_newNick.empty() )
915  {
916  m_parent->removePresenceHandler( m_nick.bareJID(), this );
917  m_parent->disposeMessageSession( m_session );
918  m_joined = false;
919  m_session = 0;
920  }
921  else
922  m_newNick = "";
923 
924  m_roomHandler->handleMUCError( this, presence.error()
925  ? presence.error()->error()
927  }
928  else
929  {
930  const MUCUser* mu = presence.findExtension<MUCUser>( ExtMUCUser );
931  if( !mu )
932  return;
933 
934  MUCRoomParticipant party;
935  party.nick = new JID( presence.from() );
936  party.status = presence.status();
937  party.affiliation = mu->affiliation();
938  party.role = mu->role();
939  party.jid = mu->jid() ? new JID( *(mu->jid()) ) : 0;
940  party.actor = mu->actor() ? new JID( *(mu->actor()) ) : 0;
941  party.reason = mu->reason() ? *(mu->reason()) : EmptyString;
942  party.newNick = mu->newNick() ? *(mu->newNick()) : EmptyString;
943  party.alternate = mu->alternate() ? new JID( *(mu->alternate()) ) : 0;
944  party.flags = mu->flags();
945 
946  if( party.flags & FlagNonAnonymous )
947  setNonAnonymous();
948 
949  if( party.flags & UserSelf )
950  {
951  m_role = party.role;
952  m_affiliation = party.affiliation;
953  }
954  if( party.flags & UserNewRoom )
955  {
956  m_creationInProgress = true;
957  if( instantRoomHook() || m_roomHandler->handleMUCRoomCreation( this ) )
959  }
960  if( party.flags & UserNickAssigned )
961  m_nick.setResource( presence.from().resource() );
962 
963  if( party.flags & UserNickChanged && !party.newNick.empty()
964  && m_nick.resource() == presence.from().resource()
965  && party.newNick == m_newNick )
966  party.flags |= UserSelf;
967 
968  if( party.flags & UserNickChanged && party.flags & UserSelf && !party.newNick.empty() )
969  m_nick.setResource( party.newNick );
970 
971  if( m_roomHandler )
972  m_roomHandler->handleMUCParticipantPresence( this, party, presence );
973 
974  delete party.nick;
975  delete party.jid;
976  delete party.actor;
977  delete party.alternate;
978  }
979  }
980 
981  void MUCRoom::instantRoom( int context )
982  {
983  if( !m_creationInProgress || !m_parent || !m_joined )
984  return;
985 
986  IQ iq( IQ::Set, m_nick.bareJID() );
987  iq.addExtension( new MUCOwner( context == CreateInstantRoom
988  ? MUCOwner::TypeInstantRoom : MUCOwner::TypeCancelConfig ) );
989 
990  m_parent->send( iq, this, context );
991 
992  m_creationInProgress = false;
993  }
994 
996  {
997  if( !m_parent || !m_joined )
998  return;
999 
1000  IQ iq( IQ::Get, m_nick.bareJID() );
1001  iq.addExtension( new MUCOwner( MUCOwner::TypeRequestConfig ) );
1002 
1003  m_parent->send( iq, this, RequestRoomConfig );
1004 
1005  if( m_creationInProgress )
1006  m_creationInProgress = false;
1007  }
1008 
1010  {
1011  if( !m_parent || !m_joined )
1012  return;
1013 
1014  IQ iq( IQ::Set, m_nick.bareJID() );
1015  iq.addExtension( new MUCOwner( MUCOwner::TypeSendConfig, form ) );
1016 
1017  m_parent->send( iq, this, SendRoomConfig );
1018  }
1019 
1020  void MUCRoom::setNonAnonymous()
1021  {
1022  m_flags |= FlagNonAnonymous;
1023  m_flags &= ~( FlagSemiAnonymous | FlagFullyAnonymous );
1024  }
1025 
1026  void MUCRoom::setSemiAnonymous()
1027  {
1028  m_flags &= ~( FlagNonAnonymous | FlagFullyAnonymous );
1029  m_flags |= FlagSemiAnonymous;
1030  }
1031 
1032  void MUCRoom::setFullyAnonymous()
1033  {
1034  m_flags &= ~( FlagNonAnonymous | FlagSemiAnonymous );
1035  m_flags |= FlagFullyAnonymous;
1036  }
1037 
1038  void MUCRoom::handleMessage( const Message& msg, MessageSession* /*session*/ )
1039  {
1040  if( !m_roomHandler )
1041  return;
1042 
1043  if( msg.subtype() == Message::Error )
1044  {
1045  m_roomHandler->handleMUCError( this, msg.error() ? msg.error()->error() : StanzaErrorUndefined );
1046  }
1047  else
1048  {
1049  const MUCUser* mu = msg.findExtension<MUCUser>( ExtMUCUser );
1050  if( mu )
1051  {
1052  const int flags = mu->flags();
1053  if( flags & FlagNonAnonymous )
1054  setNonAnonymous();
1055  if( flags & FlagPublicLogging )
1056  {
1057  m_flags &= ~FlagPublicLoggingOff;
1058  m_flags |= FlagPublicLogging;
1059  }
1060  if( flags & FlagPublicLoggingOff )
1061  {
1062  m_flags &= ~FlagPublicLogging;
1063  m_flags |= FlagPublicLoggingOff;
1064  }
1065  if( flags & FlagSemiAnonymous )
1066  setSemiAnonymous();
1067  if( flags & FlagFullyAnonymous )
1068  setFullyAnonymous();
1069 
1070  if( mu->operation() == OpDeclineFrom && mu->jid() )
1071  m_roomHandler->handleMUCInviteDecline( this, JID( *(mu->jid()) ),
1072  mu->reason() ? *(mu->reason()) : EmptyString );
1073  }
1074 
1075  const DataForm* df = msg.findExtension<DataForm>( ExtDataForm );
1076  if( m_roomConfigHandler && df )
1077  {
1078  m_roomConfigHandler->handleMUCRequest( this, *df );
1079  return;
1080  }
1081 
1082  if( !msg.subject().empty() )
1083  {
1084  m_roomHandler->handleMUCSubject( this, msg.from().resource(), msg.subject() );
1085  }
1086  else if( !msg.body().empty() || !msg.extensions().empty() )
1087  {
1088  std::string when;
1089  bool privMsg = false;
1090  if( msg.when() )
1091  when = msg.when()->stamp();
1092 
1093  if( msg.subtype() & ( Message::Chat | Message::Normal ) )
1094  privMsg = true;
1095 
1096  m_roomHandler->handleMUCMessage( this, msg, privMsg );
1097  }
1098  }
1099  }
1100 
1101  void MUCRoom::handleIqID( const IQ& iq, int context )
1102  {
1103  if( !m_roomConfigHandler )
1104  return;
1105 
1106  switch( iq.subtype() )
1107  {
1108  case IQ::Result:
1109  handleIqResult( iq, context );
1110  break;
1111  case IQ::Error:
1112  handleIqError( iq, context );
1113  break;
1114  default:
1115  break;
1116  }
1117  }
1118 
1119  void MUCRoom::handleIqResult( const IQ& iq, int context )
1120  {
1121  switch( context )
1122  {
1123  case SetRNone:
1124  case SetVisitor:
1125  case SetParticipant:
1126  case SetModerator:
1127  case SetANone:
1128  case SetOutcast:
1129  case SetMember:
1130  case SetAdmin:
1131  case SetOwner:
1132  case CreateInstantRoom:
1133  case CancelRoomCreation:
1134  case SendRoomConfig:
1135  case DestroyRoom:
1136  case StoreVoiceList:
1137  case StoreBanList:
1138  case StoreMemberList:
1139  case StoreModeratorList:
1140  case StoreAdminList:
1141  m_roomConfigHandler->handleMUCConfigResult( this, true, static_cast<MUCOperation>( context ) );
1142  break;
1143  case RequestRoomConfig:
1144  {
1145  const MUCOwner* mo = iq.findExtension<MUCOwner>( ExtMUCOwner );
1146  if( !mo )
1147  break;
1148 
1149  if( mo->form() )
1150  m_roomConfigHandler->handleMUCConfigForm( this, *(mo->form()) );
1151  break;
1152  }
1153  case RequestVoiceList:
1154  case RequestBanList:
1155  case RequestMemberList:
1156  case RequestModeratorList:
1157  case RequestOwnerList:
1158  case RequestAdminList:
1159  {
1160  const MUCAdmin* ma = iq.findExtension<MUCAdmin>( ExtMUCAdmin );
1161  if( !ma )
1162  break;
1163 
1164  m_roomConfigHandler->handleMUCConfigList( this, ma->list(), static_cast<MUCOperation>( context ) );
1165  break;
1166  }
1167  default:
1168  break;
1169  }
1170  }
1171 
1172  void MUCRoom::handleIqError( const IQ& /*iq*/, int context )
1173  {
1174  switch( context )
1175  {
1176  case SetRNone:
1177  case SetVisitor:
1178  case SetParticipant:
1179  case SetModerator:
1180  case SetANone:
1181  case SetOutcast:
1182  case SetMember:
1183  case SetAdmin:
1184  case SetOwner:
1185  case CreateInstantRoom:
1186  case CancelRoomCreation:
1187  case RequestRoomConfig:
1188  case SendRoomConfig:
1189  case DestroyRoom:
1190  case RequestVoiceList:
1191  case StoreVoiceList:
1192  case RequestBanList:
1193  case StoreBanList:
1194  case RequestMemberList:
1195  case StoreMemberList:
1196  case RequestModeratorList:
1197  case StoreModeratorList:
1198  case RequestOwnerList:
1199  case StoreOwnerList:
1200  case RequestAdminList:
1201  case StoreAdminList:
1202  m_roomConfigHandler->handleMUCConfigResult( this, false, static_cast<MUCOperation>( context ) );
1203  break;
1204  }
1205  }
1206 
1207  void MUCRoom::handleDiscoInfo( const JID& /*from*/, const Disco::Info& info, int context )
1208  {
1209  switch( context )
1210  {
1211  case GetRoomInfo:
1212  {
1213  int oldflags = m_flags;
1214  m_flags = 0;
1215  if( oldflags & FlagPublicLogging )
1216  m_flags |= FlagPublicLogging;
1217 
1218  std::string name;
1219  const StringList& l = info.features();
1220  StringList::const_iterator it = l.begin();
1221  for( ; it != l.end(); ++it )
1222  {
1223  if( (*it) == "muc_hidden" )
1224  m_flags |= FlagHidden;
1225  else if( (*it) == "muc_membersonly" )
1226  m_flags |= FlagMembersOnly;
1227  else if( (*it) == "muc_moderated" )
1228  m_flags |= FlagModerated;
1229  else if( (*it) == "muc_nonanonymous" )
1230  setNonAnonymous();
1231  else if( (*it) == "muc_open" )
1232  m_flags |= FlagOpen;
1233  else if( (*it) == "muc_passwordprotected" )
1234  m_flags |= FlagPasswordProtected;
1235  else if( (*it) == "muc_persistent" )
1236  m_flags |= FlagPersistent;
1237  else if( (*it) == "muc_public" )
1238  m_flags |= FlagPublic;
1239  else if( (*it) == "muc_semianonymous" )
1240  setSemiAnonymous();
1241  else if( (*it) == "muc_temporary" )
1242  m_flags |= FlagTemporary;
1243  else if( (*it) == "muc_fullyanonymous" )
1244  setFullyAnonymous();
1245  else if( (*it) == "muc_unmoderated" )
1246  m_flags |= FlagUnmoderated;
1247  else if( (*it) == "muc_unsecured" )
1248  m_flags |= FlagUnsecured;
1249  }
1250 
1251  const Disco::IdentityList& il = info.identities();
1252  if( il.size() )
1253  name = il.front()->name();
1254 
1255  if( m_roomHandler )
1256  m_roomHandler->handleMUCInfo( this, m_flags, name, info.form() );
1257  break;
1258  }
1259  default:
1260  break;
1261  }
1262  }
1263 
1264  void MUCRoom::handleDiscoItems( const JID& /*from*/, const Disco::Items& items, int context )
1265  {
1266  if( !m_roomHandler )
1267  return;
1268 
1269  switch( context )
1270  {
1271  case GetRoomItems:
1272  {
1273  m_roomHandler->handleMUCItems( this, items.items() );
1274  break;
1275  }
1276  default:
1277  break;
1278  }
1279  }
1280 
1281  void MUCRoom::handleDiscoError( const JID& /*from*/, const Error* /*error*/, int context )
1282  {
1283  if( !m_roomHandler )
1284  return;
1285 
1286  switch( context )
1287  {
1288  case GetRoomInfo:
1289  m_roomHandler->handleMUCInfo( this, 0, EmptyString, 0 );
1290  break;
1291  case GetRoomItems:
1292  m_roomHandler->handleMUCItems( this, Disco::ItemList() );
1293  break;
1294  default:
1295  break;
1296  }
1297  }
1298 
1299  StringList MUCRoom::handleDiscoNodeFeatures( const JID& /*from*/, const std::string& /*node*/ )
1300  {
1301  return StringList();
1302  }
1303 
1305  const std::string& /*node*/ )
1306  {
1307  return Disco::IdentityList();
1308  }
1309 
1310  Disco::ItemList MUCRoom::handleDiscoNodeItems( const JID& /*from*/, const JID& /*to*/,
1311  const std::string& node )
1312  {
1313  Disco::ItemList l;
1314  if( node == XMLNS_MUC_ROOMS && m_publish )
1315  {
1316  l.push_back( new Disco::Item( m_nick.bareJID(), EmptyString,
1317  m_publishNick ? m_nick.resource() : EmptyString ) );
1318  }
1319  return l;
1320  }
1321 
1322 }
virtual void handleMUCRequest(MUCRoom *room, const DataForm &form)=0
An abstraction of a MUC user query.
Definition: mucroom.h:201
void setNick(const std::string &nick)
Definition: mucroom.cpp:711
void addHistory(const std::string &message, const JID &from, const std::string &stamp)
Definition: mucroom.cpp:776
An abstraction of a Disco query element (from Service Discovery, XEP-0030) in the disco::items namesp...
Definition: disco.h:275
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition: tag.cpp:522
bool setResource(const std::string &resource)
Definition: jid.cpp:64
const std::string XMLNS_MUC_REQUEST
Definition: gloox.cpp:75
void setRole(const std::string &nick, MUCRoomRole role, const std::string &reason=EmptyString)
Definition: mucroom.cpp:822
std::list< Item * > ItemList
Definition: disco.h:261
const DelayedDelivery * when() const
Definition: message.h:131
MessageType subtype() const
Definition: message.h:76
void removeIDHandler(IqHandler *ih)
virtual const std::string & filterString() const
Definition: mucroom.cpp:590
void requestRoomConfig()
Definition: mucroom.cpp:995
const StanzaExtension * findExtension(int type) const
Definition: stanza.cpp:57
An abstraction of a message session between any two entities.
This interface enables inheriting classes to be notified about certain events in a MUC room...
virtual void handleMUCInviteDecline(MUCRoom *room, const JID &invitee, const std::string &reason)=0
An abstraction of a MUC query.
Definition: mucroom.h:127
std::list< std::string > StringList
Definition: gloox.h:1251
void setSubject(const std::string &subject)
Definition: mucroom.cpp:705
void invite(const JID &invitee, const std::string &reason, const std::string &thread=EmptyString)
Definition: mucroom.cpp:745
const std::string & stamp() const
const std::string xmlns() const
Definition: tag.cpp:543
An abstraction of an IQ stanza.
Definition: iq.h:33
const StanzaExtensionList & extensions() const
Definition: stanza.h:113
An abstraction of a XEP-0004 Data Form.
Definition: dataform.h:56
const std::string * alternate() const
Definition: mucroom.h:279
void getDiscoItems(const JID &to, const std::string &node, DiscoHandler *dh, int context, const std::string &tid=EmptyString)
Definition: disco.h:466
void addExtension(const StanzaExtension *se)
Definition: stanza.cpp:52
void removeDiscoHandler(DiscoHandler *dh)
Definition: disco.cpp:481
This is an implementation of XEP-0203 (Delayed Delivery).
std::list< Identity * > IdentityList
Definition: disco.h:51
void send(Tag *tag)
static Message * declineInvitation(const JID &room, const JID &invitor, const std::string &reason=EmptyString)
Definition: mucroom.cpp:755
virtual void handleMUCSubject(MUCRoom *room, const std::string &nick, const std::string &subject)=0
virtual void addField(DataFormField *field)
virtual void handleMUCMessage(MUCRoom *room, const Message &msg, bool priv)=0
virtual bool handleMUCRoomCreation(MUCRoom *room)=0
const StringList & features() const
Definition: disco.h:80
STL namespace.
void registerStanzaExtension(StanzaExtension *ext)
MUCRoomRole role() const
Definition: mucroom.h:243
virtual void handleMUCConfigResult(MUCRoom *room, bool success, MUCOperation operation)=0
const std::string & bare() const
Definition: jid.h:67
std::list< Tag * > TagList
Definition: tag.h:26
IqType subtype() const
Definition: iq.h:74
const ItemList & items() const
Definition: disco.h:311
void removeNodeHandler(DiscoNodeHandler *nh, const std::string &node)
Definition: disco.cpp:502
MUCUserOperation operation() const
Definition: mucroom.h:291
void registerMessageHandler(MessageHandler *mh)
const std::string nick() const
Definition: mucroom.h:389
const std::string & name() const
Definition: tag.h:394
void storeList(const MUCListItemList items, MUCOperation operation)
Definition: mucroom.cpp:897
virtual const std::string & filterString() const
Definition: mucroom.cpp:450
void send(const std::string &message)
Definition: mucroom.cpp:699
virtual Tag * tag() const
Definition: mucroom.cpp:596
Tag * findChild(const std::string &name) const
Definition: tag.cpp:624
virtual void handleDiscoError(const JID &from, const Error *error, int context)
Definition: mucroom.cpp:1281
const std::string status(const std::string &lang="default") const
Definition: presence.h:106
A stanza error abstraction implemented as a StanzaExtension.
Definition: error.h:34
const DataForm * form() const
Definition: disco.h:99
An abstraction of a presence stanza.
Definition: presence.h:32
This is a MessageSession, adapted to be used in a MUC context.
const std::string body(const std::string &lang="default") const
Definition: message.h:87
TagList findChildren(const std::string &name, const std::string &xmlns=EmptyString) const
Definition: tag.cpp:714
virtual void handleMUCError(MUCRoom *room, StanzaError error)=0
virtual void handleMUCItems(MUCRoom *room, const Disco::ItemList &items)=0
virtual void handleDiscoItems(const JID &from, const Disco::Items &items, int context)
Definition: mucroom.cpp:1264
virtual Disco::ItemList handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node=EmptyString)
Definition: mucroom.cpp:1310
void addChild(Tag *child)
Definition: tag.cpp:424
const std::string XMLNS_X_DATA
Definition: gloox.cpp:49
virtual void handleMessage(const Message &msg, MessageSession *session=0)
Definition: mucroom.cpp:1038
An abstraction of a message stanza.
Definition: message.h:33
void registerNodeHandler(DiscoNodeHandler *nh, const std::string &node)
Definition: disco.cpp:497
virtual void setSubject(const std::string &subject)
void setPublish(bool publish, bool publishNick)
Definition: mucroom.cpp:762
void setRoomConfig(DataForm *form)
Definition: mucroom.cpp:1009
const IdentityList & identities() const
Definition: disco.h:93
void setRequestHistory(int value, HistoryRequestType type)
Definition: mucroom.cpp:786
const std::string XMLNS_MUC_ADMIN
Definition: gloox.cpp:69
std::list< MUCListItem > MUCListItemList
static Message * createDataForm(const JID &room, const DataForm *df)
Definition: mucroom.cpp:800
const std::string XMLNS_MUC_USER
Definition: gloox.cpp:68
The namespace for the gloox library.
Definition: adhoc.cpp:27
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
const Error * error() const
Definition: stanza.cpp:47
const std::string & full() const
Definition: jid.h:61
virtual void join(Presence::PresenceType type=Presence::Available, const std::string &status=EmptyString, int priority=0)
Definition: mucroom.cpp:655
void getRoomItems()
Definition: mucroom.cpp:730
MUC(const std::string &password, HistoryRequestType historyType=HistoryUnknown, const std::string &historySince=EmptyString, int historyValue=0)
Definition: mucroom.cpp:543
int flags() const
Definition: mucroom.h:732
virtual void send(const std::string &message)
virtual Disco::IdentityList handleDiscoNodeIdentities(const JID &from, const std::string &node)
Definition: mucroom.cpp:1304
virtual void handleMUCConfigForm(MUCRoom *room, const DataForm &form)=0
void disposeMessageSession(MessageSession *session)
PresenceType subtype() const
Definition: presence.h:76
MUCUser(MUCUserOperation operation, const std::string &to, const std::string &reason, const std::string &thread=EmptyString)
Definition: mucroom.cpp:298
An abstraction of a JID.
Definition: jid.h:30
void setAffiliation(const std::string &nick, MUCRoomAffiliation affiliation, const std::string &reason)
Definition: mucroom.cpp:853
void removePresenceHandler(PresenceHandler *ph)
MUCRoom(ClientBase *parent, const JID &nick, MUCRoomHandler *mrh, MUCRoomConfigHandler *mrch=0)
Definition: mucroom.cpp:619
bool addAttribute(Attribute *attr)
Definition: tag.cpp:354
An abstraction of a Disco Info element (from Service Discovery, XEP-0030) as a StanzaExtension.
Definition: disco.h:65
const std::string & resource() const
Definition: jid.h:116
void requestList(MUCOperation operation)
Definition: mucroom.cpp:887
const JID & from() const
Definition: stanza.h:51
void registerPresenceHandler(PresenceHandler *ph)
virtual void handleMUCParticipantPresence(MUCRoom *room, const MUCRoomParticipant participant, const Presence &presence)=0
An abstraction of a Disco item (Service Discovery, XEP-0030).
Definition: disco.h:352
virtual void handlePresence(const Presence &presence)
Definition: mucroom.cpp:907
void requestVoice()
Definition: mucroom.cpp:807
int flags() const
Definition: mucroom.h:231
virtual bool instantRoomHook() const
Definition: mucroom.h:778
virtual ~MUCRoom()
Definition: mucroom.cpp:637
void getDiscoInfo(const JID &to, const std::string &node, DiscoHandler *dh, int context, const std::string &tid=EmptyString)
Definition: disco.h:451
const std::string getID()
const std::string & findAttribute(const std::string &name) const
Definition: tag.cpp:589
void acknowledgeInstantRoom()
Definition: mucroom.h:665
const std::string name() const
Definition: mucroom.h:376
StanzaError error() const
Definition: error.h:75
const std::string XMLNS_MUC_ROOMS
Definition: gloox.cpp:74
const TagList & children() const
Definition: tag.cpp:510
const std::string cdata() const
Definition: tag.cpp:497
const std::string XMLNS_MUC_OWNER
Definition: gloox.cpp:72
void getRoomInfo()
Definition: mucroom.cpp:724
virtual void handleIqID(const IQ &iq, int context)
Definition: mucroom.cpp:1101
void destroy(const std::string &reason=EmptyString, const JID &alternate=JID(), const std::string &password=EmptyString)
Definition: mucroom.cpp:688
virtual void handleDiscoInfo(const JID &from, const Disco::Info &info, int context)
Definition: mucroom.cpp:1207
const char * historyTypeValues[]
Definition: mucroom.cpp:48
void leave(const std::string &msg=EmptyString)
Definition: mucroom.cpp:671
JID bareJID() const
Definition: jid.h:74
virtual Disco * disco() const
Definition: clientbase.h:233
MUCRoomAffiliation affiliation() const
Definition: mucroom.h:237
const std::string subject(const std::string &lang="default") const
Definition: message.h:101
virtual void handleMUCConfigList(MUCRoom *room, const MUCListItemList &items, MUCOperation operation)=0
virtual void handleMUCInfo(MUCRoom *room, int features, const std::string &name, const DataForm *infoForm)=0
virtual Tag * tag() const
Definition: mucroom.cpp:457
const std::string EmptyString
Definition: gloox.cpp:124
MUCRoomAffiliation affiliation
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
Definition: clientbase.h:76
This is an abstraction of an XML element.
Definition: tag.h:46
MUCRoomAffiliation
Definition: gloox.h:1150
void setPresence(Presence::PresenceType presence, const std::string &msg=EmptyString)
Definition: mucroom.cpp:736
virtual StringList handleDiscoNodeFeatures(const JID &from, const std::string &node)
Definition: mucroom.cpp:1299
const std::string XMLNS_MUC
Definition: gloox.cpp:67
MUCRoomRole
Definition: gloox.h:1163
An abstract interface that can be implemented for MUC room configuration.