16 #include "clientbase.h"
20 #include "mucmessagesession.h"
31 static const char* affiliationValues [] = {
40 static const char* roleValues [] = {
50 "maxchars",
"maxstanzas",
"seconds",
"since"
58 static inline MUCRoomRole roleType(
const std::string& type )
60 return static_cast<MUCRoomRole>( util::lookup( type, roleValues ) );
63 MUCRoom::MUCAdmin::MUCAdmin(
MUCRoomRole role,
const std::string& nick,
64 const std::string& reason )
67 m_list.push_back( MUCListItem( nick, role, reason ) );
70 MUCRoom::MUCAdmin::MUCAdmin( MUCRoomAffiliation affiliation,
const std::string& nick,
71 const std::string& reason )
74 m_list.push_back( MUCListItem( nick, affiliation, reason ) );
77 MUCRoom::MUCAdmin::MUCAdmin( MUCOperation operation,
const MUCListItemList& jids )
113 m_list.push_back( MUCListItem( JID() ) );
116 MUCRoom::MUCAdmin::MUCAdmin(
const Tag* tag )
119 if( !tag || tag->name() !=
"query" || tag->xmlns() !=
XMLNS_MUC_ADMIN )
122 const TagList& items = tag->findChildren(
"item" );
123 TagList::const_iterator it = items.begin();
124 for( ; it != items.end(); ++it )
126 m_list.push_back( MUCListItem( JID( (*it)->findAttribute(
"jid" ) ),
127 roleType( (*it)->findAttribute(
"role" ) ),
128 affiliationType( (*it)->findAttribute(
"affiliation" ) ),
129 (*it)->findAttribute(
"nick" ) ) );
131 m_role = roleType( (*it)->findAttribute(
"role" ) );
133 m_affiliation = affiliationType( (*it)->findAttribute(
"affiliation" ) );
137 MUCRoom::MUCAdmin::~MUCAdmin()
141 const std::string& MUCRoom::MUCAdmin::filterString()
const
143 static const std::string filter =
"/iq/query[@xmlns='" +
XMLNS_MUC_ADMIN +
"']";
147 Tag* MUCRoom::MUCAdmin::tag()
const
149 Tag* t =
new Tag(
"query" );
150 t->setXmlns( XMLNS_MUC_ADMIN );
152 if( m_list.empty() || ( m_affiliation == AffiliationInvalid && m_role == RoleInvalid ) )
155 MUCListItemList::const_iterator it = m_list.begin();
156 for( ; it != m_list.end(); ++it )
158 Tag* i =
new Tag( t,
"item" );
160 i->addAttribute(
"jid", (*it).jid().bare() );
161 if( !(*it).nick().empty() )
162 i->addAttribute(
"nick", (*it).nick() );
165 if( (*it).role() != RoleInvalid )
167 else if( m_role != RoleInvalid )
169 if( rol != RoleInvalid )
170 i->addAttribute(
"role", util::lookup( rol, roleValues ) );
173 if( (*it).affiliation() != AffiliationInvalid )
174 aff = (*it).affiliation();
175 else if( m_affiliation != AffiliationInvalid )
177 if( aff != AffiliationInvalid )
178 i->addAttribute(
"affiliation", util::lookup( aff, affiliationValues ) );
179 if( !(*it).reason().empty() )
180 new Tag( i,
"reason", (*it).reason() );
188 MUCRoom::MUCOwner::MUCOwner( QueryType type, DataForm* form )
189 : StanzaExtension(
ExtMUCOwner ), m_type( type ), m_form( form )
198 case TypeCancelConfig:
201 case TypeInstantRoom:
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 )
217 MUCRoom::MUCOwner::MUCOwner(
const Tag* tag )
218 : StanzaExtension(
ExtMUCOwner ), m_type( TypeIncomingTag ), m_form( 0 )
220 if( !tag || tag->name() !=
"query" || tag->xmlns() !=
XMLNS_MUC_OWNER )
223 const TagList& l = tag->children();
224 TagList::const_iterator it = l.begin();
225 for( ; it != l.end(); ++it )
227 const std::string& name = (*it)->name();
230 m_form =
new DataForm( (*it) );
233 else if( name ==
"destroy" )
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" );
245 MUCRoom::MUCOwner::~MUCOwner()
250 const std::string& MUCRoom::MUCOwner::filterString()
const
252 static const std::string filter =
"/iq/query[@xmlns='" +
XMLNS_MUC_OWNER +
"']";
256 Tag* MUCRoom::MUCOwner::tag()
const
261 Tag* t =
new Tag(
"query" );
262 t->setXmlns( XMLNS_MUC_OWNER );
266 case TypeInstantRoom:
268 case TypeCancelConfig:
269 case TypeIncomingTag:
271 t->addChild( m_form->tag() );
275 Tag* d =
new Tag( t,
"destroy" );
277 d->addAttribute(
"jid", m_jid.bare() );
279 if( !m_reason.empty() )
280 new Tag( d,
"reason", m_reason );
283 new Tag( d,
"password", m_pwd );
287 case TypeRequestConfig:
299 const std::string& reason,
const std::string& thread )
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() )
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 )
320 TagList::const_iterator it = l.begin();
321 for( ; it != l.end(); ++it )
323 if( (*it)->name() ==
"item" )
325 m_affiliation = getEnumAffiliation( (*it)->findAttribute(
"affiliation" ) );
326 m_role = getEnumRole( (*it)->findAttribute(
"role" ) );
328 if( (*it)->hasAttribute(
"jid" ) )
329 m_jid =
new std::string( (*it)->findAttribute(
"jid" ) );
331 if( ( t = (*it)->
findChild(
"actor" ) ) )
334 if( ( t = (*it)->
findChild(
"reason" ) ) )
335 m_reason =
new std::string( t->
cdata() );
337 if( (*it)->hasAttribute(
"nick" ) )
338 m_newNick =
new std::string( (*it)->findAttribute(
"nick" ) );
340 else if( (*it)->name() ==
"status" )
342 const std::string& code = (*it)->findAttribute(
"code" );
345 else if( code ==
"101" )
347 else if( code ==
"110" )
349 else if( code ==
"170" )
351 else if( code ==
"201" )
353 else if( code ==
"210" )
355 else if( code ==
"301" )
357 else if( code ==
"303" )
359 else if( code ==
"307" )
361 else if( code ==
"321" )
363 else if( code ==
"322" )
365 else if( code ==
"332" )
368 else if( (*it)->name() ==
"destroy" )
371 if( (*it)->hasAttribute(
"jid" ) )
372 m_alternate =
new std::string( (*it)->findAttribute(
"jid" ) );
374 if( ( t = (*it)->
findChild(
"reason" ) ) )
375 m_reason =
new std::string( t->
cdata() );
379 else if( (*it)->name() ==
"invite" )
382 m_jid =
new std::string( (*it)->findAttribute(
"from" ) );
386 m_jid->assign( (*it)->findAttribute(
"to" ) );
388 if( (*it)->hasChild(
"reason" ) )
389 m_reason =
new std::string( (*it)->findChild(
"reason" )->cdata() );
390 if( (*it)->hasChild(
"continue" ) )
393 m_thread =
new std::string( (*it)->findChild(
"continue" )->findAttribute(
"thread" ) );
396 else if( (*it)->name() ==
"decline" )
399 m_jid =
new std::string( (*it)->findAttribute(
"from" ) );
403 m_jid->assign( (*it)->findAttribute(
"from" ) );
405 if( (*it)->hasChild(
"reason" ) )
406 m_reason =
new std::string( (*it)->findChild(
"reason" )->cdata() );
408 else if( (*it)->name() ==
"password" )
410 m_password =
new std::string( (*it)->cdata() );
428 if(
role ==
"moderator" )
430 if(
role ==
"participant" )
432 if(
role ==
"visitor" )
452 static const std::string filter =
"/presence/x[@xmlns='" +
XMLNS_MUC_USER +
"']"
464 Tag* i =
new Tag( t,
"item" );
468 i->
addAttribute(
"role", util::lookup( m_role, roleValues ) );
470 i->
addAttribute(
"affiliation", util::lookup( m_affiliation, affiliationValues ) );
473 new Tag( i,
"actor",
"jid", *m_actor );
476 new Tag( i,
"reason", *m_reason );
479 new Tag( t,
"status",
"code",
"100" );
481 new Tag( t,
"status",
"code",
"101" );
483 new Tag( t,
"status",
"code",
"110" );
485 new Tag( t,
"status",
"code",
"170" );
487 new Tag( t,
"status",
"code",
"201" );
489 new Tag( t,
"status",
"code",
"210" );
491 new Tag( t,
"status",
"code",
"301" );
493 new Tag( t,
"status",
"code",
"303" );
495 new Tag( t,
"status",
"code",
"307" );
497 new Tag( t,
"status",
"code",
"321" );
499 new Tag( t,
"status",
"code",
"322" );
501 new Tag( t,
"status",
"code",
"332" );
505 Tag* d =
new Tag( t,
"destroy" );
509 new Tag( d,
"reason", *m_reason );
511 else if( m_operation !=
OpNone && m_jid )
515 d =
new Tag( t,
"invite",
"to", *m_jid );
517 d =
new Tag( t,
"invite",
"from", *m_jid );
519 d =
new Tag( t,
"decline",
"to", *m_jid );
521 d =
new Tag( t,
"decline",
"from", *m_jid );
524 new Tag( d,
"reason", *m_reason );
528 Tag* c =
new Tag( d,
"continue" );
534 new Tag( t,
"password", *m_password );
545 const std::string& historySince,
548 m_password( password.empty() ? 0 : new std::string( password ) ),
549 m_historySince( new std::string( historySince ) ),
550 m_historyType( historyType ), m_historyValue( historyValue )
556 m_password( 0 ), m_historySince( 0 ),
563 TagList::const_iterator it = l.begin();
564 for( ; it != l.end(); ++it )
566 if( (*it)->name() ==
"history" )
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" ) );
577 else if( (*it)->name() ==
"password" )
579 m_password =
new std::string( (*it)->cdata() );
587 delete m_historySince;
592 static const std::string filter =
"/presence/x[@xmlns='" +
XMLNS_MUC +
"']";
604 Tag* h =
new Tag( t,
"history" );
612 new Tag( t,
"password", *m_password );
621 : m_parent( parent ), m_nick(
nick ), m_joined( false ), m_roomHandler( mrh ),
622 m_roomConfigHandler( mrch ), m_session( 0 ), m_affiliation(
AffiliationNone ),
624 m_flags( 0 ), m_creationInProgress( false ), m_configChanged( false ),
625 m_publishNick( false ), m_publish( false ), m_unique( false )
657 if( m_joined || !m_parent )
666 pres.
addExtension(
new MUC( m_password, m_historyType, m_historySince, m_historyValue ) );
668 m_parent->
send( pres );
679 m_parent->
send( pres );
693 const std::string&
id = m_parent->
getID();
695 iq.
addExtension(
new MUCOwner( alternate, reason, password ) );
701 if( m_session && m_joined )
702 m_session->
send( message );
707 if( m_session && m_joined )
708 m_session->
send( message, subject, sel );
713 if( m_session && m_joined )
719 if( m_parent && m_joined )
753 if( !m_parent || !m_joined )
758 m_parent->
send( msg );
771 m_publishNick = publishNick;
784 if( !m_joined || !m_parent )
794 m_historyType = type;
796 m_historyValue = value;
802 m_historySince = since;
815 if( !m_parent || !m_joined )
829 const std::string& reason )
856 m_parent->
send( iq,
this, action );
860 const std::string& reason )
890 m_parent->
send( iq,
this, action );
895 if( !m_parent || !m_joined || !m_roomConfigHandler )
900 m_parent->
send( iq,
this, operation );
905 if( !m_parent || !m_joined )
910 m_parent->
send( iq,
this, operation );
915 if( ( presence.
from().
bare() != m_nick.
bare() ) || !m_roomHandler )
920 if( m_newNick.empty() )
945 party.
jid = mu->jid() ?
new JID( *(mu->jid()) ) : 0;
946 party.
actor = mu->actor() ?
new JID( *(mu->actor()) ) : 0;
962 m_creationInProgress =
true;
971 && party.
newNick == m_newNick )
987 void MUCRoom::instantRoom(
int context )
989 if( !m_creationInProgress || !m_parent || !m_joined )
994 ? MUCOwner::TypeInstantRoom : MUCOwner::TypeCancelConfig ) );
996 m_parent->
send( iq,
this, context );
998 m_creationInProgress =
false;
1003 if( !m_parent || !m_joined )
1007 iq.
addExtension(
new MUCOwner( MUCOwner::TypeRequestConfig ) );
1011 if( m_creationInProgress )
1012 m_creationInProgress =
false;
1017 if( !m_parent || !m_joined )
1021 iq.
addExtension(
new MUCOwner( MUCOwner::TypeSendConfig, form ) );
1026 void MUCRoom::setNonAnonymous()
1032 void MUCRoom::setSemiAnonymous()
1038 void MUCRoom::setFullyAnonymous()
1046 if( !m_roomHandler )
1074 setFullyAnonymous();
1082 if( m_roomConfigHandler && df )
1095 bool privMsg =
false;
1109 if( !m_roomConfigHandler )
1115 handleIqResult( iq, context );
1118 handleIqError( iq, context );
1125 void MUCRoom::handleIqResult(
const IQ& iq,
int context )
1178 void MUCRoom::handleIqError(
const IQ& ,
int context )
1219 int oldflags = m_flags;
1226 StringList::const_iterator it = l.begin();
1227 for( ; it != l.end(); ++it )
1229 if( (*it) ==
"muc_hidden" )
1231 else if( (*it) ==
"muc_membersonly" )
1233 else if( (*it) ==
"muc_moderated" )
1235 else if( (*it) ==
"muc_nonanonymous" )
1237 else if( (*it) ==
"muc_open" )
1239 else if( (*it) ==
"muc_passwordprotected" )
1241 else if( (*it) ==
"muc_persistent" )
1243 else if( (*it) ==
"muc_public" )
1245 else if( (*it) ==
"muc_semianonymous" )
1247 else if( (*it) ==
"muc_temporary" )
1249 else if( (*it) ==
"muc_fullyanonymous" )
1250 setFullyAnonymous();
1251 else if( (*it) ==
"muc_unmoderated" )
1253 else if( (*it) ==
"muc_unsecured" )
1259 name = il.front()->name();
1272 if( !m_roomHandler )
1289 if( !m_roomHandler )
1311 const std::string& )
1317 const std::string& node )
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
const std::string getID()
void registerPresenceHandler(PresenceHandler *ph)
virtual Disco * disco() const
void removeIDHandler(IqHandler *ih)
void disposeMessageSession(MessageSession *session)
void registerStanzaExtension(StanzaExtension *ext)
void removePresenceHandler(PresenceHandler *ph)
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.
const StringList & features() const
const DataForm * form() const
const IdentityList & identities() const
An abstraction of a Disco item (Service Discovery, XEP-0030).
An abstraction of a Disco query element (from Service Discovery, XEP-0030) in the disco::items namesp...
const ItemList & items() const
void removeDiscoHandler(DiscoHandler *dh)
void removeNodeHandler(DiscoNodeHandler *nh, const std::string &node)
void getDiscoInfo(const JID &to, const std::string &node, DiscoHandler *dh, int context, const std::string &tid=EmptyString)
void registerNodeHandler(DiscoNodeHandler *nh, const std::string &node)
std::list< Identity * > IdentityList
void getDiscoItems(const JID &to, const std::string &node, DiscoHandler *dh, int context, const std::string &tid=EmptyString)
std::list< Item * > ItemList
A stanza error abstraction implemented as a StanzaExtension.
StanzaError error() const
An abstraction of an IQ stanza.
const std::string & resource() const
const std::string & full() const
const std::string & bare() const
bool setResource(const std::string &resource)
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.
MUCRoomAffiliation affiliation() const
MUCUser(MUCUserOperation operation, const std::string &to, const std::string &reason, const std::string &thread=EmptyString)
virtual const std::string & filterString() const
const std::string * alternate() const
MUCUserOperation operation() const
virtual Tag * tag() const
An abstraction of a MUC query.
virtual const std::string & filterString() const
MUC(const std::string &password, HistoryRequestType historyType=HistoryUnknown, const std::string &historySince=EmptyString, int historyValue=0)
virtual Tag * tag() const
void setPublish(bool publish, bool publishNick)
MUCRoomAffiliation affiliation() const
virtual bool instantRoomHook() const
MUCRoom(ClientBase *parent, const JID &nick, MUCRoomHandler *mrh, MUCRoomConfigHandler *mrch=0)
void setPresence(Presence::PresenceType presence, const std::string &msg=EmptyString)
virtual void handleIqID(const IQ &iq, int context)
void send(const std::string &message)
void setRequestHistory(int value, HistoryRequestType type)
virtual void handleDiscoInfo(const JID &from, const Disco::Info &info, int context)
void acknowledgeInstantRoom()
void requestList(MUCOperation operation)
void setRoomConfig(DataForm *form)
virtual void handlePresence(const Presence &presence)
void setAffiliation(const std::string &nick, MUCRoomAffiliation affiliation, const std::string &reason)
static Message * declineInvitation(const JID &room, const JID &invitor, const std::string &reason=EmptyString)
virtual void join(Presence::PresenceType type=Presence::Available, const std::string &status=EmptyString, int priority=0)
virtual void handleDiscoError(const JID &from, const Error *error, int context)
virtual Disco::ItemList handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node=EmptyString)
virtual void handleDiscoItems(const JID &from, const Disco::Items &items, int context)
void addHistory(const std::string &message, const JID &from, const std::string &stamp)
void destroy(const std::string &reason=EmptyString, const JID &alternate=JID(), const std::string &password=EmptyString)
static Message * createDataForm(const JID &room, const DataForm *df)
void leave(const std::string &msg=EmptyString)
virtual Disco::IdentityList handleDiscoNodeIdentities(const JID &from, const std::string &node)
void setSubject(const std::string &subject)
virtual StringList handleDiscoNodeFeatures(const JID &from, const std::string &node)
void setRole(const std::string &nick, MUCRoomRole role, const std::string &reason=EmptyString)
void storeList(const MUCListItemList items, MUCOperation operation)
void invite(const JID &invitee, const std::string &reason, const std::string &thread=EmptyString)
virtual void handleMessage(const Message &msg, MessageSession *session=0)
const std::string name() const
const std::string nick() const
void setNick(const std::string &nick)
An abstraction of a message session between any two entities.
void registerMessageHandler(MessageHandler *mh)
An abstraction of a message stanza.
const std::string subject(const std::string &lang="default") const
const std::string body(const std::string &lang="default") const
MessageType subtype() const
const DelayedDelivery * when() const
An abstraction of a presence stanza.
PresenceType subtype() const
const std::string status(const std::string &lang="default") const
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
void addExtension(const StanzaExtension *se)
const Error * error() const
const StanzaExtensionList & extensions() const
const StanzaExtension * findExtension(int type) const
This is an abstraction of an XML element.
Tag * findChild(const std::string &name) const
const std::string xmlns() const
bool addAttribute(Attribute *attr)
const std::string cdata() const
const std::string & findAttribute(const std::string &name) const
const std::string & name() const
const TagList & children() const
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
The namespace for the gloox library.
std::list< Tag * > TagList
const std::string XMLNS_MUC_OWNER
std::list< const StanzaExtension * > StanzaExtensionList
std::list< std::string > StringList
const std::string XMLNS_MUC_REQUEST
const char * historyTypeValues[]
const std::string XMLNS_X_DATA
@ UserAffiliationChangedWNR
std::list< MUCListItem > MUCListItemList
const std::string EmptyString
const std::string XMLNS_MUC_USER
const std::string XMLNS_MUC_ADMIN
const std::string XMLNS_MUC_ROOMS
const std::string XMLNS_MUC
MUCRoomAffiliation affiliation