Ensure implicit room-members are real
If a message/event is sent to a room that's tied to a user that hasn't been formally declared (through IM_ROOM_PARTICIPANTS or IM_ROOM_PARTICIPANT_JOINED), that user won't be unconditionally kept anymore. Now, after adding an implicit user, the participant list will be requested again― upon receiving the list, all implicitly-defined users will be removed. If they really existed to begin with, they should be re-added quickly through this re-sending of IM_ROOM_PARTICIPANTS. Ghosts should be treated as ghosts, not users.
This commit is contained in:
parent
0bab0a89a8
commit
5e0782b553
|
@ -10,7 +10,6 @@
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <Notification.h>
|
#include <Notification.h>
|
||||||
#include <StringFormat.h>
|
#include <StringFormat.h>
|
||||||
#include <StringList.h>
|
|
||||||
|
|
||||||
#include "AppPreferences.h"
|
#include "AppPreferences.h"
|
||||||
#include "Cardie.h"
|
#include "Cardie.h"
|
||||||
|
@ -199,6 +198,28 @@ Conversation::ImMessage(BMessage* msg)
|
||||||
_CacheRoomFlags();
|
_CacheRoomFlags();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IM_ROOM_PARTICIPANTS:
|
||||||
|
{
|
||||||
|
// Get rid of implicity-defined users rq
|
||||||
|
for (int i = 0; i < fGuests.CountStrings(); i++) {
|
||||||
|
RemoveUser(UserById(fGuests.StringAt(i)));
|
||||||
|
fGuests.Remove(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
BStringList ids;
|
||||||
|
BStringList names;
|
||||||
|
msg->FindStrings("user_name", &names);
|
||||||
|
if (msg->FindStrings("user_id", &ids) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (int i = 0; i < ids.CountStrings(); i++) {
|
||||||
|
BMessage user;
|
||||||
|
user.AddString("user_name", names.StringAt(i));
|
||||||
|
user.AddString("user_id", ids.StringAt(i));
|
||||||
|
_EnsureUser(&user, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IM_ROOM_PARTICIPANT_JOINED:
|
case IM_ROOM_PARTICIPANT_JOINED:
|
||||||
{
|
{
|
||||||
BString user_id;
|
BString user_id;
|
||||||
|
@ -206,7 +227,7 @@ Conversation::ImMessage(BMessage* msg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (UserById(user_id) == NULL) {
|
if (UserById(user_id) == NULL) {
|
||||||
_EnsureUser(msg);
|
_EnsureUser(msg, false);
|
||||||
GetView()->MessageReceived(msg);
|
GetView()->MessageReceived(msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -437,10 +458,12 @@ Conversation::UserById(BString id)
|
||||||
void
|
void
|
||||||
Conversation::AddUser(User* user)
|
Conversation::AddUser(User* user)
|
||||||
{
|
{
|
||||||
|
if (user == NULL)
|
||||||
|
return;
|
||||||
BMessage msg;
|
BMessage msg;
|
||||||
msg.AddString("user_id", user->GetId());
|
msg.AddString("user_id", user->GetId());
|
||||||
msg.AddString("user_name", user->GetName());
|
msg.AddString("user_name", user->GetName());
|
||||||
_EnsureUser(&msg);
|
_EnsureUser(&msg, false);
|
||||||
_SortConversationList();
|
_SortConversationList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +471,8 @@ Conversation::AddUser(User* user)
|
||||||
void
|
void
|
||||||
Conversation::RemoveUser(User* user)
|
Conversation::RemoveUser(User* user)
|
||||||
{
|
{
|
||||||
|
if (user == NULL)
|
||||||
|
return;
|
||||||
fUsers.RemoveItemFor(user->GetId());
|
fUsers.RemoveItemFor(user->GetId());
|
||||||
user->UnregisterObserver(this);
|
user->UnregisterObserver(this);
|
||||||
GetView()->UpdateUserList(fUsers);
|
GetView()->UpdateUserList(fUsers);
|
||||||
|
@ -473,7 +498,8 @@ Conversation::SetRole(BString id, Role* role)
|
||||||
fRoles.RemoveItemFor(id);
|
fRoles.RemoveItemFor(id);
|
||||||
delete oldRole;
|
delete oldRole;
|
||||||
}
|
}
|
||||||
fRoles.AddItem(id, role);
|
if (role != NULL)
|
||||||
|
fRoles.AddItem(id, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -579,7 +605,7 @@ Conversation::_EnsureCachePath()
|
||||||
|
|
||||||
|
|
||||||
User*
|
User*
|
||||||
Conversation::_EnsureUser(BMessage* msg)
|
Conversation::_EnsureUser(BMessage* msg, bool implicit)
|
||||||
{
|
{
|
||||||
BString id = msg->FindString("user_id");
|
BString id = msg->FindString("user_id");
|
||||||
BString name = msg->FindString("user_name");
|
BString name = msg->FindString("user_name");
|
||||||
|
@ -589,19 +615,27 @@ Conversation::_EnsureUser(BMessage* msg)
|
||||||
User* serverUser = fLooper->UserById(id);
|
User* serverUser = fLooper->UserById(id);
|
||||||
|
|
||||||
// Not here, but found in server
|
// Not here, but found in server
|
||||||
if (user == NULL && serverUser != NULL) {
|
if (user == NULL && serverUser != NULL)
|
||||||
fUsers.AddItem(id, serverUser);
|
|
||||||
user = serverUser;
|
user = serverUser;
|
||||||
GetView()->UpdateUserList(fUsers);
|
|
||||||
_UpdateIcon(user);
|
|
||||||
NotifyInteger(INT_ROOM_MEMBERS, fUsers.CountItems());
|
|
||||||
}
|
|
||||||
// Not anywhere; create user
|
// Not anywhere; create user
|
||||||
else if (user == NULL) {
|
else if (user == NULL) {
|
||||||
user = new User(id, _GetServer()->Looper());
|
user = new User(id, _GetServer()->Looper());
|
||||||
user->SetProtocolLooper(fLooper);
|
user->SetProtocolLooper(fLooper);
|
||||||
|
|
||||||
fLooper->AddUser(user);
|
fLooper->AddUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's been implicitly defined (rather than explicit join), shame!
|
||||||
|
if (UserById(id) == NULL && implicit == true) {
|
||||||
|
fGuests.Add(id);
|
||||||
|
// The response to this will be used to determine if this guest stays
|
||||||
|
BMessage msg(IM_MESSAGE);
|
||||||
|
msg.AddInt32("im_what", IM_GET_ROOM_PARTICIPANTS);
|
||||||
|
msg.AddString("chat_id", fID);
|
||||||
|
fLooper->MessageReceived(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserById(id) == NULL) {
|
||||||
|
fUsers.AddItem(id, user);
|
||||||
fUsers.AddItem(id, user);
|
fUsers.AddItem(id, user);
|
||||||
GetView()->UpdateUserList(fUsers);
|
GetView()->UpdateUserList(fUsers);
|
||||||
_UpdateIcon(user);
|
_UpdateIcon(user);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <DateTimeFormat.h>
|
#include <DateTimeFormat.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
#include <StringList.h>
|
||||||
|
|
||||||
#include <libsupport/KeyMap.h>
|
#include <libsupport/KeyMap.h>
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ private:
|
||||||
void _LoadRoomFlags();
|
void _LoadRoomFlags();
|
||||||
|
|
||||||
void _EnsureCachePath();
|
void _EnsureCachePath();
|
||||||
User* _EnsureUser(BMessage* msg);
|
User* _EnsureUser(BMessage* msg, bool implicit = true);
|
||||||
Role* _GetRole(BMessage* msg);
|
Role* _GetRole(BMessage* msg);
|
||||||
|
|
||||||
void _UpdateIcon(User* user = NULL);
|
void _UpdateIcon(User* user = NULL);
|
||||||
|
@ -113,7 +114,8 @@ private:
|
||||||
int32 fRoomFlags;
|
int32 fRoomFlags;
|
||||||
int32 fDisallowedFlags;
|
int32 fDisallowedFlags;
|
||||||
|
|
||||||
UserMap fUsers;
|
UserMap fUsers; // For defined, certain members of the room
|
||||||
|
BStringList fGuests; // IDs of implicitly-defined users
|
||||||
RoleMap fRoles;
|
RoleMap fRoles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -458,7 +458,6 @@ Server::ImMessage(BMessage* msg)
|
||||||
chat->AddUser(user);
|
chat->AddUser(user);
|
||||||
chat->ShowView(false, true);
|
chat->ShowView(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IM_JOIN_ROOM:
|
case IM_JOIN_ROOM:
|
||||||
|
@ -466,27 +465,6 @@ Server::ImMessage(BMessage* msg)
|
||||||
SendProtocolMessage(msg);
|
SendProtocolMessage(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IM_ROOM_PARTICIPANTS:
|
|
||||||
{
|
|
||||||
Conversation* chat = _EnsureConversation(msg);
|
|
||||||
BStringList ids;
|
|
||||||
BStringList name;
|
|
||||||
|
|
||||||
msg->FindStrings("user_name", &name);
|
|
||||||
if (msg->FindStrings("user_id", &ids) != B_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ProtocolLooper* protoLooper = _LooperFromMessage(msg);
|
|
||||||
|
|
||||||
for (int i = 0; i < ids.CountStrings(); i++) {
|
|
||||||
User* user = _EnsureUser(ids.StringAt(i), protoLooper);
|
|
||||||
|
|
||||||
if (name.CountStrings() >= i && !name.StringAt(i).IsEmpty())
|
|
||||||
user->SetNotifyName(name.StringAt(i));
|
|
||||||
chat->AddUser(user);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IM_MESSAGE_RECEIVED:
|
case IM_MESSAGE_RECEIVED:
|
||||||
if (msg->HasString("chat_id") == false) {
|
if (msg->HasString("chat_id") == false) {
|
||||||
ProtocolLooper* looper = _LooperFromMessage(msg);
|
ProtocolLooper* looper = _LooperFromMessage(msg);
|
||||||
|
@ -499,6 +477,7 @@ Server::ImMessage(BMessage* msg)
|
||||||
case IM_ROOM_CREATED:
|
case IM_ROOM_CREATED:
|
||||||
case IM_ROOM_METADATA:
|
case IM_ROOM_METADATA:
|
||||||
case IM_ROOM_ROLECHANGED:
|
case IM_ROOM_ROLECHANGED:
|
||||||
|
case IM_ROOM_PARTICIPANTS:
|
||||||
case IM_ROOM_PARTICIPANT_JOINED:
|
case IM_ROOM_PARTICIPANT_JOINED:
|
||||||
case IM_ROOM_PARTICIPANT_LEFT:
|
case IM_ROOM_PARTICIPANT_LEFT:
|
||||||
case IM_ROOM_PARTICIPANT_BANNED:
|
case IM_ROOM_PARTICIPANT_BANNED:
|
||||||
|
|
Ŝarĝante…
Reference in New Issue