Libpurple + Libtransport: Support aliases in rooms, fix joining rooms on protocols where you cannot join with custom nickname, show topic in the service discovery for rooms.
This commit is contained in:
parent
dc6c6f8337
commit
9de5e656da
8 changed files with 89 additions and 35 deletions
|
@ -704,14 +704,19 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, (room + "/" + nickname).c_str());
|
||||
} else {
|
||||
comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, room.c_str());
|
||||
np->handleParticipantChanged(np->m_accounts[account], nickname, room, 0, pbnetwork::STATUS_ONLINE);
|
||||
const char *disp;
|
||||
if ((disp = purple_connection_get_display_name(account->gc))) {
|
||||
handleRoomNicknameChanged(np->m_accounts[account], room, disp);
|
||||
}
|
||||
else {
|
||||
handleRoomNicknameChanged(np->m_accounts[account], room, purple_account_get_username(account));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CONFIG_STRING(config, "service.protocol") != "prpl-jabber") {
|
||||
np->handleParticipantChanged(np->m_accounts[account], nickname, room, 0, pbnetwork::STATUS_ONLINE);
|
||||
const char *disp;
|
||||
if ((disp = purple_connection_get_display_name(account->gc))) {
|
||||
handleRoomNicknameChanged(np->m_accounts[account], room, disp);
|
||||
np->handleParticipantChanged(np->m_accounts[account], nickname, room, 0, pbnetwork::STATUS_ONLINE, "", disp);
|
||||
}
|
||||
else {
|
||||
handleRoomNicknameChanged(np->m_accounts[account], room, purple_account_get_username(account));
|
||||
np->handleParticipantChanged(np->m_accounts[account], nickname, room, 0, pbnetwork::STATUS_ONLINE, "", purple_account_get_username(account));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1182,6 +1187,7 @@ static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gbool
|
|||
while (l != NULL) {
|
||||
PurpleConvChatBuddy *cb = (PurpleConvChatBuddy *)l->data;
|
||||
std::string name(cb->name);
|
||||
std::string alias = cb->alias ? cb->alias : cb->name;
|
||||
int flags = GPOINTER_TO_INT(cb->flags);
|
||||
if (flags & PURPLE_CBFLAGS_OP || flags & PURPLE_CBFLAGS_HALFOP) {
|
||||
// item->addAttribute("affiliation", "admin");
|
||||
|
@ -1199,7 +1205,7 @@ static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gbool
|
|||
// item->addAttribute("role", "participant");
|
||||
}
|
||||
|
||||
np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name_wrapped(conv), (int) flags, pbnetwork::STATUS_ONLINE);
|
||||
np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name_wrapped(conv), (int) flags, pbnetwork::STATUS_ONLINE, "", "", alias);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
@ -1597,14 +1603,47 @@ static PurpleXferUiOps xferUiOps =
|
|||
|
||||
static void RoomlistProgress(PurpleRoomlist *list, gboolean in_progress)
|
||||
{
|
||||
if (!in_progress)
|
||||
{
|
||||
if (!in_progress) {
|
||||
GList *fields = purple_roomlist_get_fields(list);
|
||||
GList *field;
|
||||
int topicId = -1;
|
||||
int id = 0;
|
||||
for (field = fields; field != NULL; field = field->next, id++) {
|
||||
PurpleRoomlistField *f = (PurpleRoomlistField *) field->data;
|
||||
if (!f || !f->name) {
|
||||
continue;
|
||||
}
|
||||
std::string fstring = f->name;
|
||||
if (fstring == "topic") {
|
||||
topicId = id;
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, "Uknown RoomList field " << fstring);
|
||||
}
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, "RoomList topic ID: " << topicId);
|
||||
|
||||
GList *rooms;
|
||||
std::list<std::string> m_rooms;
|
||||
for (rooms = list->rooms; rooms != NULL; rooms = rooms->next)
|
||||
{
|
||||
std::list<std::string> m_topics;
|
||||
for (rooms = list->rooms; rooms != NULL; rooms = rooms->next) {
|
||||
PurpleRoomlistRoom *room = (PurpleRoomlistRoom *)rooms->data;
|
||||
m_rooms.push_back(room->name);
|
||||
|
||||
if (topicId == -1) {
|
||||
m_topics.push_back(room->name);
|
||||
}
|
||||
else {
|
||||
char *topic = (char *) g_list_nth_data(purple_roomlist_room_get_fields(room), topicId);
|
||||
if (topic) {
|
||||
m_topics.push_back(topic);
|
||||
}
|
||||
else {
|
||||
LOG4CXX_WARN(logger, "RoomList topic is NULL");
|
||||
m_topics.push_back(room->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string user = "";
|
||||
|
@ -1613,7 +1652,7 @@ static void RoomlistProgress(PurpleRoomlist *list, gboolean in_progress)
|
|||
}
|
||||
|
||||
LOG4CXX_INFO(logger, "RoomList is fetched for user " << user);
|
||||
np->handleRoomList(user, m_rooms, m_rooms);
|
||||
np->handleRoomList(user, m_rooms, m_topics);
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, "RoomList is still in progress");
|
||||
|
@ -1928,6 +1967,9 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
|
|||
if (CONFIG_STRING(config, "service.protocol") == "prpl-telegram") {
|
||||
cfg.setNeedPassword(false);
|
||||
}
|
||||
if (CONFIG_STRING(config, "service.protocol") != "prpl-irc") {
|
||||
cfg.setNeedRegistration(false);
|
||||
}
|
||||
np->sendConfig(cfg);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,12 +44,6 @@ class Conversation {
|
|||
PARTICIPANT_FLAG_ROOM_NOT_FOUD = 64
|
||||
} ParticipantFlag;
|
||||
|
||||
typedef struct _Participant {
|
||||
ParticipantFlag flag;
|
||||
int status;
|
||||
std::string statusMessage;
|
||||
} Participant;
|
||||
|
||||
/// Creates new conversation.
|
||||
|
||||
/// \param conversationManager ConversationManager associated with this Conversation.
|
||||
|
@ -81,7 +75,7 @@ class Conversation {
|
|||
/// \param status Current status of this participant.
|
||||
/// \param statusMessage Current status message of this participant.
|
||||
/// \param newname If participant was renamed, this variable contains his new name.
|
||||
void handleParticipantChanged(const std::string &nickname, ParticipantFlag flag, int status = Swift::StatusShow::None, const std::string &statusMessage = "", const std::string &newname = "", const std::string &iconhash = "");
|
||||
void handleParticipantChanged(const std::string &nickname, ParticipantFlag flag, int status = Swift::StatusShow::None, const std::string &statusMessage = "", const std::string &newname = "", const std::string &iconhash = "", const std::string &alias = "");
|
||||
|
||||
/// Sets XMPP user nickname in MUC rooms.
|
||||
|
||||
|
@ -176,7 +170,12 @@ class Conversation {
|
|||
// every time, so we can get history messages for IRC for example.
|
||||
boost::shared_ptr<Swift::Message> m_subject;
|
||||
std::list<boost::shared_ptr<Swift::Message> > m_cachedMessages;
|
||||
std::map<std::string, Swift::Presence::ref> m_participants;
|
||||
|
||||
typedef struct {
|
||||
Swift::Presence::ref presence;
|
||||
std::string alias;
|
||||
} Participant;
|
||||
std::map<std::string, Participant> m_participants;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -103,7 +103,8 @@ class NetworkPlugin {
|
|||
/// \param statusMessage Current status message of participant.
|
||||
/// \param newname New name of participant if he changed the nickname. Otherwise empty.
|
||||
void handleParticipantChanged(const std::string &user, const std::string &nickname, const std::string &room, int flags,
|
||||
pbnetwork::StatusType = pbnetwork::STATUS_NONE, const std::string &statusMessage = "", const std::string &newname = "");
|
||||
pbnetwork::StatusType = pbnetwork::STATUS_NONE, const std::string &statusMessage = "", const std::string &newname = "",
|
||||
const std::string &alias = "");
|
||||
|
||||
/// Call this function when user disconnected the legacy network because of some legacy network error.
|
||||
/// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld")
|
||||
|
|
|
@ -112,6 +112,7 @@ message Participant {
|
|||
optional string statusMessage = 6;
|
||||
optional string newname = 7;
|
||||
optional string iconHash = 8;
|
||||
optional string alias = 9;
|
||||
}
|
||||
|
||||
message VCard {
|
||||
|
|
|
@ -207,6 +207,11 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
|
|||
n = " ";
|
||||
}
|
||||
|
||||
std::map<std::string, Participant>::iterator it = m_participants.find(n);
|
||||
if (it != m_participants.end() && !it->second.alias.empty()) {
|
||||
n = it->second.alias;
|
||||
}
|
||||
|
||||
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
|
||||
LOG4CXX_INFO(logger, "MSG FROM " << message->getFrom().toString());
|
||||
}
|
||||
|
@ -216,16 +221,16 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
|
|||
|
||||
std::string Conversation::getParticipants() {
|
||||
std::string ret;
|
||||
for (std::map<std::string, Swift::Presence::ref>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
|
||||
ret += (*it).second->getFrom().getResource() + ", ";
|
||||
for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
|
||||
ret += (*it).second.presence->getFrom().getResource() + ", ";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Conversation::sendParticipants(const Swift::JID &to) {
|
||||
for (std::map<std::string, Swift::Presence::ref>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
|
||||
(*it).second->setTo(to);
|
||||
m_conversationManager->getComponent()->getFrontend()->sendPresence((*it).second);
|
||||
for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
|
||||
(*it).second.presence->setTo(to);
|
||||
m_conversationManager->getComponent()->getFrontend()->sendPresence((*it).second.presence);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,17 +357,18 @@ void Conversation::setNickname(const std::string &nickname) {
|
|||
void Conversation::handleRawPresence(Swift::Presence::ref presence) {
|
||||
// TODO: Detect nickname change.
|
||||
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
|
||||
m_participants[presence->getFrom().getResource()] = presence;
|
||||
m_participants[presence->getFrom().getResource()].presence = presence;
|
||||
}
|
||||
|
||||
void Conversation::handleParticipantChanged(const std::string &nick, Conversation::ParticipantFlag flag, int status, const std::string &statusMessage, const std::string &newname, const std::string &iconhash) {
|
||||
Swift::Presence::ref presence = generatePresence(nick, flag, status, statusMessage, newname, iconhash);
|
||||
void Conversation::handleParticipantChanged(const std::string &nick, Conversation::ParticipantFlag flag, int status, const std::string &statusMessage, const std::string &newname, const std::string &iconhash, const std::string &alias) {
|
||||
Swift::Presence::ref presence = generatePresence(alias.empty() ? nick : alias, flag, status, statusMessage, newname, iconhash);
|
||||
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
m_participants.erase(nick);
|
||||
}
|
||||
else {
|
||||
m_participants[nick] = presence;
|
||||
m_participants[nick].presence = presence;
|
||||
m_participants[nick].alias = alias;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -636,7 +636,7 @@ void NetworkPluginServer::handleParticipantChangedPayload(const std::string &dat
|
|||
return;
|
||||
}
|
||||
|
||||
conv->handleParticipantChanged(payload.nickname(), (Conversation::ParticipantFlag) payload.flag(), payload.status(), payload.statusmessage(), payload.newname(), payload.iconhash());
|
||||
conv->handleParticipantChanged(payload.nickname(), (Conversation::ParticipantFlag) payload.flag(), payload.status(), payload.statusmessage(), payload.newname(), payload.iconhash(), payload.alias());
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleRoomChangedPayload(const std::string &data) {
|
||||
|
@ -646,11 +646,14 @@ void NetworkPluginServer::handleRoomChangedPayload(const std::string &data) {
|
|||
}
|
||||
|
||||
User *user = m_userManager->getUser(payload.username());
|
||||
if (!user)
|
||||
if (!user) {
|
||||
LOG4CXX_ERROR(logger, "RoomChangePayload for unknown user " << user);
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(payload.room());
|
||||
if (!conv) {
|
||||
LOG4CXX_ERROR(logger, "RoomChangePayload for unknown conversation " << payload.room());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -220,6 +220,7 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
|
|||
if (CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needRegistration", false)
|
||||
&& CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needPassword", true)) {
|
||||
m_userRegistry->onPasswordInvalid(presence->getFrom());
|
||||
LOG4CXX_INFO(logger, userkey << ": Tried to login, but is not registered.");
|
||||
return;
|
||||
}
|
||||
res.password = "";
|
||||
|
|
|
@ -287,7 +287,7 @@ void NetworkPlugin::handleDisconnected(const std::string &user, int error, const
|
|||
send(message);
|
||||
}
|
||||
|
||||
void NetworkPlugin::handleParticipantChanged(const std::string &user, const std::string &nickname, const std::string &room, int flags, pbnetwork::StatusType status, const std::string &statusMessage, const std::string &newname) {
|
||||
void NetworkPlugin::handleParticipantChanged(const std::string &user, const std::string &nickname, const std::string &room, int flags, pbnetwork::StatusType status, const std::string &statusMessage, const std::string &newname, const std::string &alias) {
|
||||
pbnetwork::Participant d;
|
||||
d.set_username(user);
|
||||
d.set_nickname(nickname);
|
||||
|
@ -296,6 +296,7 @@ void NetworkPlugin::handleParticipantChanged(const std::string &user, const std:
|
|||
d.set_newname(newname);
|
||||
d.set_status((pbnetwork::StatusType) status);
|
||||
d.set_statusmessage(statusMessage);
|
||||
d.set_alias(alias);
|
||||
|
||||
std::string message;
|
||||
d.SerializeToString(&message);
|
||||
|
|
Loading…
Add table
Reference in a new issue