summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2014-10-27 14:51:07 (GMT)
committerSwift Review <review@swift.im>2014-10-30 13:58:51 (GMT)
commit286ef105d813a12640d64b71101cafe53f212234 (patch)
tree39e3814048dd639b9a118a3b16f22b49235efd93 /Swiften/MUC/MUCImpl.cpp
parent190cdcf7478950a90a5c8666d82047e4f33e0d2c (diff)
downloadswift-286ef105d813a12640d64b71101cafe53f212234.zip
swift-286ef105d813a12640d64b71101cafe53f212234.tar.bz2
Resend presence to MUC on join completion only if it changed since join.
Test-Information: Added test case to assure presence is not resend after join completion if it did not change. The other test cases are untouched and still all succeed. Change-Id: I2aace1aee8ca3deab9cd9050a25233617b3b0678
Diffstat (limited to 'Swiften/MUC/MUCImpl.cpp')
-rw-r--r--Swiften/MUC/MUCImpl.cpp31
1 files changed, 28 insertions, 3 deletions
diff --git a/Swiften/MUC/MUCImpl.cpp b/Swiften/MUC/MUCImpl.cpp
index ab5faf4..778c290 100644
--- a/Swiften/MUC/MUCImpl.cpp
+++ b/Swiften/MUC/MUCImpl.cpp
@@ -11,12 +11,13 @@
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Presence/DirectedPresenceSender.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Queries/IQRouter.h>
+#include <Swiften/Elements/CapsInfo.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/Elements/MUCAdminPayload.h>
#include <Swiften/Elements/MUCPayload.h>
@@ -63,33 +64,49 @@ void MUCImpl::joinWithContextSince(const std::string &nick, const boost::posix_t
}
std::map<std::string, MUCOccupant> MUCImpl::getOccupants() const {
return occupants;
}
+bool MUCImpl::isEqualExceptID(const Presence& lhs, const Presence& rhs) {
+ bool isEqual = false;
+ if (lhs.getFrom() == rhs.getFrom() && lhs.getTo() == rhs.getTo() && lhs.getStatus() == rhs.getStatus() && lhs.getShow() == rhs.getShow()) {
+ CapsInfo::ref lhsCaps = lhs.getPayload<CapsInfo>();
+ CapsInfo::ref rhsCaps = rhs.getPayload<CapsInfo>();
+
+ if (!!lhsCaps && !!rhsCaps) {
+ isEqual = (*lhsCaps == *rhsCaps);
+ }
+ else {
+ isEqual = (!lhsCaps && !rhsCaps);
+ }
+ }
+ return isEqual;
+}
+
void MUCImpl::internalJoin(const std::string &nick) {
//TODO: history request
joinComplete_ = false;
joinSucceeded_ = false;
mucRegistry->addMUC(getJID());
ownMUCJID = JID(ownMUCJID.getNode(), ownMUCJID.getDomain(), nick);
- Presence::ref joinPresence = boost::make_shared<Presence>(*presenceSender->getLastSentUndirectedPresence());
+ Presence::ref joinPresence = presenceSender->getLastSentUndirectedPresence() ? (*presenceSender->getLastSentUndirectedPresence())->clone() : boost::make_shared<Presence>();
assert(joinPresence->getType() == Presence::Available);
joinPresence->setTo(ownMUCJID);
MUCPayload::ref mucPayload = boost::make_shared<MUCPayload>();
if (joinSince_ != boost::posix_time::not_a_date_time) {
mucPayload->setSince(joinSince_);
}
if (password) {
mucPayload->setPassword(*password);
}
joinPresence->addPayload(mucPayload);
-
+ joinRequestPresence_ = joinPresence;
presenceSender->sendPresence(joinPresence);
}
void MUCImpl::changeNickname(const std::string& newNickname) {
Presence::ref changeNicknamePresence = boost::make_shared<Presence>();
changeNicknamePresence->setTo(ownMUCJID.toBare().toString() + std::string("/") + newNickname);
@@ -134,13 +151,19 @@ void MUCImpl::handleIncomingPresence(Presence::ref presence) {
std::string reason;
onJoinFailed(presence->getPayload<ErrorPayload>());
return;
}
else {
joinSucceeded_ = true;
- presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence);
+ presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence);
+ if (presenceSender->getLastSentUndirectedPresence() && !isEqualExceptID(**(presenceSender->getLastSentUndirectedPresence()), *joinRequestPresence_)) {
+ // our presence changed between join request and join complete, send current presence to MUC
+ Presence::ref latestPresence = boost::make_shared<Presence>(**presenceSender->getLastSentUndirectedPresence());
+ latestPresence->setTo(ownMUCJID);
+ presenceSender->sendPresence(latestPresence);
+ }
}
}
std::string nick = presence->getFrom().getResource();
if (nick.empty()) {
return;
@@ -242,12 +265,13 @@ void MUCImpl::handleIncomingPresence(Presence::ref presence) {
presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence);
ownMUCJID = presence->getFrom();
presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence);
}
onJoinComplete(getOwnNick());
}
+ // MUC status 201: a new room has been created
if (status.code == 201) {
isLocked = true;
/* Room is created and locked */
/* Currently deal with this by making an instant room */
if (ownMUCJID != presence->getFrom()) {
presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence);
@@ -256,12 +280,13 @@ void MUCImpl::handleIncomingPresence(Presence::ref presence) {
}
if (createAsReservedIfNew) {
unlocking = true;
requestConfigurationForm();
}
else {
+ // Accept default room configuration and create an instant room http://xmpp.org/extensions/xep-0045.html#createroom-instant
MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload());
presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence);
mucPayload->setPayload(boost::make_shared<Form>(Form::SubmitType));
boost::shared_ptr< GenericRequest<MUCOwnerPayload> > request = boost::make_shared< GenericRequest<MUCOwnerPayload> >(IQ::Set, getJID(), mucPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MUCImpl::handleCreationConfigResponse, this, _1, _2));
request->send();