Files
@ be869bbbca9b
Branch filter:
Location: libtransport.git/libtransport/Conversation.cpp - annotation
be869bbbca9b
15.4 KiB
text/x-c++hdr
Travis: add swiften2 distribution to build matrix
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d 78e71f9345c7 78e71f9345c7 78e71f9345c7 78e71f9345c7 78e71f9345c7 78e71f9345c7 78e71f9345c7 78e71f9345c7 05bf03704aec 76c678dd6f1d cc64a76c8be5 cc64a76c8be5 cc64a76c8be5 cc64a76c8be5 65ad5a210697 5f04f459038b cc64a76c8be5 76c678dd6f1d 05bf03704aec 05bf03704aec 76c678dd6f1d 943dc1925b7c 76c678dd6f1d 943dc1925b7c 5b89dae8ca9a 8b6973539f23 70cf46773b85 10d29c265be5 c80c02ccb158 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 76c678dd6f1d 76c678dd6f1d b5c026470f07 76c678dd6f1d 76c678dd6f1d 10d29c265be5 10d29c265be5 10d29c265be5 10d29c265be5 10d29c265be5 4717bd007185 4717bd007185 4717bd007185 4717bd007185 10d29c265be5 4717bd007185 4717bd007185 9d2692c5d271 4717bd007185 4717bd007185 4717bd007185 4717bd007185 4717bd007185 4717bd007185 97a2cd5b2af5 97a2cd5b2af5 4717bd007185 4717bd007185 4717bd007185 3ff7f9249074 3ff7f9249074 3ff7f9249074 97a2cd5b2af5 97a2cd5b2af5 97a2cd5b2af5 3ff7f9249074 6d2f8c192761 97a2cd5b2af5 97a2cd5b2af5 fe47e0979be9 97a2cd5b2af5 4717bd007185 4717bd007185 4717bd007185 8c529dbabbbc 8c529dbabbbc 8c529dbabbbc 8c529dbabbbc 8c529dbabbbc 6d2f8c192761 c0687aba7478 6d2f8c192761 c0687aba7478 c0687aba7478 c0687aba7478 c0687aba7478 c0687aba7478 c0687aba7478 c0687aba7478 c0687aba7478 6d2f8c192761 4f9457bdd83a 4f9457bdd83a c0687aba7478 4f9457bdd83a 4f9457bdd83a fe47e0979be9 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a c0687aba7478 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a c80c02ccb158 4f9457bdd83a c80c02ccb158 408413abf255 c80c02ccb158 c80c02ccb158 408413abf255 408413abf255 408413abf255 4f9457bdd83a fe47e0979be9 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 4f9457bdd83a 6d2f8c192761 943dc1925b7c 2add374fbd61 2add374fbd61 2add374fbd61 761c746d1008 761c746d1008 0b0e020cdf91 0b0e020cdf91 0b0e020cdf91 761c746d1008 761c746d1008 761c746d1008 2add374fbd61 5b89dae8ca9a ff3adaa3f33f ff3adaa3f33f ff3adaa3f33f ff3adaa3f33f ff3adaa3f33f 0a33a3100eb9 5b89dae8ca9a 2add374fbd61 ff3adaa3f33f 2add374fbd61 2add374fbd61 2add374fbd61 2add374fbd61 2add374fbd61 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 df3276119498 2add374fbd61 0a33a3100eb9 2add374fbd61 0a33a3100eb9 943dc1925b7c ff3adaa3f33f 943dc1925b7c 943dc1925b7c 0185f9487299 10d29c265be5 0185f9487299 0185f9487299 9d2692c5d271 0185f9487299 943dc1925b7c 0a33a3100eb9 76c678dd6f1d 2add374fbd61 8c529dbabbbc 10d29c265be5 8c529dbabbbc 8c529dbabbbc 9d2692c5d271 e14d3c30e92e e14d3c30e92e e14d3c30e92e e14d3c30e92e e14d3c30e92e 7e9ea5150d9c 9de5e656da7d 9de5e656da7d 9de5e656da7d 9de5e656da7d 9de5e656da7d 7e9ea5150d9c 05bf03704aec 2add374fbd61 4f9457bdd83a 4f9457bdd83a 0a33a3100eb9 0a33a3100eb9 24d902983a17 24d902983a17 9de5e656da7d 9de5e656da7d 24d902983a17 24d902983a17 24d902983a17 24d902983a17 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 2ca447264ae8 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 c80c02ccb158 99e958e8c83a 99e958e8c83a 99e958e8c83a 99e958e8c83a 99e958e8c83a 9de5e656da7d 9de5e656da7d 9de5e656da7d 1055c577d2d3 1055c577d2d3 1055c577d2d3 7e9ea5150d9c 6d2f8c192761 8761e976aeca 8761e976aeca 8761e976aeca 8761e976aeca 8761e976aeca 8761e976aeca fe47e0979be9 7e9ea5150d9c 7805d876f88d 7805d876f88d 7805d876f88d 7805d876f88d 7805d876f88d 7805d876f88d 7805d876f88d 7805d876f88d fe47e0979be9 7805d876f88d 7805d876f88d 7e9ea5150d9c 7e9ea5150d9c 7e9ea5150d9c 5f04f459038b 6699a898fbec 0a33a3100eb9 8c529dbabbbc 8c529dbabbbc 10d29c265be5 8c529dbabbbc 8c529dbabbbc 9d2692c5d271 8c529dbabbbc 8c529dbabbbc 0a33a3100eb9 0a33a3100eb9 8e03fbec4701 8e03fbec4701 8e03fbec4701 8e03fbec4701 8e03fbec4701 99d1c435b90f 8e03fbec4701 99d1c435b90f 99d1c435b90f 8e03fbec4701 8e03fbec4701 0a33a3100eb9 0a33a3100eb9 65ad5a210697 65ad5a210697 65ad5a210697 6d2f8c192761 6d2f8c192761 61e7cfaa7f98 65ad5a210697 65ad5a210697 65ad5a210697 65ad5a210697 65ad5a210697 6d2f8c192761 6d2f8c192761 61e7cfaa7f98 58fbe0d388c6 58fbe0d388c6 58fbe0d388c6 58fbe0d388c6 58fbe0d388c6 6d2f8c192761 6d2f8c192761 61e7cfaa7f98 65ad5a210697 65ad5a210697 65ad5a210697 65ad5a210697 65ad5a210697 65ad5a210697 70cf46773b85 70cf46773b85 70cf46773b85 70cf46773b85 de8114d2da06 70cf46773b85 65ad5a210697 65ad5a210697 76c678dd6f1d 457d19d1ec41 65ad5a210697 19786b3bb708 19786b3bb708 19786b3bb708 19786b3bb708 8e03fbec4701 1af263f488e8 19786b3bb708 19786b3bb708 8e03fbec4701 8e03fbec4701 457d19d1ec41 457d19d1ec41 457d19d1ec41 457d19d1ec41 457d19d1ec41 8e03fbec4701 457d19d1ec41 5f04f459038b 5f04f459038b 6d2f8c192761 5f04f459038b 65ad5a210697 457d19d1ec41 6d2f8c192761 1055c577d2d3 1055c577d2d3 1055c577d2d3 6b83d9f942fa 70cf46773b85 70cf46773b85 70cf46773b85 70cf46773b85 70cf46773b85 70cf46773b85 70cf46773b85 e5aab1415d9e e5aab1415d9e fe47e0979be9 9de5e656da7d e5aab1415d9e e5aab1415d9e 80d1f8f90fed 3bfd7407b989 3bfd7407b989 3bfd7407b989 3bfd7407b989 3bfd7407b989 80d1f8f90fed 80d1f8f90fed 80d1f8f90fed 9de5e656da7d 9de5e656da7d 1055c577d2d3 1055c577d2d3 1055c577d2d3 1055c577d2d3 1055c577d2d3 9de5e656da7d 9de5e656da7d 1055c577d2d3 1055c577d2d3 88607aff3c0b 88607aff3c0b fe47e0979be9 88607aff3c0b 8e03fbec4701 5f04f459038b 8e03fbec4701 8b6973539f23 c80c02ccb158 c80c02ccb158 fe47e0979be9 8b6973539f23 17fe52b61f81 17fe52b61f81 17fe52b61f81 17fe52b61f81 17fe52b61f81 61e7cfaa7f98 17fe52b61f81 17fe52b61f81 76c678dd6f1d 76c678dd6f1d 76c678dd6f1d | /**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include <iostream>
#include "transport/Conversation.h"
#include "transport/ConversationManager.h"
#include "transport/User.h"
#include "transport/Transport.h"
#include "transport/Buddy.h"
#include "transport/RosterManager.h"
#include "transport/Frontend.h"
#include "transport/Config.h"
#include "transport/Logging.h"
#include "Swiften/Elements/MUCItem.h"
#include "Swiften/Elements/MUCOccupant.h"
#include "Swiften/Elements/MUCUserPayload.h"
#include "Swiften/Elements/Delay.h"
#include "Swiften/Elements/MUCPayload.h"
#include "Swiften/Elements/VCardUpdate.h"
namespace Transport {
DEFINE_LOGGER(logger, "Conversation");
Conversation::Conversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMUC) : m_conversationManager(conversationManager) {
m_legacyName = legacyName;
m_muc = isMUC;
m_jid = m_conversationManager->getUser()->getJID().toBare();
m_sentInitialPresence = false;
m_nicknameChanged = false;
m_mucEscaping = false;
m_sentInitialSubject = false;
if (CONFIG_BOOL_DEFAULTED(conversationManager->getComponent()->getConfig(), "features.rawxml", false)) {
m_sentInitialPresence = true;
}
}
Conversation::~Conversation() {
}
void Conversation::setMUCEscaping(bool mucEscaping) {
LOG4CXX_INFO(logger, m_jid.toString() << ": Setting MUC escaping to " << mucEscaping);
m_mucEscaping = mucEscaping;
}
void Conversation::destroyRoom() {
if (m_muc) {
Swift::Presence::ref presence = Swift::Presence::create();
std::string legacyName = m_legacyName;
if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
}
legacyName = Swift::JID::getEscapedNode(legacyName);
presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), m_nickname));
presence->setType(Swift::Presence::Unavailable);
Swift::MUCItem item;
item.affiliation = Swift::MUCOccupant::NoAffiliation;
item.role = Swift::MUCOccupant::NoRole;
item.actor = "Transport";
item.reason = "Spectrum 2 transport is being shut down.";
Swift::MUCUserPayload *p = new Swift::MUCUserPayload ();
p->addItem(item);
Swift::MUCUserPayload::StatusCode c;
c.code = 332;
p->addStatusCode(c);
Swift::MUCUserPayload::StatusCode c2;
c2.code = 307;
p->addStatusCode(c2);
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(p));
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
presence->setTo(jid);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
}
}
}
void Conversation::setRoom(const std::string &room) {
m_room = room;
m_legacyName = m_room + "/" + m_legacyName;
}
void Conversation::cacheMessage(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Message> &message) {
boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Delay> delay(SWIFTEN_SHRPTR_NAMESPACE::make_shared<Swift::Delay>());
delay->setStamp(timestamp);
message->addPayload(delay);
m_cachedMessages.push_back(message);
if (m_cachedMessages.size() > 100) {
m_cachedMessages.pop_front();
}
}
void Conversation::handleRawMessage(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Message> &message) {
if (message->getType() != Swift::Message::Groupchat) {
if (m_conversationManager->getComponent()->inServerMode() && m_conversationManager->getUser()->shouldCacheMessages()) {
cacheMessage(message);
}
else {
m_conversationManager->getComponent()->getFrontend()->sendMessage(message);
}
}
else {
if (m_jids.empty()) {
cacheMessage(message);
}
else {
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
message->setTo(jid);
// Subject has to be sent after our own presence (the one with code 110)
if (!message->getSubject().empty()) {
m_subject = message;
if (m_sentInitialPresence == false) {
LOG4CXX_INFO(logger, m_jid.toString() << ": Caching subject message, initial presence not sent yet.");
return;
}
else {
LOG4CXX_INFO(logger, m_jid.toString() << ": Forwarding subject message.");
}
}
m_conversationManager->getComponent()->getFrontend()->sendMessage(message);
}
}
}
}
void Conversation::handleMessage(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Message> &message, const std::string &nickname) {
if (m_muc) {
message->setType(Swift::Message::Groupchat);
}
else {
if (message->getType() == Swift::Message::Headline) {
if (m_conversationManager->getUser()->getUserSetting("send_headlines") != "1") {
message->setType(Swift::Message::Chat);
}
}
else {
message->setType(Swift::Message::Chat);
}
}
std::string n = nickname;
if (n.empty() && !m_room.empty() && !m_muc) {
n = m_nickname;
}
if (message->getType() != Swift::Message::Groupchat) {
message->setTo(m_jid);
// normal message
if (n.empty()) {
Buddy *buddy = m_conversationManager->getUser()->getRosterManager()->getBuddy(m_legacyName);
if (buddy) {
message->setFrom(buddy->getJID());
}
else {
std::string name = m_legacyName;
if (CONFIG_BOOL_DEFAULTED(m_conversationManager->getComponent()->getConfig(), "service.jid_escaping", true)) {
name = Swift::JID::getEscapedNode(m_legacyName);
}
else {
if (name.find_last_of("@") != std::string::npos) {
name.replace(name.find_last_of("@"), 1, "%");
}
}
message->setFrom(Swift::JID(name, m_conversationManager->getComponent()->getJID().toBare(), "bot"));
}
}
// PM message
else {
if (m_room.empty()) {
message->setFrom(Swift::JID(n, m_conversationManager->getComponent()->getJID().toBare(), "user"));
}
else {
std::string legacyName = m_room;
if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
}
legacyName = Swift::JID::getEscapedNode(legacyName);
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
}
}
}
else {
std::string legacyName = m_legacyName;
if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
}
legacyName = Swift::JID::getEscapedNode(legacyName);
std::string n = nickname;
if (n.empty()) {
n = " ";
}
std::map<std::string, Participant>::iterator it = m_participants.find(n);
if (it != m_participants.end() && !it->second.alias.empty()) {
n = it->second.alias;
}
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
LOG4CXX_INFO(logger, "MSG FROM " << message->getFrom().toString());
}
handleRawMessage(message);
}
std::string Conversation::getParticipants() {
std::string ret;
for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
ret += (*it).second.presence->getFrom().getResource() + ", ";
}
return ret;
}
void Conversation::sendParticipants(const Swift::JID &to, const std::string &nickname) {
// When user tries to join this room from another resource using
// different nickname than the original one has, we have to rename
// him.
LOG4CXX_INFO(logger, m_jid.toString() << ": Sending participants to " << to.toString() << ", Nickname:" << nickname << ", Conversation nickname:" << m_nickname);
if (m_nickname != nickname && !nickname.empty()) {
Swift::Presence::ref presence;
std::string tmp = m_nickname;
// At first connect the user.
m_nickname = nickname;
presence = generatePresence(nickname, 0, (int) Swift::StatusShow::Online, "", "", "");
presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
// Now change his nickname to the right one.
m_nicknameChanged = true;
presence = generatePresence(nickname, 0, (int) Swift::StatusShow::Online, "", tmp, "");
presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
}
// Self presence has to be sent as first.
Swift::Presence::ref presence = generatePresence(m_nickname, 0, (int) Swift::StatusShow::Online, "", "", "");
presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
(*it).second.presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence((*it).second.presence);
}
}
void Conversation::sendCachedMessages(const Swift::JID &to) {
for (std::list<SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Message> >::const_iterator it = m_cachedMessages.begin(); it != m_cachedMessages.end(); it++) {
if (to.isValid()) {
(*it)->setTo(to);
}
else {
(*it)->setTo(m_jid.toBare());
}
m_conversationManager->getComponent()->getFrontend()->sendMessage(*it);
}
if (m_subject) {
if (to.isValid()) {
m_subject->setTo(to);
}
else {
m_subject->setTo(m_jid.toBare());
}
m_conversationManager->getComponent()->getFrontend()->sendMessage(m_subject);
}
m_cachedMessages.clear();
}
Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname, const std::string &iconhash) {
std::string nickname = nick;
Swift::Presence::ref presence = Swift::Presence::create();
std::string legacyName = m_legacyName;
if (m_muc) {
if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
}
legacyName = Swift::JID::getEscapedNode(legacyName);
}
presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
presence->setType(Swift::Presence::Available);
if (!statusMessage.empty())
presence->setStatus(statusMessage);
Swift::StatusShow s((Swift::StatusShow::Type) status);
if (s.getType() == Swift::StatusShow::None) {
presence->setType(Swift::Presence::Unavailable);
}
presence->setShow(s.getType());
Swift::MUCUserPayload *p = new Swift::MUCUserPayload ();
if (m_nickname == nickname) {
if (flag & PARTICIPANT_FLAG_CONFLICT) {
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::Conflict)));
LOG4CXX_INFO(logger, m_jid.toString() << ": Generating error presence: PARTICIPANT_FLAG_CONFLICT");
return presence;
}
else if (flag & PARTICIPANT_FLAG_NOT_AUTHORIZED) {
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::NotAuthorized, Swift::ErrorPayload::Auth, statusMessage)));
LOG4CXX_INFO(logger, m_jid.toString() << ": Generating error presence: PARTICIPANT_FLAG_NOT_AUTHORIZED");
return presence;
}
else if (flag & PARTICIPANT_FLAG_ROOM_NOT_FOUD) {
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::ItemNotFound, Swift::ErrorPayload::Cancel, statusMessage)));
LOG4CXX_INFO(logger, m_jid.toString() << ": Generating error presence: PARTICIPANT_FLAG_ROOM_NOT_FOUND");
return presence;
}
else {
Swift::MUCUserPayload::StatusCode c;
c.code = 110;
p->addStatusCode(c);
if (m_nicknameChanged) {
Swift::MUCUserPayload::StatusCode c;
c.code = 210;
p->addStatusCode(c);
m_nicknameChanged = false;
}
m_sentInitialPresence = true;
}
}
Swift::MUCItem item;
item.affiliation = Swift::MUCOccupant::Member;
item.role = Swift::MUCOccupant::Participant;
if (flag & PARTICIPANT_FLAG_MODERATOR) {
item.affiliation = Swift::MUCOccupant::Admin;
item.role = Swift::MUCOccupant::Moderator;
}
if (!newname.empty()) {
item.nick = newname;
Swift::MUCUserPayload::StatusCode c;
c.code = 303;
p->addStatusCode(c);
presence->setType(Swift::Presence::Unavailable);
}
if (!iconhash.empty()) {
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(new Swift::VCardUpdate (iconhash)));
}
p->addItem(item);
presence->addPayload(SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::Payload>(p));
return presence;
}
void Conversation::setNickname(const std::string &nickname) {
if (!nickname.empty() && m_nickname != nickname) {
m_nicknameChanged = true;
}
m_nickname = nickname;
}
void Conversation::handleRawPresence(Swift::Presence::ref presence) {
// TODO: Detect nickname change.
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
m_participants[presence->getFrom().getResource()].presence = presence;
}
void Conversation::removeJID(const Swift::JID &jid) {
if (m_muc) {
Swift::Presence::ref presence = generatePresence(m_nickname, 0, Swift::StatusShow::None, "");
presence->setTo(jid);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
}
m_jids.remove(jid);
}
void Conversation::handleParticipantChanged(const std::string &nick, Conversation::ParticipantFlag flag, int status, const std::string &statusMessage, const std::string &newname, const std::string &iconhash, const std::string &alias) {
Swift::Presence::ref presence = generatePresence(alias.empty() ? nick : alias, flag, status, statusMessage, newname, iconhash);
if (presence->getType() == Swift::Presence::Unavailable) {
m_participants.erase(nick);
}
else {
m_participants[nick].presence = presence;
m_participants[nick].alias = alias;
}
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
presence->setTo(jid);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
}
if (!newname.empty()) {
handleParticipantChanged(newname, flag, status, statusMessage, "", iconhash);
}
if (m_sentInitialPresence && !m_sentInitialSubject && m_subject) {
m_sentInitialSubject = true;
m_conversationManager->getComponent()->getFrontend()->sendMessage(m_subject);
}
// We send error presences only to inform user that he is disconnected
// from the room. This code must be extended in case we start sending error
// presences in other situations.
if (presence->getType() == Swift::Presence::Error) {
LOG4CXX_INFO(logger, m_jid.toString() << ": Leaving the conversation " << m_legacyName << " because of error.");
m_conversationManager->getUser()->leaveRoom(m_legacyName);
}
}
}
|