soc.2009.transport: 6d81c0a3: Better order in User::receivedPresence a...

hanzz at soc.pidgin.im hanzz at soc.pidgin.im
Tue Jul 14 13:05:48 EDT 2009


-----------------------------------------------------------------
Revision: 6d81c0a370fe09bfb2ac55f406691e29ea7cc7ae
Ancestor: 9b79ee59b6c40b373c609d487979d63fd22307f0
Author: hanzz at soc.pidgin.im
Date: 2009-07-14T10:17:34
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/6d81c0a370fe09bfb2ac55f406691e29ea7cc7ae

Modified files:
        protocols/irc.cpp user.cpp user.h

ChangeLog: 

Better order in User::receivedPresence and independent receivedPresence handler for IRC

-------------- next part --------------
============================================================
--- protocols/irc.cpp	f95d3d8e4f56dced0ce40fe439c16ee9ed7997c6
+++ protocols/irc.cpp	d3d011c5e921d54c5b2ec67256ad7f876601fdc3
@@ -21,6 +21,7 @@
 #include "irc.h"
 #include "../main.h"
 #include "../muchandler.h"
+#include "../usermanager.h"
 
 IRCProtocol::IRCProtocol(GlooxMessageHandler *main){
 	m_main = main;
@@ -93,6 +94,7 @@ bool IRCProtocol::onPresenceReceived(Use
 }
 
 bool IRCProtocol::onPresenceReceived(User *user, const Presence &stanza) {
+	Tag *stanzaTag = stanza.tag();
 	if (stanza.to().username()!="") {
 		IRCProtocolData *data = (IRCProtocolData *) user->protocolData();
 		GHashTable *m_mucs = user->mucs();
@@ -120,11 +122,121 @@ bool IRCProtocol::onPresenceReceived(Use
 			}
 		}
 	}
-	return false;
+	
+	// this presence is for the transport
+	if ( !tempAccountsAllowed() || isMUC(NULL, stanza.to().bare()) ){
+		if(stanza.presence() == Presence::Unavailable) {
+			// disconnect from legacy network if we are connected
+			if (user->isConnected()) {
+				if (g_hash_table_size(user->mucs()) == 0) {
+					Log().Get(user->jid()) << "disconecting";
+					purple_account_disconnect(user->account());
+					m_main->userManager()->removeUserTimer(user);
+				}
+// 				else {
+// 					iter = m_resources.begin();
+// 					m_resource=(*iter).first;
+// 				}
+			}
+			else {
+				if (!user->resources().empty() && int(time(NULL))>int(user->connectionStart())+10){
+					std::map<std::string,Resource> ::iterator iter = user->resources().begin();
+					iter = user->resources().begin();
+					std::string res = (*iter).first;
+					user->setActiveResource(res);
+				}
+				else if (user->account()){
+					Log().Get(user->jid()) << "disconecting2";
+					purple_account_disconnect(user->account());
+				}
+			}
+		} else {
+			std::string resource = stanza.from().resource();
+			std::map<std::string,Resource> ::iterator iter = user->resources().begin();
+			iter = user->resources().find(resource);
+			if(iter == user->resources().end()){
+				user->resources()[resource].priority = stanza.priority();
+				Tag *c = stanzaTag->findChildWithAttrib("xmlns","http://jabber.org/protocol/caps");
+				// presence has caps
+				if (c!=NULL){
+					if (m_main->hasCaps(c->findAttribute("ver"))){
+						user->resources()[resource].capsVersion = c->findAttribute("ver");
+					}
+				}
+				if (user->resources()[resource].priority > user->resources()[user->resource()].priority)
+					user->setActiveResource(resource);
+			}
+
+			Log().Get(user->jid()) << "resource: " << user->resource();
+			if (!user->isConnected()) {
+				// we are not connected to legacy network, so we should do it when disco#info arrive :)
+				Log().Get(user->jid()) << "connecting: resource=" << user->resource();
+				if (user->readyForConnect()==false){
+					user->setReadyForConnect(true);
+					if (user->getResource().capsVersion.empty()){
+						// caps not arrived yet, so we can't connect just now and we have to wait for caps
+					}
+					else{
+						user->connect();
+					}
+				}
+			}
+			else {
+				Log().Get(user->jid()) << "mirroring presence to legacy network";
+				// we are already connected so we have to change status
+				PurpleSavedStatus *status;
+				int PurplePresenceType;
+				std::string statusMessage;
+				
+				// mirror presence types
+				switch(stanza.presence()) {
+					case Presence::Available: {
+						PurplePresenceType=PURPLE_STATUS_AVAILABLE;
+						break;
+					}
+					case Presence::Chat: {
+						PurplePresenceType=PURPLE_STATUS_AVAILABLE;
+						break;
+					}
+					case Presence::Away: {
+						PurplePresenceType=PURPLE_STATUS_AWAY;
+						break;
+					}
+					case Presence::DND: {
+						PurplePresenceType=PURPLE_STATUS_UNAVAILABLE;
+						break;
+					}
+					case Presence::XA: {
+						PurplePresenceType=PURPLE_STATUS_EXTENDED_AWAY;
+						break;
+					}
+					default: break;
+				}
+				// send presence to our legacy network
+				status = purple_savedstatus_new(NULL, (PurpleStatusPrimitive)PurplePresenceType);
+
+				statusMessage.clear();
+
+				if (user->hasTransportFeature(TRANSPORT_MANGLE_STATUS)) {
+					m_main->sql()->getRandomStatus(statusMessage);
+                    statusMessage.append(" - ");
+				}
+
+				statusMessage.append(stanza.status());
+
+				if (!statusMessage.empty())
+					purple_savedstatus_set_message(status,statusMessage.c_str());
+				purple_savedstatus_activate_for_account(status,user->account());
+			}
+		}
+	}
+	delete stanzaTag;
+	return true;
 }
 
 
 void IRCProtocol::onDestroy(User *user) {
-	delete user->protocolData();
+	IRCProtocolData *data = (IRCProtocolData *) user->protocolData();
+	delete data;
 }
 
============================================================
--- user.cpp	c9338d2e560bd740805757911c09b82be3f05dde
+++ user.cpp	b75f2979ddcc65d9d120b712d8df4e28d5f4f4e9
@@ -1053,8 +1053,18 @@ void User::receivedPresence(const Presen
  */
 void User::receivedPresence(const Presence &stanza){
 
-	if (p->protocol()->onPresenceReceived(this, stanza))
+
+	Tag *stanzaTag = stanza.tag();
+	if (!stanzaTag)
 		return;
+	if (m_lang == NULL) {
+		std::string lang = stanzaTag->findAttribute("xml:lang");
+		if (lang == "")
+			lang = "en";
+		setLang(lang.c_str());
+		localization.loadLocale(getLang());
+		Log().Get("LANG") << lang << " " << lang.c_str();
+	}
 
 	if (m_connected){
 
@@ -1082,16 +1092,9 @@ void User::receivedPresence(const Presen
 		}
 	}
 
-	Tag *stanzaTag = stanza.tag();
-	if (!stanzaTag)
+	if (p->protocol()->onPresenceReceived(this, stanza)) {
+		delete stanzaTag;
 		return;
-	if (m_lang == NULL) {
-		std::string lang = stanzaTag->findAttribute("xml:lang");
-		if (lang == "")
-			lang = "en";
-		setLang(lang.c_str());
-		localization.loadLocale(getLang());
-		Log().Get("LANG") << lang << " " << lang.c_str();
 	}
 
 	// this presence is for the transport
============================================================
--- user.h	9b3bb92926f4d285cadb3dad89ed59f0701509a4
+++ user.h	b38e79524dc7c25b1e5ab66cf829d89e75b185b4
@@ -142,14 +142,16 @@ class User {
 			if (priority != -256) m_resources[resource].priority = priority;
 			if (!caps.empty()) m_resources[resource].capsVersion = caps;
 		}
+		void setActiveResource(std::string resource) { m_resource = resource; }
 		bool hasResource(const std::string r) {return m_resources.find(r) != m_resources.end(); }
-		Resource & getResource(const std::string r) { return m_resources[r];}
+		Resource & getResource(const std::string r = "") { if (r.empty()) return m_resources[m_resource]; else return m_resources[r];}
 		
 		PurpleAccount *account() { return m_account; }
 		std::map<std::string,Resource> & resources() { return m_resources; }
 		int reconnectCount() { return m_reconnectCount; }
 		bool isVIP() { return m_vip; }
 		bool readyForConnect() { return m_readyForConnect; }
+		void setReadyForConnect(bool ready) { m_readyForConnect = ready; }
 		std::string & username() { return m_username; }
 		std::string & jid() { return m_jid; }
 		std::string & resource() { return m_resource; }


More information about the Commits mailing list