/* * xmpp_muc.cxx * * Extensible Messaging and Presence Protocol (XMPP) * JEP-0045 Multi-User Chat * * Portable Windows Library * * Copyright (c) 2004 Reitek S.p.A. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Post Increment * * Contributor(s): ______________________________________. * * $Log: xmpp_muc.cxx,v $ * Revision 1.2 2005/08/04 03:19:08 dereksmithies * Add xmpp_muc (XMPP multi user conference) to the compile process for unix. * Correct compile errors under unix. * * Revision 1.1 2004/05/09 07:23:50 rjongbloed * More work on XMPP, thanks Federico Pinna and Reitek S.p.A. * * */ #ifdef __GNUC__ #pragma implementation "xmpp_muc.h" #endif #include #include #if P_EXPAT XMPP::MUC::User::User() { } XMPP::MUC::User::~User() { } PObject::Comparison XMPP::MUC::User::Compare(const PObject & obj) const { if (PIsDescendant(&obj, XMPP::MUC::User)) return m_Nick.Compare(((const XMPP::MUC::User&)obj).m_Nick); else if (PIsDescendant(&obj, PString)) return m_Nick.Compare((const PString&)obj); PAssertAlways(PInvalidCast); return PObject::LessThan; } /////////////////////////////////////////////////////// PString XMPP::MUC::Namespace("http://jabber.org/protocol/muc"); PString XMPP::MUC::User::Namespace("http://jabber.org/protocol/muc#user"); XMPP::MUC::Room::Room(C2S::StreamHandler * handler, const JID& jid, const PString& nick) : m_Handler(handler), m_RoomJID(jid) { PCREATE_SMART_NOTIFIEE; if (PAssertNULL(m_Handler) == NULL) return; m_User.m_Nick = nick; m_User.m_Role = XMPP::MUC::User::None; m_User.m_Affiliation = XMPP::MUC::User::None_a; m_RoomJID.SetResource(PString::Empty()); m_Handler->SessionReleasedHandlers().Add(new PCREATE_SMART_NOTIFIER(OnSessionReleased)); m_Handler->PresenceHandlers().Add(new PCREATE_SMART_NOTIFIER(OnPresence)); m_Handler->MessageSenderHandlers(m_RoomJID).Add(new PCREATE_SMART_NOTIFIER(OnMessage)); } BOOL XMPP::MUC::Room::Enter() { if (PAssertNULL(m_Handler) == NULL) return FALSE; JID ourUser(m_RoomJID); ourUser.SetResource(m_User.m_Nick); XMPP::Presence pre; pre.SetTo(ourUser); pre.SetStatus("Available"); pre.SetPriority(0); PXMLElement * x = new PXMLElement(NULL, "x"); x->SetAttribute(XMPP::Namespace, XMPP::MUC::Namespace); pre.AddElement(x); return m_Handler->Write(pre); } BOOL XMPP::MUC::Room::Leave() { if (PAssertNULL(m_Handler) == NULL) return FALSE; XMPP::Presence pre; pre.SetTo(m_RoomJID); pre.SetType(XMPP::Presence::Unavailable); return m_Handler->Write(pre); } BOOL XMPP::MUC::Room::SendMessage(const PString& msg) { XMPP::Message _msg; _msg.SetBody(msg); return SendMessage(_msg); } BOOL XMPP::MUC::Room::SendMessage(Message& msg) { if (PAssertNULL(m_Handler) == NULL) return FALSE; msg.SetTo(m_RoomJID); msg.SetType(XMPP::Message::GroupChat); return m_Handler->Write(msg); } void XMPP::MUC::Room::OnMessage(Message& msg) { m_MessageHandlers.Fire(msg); } void XMPP::MUC::Room::OnRoomJoined() { m_RoomJoinedHandlers.Fire(*this); } void XMPP::MUC::Room::OnRoomLeft() { m_RoomLeftHandlers.Fire(*this); } void XMPP::MUC::Room::OnUserAdded(User& user) { m_UserAddedHandlers.Fire(user); } void XMPP::MUC::Room::OnUserRemoved(User& user) { m_UserRemovedHandlers.Fire(user); } void XMPP::MUC::Room::OnUserChanged(User& user) { m_UserChangedHandlers.Fire(user); } void XMPP::MUC::Room::OnSessionReleased(C2S::StreamHandler&, INT) { m_User.m_Role = XMPP::MUC::User::None; m_User.m_Affiliation = XMPP::MUC::User::None_a; OnRoomLeft(); } void XMPP::MUC::Room::OnMessage(XMPP::Message& msg, INT) { OnMessage(msg); } void XMPP::MUC::Room::OnPresence(XMPP::Presence& msg, INT) { JID from = msg.GetFrom(); PString res = from.GetResource(); if (m_RoomJID != from) // It's not about this room return; XMPP::MUC::User::Role role = User::Unknown; XMPP::MUC::User::Affiliation affiliation = User::Unknown_a; PXMLElement * x = msg.GetElement("x"); if (x != NULL && x->GetAttribute(XMPP::Namespace) == XMPP::MUC::User::Namespace) { PXMLElement * item = x->GetElement("item"); if (item != NULL) { PString attr = item->GetAttribute("role"); if (attr *= "none") role = XMPP::MUC::User::None; else if (attr *= "moderator") role = XMPP::MUC::User::Moderator; else if (attr *= "participant") role = XMPP::MUC::User::Participant; else if (attr *= "visitor") role = XMPP::MUC::User::Visitor; attr = item->GetAttribute("affiliation"); if (attr *= "none") affiliation = XMPP::MUC::User::None_a; else if (attr *= "owner") affiliation = XMPP::MUC::User::Owner; else if (attr *= "admin") affiliation = XMPP::MUC::User::Admin; else if (attr *= "member") affiliation = XMPP::MUC::User::Member; else if (attr *= "outcast") affiliation = XMPP::MUC::User::Outcast; } } if (res == m_User.m_Nick) { // is this about us? if (msg.GetType() == XMPP::Presence::Unavailable) { OnRoomLeft(); m_User.m_Role = XMPP::MUC::User::None; m_User.m_Affiliation = XMPP::MUC::User::None_a; } else if (m_User.m_Role == XMPP::MUC::User::None) { m_User.m_Role = role; m_User.m_Affiliation = affiliation; OnRoomJoined(); } else { m_User.m_Role = role; m_User.m_Affiliation = affiliation; // TODO: raise a "LocalUserChanged" event... } } else { XMPP::MUC::User user; user.m_Nick = res; user.m_Role = role; user.m_Affiliation = affiliation; XMPP::MUC::User * puser; PINDEX i = m_OtherUsers.GetValuesIndex(user); if (i != P_MAX_INDEX) { // known user? if (msg.GetType() == XMPP::Presence::Unavailable) { OnUserRemoved(user); m_OtherUsers.RemoveAt(i); } else { puser = (XMPP::MUC::User *)m_OtherUsers.GetAt(i); puser->m_Role = role; puser->m_Affiliation = affiliation; OnUserChanged(user); } } else { // new user! puser = new XMPP::MUC::User; puser->m_Role = role; puser->m_Affiliation = affiliation; m_OtherUsers.Append(puser); OnUserAdded(user); } } } #endif // P_EXPAT // End of File ///////////////////////////////////////////////////////////////