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 #ifndef MUCROOM_H__ 16 #define MUCROOM_H__ 17 18 #include "discohandler.h" 19 #include "disconodehandler.h" 20 #include "dataform.h" 21 #include "presencehandler.h" 22 #include "iqhandler.h" 23 #include "messagehandler.h" 24 #include "mucroomhandler.h" 25 #include "mucroomconfighandler.h" 26 #include "jid.h" 27 #include "stanzaextension.h" 28 29 #include <string> 30 31 namespace gloox 32 { 33 34 class ClientBase; 35 class MUCMessageSession; 36 class Message; 37 38 /** 39 * @brief This is an implementation of @xep{0045} (Multi-User Chat). 40 * 41 * Usage is pretty simple: 42 * 43 * Derrive an object from MUCRoomHandler and implement its virtuals: 44 * @code 45 * class MyClass : public MUCRoomHandler 46 * { 47 * ... 48 * }; 49 * @endcode 50 * 51 * Then create a new MUCRoom object and pass it a valid ClientBase, the desired full room JID, 52 * your MUCRoomHandler-derived object, and an optional MUCRoomConfigHandler-derived object. 53 * @code 54 * void MyOtherClass::joinRoom( const std::string& room, const std::string& service, 55 * const std::string& nick ) 56 * { 57 * MyClass* myHandler = new MyClass(...); 58 * JID roomJID( room + "@" + service + "/" + nick ); 59 * m_room = new MUCRoom( m_clientbase, roomJID, myHandler, 0 ); 60 * m_room->join(); 61 * } 62 * @endcode 63 * 64 * When joining the room was successful, the various MUCRoomHandler functions will start to 65 * be called. If joining was not successful, MUCRoomHandler::handleMUCError() will be called, 66 * giving a hint at the reason for the failure. 67 * 68 * To set up your own room, or to configure an existing room, you should also derive a 69 * class from MUCRoomConfigHandler and register it with the MUCRoom (either by using it 70 * with MUCRoom's constructor, or by calling registerMUCRoomConfigHandler()). 71 * 72 * To quickly create an instant room, see InstantMUCRoom. 73 * 74 * To quickly create an instant room to turn a one-to-one chat into a multi-user chat, 75 * see UniqueMUCRoom. 76 * 77 * To send a private message to a room participant, use 78 * @link MessageSession gloox::MessageSession @endlink with the participant's full room JID 79 * (room\@service/nick). 80 * 81 * XEP version: 1.21 82 * @author Jakob Schröter <js@camaya.net> 83 * @since 0.9 84 */ 85 class GLOOX_API MUCRoom : private DiscoHandler, private PresenceHandler, 86 public IqHandler, private MessageHandler, private DiscoNodeHandler 87 { 88 public: 89 /** 90 * Allowable history request types. To disable sending of history, use any value except 91 * HistoryUnknown and specify a zero-length time span (using setRequestHistory()). 92 */ 93 enum HistoryRequestType 94 { 95 HistoryMaxChars, /**< Limit the total number of characters in the history to "X" 96 * (where the character count is the characters of the complete 97 * XML stanzas, not only their XML character data). */ 98 HistoryMaxStanzas, /**< Limit the total number of messages in the history to "X". */ 99 HistorySeconds, /**< Send only the messages received in the last "X" seconds. */ 100 HistorySince, /**< Send only the messages received since the datetime specified 101 * (which MUST conform to the DateTime profile specified in Jabber 102 * Date and Time Profiles (@xep{0082})). */ 103 HistoryUnknown /**< It is up to the service to decide how much history to send. 104 * This is the default. */ 105 }; 106 107 /** 108 * Available operations. 109 */ 110 enum MUCUserOperation 111 { 112 OpNone, /**< No operation. */ 113 OpInviteTo, /**< Invitation being sent to soemone. */ 114 OpInviteFrom, /**< Invitation received from someone. */ 115 OpDeclineTo, /**< Someone's invitation declined. */ 116 OpDeclineFrom /**< Someone declined an invitation. */ 117 }; 118 119 /** 120 * @brief An abstraction of a MUC query. 121 * 122 * You should not need to use this class directly. 123 * 124 * @author Jakob Schröter <js@camaya.net> 125 * @since 1.0 126 */ 127 class MUC : public StanzaExtension 128 { 129 public: 130 /** 131 * Creates a new MUC object. 132 * @param password An optional room password. 133 * @param historyType The type of room history to request. 134 * @param historySince A string describing the amount of room history. 135 * @param historyValue The amount of requested room history. 136 */ 137 MUC( const std::string& password, HistoryRequestType historyType = HistoryUnknown, 138 const std::string& historySince = EmptyString, int historyValue = 0 ); 139 140 /** 141 * Constructs a new MUCUser object from the given Tag. 142 * @param tag The Tag to parse. 143 */ 144 MUC( const Tag* tag = 0 ); 145 146 /** 147 * Virtual destructor. 148 */ 149 virtual ~MUC(); 150 151 /** 152 * Returns a pointer to the current password, or 0. 153 * @return A pointer to the current password, or 0. 154 */ password()155 const std::string* password() const { return m_password; } 156 157 /** 158 * Returns a pointer to the description of the amount of room history requested. 159 * @return A pointer to the description of the amount of room history requested. 160 */ historySince()161 const std::string* historySince() const { return m_historySince; } 162 163 // reimplemented from StanzaExtension 164 virtual const std::string& filterString() const; 165 166 // reimplemented from StanzaExtension newInstance(const Tag * tag)167 virtual StanzaExtension* newInstance( const Tag* tag ) const 168 { 169 return new MUC( tag ); 170 } 171 172 // reimplemented from StanzaExtension 173 virtual Tag* tag() const; 174 175 // reimplemented from StanzaExtension clone()176 virtual StanzaExtension* clone() const 177 { 178 MUC* m = new MUC(); 179 m->m_password = m_password ? new std::string( *m_password ) : 0; 180 m->m_historySince = m_historySince ? new std::string( *m_historySince ) : 0; 181 m->m_historyType = m_historyType; 182 m->m_historyValue = m_historyValue; 183 return m; 184 } 185 186 private: 187 std::string* m_password; 188 std::string* m_historySince; 189 HistoryRequestType m_historyType; 190 int m_historyValue; 191 }; 192 193 /** 194 * @brief An abstraction of a MUC user query. 195 * 196 * You should not need to use this class directly. 197 * 198 * @author Jakob Schröter <js@camaya.net> 199 * @since 1.0 200 */ 201 class MUCUser : public StanzaExtension 202 { 203 public: 204 /** 205 * Constructor. 206 * @param operation An operation to perform. 207 * @param to The recipient. 208 * @param reason The reason for the operation. 209 * @param thread If this is an invitation, and if the invitation is part of 210 * a transformation of a one-to-one chat to a MUC, include the one-to-one chat's 211 * thread ID here. Defaults to the empty string (i.e. not a continuation). 212 */ 213 MUCUser( MUCUserOperation operation, const std::string& to, const std::string& reason, 214 const std::string& thread = EmptyString ); 215 216 /** 217 * Constructs a new MUCUser object from the given Tag. 218 * @param tag The Tag to parse. 219 */ 220 MUCUser( const Tag* tag = 0 ); 221 222 /** 223 * Virtual destructor. 224 */ 225 virtual ~MUCUser(); 226 227 /** 228 * Returns the current room flags. 229 * @return The current room flags. 230 */ flags()231 int flags() const { return m_flags; } 232 233 /** 234 * Returns the user's current room affiliation. 235 * @return The user's current room affiliation. 236 */ affiliation()237 MUCRoomAffiliation affiliation() const { return m_affiliation; } 238 239 /** 240 * Returns the user's current room role. 241 * @return The user's current room role. 242 */ role()243 MUCRoomRole role() const { return m_role; } 244 245 /** 246 * 247 */ jid()248 const std::string* jid() const { return m_jid; } 249 250 /** 251 * 252 */ actor()253 const std::string* actor() const { return m_actor; } 254 255 /** 256 * 257 */ password()258 const std::string* password() const { return m_password; } 259 260 /** 261 * 262 */ thread()263 const std::string* thread() const { return m_thread; } 264 265 /** 266 * 267 */ reason()268 const std::string* reason() const { return m_reason; } 269 270 /** 271 * 272 */ newNick()273 const std::string* newNick() const { return m_newNick; } 274 275 /** 276 * Returns an alternate venue, if set. 277 * @return An alternate venue, if set. 278 */ alternate()279 const std::string* alternate() const { return m_alternate; } 280 281 /** 282 * Whether or not the 'continue' flag is set. 283 * @return Whether or not the 'continue' flag is set. 284 */ continued()285 bool continued() const { return m_continue; } 286 287 /** 288 * Returns the current operation. 289 * @return The current operation. 290 */ operation()291 MUCUserOperation operation() const { return m_operation; } 292 293 // reimplemented from StanzaExtension 294 virtual const std::string& filterString() const; 295 296 // reimplemented from StanzaExtension newInstance(const Tag * tag)297 virtual StanzaExtension* newInstance( const Tag* tag ) const 298 { 299 return new MUCUser( tag ); 300 } 301 302 // reimplemented from StanzaExtension 303 virtual Tag* tag() const; 304 305 // reimplemented from StanzaExtension clone()306 virtual StanzaExtension* clone() const 307 { 308 MUCUser* m = new MUCUser(); 309 m->m_affiliation = m_affiliation; 310 m->m_role = m_role; 311 m->m_jid = m_jid ? new std::string( *m_jid ) : 0; 312 m->m_actor = m_actor ? new std::string( *m_actor ) : 0; 313 m->m_thread = m_thread ? new std::string( *m_thread ) : 0; 314 m->m_reason = m_reason ? new std::string( *m_reason ) : 0; 315 m->m_newNick = m_newNick ? new std::string( *m_newNick ) : 0; 316 m->m_password = m_password ? new std::string( *m_password ) : 0; 317 m->m_alternate = m_alternate ? new std::string( *m_alternate ) : 0; 318 m->m_operation = m_operation; 319 m->m_flags = m_flags; 320 m->m_del = m_del; 321 m->m_continue = m_continue; 322 return m; 323 } 324 325 private: 326 static MUCRoomAffiliation getEnumAffiliation( const std::string& affiliation ); 327 static MUCRoomRole getEnumRole( const std::string& role ); 328 329 330 MUCRoomAffiliation m_affiliation; 331 MUCRoomRole m_role; 332 std::string* m_jid; 333 std::string* m_actor; 334 std::string* m_thread; 335 std::string* m_reason; 336 std::string* m_newNick; 337 std::string* m_password; 338 std::string* m_alternate; 339 MUCUserOperation m_operation; 340 int m_flags; 341 bool m_del; 342 bool m_continue; 343 }; 344 345 /** 346 * Creates a new abstraction of a Multi-User Chat room. The room is not joined automatically. 347 * Use join() to join the room, use leave() to leave it. 348 * @param parent The ClientBase object to use for the communication. 349 * @param nick The room's name and service plus the desired nickname in the form 350 * room\@service/nick. 351 * @param mrh The MUCRoomHandler that will listen to room events. May be 0 and may be specified 352 * later using registerMUCRoomHandler(). However, without one, MUC is no joy. 353 * @param mrch The MUCRoomConfigHandler that will listen to room config result. Defaults to 0 354 * initially. However, at the latest you need one when you create a new room which is not an 355 * instant room. You can set a MUCRoomConfigHandler using registerMUCRoomConfigHandler(). 356 */ 357 MUCRoom( ClientBase* parent, const JID& nick, MUCRoomHandler* mrh, MUCRoomConfigHandler* mrch = 0 ); 358 359 /** 360 * Virtual Destructor. 361 */ 362 virtual ~MUCRoom(); 363 364 /** 365 * Use this function to set a password to use when joining a (password protected) 366 * room. 367 * @param password The password to use for this room. 368 * @note This function does not password-protect a room. 369 */ setPassword(const std::string & password)370 void setPassword( const std::string& password ) { m_password = password; } 371 372 /** 373 * A convenience function that returns the room's name. 374 * @return The room's name. 375 */ name()376 const std::string name() const { return m_nick.username(); } 377 378 /** 379 * A convenience function that returns the name/address of the MUC service the room is running on 380 * (e.g., conference.jabber.org). 381 * @return The MUC service's name/address. 382 */ service()383 const std::string service() const { return m_nick.server(); } 384 385 /** 386 * A convenience function that returns the user's nickname in the room. 387 * @return The user's nickname. 388 */ nick()389 const std::string nick() const { return m_nick.resource(); } 390 391 /** 392 * Join this room. 393 * @param type The presence to join with, defaults to Available. 394 * @param status The presence's optional status text. 395 * @param priority The presence's optional priority, defaults to 0. 396 * ClientBase will automatically include the default Presence extensions added using 397 * @link gloox::ClientBase::addPresenceExtension() ClientBase::addPresenceExtension() @endlink. 398 */ 399 virtual void join( Presence::PresenceType type = Presence::Available, 400 const std::string& status = EmptyString, 401 int priority = 0 ); 402 403 /** 404 * Leave this room. 405 * @param msg An optional msg indicating the reason for leaving the room. Default: empty. 406 */ 407 void leave( const std::string& msg = EmptyString ); 408 409 /** 410 * Sends a chat message to the room. 411 * @param message The message to send. 412 */ 413 void send( const std::string& message ); 414 415 /** 416 * Sets the subject of the room to the given string. 417 * The MUC service may decline the request to set a new subject. You should 418 * not assume the subject was set successfully util it is acknowledged via the MUCRoomHandler. 419 * @param subject The new subject. 420 */ 421 void setSubject( const std::string& subject ); 422 423 /** 424 * Returns the user's current affiliation with this room. 425 * @return The user's current affiliation. 426 */ affiliation()427 MUCRoomAffiliation affiliation() const { return m_affiliation; } 428 429 /** 430 * Returns the user's current role in this room. 431 * @return The user's current role. 432 */ role()433 MUCRoomRole role() const { return m_role; } 434 435 /** 436 * Use this function to change the user's nickname in the room. 437 * The MUC service may decline the request to set a new nickname. You should not assume 438 * the nick change was successful until it is acknowledged via the MUCRoomHandler. 439 * @param nick The user's new nickname. 440 */ 441 void setNick( const std::string& nick ); 442 443 /** 444 * Use this function to set the user's presence in this room. It is not possible to 445 * use Unavailable with this function. 446 * @param presence The user's new presence. 447 * @param msg An optional status message. Default: empty. 448 */ 449 void setPresence( Presence::PresenceType presence, const std::string& msg = EmptyString ); 450 451 /** 452 * Use this function to invite another user to this room. 453 * @param invitee The (bare) JID of the user to invite. 454 * @param reason The user-supplied reason for the invitation. 455 * @param thread If this invitation is part of a transformation of a 456 * one-to-one chat to a MUC, include the one-to-one chat's thread ID here. Defaults 457 * to the empty string (i.e. not a continuation). 458 */ 459 void invite( const JID& invitee, const std::string& reason, const std::string& thread = EmptyString ); 460 461 /** 462 * Use this function to request basic room info, possibly prior to joining it. 463 * Results are announced using the MUCRoomHandler. 464 */ 465 void getRoomInfo(); 466 467 /** 468 * Use this function to request information about the current room occupants, 469 * possibly prior to joining it. The room ay be configured not to disclose such 470 * information. 471 * Results are announced using the MUCRoomHandler. 472 */ 473 void getRoomItems(); 474 475 /** 476 * The MUC spec enables other entities to discover via Service Discovery which rooms 477 * an entity is in. By default, gloox does not publish such info for privacy reasons. 478 * This function can be used to enable publishing the info for @b this room. 479 * @param publish Whether to enable other entities to discover the user's presence in 480 * @b this room. 481 * @param publishNick Whether to publish the nickname used in the room. This parameter 482 * is ignored if @c publish is @b false. 483 */ 484 void setPublish( bool publish, bool publishNick ); 485 486 /** 487 * Use this function to register a (new) MUCRoomHandler with this room. There can be only one 488 * MUCRoomHandler per room at any one time. 489 * @param mrl The MUCRoomHandler to register. 490 */ registerMUCRoomHandler(MUCRoomHandler * mrl)491 void registerMUCRoomHandler( MUCRoomHandler* mrl ) { m_roomHandler = mrl; } 492 493 /** 494 * Use this function to remove the registered MUCRoomHandler. 495 */ removeMUCRoomHandler()496 void removeMUCRoomHandler() { m_roomHandler = 0; } 497 498 /** 499 * Use this function to register a (new) MUCRoomConfigHandler with this room. There can 500 * be only one MUCRoomConfigHandler per room at any one time. 501 * @param mrch The MUCRoomConfigHandler to register. 502 */ registerMUCRoomConfigHandler(MUCRoomConfigHandler * mrch)503 void registerMUCRoomConfigHandler( MUCRoomConfigHandler* mrch ) { m_roomConfigHandler = mrch; } 504 505 /** 506 * Use this function to remove the registered MUCRoomConfigHandler. 507 */ removeMUCRoomConfigHandler()508 void removeMUCRoomConfigHandler() { m_roomConfigHandler = 0; } 509 510 /** 511 * Use this function to add history to a (newly created) room. The use case from the MUC spec 512 * is to add history to a room that was created in the process of a transformation of a 513 * one-to-one chat to a multi-user chat. 514 * @param message A reason for declining the invitation. 515 * @param from The JID of the original author of this part of the history. 516 * @param stamp The datetime of the original message in the format: 20061224T12:15:23Z 517 * @note You should not attempt to use this function before 518 * MUCRoomHandler::handleMUCParticipantPresence() was called for the first time. 519 */ 520 void addHistory( const std::string& message, const JID& from, const std::string& stamp ); 521 522 /** 523 * Use this function to request room history. Set @c value to zero to disable the room 524 * history request. You should not use HistorySince type with this function. 525 * History is sent only once after entering a room. You should use this function before joining. 526 * @param value Represents either the number of requested characters, the number of requested 527 * message stanzas, or the number seconds, depending on the value of @c type. 528 * @param type 529 * @note If this function is not used to request a specific amount of room history, it is up 530 * to the MUC service to decide how much history to send. 531 */ 532 void setRequestHistory( int value, HistoryRequestType type ); 533 534 /** 535 * Use this function to request room history since specific datetime. 536 * History is sent only once after entering a room. You should use this function before joining. 537 * @param since A string representing a datetime conforming to the DateTime profile specified 538 * in Jabber Date and Time Profiles (@xep{0082}). 539 * @note If this function is not used to request a specific amount of room history, it is up 540 * to the MUC service to decide how much history to send. 541 */ 542 void setRequestHistory( const std::string& since ); 543 544 /** 545 * This static function allows to formally decline a MUC 546 * invitation received via the MUCInvitationListener. 547 * @param room The JID of the room the invitation came from. 548 * @param invitor The JID of the invitor. 549 * @param reason An optional reason for the decline. 550 * @return A pointer to a Message. You will have to send (and 551 * possibly delete) this Message manually. 552 */ 553 static Message* declineInvitation( const JID& room, const JID& invitor, 554 const std::string& reason = EmptyString); 555 556 /** 557 * It is not possible for a visitor to speak in a moderated room. Use this function to request 558 * voice from the moderator. 559 */ 560 void requestVoice(); 561 562 /** 563 * Use this function to kick a user from the room. 564 * Depending on service and/or room configuration and role/affiliation 565 * this may not always succeed. Usually, a role of 'moderator' is necessary. 566 * @note This is a convenience function. It directly uses setRole() with a MUCRoomRole of RoleNone. 567 * @param nick The nick of the user to be kicked. 568 * @param reason An optional reason for the kick. 569 */ 570 void kick( const std::string& nick, const std::string& reason = EmptyString ) 571 { setRole( nick, RoleNone, reason ); } 572 573 /** 574 * Use this function to ban a user from the room. 575 * Depending on service and/or room configuration and role/affiliation 576 * this may not always succeed. Usually, an affiliation of admin is necessary. 577 * @note This is a convenience function. It directly uses setAffiliation() with a MUCRoomAffiliation 578 * of RoleOutcast. 579 * @param nick The nick of the user to be banned. 580 * @param reason An optional reason for the ban. 581 */ ban(const std::string & nick,const std::string & reason)582 void ban( const std::string& nick, const std::string& reason ) 583 { setAffiliation( nick, AffiliationOutcast, reason ); } 584 585 /** 586 * Use this function to grant voice to a user in a moderated room. 587 * Depending on service and/or room configuration and role/affiliation 588 * this may not always succeed. Usually, a role of 'moderator' is necessary. 589 * @note This is a convenience function. It directly uses setRole() with a MUCRoomRole 590 * of RoleParticipant. 591 * @param nick The nick of the user to be granted voice. 592 * @param reason An optional reason for the grant. 593 */ grantVoice(const std::string & nick,const std::string & reason)594 void grantVoice( const std::string& nick, const std::string& reason ) 595 { setRole( nick, RoleParticipant, reason ); } 596 597 /** 598 * Use this function to create a Tag that approves a voice request or registration request 599 * delivered via MUCRoomConfigHandler::handleMUCVoiceRequest(). You will need to send this 600 * Tag off manually using Client/ClientBase. 601 * @param room The room's JID. This is needed because you can use this function outside of 602 * room context (e.g, if the admin is not in the room). 603 * @param df The filled-in DataForm from the voice/registration request. The form object 604 * will be owned by the returned Message. 605 */ 606 static Message* createDataForm( const JID& room, const DataForm* df ); 607 608 /** 609 * Use this function to revoke voice from a user in a moderated room. 610 * Depending on service and/or room configuration and role/affiliation 611 * this may not always succeed. Usually, a role of 'moderator' is necessary. 612 * @note This is a convenience function. It directly uses setRole() with a MUCRoomRole 613 * of RoleVisitor. 614 * @param nick The nick of the user. 615 * @param reason An optional reason for the revoke. 616 */ revokeVoice(const std::string & nick,const std::string & reason)617 void revokeVoice( const std::string& nick, const std::string& reason ) 618 { setRole( nick, RoleVisitor, reason ); } 619 620 /** 621 * Use this function to change the role of a user in the room. 622 * Usually, at least moderator privileges are required to succeed. 623 * @param nick The nick of the user who's role shall be modfified. 624 * @param role The user's new role in the room. 625 * @param reason An optional reason for the role change. 626 */ 627 void setRole( const std::string& nick, MUCRoomRole role, const std::string& reason = EmptyString ); 628 629 /** 630 * Use this function to change the affiliation of a user in the room. 631 * Usually, at least admin privileges are required to succeed. 632 * @param nick The nick of the user who's affiliation shall be modfified. 633 * @param affiliation The user's new affiliation in the room. 634 * @param reason An optional reason for the affiliation change. 635 */ 636 void setAffiliation( const std::string& nick, MUCRoomAffiliation affiliation, 637 const std::string& reason ); 638 639 /** 640 * Use this function to request the room's configuration form. 641 * It can be used either after MUCRoomHandler::handleMUCRoomCreation() was called, 642 * or at any later time. 643 * 644 * Usually owner privileges are required for this action to 645 * succeed. 646 * 647 * Use setRoomConfig() to send the modified room config back. 648 */ 649 void requestRoomConfig(); 650 651 /** 652 * After requesting (using requestRoomConfig()) and 653 * editing/filling in the room's configuration, 654 * use this function to send it back to the server. 655 * @param form The form to send. The function will delete the 656 * object pointed to. 657 */ 658 void setRoomConfig( DataForm* form ); 659 660 /** 661 * Use this function to accept the room's default configuration. This function is useful 662 * only after MUCRoomHandler::handleMUCRoomCreation() was called. This is a NOOP at 663 * any other time. 664 */ acknowledgeInstantRoom()665 void acknowledgeInstantRoom() 666 { instantRoom( CreateInstantRoom ); } 667 668 /** 669 * Use this function to cancel the creation of a room. This function is useful only after 670 * MUCRoomHandler::handleMUCRoomCreation() was called. This is a NOOP at any other time. 671 */ cancelRoomCreation()672 void cancelRoomCreation() 673 { instantRoom( CancelRoomCreation ); } 674 675 /** 676 * Use this function to destroy the room. All the occupants will be removed from the room. 677 * @param reason An optional reason for the destruction. 678 * @param alternate A pointer to a JID of an alternate venue (e.g., another MUC room). 679 * May be 0. 680 * @param password An optional password for the alternate venue. 681 * 682 * Usually owner privileges are required for this action to succeed. 683 */ 684 void destroy( const std::string& reason = EmptyString, 685 const JID& alternate = JID(), const std::string& password = EmptyString ); 686 687 /** 688 * Use this function to request a particluar list of room occupants. 689 * @note There must be a MUCRoomConfigHandler registered with this room for this 690 * function to be executed. 691 * @param operation The following types of lists are available: 692 * @li Voice List: List of people having voice in a moderated room. Use RequestVoiceList. 693 * @li Members List: List of members of a room. Use RequestMemberList. 694 * @li Ban List: List of people banned from the room. Use RequestBanList. 695 * @li Moderator List: List of room moderators. Use RequestModeratorList. 696 * @li Admin List: List of room admins. Use RequestAdminList. 697 * @li Owner List: List of room owners. Use RequestOwnerList. 698 * Any other value of @c operation will be ignored. 699 */ 700 void requestList( MUCOperation operation ); 701 702 /** 703 * Use this function to store a (modified) list for the room. 704 * @param items The list of items. Example:<br> 705 * You want to set the Voice List. The privilege of Voice refers to the role of Participant. 706 * Furthermore, you only store the delta of the original (Voice)List. (Optionally, you could 707 * probably store the whole list, however, remeber to include those items that were modified, 708 * too.) 709 * You want to, say, add one occupant to the Voice List, and remove another one. 710 * Therefore you store: 711 * @li GuyOne, role participant -- this guy gets voice granted, he/she is now a participant. 712 * @li GuyTwo, role visitor -- this guy gets voice revoked, he/she is now a mere visitor 713 * (Visitor is the Role "below" Participant in the privileges hierarchy). 714 * 715 * For operations modifying Roles, you should specifiy only the new Role in the MUCListItem 716 * structure, for those modifying Affiliations, you should only specify the new Affiliation, 717 * respectively. The nickname is mandatory in the MUCListItem structure. Items without nickname 718 * will be ignored. 719 * 720 * You may specify a reason for the role/affiliation change in the MUCListItem structure. 721 * You should not specify a JID in the MUCListItem structure, it will be ignored. 722 * 723 * @param operation See requestList() for a list of available list types. Any other value will 724 * be ignored. 725 */ 726 void storeList( const MUCListItemList items, MUCOperation operation ); 727 728 /** 729 * Returns the currently known room flags. 730 * @return ORed MUCRoomFlag's describing the current room configuration. 731 */ flags()732 int flags() const { return m_flags; } 733 734 // reimplemented from DiscoHandler 735 virtual void handleDiscoInfo( const JID& from, const Disco::Info& info, int context ); 736 737 // reimplemented from DiscoHandler 738 // reimplemented from DiscoHandler 739 virtual void handleDiscoItems( const JID& from, const Disco::Items& items, int context ); 740 741 // reimplemented from DiscoHandler 742 virtual void handleDiscoError( const JID& from, const Error* error, int context ); 743 744 // reimplemented from PresenceHandler 745 virtual void handlePresence( const Presence& presence ); 746 747 // reimplemented from MessageHandler 748 virtual void handleMessage( const Message& msg, MessageSession* session = 0 ); 749 750 // reimplemented from IqHandler handleIq(const IQ & iq)751 virtual bool handleIq( const IQ& iq ) { (void)iq; return false; } 752 753 // reimplemented from IqHandler 754 virtual void handleIqID( const IQ& iq, int context ); 755 756 // reimplemented from DiscoNodeHandler 757 virtual StringList handleDiscoNodeFeatures( const JID& from, const std::string& node ); 758 759 // reimplemented from DiscoNodeHandler 760 virtual Disco::IdentityList handleDiscoNodeIdentities( const JID& from, 761 const std::string& node ); 762 763 // reimplemented from DiscoNodeHandler 764 virtual Disco::ItemList handleDiscoNodeItems( const JID& from, const JID& to, 765 const std::string& node = EmptyString ); 766 767 protected: 768 /** 769 * Sets the room's name. 770 * @param name The room's name. 771 */ setName(const std::string & name)772 void setName( const std::string& name ) { m_nick.setUsername( name ); } 773 774 /** 775 * Acknowledges instant room creation w/o a call to the MUCRoomConfigHandler. 776 * @return Whether an instant room is being created. 777 */ instantRoomHook()778 virtual bool instantRoomHook() const { return false; } 779 780 ClientBase* m_parent; 781 JID m_nick; 782 783 bool m_joined; 784 785 private: 786 #ifdef MUCROOM_TEST 787 public: 788 #endif 789 /** 790 * @brief An abstraction of a MUC owner query. 791 * 792 * @author Jakob Schröter <js@camaya.net> 793 * @since 1.0 794 */ 795 class MUCOwner : public StanzaExtension 796 { 797 public: 798 799 /** 800 * Describes available query types for the muc#owner namespace. 801 */ 802 enum QueryType 803 { 804 TypeCreate, /**< Create a room. */ 805 TypeRequestConfig, /**< Request room config. */ 806 TypeSendConfig, /**< Submit configuration form to MUC service. */ 807 TypeCancelConfig, /**< Cancel room configuration. */ 808 TypeInstantRoom, /**< Request an instant room */ 809 TypeDestroy, /**< Destroy the room. */ 810 TypeIncomingTag /**< The Query has been created from an incoming Tag. */ 811 }; 812 813 /** 814 * Creates a new MUCOwner object for the given query, possibly including 815 * the given DataForm. 816 * @param type The intended query type. 817 * @param form An optional pointer to a DataForm. Necessity depends on the query type. 818 */ 819 MUCOwner( QueryType type, DataForm* form = 0 ); 820 821 /** 822 * Creates a new query that destroys the current room. 823 * @param alternate An optional alternate discussion venue. 824 * @param reason An optional reason for the room destruction. 825 * @param password An optional password for the new room. 826 */ 827 MUCOwner( const JID& alternate = JID(), const std::string& reason = EmptyString, 828 const std::string& password = EmptyString); 829 830 /** 831 * Creates a new MUCOwner object from the given Tag. 832 * @param tag A Tag to parse. 833 */ 834 MUCOwner( const Tag* tag ); 835 836 /** 837 * Virtual destructor. 838 */ 839 virtual ~MUCOwner(); 840 841 /** 842 * Returns a pointer to a DataForm, included in the MUCOwner object. May be 0. 843 * @return A pointer to a configuration form. 844 */ form()845 const DataForm* form() const { return m_form; } 846 847 // reimplemented from StanzaExtension 848 const std::string& filterString() const; 849 850 // reimplemented from StanzaExtension newInstance(const Tag * tag)851 StanzaExtension* newInstance( const Tag* tag ) const 852 { 853 return new MUCOwner( tag ); 854 } 855 856 // reimplemented from StanzaExtension 857 Tag* tag() const; 858 859 // reimplemented from StanzaExtension clone()860 virtual StanzaExtension* clone() const 861 { 862 MUCOwner* m = new MUCOwner(); 863 m->m_type = m_type; 864 m->m_jid = m_jid; 865 m->m_reason = m_reason; 866 m->m_pwd = m_pwd; 867 m->m_form = m_form ? new DataForm( *m_form ) : 0; 868 return m; 869 } 870 871 private: 872 QueryType m_type; 873 JID m_jid; 874 std::string m_reason; 875 std::string m_pwd; 876 DataForm* m_form; 877 }; 878 879 /** 880 * @brief An abstraction of a MUC admin query. 881 * 882 * @author Jakob Schröter <js@camaya.net> 883 * @since 1.0 884 */ 885 class MUCAdmin : public StanzaExtension 886 { 887 public: 888 /** 889 * Creates a new object that can be used to change the role of a room participant. 890 * @param role The participant's new role. 891 * @param nick The participant's nick. 892 * @param reason An optional reason for the role change. 893 */ 894 MUCAdmin( MUCRoomRole role, const std::string& nick, 895 const std::string& reason = EmptyString ); 896 897 /** 898 * Creates a new object that can be used to change the affiliation of a room participant. 899 * @param affiliation The participant's new affiliation. 900 * @param nick The participant's nick. 901 * @param reason An optional reason for the role change. 902 */ 903 MUCAdmin( MUCRoomAffiliation affiliation, const std::string& nick, 904 const std::string& reason = EmptyString ); 905 906 /** 907 * Creates a new object that can be used to request or store a role/affiliation 908 * list. 909 * @param operation The MUCOperation to carry out. Only the Request* and Store* 910 * operations are valid. Any other value will be ignored. 911 * @param jids A list of bare JIDs. Only the JID member of the MUCListItem 912 * structure should be set. The type of the list will be determined from the 913 * @c operation parameter. 914 */ 915 MUCAdmin( MUCOperation operation, const MUCListItemList& jids = MUCListItemList() ); 916 917 /** 918 * Constructs a new MUCAdmin object from the given Tag. 919 * @param tag The Tag to parse. 920 */ 921 MUCAdmin( const Tag* tag = 0 ); 922 923 /** 924 * Virtual destructor. 925 */ 926 virtual ~MUCAdmin(); 927 928 /** 929 * Returns the contained list of MUC items. 930 * @return The contained list of MUC items. 931 */ list()932 const MUCListItemList& list() const { return m_list; } 933 934 // reimplemented from StanzaExtension 935 const std::string& filterString() const; 936 937 // reimplemented from StanzaExtension newInstance(const Tag * tag)938 StanzaExtension* newInstance( const Tag* tag ) const 939 { 940 return new MUCAdmin( tag ); 941 } 942 943 // reimplemented from StanzaExtension 944 Tag* tag() const; 945 946 // reimplemented from StanzaExtension clone()947 virtual StanzaExtension* clone() const 948 { 949 return new MUCAdmin( *this ); 950 } 951 952 private: 953 MUCListItemList m_list; 954 MUCRoomAffiliation m_affiliation; 955 MUCRoomRole m_role; 956 }; 957 958 void handleIqResult( const IQ& iq, int context ); 959 void handleIqError( const IQ& iq, int context ); 960 void setNonAnonymous(); 961 void setSemiAnonymous(); 962 void setFullyAnonymous(); 963 void acknowledgeRoomCreation(); 964 void instantRoom( int context ); 965 966 MUCRoomHandler* m_roomHandler; 967 MUCRoomConfigHandler* m_roomConfigHandler; 968 MUCMessageSession* m_session; 969 970 typedef std::list<MUCRoomParticipant> ParticipantList; 971 ParticipantList m_participants; 972 973 std::string m_password; 974 std::string m_newNick; 975 976 MUCRoomAffiliation m_affiliation; 977 MUCRoomRole m_role; 978 979 HistoryRequestType m_historyType; 980 981 std::string m_historySince; 982 int m_historyValue; 983 int m_flags; 984 bool m_creationInProgress; 985 bool m_configChanged; 986 bool m_publishNick; 987 bool m_publish; 988 bool m_unique; 989 990 }; 991 992 } 993 994 #endif // MUCROOM_H__ 995