soc.2009.transport: df1bcd1a: Added fist support for more networks whe...
hanzz at soc.pidgin.im
hanzz at soc.pidgin.im
Wed Jul 8 06:21:14 EDT 2009
-----------------------------------------------------------------
Revision: df1bcd1abffc000060e72cbf51963d52a5e06116
Ancestor: 19ccfab6a5c710a9aeaf4f97fcb41281915065ce
Author: hanzz at soc.pidgin.im
Date: 2009-07-08T10:17:36
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/df1bcd1abffc000060e72cbf51963d52a5e06116
Modified files:
main.cpp muchandler.cpp protocols/abstractprotocol.h
protocols/irc.h user.cpp user.h usermanager.cpp
usermanager.h
ChangeLog:
Added fist support for more networks when using IRC.
-------------- next part --------------
============================================================
--- main.cpp f46041ac93f13d8539a87a80f8a16df860bdcfd9
+++ main.cpp e0f407e8249bf0ef194d20b688f32f902d5c25d4
@@ -1119,8 +1119,15 @@ void GlooxMessageHandler::handleSubscrip
reply->addAttribute( "type", "subscribed" );
j->send( reply );
}
-
- User *user = userManager()->getUserByJID(stanza.from().bare());
+
+ User *user;
+ if (protocol()->isMUC(NULL, stanza.to().bare())) {
+ std::string server = stanza.to().username().substr(stanza.to().username().find("%") + 1, stanza.to().username().length() - stanza.to().username().find("%"));
+ user = userManager()->getUserByJID(stanza.from().bare() + server);
+ }
+ else {
+ user = userManager()->getUserByJID(stanza.from().bare());
+ }
if (user)
user->receivedSubscription(stanza);
@@ -1134,7 +1141,7 @@ void GlooxMessageHandler::handlePresence
Tag *c = NULL;
Log().Get(stanza.from().full()) << "Presence received (" << stanza.subtype() << ") for: " << stanza.to().full();
- if (stanza.presence() != Presence::Unavailable && stanza.to().username() == ""){
+ if (stanza.presence() != Presence::Unavailable && ((stanza.to().username() == "" && !protocol()->tempAccountsAllowed()) || protocol()->isMUC(NULL, stanza.to().bare()))){
Tag *stanzaTag = stanza.tag();
if (!stanzaTag) return;
Tag *c = stanzaTag->findChildWithAttrib("xmlns","http://jabber.org/protocol/caps");
@@ -1168,8 +1175,14 @@ void GlooxMessageHandler::handlePresence
}
delete stanzaTag;
}
-
- User *user = userManager()->getUserByJID(stanza.from().bare());
+ User *user;
+ if (protocol()->isMUC(NULL, stanza.to().bare())) {
+ std::string server = stanza.to().username().substr(stanza.to().username().find("%") + 1, stanza.to().username().length() - stanza.to().username().find("%"));
+ user = userManager()->getUserByJID(stanza.from().bare() + server);
+ }
+ else {
+ user = userManager()->getUserByJID(stanza.from().bare());
+ }
if (user==NULL){
// we are not connected and probe arrived => answer with unavailable
if (stanza.subtype() == Presence::Probe){
@@ -1180,9 +1193,9 @@ void GlooxMessageHandler::handlePresence
tag->addAttribute("type","unavailable");
j->send(tag);
}
- else if (stanza.to().username() == "" && stanza.presence() != Presence::Unavailable){
+ else if (((stanza.to().username() == "" && !protocol()->tempAccountsAllowed()) || protocol()->isMUC(NULL, stanza.to().bare())) && stanza.presence() != Presence::Unavailable){
UserRow res = sql()->getUserByJid(stanza.from().bare());
- if(res.id==-1) {
+ if(res.id==-1 && !protocol()->tempAccountsAllowed()) {
// presence from unregistered user
Log().Get(stanza.from().full()) << "This user is not registered";
return;
@@ -1196,7 +1209,13 @@ void GlooxMessageHandler::handlePresence
}
Log().Get(stanza.from().full()) << "Creating new User instance";
- user = new User(this, stanza.from(), res.uin, res.password);
+ if (protocol()->tempAccountsAllowed()) {
+ std::string server = stanza.to().username().substr(stanza.to().username().find("%") + 1, stanza.to().username().length() - stanza.to().username().find("%"));
+ std::cout << "SERVER" << stanza.from().bare() + server << "\n";
+ user = new User(this, stanza.from(), stanza.to().resource() + "@" + server, "", stanza.from().bare() + server);
+ }
+ else
+ user = new User(this, stanza.from(), res.uin, res.password, stanza.from().bare());
if (c!=NULL)
if(hasCaps(c->findAttribute("ver")))
user->setResource(stanza.from().resource(), stanza.priority(), c->findAttribute("ver"));
@@ -1218,7 +1237,13 @@ void GlooxMessageHandler::handlePresence
// user->init(this);
m_userManager->addUser(user);
user->receivedPresence(stanza);
- g_timeout_add(15000,&connectUser,g_strdup(stanza.from().bare().c_str()));
+ if (protocol()->isMUC(NULL, stanza.to().bare())) {
+ std::string server = stanza.to().username().substr(stanza.to().username().find("%") + 1, stanza.to().username().length() - stanza.to().username().find("%"));
+ server = stanza.from().bare() + server;
+ g_timeout_add(15000,&connectUser,g_strdup(server.c_str()));
+ }
+ else
+ g_timeout_add(15000,&connectUser,g_strdup(stanza.from().bare().c_str()));
}
}
if (stanza.presence() == Presence::Unavailable && stanza.to().username() == ""){
@@ -1282,14 +1307,21 @@ void GlooxMessageHandler::handleMessage
void GlooxMessageHandler::handleMessage (const Message &msg, MessageSession *session) {
if (msg.from().bare() == msg.to().bare())
return;
- User *user = userManager()->getUserByJID(msg.from().bare());
+ User *user;
+ if (protocol()->isMUC(NULL, msg.to().bare())) {
+ std::string server = msg.to().username().substr(msg.to().username().find("%") + 1, msg.to().username().length() - msg.to().username().find("%"));
+ user = userManager()->getUserByJID(msg.from().bare() + server);
+ }
+ else {
+ user = userManager()->getUserByJID(msg.from().bare());
+ }
if (user!=NULL){
if (user->isConnected()){
Tag *msgTag = msg.tag();
if (!msgTag) return;
Tag *chatstates = msgTag->findChildWithAttrib("xmlns","http://jabber.org/protocol/chatstates");
if (chatstates!=NULL){
- std::string username;
+ std::string username = msg.to().username();
std::for_each( username.begin(), username.end(), replaceJidCharacters() );
user->receivedChatState(username,chatstates->name());
}
============================================================
--- muchandler.cpp 3e18d5f4399f04dec75858d6b72c4095a565516d
+++ muchandler.cpp 6019a7d276737e2f06038197b4f7985efbcd45bf
@@ -42,8 +42,11 @@ Tag * MUCHandler::handlePresence(const P
GHashTable *comps = NULL;
std::string name = stanza.to().username();
PurpleConnection *gc = purple_account_get_connection(m_user->account());
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
+ if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) {
+ if (name.find("%") != std::string::npos)
+ name = name.substr(0, name.find("%"));
comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, name.c_str());
+ }
if (comps) {
serv_join_chat(gc, comps);
}
============================================================
--- protocols/abstractprotocol.h f544b2fbcf8106db79f976d1ebaea8d22c5821fb
+++ protocols/abstractprotocol.h 100bcd8f7e0c099503fa2ce39983778594869ff0
@@ -81,6 +81,10 @@ class AbstractProtocol
* Returns ID of column used for UIN/name/ID of founded users in searchresults
*/
virtual std::string userSearchColumn() { return ""; }
+ /*
+ * Returns true if temporary accounts for MUC are allows (this is useful for IRC, if you want to connect more network from one account)
+ */
+ virtual bool tempAccountsAllowed() { return false; }
};
#endif
============================================================
--- protocols/irc.h d460c8418a38f97e977925f314c33c36f6d9e839
+++ protocols/irc.h 62b1faa991624cab024b0d4cea82efa6b19acb08
@@ -39,8 +39,8 @@ class IRCProtocol : AbstractProtocol
std::list<std::string> buddyFeatures();
std::string text(const std::string &key);
Tag *getVCardTag(User *user, GList *vcardEntries);
- bool isMUC(User *user, const std::string &jid) { return jid.find("#") == 0; }
-
+ bool isMUC(User *user, const std::string &jid) { return jid.find("#") == 0 && jid.find("%") != std::string::npos; }
+ bool tempAccountsAllowed() { return true; }
private:
GlooxMessageHandler *m_main;
============================================================
--- user.cpp 1d2333356d169ad259deff883aaebcabb15a2a07
+++ user.cpp 778cf3e19c98e3208643e0f187da5760f118c008
@@ -48,7 +48,7 @@ static void sendXhtmlTag(Tag *tag, Tag *
GlooxMessageHandler::instance()->j->send(stanzaTag);
}
-User::User(GlooxMessageHandler *parent, JID jid, const std::string &username, const std::string &password){
+User::User(GlooxMessageHandler *parent, JID jid, const std::string &username, const std::string &password, const std::string &userKey){
p = parent;
m_jid = jid.bare();
Resource r;
@@ -56,6 +56,7 @@ User::User(GlooxMessageHandler *parent,
m_resource = jid.resource();
m_username = username;
m_password = password;
+ m_userKey = userKey;
m_connected = false;
m_roster = p->sql()->getRosterByJid(m_jid);
m_vip = p->sql()->isVIP(m_jid);
@@ -70,6 +71,7 @@ User::User(GlooxMessageHandler *parent,
m_lang = NULL;
this->features = 6; // TODO: I can't be hardcoded
m_mucs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ m_tempAccounts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
PurpleValue *value;
// check default settings
@@ -528,8 +530,10 @@ void User::purpleConversationWriteChat(P
if (who == NULL)
return;
- std::string name(who);
- MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, purple_conversation_get_name(conv));
+// std::string name(who);
+ std::string name(purple_conversation_get_name(conv));
+ name = name + "%" + JID(m_username).server();
+ MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, name.c_str());
if (!isOpenedConversation(name)) {
m_conversations[name].conv = conv;
if (muc)
@@ -631,6 +635,7 @@ void User::purpleChatAddUsers(PurpleConv
void User::purpleChatAddUsers(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) {
std::string name(purple_conversation_get_name(conv));
+ name = name + "%" + JID(m_username).server();
MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, name.c_str());
if (!muc)
return;
@@ -642,14 +647,18 @@ void User::purpleChatRenameUser(PurpleCo
}
void User::purpleChatRenameUser(PurpleConversation *conv, const char *old_name, const char *new_name, const char *new_alias) {
- MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, purple_conversation_get_name(conv));
+ std::string name(purple_conversation_get_name(conv));
+ name = name + "%" + JID(m_username).server();
+ MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, name.c_str());
if (muc) {
muc->renameUser(old_name, new_name, new_alias);
}
}
void User::purpleChatRemoveUsers(PurpleConversation *conv, GList *users) {
- MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, purple_conversation_get_name(conv));
+ std::string name(purple_conversation_get_name(conv));
+ name = name + "%" + JID(m_username).server();
+ MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, name.c_str());
if (muc) {
muc->removeUsers(users);
}
@@ -753,7 +762,8 @@ void User::receivedMessage(const Message
void User::receivedMessage(const Message& msg){
PurpleConversation * conv;
std::string username = msg.to().username();
- std::for_each( username.begin(), username.end(), replaceJidCharacters() );
+ if (!p->protocol()->isMUC(this, username))
+ std::for_each( username.begin(), username.end(), replaceJidCharacters() );
// open new conversation or get the opened one
if (!isOpenedConversation(username)){
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,m_account,username.c_str());
@@ -764,7 +774,6 @@ void User::receivedMessage(const Message
conv = m_conversations[username].conv;
m_conversations[username].resource = msg.from().resource();
}
-
std::string body = msg.body();
if (body.find("/transport ") == 0) {
@@ -868,7 +877,7 @@ void User::connect(){
m_connectionStart = time(NULL);
m_readyForConnect = false;
purple_account_set_string(m_account,"bind",std::string(m_bindIP).c_str());
- purple_account_set_string(m_account,"lastUsedJid",std::string(m_jid +"/"+m_resource).c_str());
+ purple_account_set_string(m_account,"lastUsedJid",m_userKey.c_str());
purple_account_set_password(m_account,m_password.c_str());
Log().Get(m_jid) << "UIN:" << m_username << " PASSWORD:" << m_password;
@@ -908,6 +917,16 @@ void User::connected() {
void User::connected() {
m_connected = true;
m_reconnectCount = 0;
+ for (std::list <Tag*>::iterator it = m_autoConnectRooms.begin(); it != m_autoConnectRooms.end() ; it++ ) {
+ Presence stanza((*it));
+ MUCHandler *muc = new MUCHandler(this, stanza.to().bare(), stanza.from().full());
+ g_hash_table_replace(m_mucs, g_strdup(stanza.to().username().c_str()), muc);
+ Tag * ret = muc->handlePresence(stanza);
+ if (ret)
+ p->j->send(ret);
+ delete (*it);
+ };
+
}
void User::receivedSubscription(const Subscription &subscription) {
@@ -1037,33 +1056,35 @@ void User::receivedPresence(const Presen
* Received jabber presence...
*/
void User::receivedPresence(const Presence &stanza){
- // we're connected
-
-
- if (m_connected){
-
- if (stanza.to().username()!="") {
- MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, stanza.to().username().c_str());
- if (muc) {
- Tag * ret = muc->handlePresence(stanza);
- if (ret)
- p->j->send(ret);
- if (stanza.presence() == Presence::Unavailable) {
- g_hash_table_remove(m_mucs, stanza.to().username().c_str());
- m_conversations.erase(stanza.to().username());
- delete muc;
- }
+ if (stanza.to().username()!="") {
+ MUCHandler *muc = (MUCHandler*) g_hash_table_lookup(m_mucs, stanza.to().username().c_str());
+ if (muc) {
+ Tag * ret = muc->handlePresence(stanza);
+ if (ret)
+ p->j->send(ret);
+ if (stanza.presence() == Presence::Unavailable) {
+ g_hash_table_remove(m_mucs, stanza.to().username().c_str());
+ m_conversations.erase(stanza.to().username());
+ delete muc;
}
- else if (p->protocol()->isMUC(this, stanza.to().bare()) && stanza.presence() != Presence::Unavailable) {
+ }
+ else if (p->protocol()->isMUC(this, stanza.to().bare()) && stanza.presence() != Presence::Unavailable) {
+ if (m_connected) {
MUCHandler *muc = new MUCHandler(this, stanza.to().bare(), stanza.from().full());
g_hash_table_replace(m_mucs, g_strdup(stanza.to().username().c_str()), muc);
Tag * ret = muc->handlePresence(stanza);
if (ret)
p->j->send(ret);
}
+ else {
+ m_autoConnectRooms.push_back(stanza.tag());
+ }
}
+ }
+ if (m_connected){
+
// respond to probe presence
if (stanza.subtype() == Presence::Probe && stanza.to().username()!=""){
std::string name(stanza.to().username());
@@ -1101,7 +1122,7 @@ void User::receivedPresence(const Presen
}
// this presence is for the transport
- if(stanza.to().username() == ""){
+ if(stanza.to().username() == "" || ((!p->protocol()->tempAccountsAllowed()) || p->protocol()->isMUC(NULL, stanza.to().bare()))){
if(stanza.presence() == Presence::Unavailable) {
// disconnect from legacy network if we are connected
std::map<std::string,Resource> ::iterator iter = m_resources.begin();
@@ -1281,6 +1302,9 @@ User::~User(){
m_roster.clear();
m_conversations.clear();
m_authRequests.clear();
+ g_hash_table_destroy(m_mucs);
+ g_hash_table_destroy(m_tempAccounts);
+ g_hash_table_destroy(m_settings);
}
============================================================
--- user.h 1f241651ccca6844d64b4cd5c47ad2ec79f49a8a
+++ user.h 0c0847596a3083b310d20db37596fd764f0c6939
@@ -75,7 +75,7 @@ class User {
class User {
public:
- User(GlooxMessageHandler *parent, JID jid, const std::string &username, const std::string &password);
+ User(GlooxMessageHandler *parent, JID jid, const std::string &username, const std::string &password, const std::string &userKey);
~User();
void connect();
@@ -161,9 +161,13 @@ class User {
GHashTable *settings() { return m_settings; }
GlooxMessageHandler *p;
+ std::string & userKey() { return m_userKey; }
private:
+ std::string m_userKey;
PurpleAccount *m_account; // PurpleAccount to which this user is connected
+ GHashTable *m_tempAccounts; // temp accounts for MUC (need to have them because of connection to more network)
+ std::list <Tag *> m_autoConnectRooms;
guint m_syncTimer; // timer used for syncing purple buddy list and roster
int m_subscribeLastCount; // number of buddies which was in subscribeCache in previous iteration of m_syncTimer
bool m_vip; // true if the user is VIP
============================================================
--- usermanager.cpp a4c6f22a6dd5f711996f393413dc2a2908bc36f2
+++ usermanager.cpp 448dbaca07667f33c290b464a2fed82140756217
@@ -41,7 +41,7 @@ User *UserManager::getUserByJID(std::str
}
User *UserManager::getUserByJID(std::string barejid){
- if (m_cachedUser && barejid == m_cachedUser->jid()) {
+ if (m_cachedUser && barejid == m_cachedUser->userKey()) {
return m_cachedUser;
}
User *user = (User*) g_hash_table_lookup(m_users, barejid.c_str());
@@ -57,8 +57,8 @@ void UserManager::removeUser(User *user)
void UserManager::removeUser(User *user){
Log().Get("logout") << "removing user";
- g_hash_table_remove(m_users, user->jid().c_str());
- if (m_cachedUser && user->jid() == m_cachedUser->jid()) {
+ g_hash_table_remove(m_users, user->userKey().c_str());
+ if (m_cachedUser && user->userKey() == m_cachedUser->userKey()) {
m_cachedUser = NULL;
}
delete user;
@@ -67,8 +67,8 @@ void UserManager::removeUserTimer(User *
void UserManager::removeUserTimer(User *user){
Log().Get("logout") << "removing user by timer";
- g_hash_table_remove(m_users, user->jid().c_str());
- if (m_cachedUser && user->jid() == m_cachedUser->jid()) {
+ g_hash_table_remove(m_users, user->userKey().c_str());
+ if (m_cachedUser && user->userKey() == m_cachedUser->userKey()) {
m_cachedUser = NULL;
}
// this will be called by gloop after all
============================================================
--- usermanager.h ec329deda93f3d3d451bf9ce02429c71b5cc6b4b
+++ usermanager.h 85a866f871c5ebeed1f12c055f311a60d50a99fb
@@ -35,7 +35,7 @@ class UserManager
~UserManager();
User *getUserByJID(std::string barejid);
User *getUserByAccount(PurpleAccount *account);
- void addUser(User *user) { g_hash_table_replace(m_users, g_strdup(user->jid().c_str()), user); }
+ void addUser(User *user) { g_hash_table_replace(m_users, g_strdup(user->userKey().c_str()), user); }
void removeUser(User *user);
void removeUserTimer(User *user);
void buddyOnline();
More information about the Commits
mailing list