Changeset - f47187d464dc
[Not reviewed]
0 2 0
HanzZ - 14 years ago 2011-08-13 02:03:49
hanzz.k@gmail.com
Probably working invisible state, but I'm lazy to test it after midnight...
2 files changed with 14 insertions and 1 deletions:
0 comments (0 inline, 0 general)
backends/libpurple/main.cpp
Show inline comments
 
@@ -266,96 +266,99 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				for (GList *it = purple_get_conversations(); it; ) {
 
					PurpleConversation *conv = (PurpleConversation *) it->data;
 
					it = it->next;
 
					if (purple_conversation_get_account(conv) == account)
 
						purple_conversation_destroy(conv);
 
				}
 

	
 
				/* Remove this account's pounces */
 
					// purple_pounce_destroy_all_by_account(account);
 

	
 
				/* This will cause the deletion of an old buddy icon. */
 
				purple_buddy_icons_set_account_icon(account, NULL, 0);
 

	
 
				purple_account_destroy(account);
 
				// force returning of memory chunks allocated by libxml2 to kernel
 
				malloc_trim(0);
 
// 				VALGRIND_DO_LEAK_CHECK;
 
			}
 
		}
 

	
 
		void handleStatusChangeRequest(const std::string &user, int status, const std::string &statusMessage) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				int st;
 
				switch(status) {
 
					case Swift::StatusShow::Away: {
 
						st = PURPLE_STATUS_AWAY;
 
						if (!purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AWAY))
 
							st = PURPLE_STATUS_EXTENDED_AWAY;
 
						else
 
							st = PURPLE_STATUS_AWAY;
 
						break;
 
					}
 
					case Swift::StatusShow::DND: {
 
						st = PURPLE_STATUS_UNAVAILABLE;
 
						break;
 
					}
 
					case Swift::StatusShow::XA: {
 
						if (!purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_EXTENDED_AWAY))
 
							st = PURPLE_STATUS_AWAY;
 
						else
 
							st = PURPLE_STATUS_EXTENDED_AWAY;
 
						break;
 
					}
 
					case Swift::StatusShow::None: {
 
						st = PURPLE_STATUS_OFFLINE;
 
						break;
 
					}
 
					case 255:
 
						st = PURPLE_STATUS_INVISIBLE;
 
						break;
 
					default:
 
						st = PURPLE_STATUS_AVAILABLE;
 
						break;
 
				}
 
				gchar *_markup = purple_markup_escape_text(statusMessage.c_str(), -1);
 
				std::string markup(_markup);
 
				g_free(_markup);
 

	
 
				// we are already connected so we have to change status
 
				const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, (PurpleStatusPrimitive) st);
 
				if (status_type != NULL) {
 
					// send presence to legacy network
 
					if (!markup.empty()) {
 
						purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, "message", markup.c_str(), NULL);
 
					}
 
					else {
 
						purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
 
					}
 
				}
 
			}
 
		}
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account);
 
				if (!conv) {
 
					conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str());
 
				}
 
				if (xhtml.empty()) {
 
					gchar *_markup = purple_markup_escape_text(message.c_str(), -1);
 
					purple_conv_im_send(PURPLE_CONV_IM(conv), _markup);
 
					g_free(_markup);
 
				}
 
				else {
 
					purple_conv_im_send(PURPLE_CONV_IM(conv), xhtml.c_str());
 
				}
 
			}
 
		}
 

	
 
		void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				std::string name = legacyName;
 
				if (CONFIG_STRING(config, "service.protocol") == "any" && legacyName.find("prpl-") == 0) {
 
					name = name.substr(name.find(".") + 1);
 
				}
 
				serv_get_info(purple_account_get_connection(account), name.c_str());
src/networkpluginserver.cpp
Show inline comments
 
/**
 
 * libtransport -- C++ library for easy XMPP Transports development
 
 *
 
 * Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
 
 *
 
 * 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 "transport/networkpluginserver.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/storagebackend.h"
 
#include "transport/rostermanager.h"
 
#include "transport/usermanager.h"
 
#include "transport/conversationmanager.h"
 
#include "transport/localbuddy.h"
 
#include "transport/config.h"
 
#include "transport/conversation.h"
 
#include "transport/vcardresponder.h"
 
#include "transport/rosterresponder.h"
 
#include "blockresponder.h"
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Elements/StreamError.h"
 
#include "Swiften/Network/BoostConnectionServer.h"
 
#include "Swiften/Elements/AttentionPayload.h"
 
#include "Swiften/Elements/XHTMLIMPayload.h"
 
#include "Swiften/Elements/InvisiblePayload.h"
 
#include "pbnetwork.pb.h"
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
#include "log4cxx/logger.h"
 
#include "popt.h"
 

	
 
using namespace log4cxx;
 

	
 
namespace Transport {
 

	
 
static unsigned long backend_id;
 

	
 
static LoggerPtr logger = Logger::getLogger("NetworkPluginServer");
 

	
 
class NetworkConversation : public Conversation {
 
	public:
 
		NetworkConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) {
 
		}
 

	
 
		// Called when there's new message to legacy network from XMPP network
 
		void sendMessage(boost::shared_ptr<Swift::Message> &message) {
 
			onMessageToSend(this, message);
 
		}
 

	
 
		boost::signal<void (NetworkConversation *, boost::shared_ptr<Swift::Message> &)> onMessageToSend;
 
};
 

	
 
class NetworkFactory : public Factory {
 
	public:
 
		NetworkFactory(NetworkPluginServer *nps) {
 
			m_nps = nps;
 
		}
 

	
 
		// Creates new conversation (NetworkConversation in this case)
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			NetworkConversation *nc = new NetworkConversation(conversationManager, legacyName);
 
			nc->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, m_nps, _1, _2));
 
			return nc;
 
		}
 

	
 
		// Creates new LocalBuddy
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) buddyInfo.flags);
 
@@ -740,97 +741,106 @@ void NetworkPluginServer::handleUserCreated(User *user) {
 
	Backend *c = getFreeClient();
 

	
 
	// Add user to queue if there's no free backend to handle him so far.
 
	if (!c) {
 
		LOG4CXX_INFO(logger, "There is no backend to handle user " << user->getJID().toString() << ". Adding him to queue.");
 
		m_waitingUsers.push_back(user);
 
		return;
 
	}
 

	
 
	// Associate users with backend
 
	user->setData(c);
 
	c->users.push_back(user);
 

	
 
// 	UserInfo userInfo = user->getUserInfo();
 
	user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user));
 
	user->onPresenceChanged.connect(boost::bind(&NetworkPluginServer::handleUserPresenceChanged, this, user, _1));
 
	user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3));
 
	user->onRoomLeft.connect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1));
 
}
 

	
 
void NetworkPluginServer::handleUserReadyToConnect(User *user) {
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Login login;
 
	login.set_user(user->getJID().toBare());
 
	login.set_legacyname(userInfo.uin);
 
	login.set_password(userInfo.password);
 

	
 
	std::string message;
 
	login.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGIN);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleUserPresenceChanged(User *user, Swift::Presence::ref presence) {
 
	if (presence->getShow() == Swift::StatusShow::None)
 
		return;
 

	
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Status status;
 
	status.set_username(user->getJID().toBare());
 
	status.set_status((int) presence->getShow());
 

	
 
	bool isInvisible = presence->getPayload<Swift::InvisiblePayload>() != NULL;
 
	if (isInvisible) {
 
		LOG4CXX_INFO(logger, "This presence is invisible");
 
		status.set_status(255);
 
	}
 
	else {
 
		status.set_status((int) presence->getShow());
 
	}
 

	
 
	status.set_statusmessage(presence->getStatus());
 

	
 
	std::string message;
 
	status.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_STATUS_CHANGED);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) {
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Room room;
 
	room.set_username(user->getJID().toBare());
 
	room.set_nickname(nickname);
 
	room.set_room(r);
 
	room.set_password(password);
 

	
 
	std::string message;
 
	room.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM);
 
 
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 

	
 
	NetworkConversation *conv = new NetworkConversation(user->getConversationManager(), r, true);
 
	conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2));
 
	conv->setNickname(nickname);
 
}
 

	
 
void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) {
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Room room;
 
	room.set_username(user->getJID().toBare());
 
	room.set_nickname("");
 
	room.set_room(r);
 
	room.set_password("");
 

	
0 comments (0 inline, 0 general)