diff --git a/application/Conversation.cpp b/application/Conversation.cpp index cb1cef2..67b6a3f 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -267,9 +267,9 @@ Conversation::RemoveUser(User* user) BString -Conversation::OwnUserId() +Conversation::GetOwnId() { - return _GetServer()->GetOwnContact(); + return fLooper->GetOwnId(); } @@ -373,7 +373,7 @@ Conversation::_EnsureUser(BMessage* msg) if (id.IsEmpty() == true) return NULL; User* user = UserById(id); - User* serverUser = _GetServer()->UserById(id); + User* serverUser = fLooper->UserById(id); // Not here, but found in server if (user == NULL && serverUser != NULL) { @@ -383,10 +383,11 @@ Conversation::_EnsureUser(BMessage* msg) } // Not anywhere; create user else if (user == NULL) { - user = new User(id, _GetServer()->Looper()); + user = new User(id, + ((TheApp*)be_app)->GetMainWindow()->GetServer()->Looper()); user->SetProtocolLooper(fLooper); - _GetServer()->AddUser(user); + fLooper->AddUser(user); fUsers.AddItem(id, user); GetView()->UpdateUserList(fUsers); @@ -398,10 +399,3 @@ Conversation::_EnsureUser(BMessage* msg) } -Server* -Conversation::_GetServer() -{ - return ((TheApp*)be_app)->GetMainWindow()->GetServer(); -} - - diff --git a/application/Conversation.h b/application/Conversation.h index ed88612..f6d1fdc 100644 --- a/application/Conversation.h +++ b/application/Conversation.h @@ -59,7 +59,7 @@ public: UserMap Users(); User* UserById(BString id); - BString OwnUserId(); + BString GetOwnId(); void AddUser(User* user); void RemoveUser(User* user); @@ -72,8 +72,7 @@ private: status_t _GetChatLogs(BMessage* msg); void _EnsureLogPath(); - User* _EnsureUser(BMessage* msg); - Server* _GetServer(); + User* _EnsureUser(BMessage* msg); BMessenger fMessenger; ProtocolLooper* fLooper; diff --git a/application/Makefile b/application/Makefile index 9d0a932..9ec10ab 100644 --- a/application/Makefile +++ b/application/Makefile @@ -53,7 +53,6 @@ SRCS = \ application/preferences/AccountView.cpp \ application/preferences/CayaPreferences.cpp \ application/preferences/PreferencesChatWindow.cpp \ - application/preferences/PreferencesDialog.cpp \ application/preferences/PreferencesAccounts.cpp \ application/preferences/PreferencesBehavior.cpp \ application/preferences/PreferencesReplicant.cpp \ @@ -76,6 +75,7 @@ SRCS = \ application/windows/AboutWindow.cpp \ application/windows/JoinWindow.cpp \ application/windows/MainWindow.cpp \ + application/windows/PreferencesWindow.cpp \ application/windows/RosterWindow.cpp \ application/windows/UserInfoWindow.cpp diff --git a/application/ProtocolLooper.cpp b/application/ProtocolLooper.cpp index 0bfd57a..0391b82 100644 --- a/application/ProtocolLooper.cpp +++ b/application/ProtocolLooper.cpp @@ -8,16 +8,19 @@ * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com */ +#include "ProtocolLooper.h" + #include #include "Account.h" -#include "ProtocolLooper.h" +#include "Conversation.h" -ProtocolLooper::ProtocolLooper(CayaProtocol* protocol) +ProtocolLooper::ProtocolLooper(CayaProtocol* protocol, int64 instance) : BLooper(), - fProtocol(protocol) + fProtocol(protocol), + fInstance(instance) { Account* account = reinterpret_cast( protocol->MessengerInterface()); @@ -43,3 +46,110 @@ ProtocolLooper::Protocol() { return fProtocol; } + + +ChatMap +ProtocolLooper::Conversations() const +{ + return fChatMap; +} + + +Conversation* +ProtocolLooper::ConversationById(BString id) +{ + bool found = false; + return fChatMap.ValueFor(id, &found); +} + + +void +ProtocolLooper::AddConversation(Conversation* chat) +{ + fChatMap.AddItem(chat->GetId(), chat); +} + + +void +ProtocolLooper::RemoveConversation(Conversation* chat) +{ + fChatMap.RemoveItemFor(chat->GetId()); +} + + +RosterMap +ProtocolLooper::Contacts() const +{ + return fRosterMap; +} + + +Contact* +ProtocolLooper::ContactById(BString id) +{ + bool found = false; + return fRosterMap.ValueFor(id, &found); +} + + +void +ProtocolLooper::AddContact(Contact* contact) +{ + fRosterMap.AddItem(contact->GetId(), contact); +} + + +UserMap +ProtocolLooper::Users() const +{ + UserMap users = fUserMap; + + for (int i = 0; i < fRosterMap.CountItems(); i++) { + User* user = (User*)fRosterMap.ValueAt(i); + users.AddItem(user->GetId(), user); + } + + return users; +} + + +User* +ProtocolLooper::UserById(BString id) +{ + bool found = false; + User* user = ContactById(id); + if (user == NULL) + user = fUserMap.ValueFor(id, &found); + + return user; +} + + +void +ProtocolLooper::AddUser(User* user) +{ + fUserMap.AddItem(user->GetId(), user); +} + + +BString +ProtocolLooper::GetOwnId() +{ + return fMySelf; +} + + +void +ProtocolLooper::SetOwnId(BString user_id) +{ + fMySelf = user_id; +} + + +int64 +ProtocolLooper::GetInstance() +{ + return fInstance; +} + + diff --git a/application/ProtocolLooper.h b/application/ProtocolLooper.h index 87eed76..795effc 100644 --- a/application/ProtocolLooper.h +++ b/application/ProtocolLooper.h @@ -7,19 +7,57 @@ #define _PROTOCOL_LOOPER_H #include +#include + +#include #include "CayaProtocol.h" +class Contact; +class Conversation; +class User; + + +typedef KeyMap ChatMap; +typedef KeyMap RosterMap; +typedef KeyMap UserMap; + + class ProtocolLooper : public BLooper { public: - ProtocolLooper(CayaProtocol* protocol); + ProtocolLooper(CayaProtocol* protocol, int64 instance); - void MessageReceived(BMessage* msg); + void MessageReceived(BMessage* msg); - CayaProtocol* Protocol(); + CayaProtocol* Protocol(); + + ChatMap Conversations() const; + Conversation* ConversationById(BString id); + void AddConversation(Conversation* chat); + void RemoveConversation(Conversation* chat); + + RosterMap Contacts() const; + Contact* ContactById(BString id); + void AddContact(Contact* contact); + + UserMap Users() const; + User* UserById(BString id); + void AddUser(User* user); + + BString GetOwnId(); + void SetOwnId(BString user_id); + + int64 GetInstance(); private: - CayaProtocol* fProtocol; + CayaProtocol* fProtocol; + int64 fInstance; + + BString fMySelf; + + ChatMap fChatMap; + RosterMap fRosterMap; + UserMap fUserMap; }; #endif // _PROTOCOL_LOOPER_H diff --git a/application/Server.cpp b/application/Server.cpp index 4072e8e..2a4390a 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -46,15 +46,15 @@ Server::Quit() Contact* contact = NULL; Conversation* conversation = NULL; - while (contact = fRosterMap.ValueAt(0)) { - contact->DeletePopUp(); - fRosterMap.RemoveItemAt(0); - } +// while (contact = fRosterMap.ValueAt(0)) { +// contact->DeletePopUp(); +// fRosterMap.RemoveItemAt(0); +// } - while (conversation = fChatMap.ValueAt(0)) { - fChatMap.RemoveItemAt(0); - delete conversation; - } +// while (conversation = fChatMap.ValueAt(0)) { +// fChatMap.RemoveItemAt(0); +// delete conversation; +// } } @@ -83,7 +83,7 @@ Server::Filter(BMessage* message, BHandler **target) BString id = message->FindString("chat_id"); if (id.Length() > 0) { bool found = false; - Conversation* item = fChatMap.ValueFor(id, &found); +// Conversation* item = fChatMap.ValueFor(id, &found); } result = B_SKIP_MESSAGE; break; @@ -170,7 +170,7 @@ Server::ImMessage(BMessage* msg) { Contact* contact = _EnsureContact(msg); if (contact != NULL) { - fMySelf = contact->GetId(); + contact->GetProtocolLooper()->SetOwnId(contact->GetId()); } break; } @@ -229,7 +229,7 @@ Server::ImMessage(BMessage* msg) { BString user_id = msg->FindString("user_id"); if (user_id.IsEmpty() == false) { - User* user = ContactById(user_id); + User* user = ContactById(user_id, msg->FindInt64("instance")); user->GetProtocolLooper()->PostMessage(msg); } break; @@ -466,7 +466,7 @@ Server::ImMessage(BMessage* msg) void Server::AddProtocolLooper(bigtime_t instanceId, CayaProtocol* cayap) { - ProtocolLooper* looper = new ProtocolLooper(cayap); + ProtocolLooper* looper = new ProtocolLooper(cayap, instanceId); fLoopers.AddItem(instanceId, looper); fAccounts.AddItem(cayap->GetName(), instanceId); } @@ -531,33 +531,53 @@ Server::SendAllProtocolMessage(BMessage* msg) RosterMap Server::Contacts() const { - return fRosterMap; + RosterMap contacts; + + for (int i = 0; i < fAccounts.CountItems(); i++) { + ProtocolLooper* fruitLoop = fLoopers.ValueFor(fAccounts.ValueAt(i)); + if (fruitLoop == NULL) continue; + + RosterMap accContacts = fruitLoop->Contacts(); + for (int i = 0; i < accContacts.CountItems(); i++) + contacts.AddItem(accContacts.KeyAt(i), accContacts.ValueAt(i)); + } + + return contacts; } Contact* -Server::ContactById(BString id) +Server::ContactById(BString id, int64 instance) { - bool found = false; - return fRosterMap.ValueFor(id, &found); + ProtocolLooper* looper = fLoopers.ValueFor(instance); + Contact* result = NULL; + if (looper != NULL) + result = looper->ContactById(id); + return result; } void -Server::AddContact(Contact* contact) +Server::AddContact(Contact* contact, int64 instance) { - fRosterMap.AddItem(contact->GetId(), contact); + ProtocolLooper* looper = fLoopers.ValueFor(instance); + if (looper != NULL) + looper->AddContact(contact); } UserMap Server::Users() const { - UserMap users = fUserMap; + UserMap users; - for (int i = 0; i < fRosterMap.CountItems(); i++) { - User* user = (User*)fRosterMap.ValueAt(i); - users.AddItem(user->GetId(), user); + for (int i = 0; i < fAccounts.CountItems(); i++) { + ProtocolLooper* fruitLoop = fLoopers.ValueFor(fAccounts.ValueAt(i)); + if (fruitLoop == NULL) continue; + + UserMap accUsers = fruitLoop->Users(); + for (int i = 0; i < accUsers.CountItems(); i++) + users.AddItem(accUsers.KeyAt(i), accUsers.ValueAt(i)); } return users; @@ -565,57 +585,69 @@ Server::Users() const User* -Server::UserById(BString id) +Server::UserById(BString id, int64 instance) { - bool found = false; - User* user = ContactById(id); - if (user == NULL) - user = fUserMap.ValueFor(id, &found); - - return user; + ProtocolLooper* looper = fLoopers.ValueFor(instance); + User* result = NULL; + if (looper != NULL) + result = looper->UserById(id); + return result; } void -Server::AddUser(User* user) +Server::AddUser(User* user, int64 instance) { - fUserMap.AddItem(user->GetId(), user); + ProtocolLooper* looper = fLoopers.ValueFor(instance); + if (looper != NULL) + looper->AddUser(user); } ChatMap Server::Conversations() const { - return fChatMap; + ChatMap chats; + + for (int i = 0; i < fAccounts.CountItems(); i++) { + ProtocolLooper* fruitLoop = fLoopers.ValueFor(fAccounts.ValueAt(i)); + if (fruitLoop == NULL) continue; + + ChatMap accChats = fruitLoop->Conversations(); + for (int i = 0; i < accChats.CountItems(); i++) + chats.AddItem(accChats.KeyAt(i), accChats.ValueAt(i)); + } + + return chats; } Conversation* -Server::ConversationById(BString id) +Server::ConversationById(BString id, int64 instance) { - bool found = false; - return fChatMap.ValueFor(id, &found); + ProtocolLooper* looper = fLoopers.ValueFor(instance); + Conversation* result = NULL; + if (looper != NULL) + result = looper->ConversationById(id); + return result; } void -Server::AddConversation(Conversation* chat) +Server::AddConversation(Conversation* chat, int64 instance) { - fChatMap.AddItem(chat->GetId(), chat); + ProtocolLooper* looper = fLoopers.ValueFor(instance); + if (looper != NULL) + looper->AddConversation(chat); } void -Server::RemoveConversation(Conversation* chat) +Server::RemoveConversation(Conversation* chat, int64 instance) { - fChatMap.RemoveItemFor(chat->GetId()); -} - - -BString -Server::GetOwnContact() -{ - return fMySelf; + ProtocolLooper* looper = fLoopers.ValueFor(instance); + if (looper != NULL) + looper->RemoveConversation(chat); } @@ -643,12 +675,15 @@ Contact* Server::_EnsureContact(BMessage* message) { BString id = message->FindString("user_id"); - Contact* contact = ContactById(id); + ProtocolLooper* looper = _LooperFromMessage(message); + if (looper == NULL) return NULL; - if (contact == NULL && id.IsEmpty() == false) { + Contact* contact = looper->ContactById(id); + + if (contact == NULL && id.IsEmpty() == false && looper != NULL) { contact = new Contact(id, Looper()); - contact->SetProtocolLooper(_LooperFromMessage(message)); - AddContact(contact); + contact->SetProtocolLooper(looper); + looper->AddContact(contact); } return contact; @@ -666,12 +701,12 @@ Server::_EnsureUser(BMessage* message) User* Server::_EnsureUser(BString id, ProtocolLooper* protoLooper) { - User* user = UserById(id); + User* user = protoLooper->UserById(id); if (user == NULL && id.IsEmpty() == false) { user = new User(id, Looper()); user->SetProtocolLooper(protoLooper); - AddUser(user); + protoLooper->AddUser(user); } return user; @@ -681,21 +716,21 @@ Server::_EnsureUser(BString id, ProtocolLooper* protoLooper) Conversation* Server::_EnsureConversation(BMessage* message) { - if (!message) + ProtocolLooper* looper; + if (!message || (looper = _LooperFromMessage(message)) == NULL) return NULL; BString chat_id = message->FindString("chat_id"); Conversation* item = NULL; if (chat_id.IsEmpty() == false) { - bool found = false; - item = fChatMap.ValueFor(chat_id, &found); + item = looper->ConversationById(chat_id); - if (!found) { + if (item == NULL) { item = new Conversation(chat_id, Looper()); - item->SetProtocolLooper(_LooperFromMessage(message)); - item->AddUser(ContactById(fMySelf)); - fChatMap.AddItem(chat_id, item); + item->SetProtocolLooper(looper); + item->AddUser(looper->ContactById(looper->GetOwnId())); + looper->AddConversation(item); } } return item; diff --git a/application/Server.h b/application/Server.h index f3fb452..f39ef36 100644 --- a/application/Server.h +++ b/application/Server.h @@ -14,6 +14,7 @@ #include "CayaConstants.h" #include "Contact.h" #include "Conversation.h" +#include "ProtocolLooper.h" #include "User.h" class CayaProtocol; @@ -21,9 +22,6 @@ class RosterItem; class ProtocolLooper; -typedef KeyMap RosterMap; -typedef KeyMap UserMap; -typedef KeyMap ChatMap; typedef KeyMap ProtocolLoopers; typedef KeyMap AccountInstances; @@ -49,20 +47,17 @@ public: void SendAllProtocolMessage(BMessage* msg); RosterMap Contacts() const; - Contact* ContactById(BString id); - void AddContact(Contact* contact); + Contact* ContactById(BString id, int64 instance); + void AddContact(Contact* contact, int64 instance); UserMap Users() const; - User* UserById(BString id); - void AddUser(User* user); + User* UserById(BString id, int64 instance); + void AddUser(User* user, int64 instance); ChatMap Conversations() const; - Conversation* ConversationById(BString id); - void AddConversation(Conversation* chat); - void RemoveConversation(Conversation* chat); - - // TODO: there should be a contact for each account. - BString GetOwnContact(); + Conversation* ConversationById(BString id, int64 instance); + void AddConversation(Conversation* chat, int64 instance); + void RemoveConversation(Conversation* chat, int64 instance); private: ProtocolLooper* _LooperFromMessage(BMessage* message); @@ -76,9 +71,6 @@ private: void _ReplicantStatusNotify(CayaStatus status); - RosterMap fRosterMap; - UserMap fUserMap; - ChatMap fChatMap; ProtocolLoopers fLoopers; AccountInstances fAccounts; diff --git a/application/views/ConversationView.cpp b/application/views/ConversationView.cpp index 62d731a..9e2ff4f 100644 --- a/application/views/ConversationView.cpp +++ b/application/views/ConversationView.cpp @@ -76,9 +76,11 @@ ConversationView::MessageReceived(BMessage* message) BString text = message->FindString("body"); if (text == "") return; + int64 instance = fConversation->GetProtocolLooper()->GetInstance(); BMessage msg(IM_MESSAGE); msg.AddInt32("im_what", IM_SEND_MESSAGE); + msg.AddInt64("instance", instance); msg.AddString("chat_id", fConversation->GetId()); msg.AddString("body", text); fConversation->ImMessage(&msg); diff --git a/application/views/RosterListView.cpp b/application/views/RosterListView.cpp index 74fa984..ee8b048 100644 --- a/application/views/RosterListView.cpp +++ b/application/views/RosterListView.cpp @@ -115,8 +115,11 @@ RosterListView::MessageReceived(BMessage* msg) BMessage* start = new BMessage(IM_MESSAGE); start->AddInt32("im_what", IM_CREATE_CHAT); start->AddString("user_id", user->GetId()); + ProtocolLooper* looper = user->GetProtocolLooper(); + + if (looper != NULL) + looper->PostMessage(start); - user->GetProtocolLooper()->PostMessage(start); break; } diff --git a/application/views/UserListView.cpp b/application/views/UserListView.cpp index f829116..8d44115 100644 --- a/application/views/UserListView.cpp +++ b/application/views/UserListView.cpp @@ -92,7 +92,7 @@ UserListView::_UserPopUp() menu->SetTargetForItems(this); // Now for the moderation items - Role* role = fChat->GetRole(fChat->OwnUserId()); + Role* role = fChat->GetRole(fChat->GetOwnId()); if (role == NULL) return menu; int32 perms = role->fPerms; UserItem* item = (UserItem*)ItemAt(CurrentSelection()); @@ -150,7 +150,7 @@ UserListView::_BlankPopUp() void UserListView::_ModerationAction(int32 im_what) { - Role* role = fChat->GetRole(fChat->OwnUserId()); + Role* role = fChat->GetRole(fChat->GetOwnId()); int32 perms = role->fPerms; UserItem* item = (UserItem*)ItemAt(CurrentSelection()); if (item == NULL) diff --git a/application/windows/MainWindow.cpp b/application/windows/MainWindow.cpp index c7c582c..cfe2813 100644 --- a/application/windows/MainWindow.cpp +++ b/application/windows/MainWindow.cpp @@ -26,7 +26,7 @@ #include "JoinWindow.h" #include "MainWindow.h" #include "NotifyMessage.h" -#include "PreferencesDialog.h" +#include "PreferencesWindow.h" #include "ReplicantStatusView.h" #include "RosterWindow.h" #include "Server.h" @@ -99,8 +99,8 @@ MainWindow::MessageReceived(BMessage* message) switch (message->what) { case CAYA_SHOW_SETTINGS: { - PreferencesDialog* dialog = new PreferencesDialog(); - dialog->Show(); + PreferencesWindow* win = new PreferencesWindow(); + win->Show(); break; } @@ -257,12 +257,8 @@ MainWindow::ImMessage(BMessage* msg) case IM_CONTACT_INFO: case IM_EXTENDED_CONTACT_INFO: case IM_STATUS_SET: - { - if (fServer->ContactById(msg->FindString("user_id")) != NULL) - if (fRosterWindow != NULL) - fRosterWindow->PostMessage(msg); + fRosterWindow->PostMessage(msg); break; - } } } @@ -428,7 +424,7 @@ MainWindow::_EnsureConversationItem(BMessage* msg) ChatMap chats = fServer->Conversations(); BString chat_id = msg->FindString("chat_id"); - Conversation* chat = fServer->ConversationById(chat_id); + Conversation* chat = fServer->ConversationById(chat_id, msg->FindInt64("instance")); if (chat != NULL) { ConversationItem* item = chat->GetListItem(); @@ -466,7 +462,11 @@ MainWindow::_RemoveListItem(ConversationItem* item) index--; fListView->RemoveItem(item); - fServer->RemoveConversation(item->GetConversation()); + Conversation* chat = item->GetConversation(); + ProtocolLooper* looper = chat->GetProtocolLooper(); + + if (chat != NULL && looper != NULL) + looper->RemoveConversation(chat); if (fListView->CountItems() == 0) { fChatView = new ConversationView(); diff --git a/application/preferences/PreferencesDialog.cpp b/application/windows/PreferencesWindow.cpp similarity index 90% rename from application/preferences/PreferencesDialog.cpp rename to application/windows/PreferencesWindow.cpp index 7a2b913..54c0e76 100644 --- a/application/preferences/PreferencesDialog.cpp +++ b/application/windows/PreferencesWindow.cpp @@ -6,21 +6,23 @@ * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com */ +#include "PreferencesWindow.h" + #include #include #include #include -#include "PreferencesDialog.h" #include "PreferencesAccounts.h" #include "PreferencesBehavior.h" #include "PreferencesChatWindow.h" #include "PreferencesReplicant.h" + const uint32 kApply = 'SAVE'; -PreferencesDialog::PreferencesDialog() +PreferencesWindow::PreferencesWindow() : BWindow(BRect(0, 0, 500, 615), "Preferences", B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE) { @@ -44,7 +46,7 @@ PreferencesDialog::PreferencesDialog() void -PreferencesDialog::MessageReceived(BMessage* msg) +PreferencesWindow::MessageReceived(BMessage* msg) { switch (msg->what) { case kApply: diff --git a/application/preferences/PreferencesDialog.h b/application/windows/PreferencesWindow.h similarity index 55% rename from application/preferences/PreferencesDialog.h rename to application/windows/PreferencesWindow.h index 641290f..ae4518f 100644 --- a/application/preferences/PreferencesDialog.h +++ b/application/windows/PreferencesWindow.h @@ -2,16 +2,16 @@ * Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved. * Distributed under the terms of the MIT License. */ -#ifndef _PREFERENCES_DIALOG_H -#define _PREFERENCES_DIALOG_H +#ifndef _PREFERENCES_WINDOW_H +#define _PREFERENCES_WINDOW_H #include -class PreferencesDialog : public BWindow { +class PreferencesWindow : public BWindow { public: - PreferencesDialog(); + PreferencesWindow(); virtual void MessageReceived(BMessage* msg); }; -#endif // _PREFERENCES_DIALOG_H +#endif // _PREFERENCES_WINDOW_H diff --git a/application/windows/RosterWindow.cpp b/application/windows/RosterWindow.cpp index 02a9db0..feb21a5 100644 --- a/application/windows/RosterWindow.cpp +++ b/application/windows/RosterWindow.cpp @@ -102,6 +102,7 @@ RosterWindow::MessageReceived(BMessage* message) User* user = ritem->GetContact(); fMessage->AddString("user_id", user->GetId()); + fMessage->AddInt64("instance", user->GetProtocolLooper()->GetInstance()); fTarget->SendMessage(fMessage); PostMessage(B_QUIT_REQUESTED); @@ -126,11 +127,18 @@ RosterWindow::ImMessage(BMessage* msg) case IM_STATUS_SET: { int32 status; - - if (msg->FindInt32("status", &status) != B_OK) + int64 instance; + BString user_id = msg->FindString("user_id"); + if (msg->FindInt32("status", &status) != B_OK + || msg->FindInt64("instance", &instance) != B_OK + || user_id.IsEmpty() == true) return; - RosterItem* rosterItem = fServer->ContactById(msg->FindString("user_id"))->GetRosterItem(); + Contact* contact = fServer->ContactById(user_id, instance); + if (contact == NULL) + return; + + RosterItem* rosterItem = contact->GetRosterItem(); if (rosterItem) { UpdateListItem(rosterItem); @@ -191,8 +199,19 @@ RosterWindow::ImMessage(BMessage* msg) case IM_CONTACT_INFO: case IM_EXTENDED_CONTACT_INFO: { - RosterItem* rosterItem - = fServer->ContactById(msg->FindString("user_id"))->GetRosterItem(); + int32 status = -1; + int64 instance; + BString user_id = msg->FindString("user_id"); + if (msg->FindInt32("status", &status) != B_OK + || msg->FindInt64("instance", &instance) != B_OK + || user_id.IsEmpty() == true) + return; + + Contact* contact = fServer->ContactById(user_id, instance); + if (contact == NULL) + return; + + RosterItem* rosterItem = contact->GetRosterItem(); if (rosterItem) UpdateListItem(rosterItem); break;