Support for buddies on more groups

This commit is contained in:
HanzZ 2011-11-30 21:43:12 +01:00
parent c48fa3e77d
commit 6b81ff06d6
11 changed files with 98 additions and 28 deletions

View file

@ -171,7 +171,9 @@ class FrotzNetworkPlugin : public NetworkPlugin {
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
np->handleConnected(user);
np->handleBuddyChanged(user, "zcode", "ZCode", "ZCode", pbnetwork::STATUS_ONLINE);
std::vector<std::string> groups;
groups.push_back("ZCode");
np->handleBuddyChanged(user, "zcode", "ZCode", groups, pbnetwork::STATUS_ONLINE);
// sleep(1);
// np->handleMessage(np->m_user, "zork", first_msg);
}

View file

@ -1052,7 +1052,22 @@ static std::string getIconHash(PurpleBuddy *m_buddy) {
static std::vector<std::string> getGroups(PurpleBuddy *m_buddy) {
std::vector<std::string> groups;
groups.push_back((purple_buddy_get_group(m_buddy) && purple_group_get_name(purple_buddy_get_group(m_buddy))) ? std::string(purple_group_get_name(purple_buddy_get_group(m_buddy))) : std::string("Buddies"));
if (purple_buddy_get_name(m_buddy)) {
GSList *buddies = purple_find_buddies(purple_buddy_get_account(m_buddy), purple_buddy_get_name(m_buddy));
while(buddies) {
PurpleGroup *g = purple_buddy_get_group((PurpleBuddy *) buddies->data);
buddies = g_slist_delete_link(buddies, buddies);
if(g && purple_group_get_name(g)) {
groups.push_back(purple_group_get_name(g));
}
}
}
if (groups.empty()) {
groups.push_back("Buddies");
}
return groups;
}
@ -1105,7 +1120,7 @@ static void buddyListNewNode(PurpleBlistNode *node) {
}
}
np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], status, message, getIconHash(buddy),
np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy), status, message, getIconHash(buddy),
blocked
);
}

View file

@ -53,7 +53,7 @@ class NetworkPlugin {
/// \param iconHash MD5 hash of buddy icon. Empty if none buddy icon.
/// \param blocked True if this buddy is blocked in privacy lists in legacy network.
void handleBuddyChanged(const std::string &user, const std::string &buddyName, const std::string &alias,
const std::string &groups, pbnetwork::StatusType status, const std::string &statusMessage = "", const std::string &iconHash = "",
const std::vector<std::string> &groups, pbnetwork::StatusType status, const std::string &statusMessage = "", const std::string &iconHash = "",
bool blocked = false
);
@ -197,8 +197,8 @@ class NetworkPlugin {
virtual void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/) {}
virtual void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/) {}
virtual void handleStatusChangeRequest(const std::string &/*user*/, int status, const std::string &statusMessage) {}
virtual void handleBuddyUpdatedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*alias*/, const std::string &/*groups*/) {}
virtual void handleBuddyRemovedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*groups*/) {}
virtual void handleBuddyUpdatedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*alias*/, const std::vector<std::string> &/*groups*/) {}
virtual void handleBuddyRemovedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::vector<std::string> &/*groups*/) {}
virtual void handleBuddyBlockToggled(const std::string &/*user*/, const std::string &/*buddyName*/, bool /*blocked*/) {}
virtual void handleTypingRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {}

View file

@ -55,7 +55,7 @@ message Buddy {
required string userName = 1;
required string buddyName = 2;
optional string alias = 3;
optional string groups = 4;
repeated string group = 4;
optional StatusType status = 5;
optional string statusMessage = 6;
optional string iconHash = 7;

View file

@ -36,6 +36,10 @@ std::string encryptPassword(const std::string &password, const std::string &key)
std::string decryptPassword(std::string &encrypted, const std::string &key);
std::string serializeGroups(const std::vector<std::string> &groups);
std::vector<std::string> deserializeGroups(std::string &groups);
}
}

View file

@ -115,12 +115,14 @@ void NetworkPlugin::handleSubject(const std::string &user, const std::string &le
}
void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::string &buddyName, const std::string &alias,
const std::string &groups, pbnetwork::StatusType status, const std::string &statusMessage, const std::string &iconHash, bool blocked) {
const std::vector<std::string> &groups, pbnetwork::StatusType status, const std::string &statusMessage, const std::string &iconHash, bool blocked) {
pbnetwork::Buddy buddy;
buddy.set_username(user);
buddy.set_buddyname(buddyName);
buddy.set_alias(alias);
buddy.set_groups(groups);
for (std::vector<std::string>::const_iterator it = groups.begin(); it != groups.end(); it++) {
buddy.add_group(*it);
}
buddy.set_status((pbnetwork::StatusType) status);
buddy.set_statusmessage(statusMessage);
buddy.set_iconhash(iconHash);
@ -424,7 +426,11 @@ void NetworkPlugin::handleBuddyChangedPayload(const std::string &data) {
handleBuddyBlockToggled(payload.username(), payload.buddyname(), payload.blocked());
}
else {
handleBuddyUpdatedRequest(payload.username(), payload.buddyname(), payload.alias(), payload.groups());
std::vector<std::string> groups;
for (int i = 0; i < payload.group_size(); i++) {
groups.push_back(payload.group(i));
}
handleBuddyUpdatedRequest(payload.username(), payload.buddyname(), payload.alias(), groups);
}
}
@ -435,7 +441,12 @@ void NetworkPlugin::handleBuddyRemovedPayload(const std::string &data) {
return;
}
handleBuddyRemovedRequest(payload.username(), payload.buddyname(), payload.groups());
std::vector<std::string> groups;
for (int i = 0; i < payload.group_size(); i++) {
groups.push_back(payload.group(i));
}
handleBuddyRemovedRequest(payload.username(), payload.buddyname(), groups);
}
void NetworkPlugin::handleChatStatePayload(const std::string &data, int type) {

View file

@ -13,10 +13,10 @@ admin_password=test
#cert=server.pfx #patch to PKCS#12 certificate
#cert_password=test #password to that certificate if any
users_per_backend=10
#backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
#backend=/usr/bin/mono /home/hanzz/code/networkplugin-csharp/msnp-sharp-backend/bin/Debug/msnp-sharp-backend.exe
#backend=/home/hanzz/code/libtransport/backends/frotz/spectrum2_frotz_backend
backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend
#backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend
#protocol=prpl-msn
protocol=any
#protocol=prpl-icq

View file

@ -320,7 +320,7 @@ bool MySQLBackend::connect() {
createDatabase();
m_setUser = new Statement(&m_conn, "sssssbs", "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, NOW(), ?) ON DUPLICATE KEY UPDATE uin=?, password=?");
m_setUser = new Statement(&m_conn, "sssssbss", "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, NOW(), ?) ON DUPLICATE KEY UPDATE uin=?, password=?");
m_getUser = new Statement(&m_conn, "s|isssssb", "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?");
m_removeUser = new Statement(&m_conn, "i", "DELETE FROM " + m_prefix + "users WHERE id=?");
@ -414,7 +414,7 @@ void MySQLBackend::setUser(const UserInfo &user) {
if (!CONFIG_STRING(m_config, "database.encryption_key").empty()) {
encrypted = Util::encryptPassword(encrypted, CONFIG_STRING(m_config, "database.encryption_key"));
}
*m_setUser << user.jid << user.uin << encrypted << user.language << user.encoding << user.vip << user.uin << user.password;
*m_setUser << user.jid << user.uin << encrypted << user.language << user.encoding << user.vip << user.uin << encrypted;
EXEC(m_setUser, setUser(user));
}
@ -444,8 +444,9 @@ void MySQLBackend::setUserOnline(long id, bool online) {
long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
// "INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)"
std::string groups = Util::serializeGroups(buddyInfo.groups);
*m_addBuddy << userId << buddyInfo.legacyName << buddyInfo.subscription;
*m_addBuddy << (buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]);
*m_addBuddy << groups;
*m_addBuddy << buddyInfo.alias << buddyInfo.flags;
EXEC(m_addBuddy, addBuddy(userId, buddyInfo));
@ -463,7 +464,8 @@ long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
void MySQLBackend::updateBuddy(long userId, const BuddyInfo &buddyInfo) {
// "UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?"
*m_updateBuddy << (buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]);
std::string groups = Util::serializeGroups(buddyInfo.groups);
*m_updateBuddy << groups;
*m_updateBuddy << buddyInfo.alias << buddyInfo.flags << buddyInfo.subscription;
*m_updateBuddy << userId << buddyInfo.legacyName;
@ -491,8 +493,9 @@ bool MySQLBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
std::string group;
*m_getBuddies >> b.id >> b.legacyName >> b.subscription >> b.alias >> group >> b.flags;
if (!group.empty())
b.groups.push_back(group);
if (!group.empty()) {
b.groups = Util::deserializeGroups(group);
}
roster.push_back(b);
}

View file

@ -198,9 +198,11 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
}
// Change groups if it's not empty. The same as above...
if (!payload.groups().empty()) {
std::vector<std::string> groups;
groups.push_back(payload.groups());
std::vector<std::string> groups;
for (int i = 0; i < payload.group_size(); i++) {
groups.push_back(payload.group(i));
}
if (!groups.empty()) {
buddy->setGroups(groups);
}
@ -1163,7 +1165,9 @@ void NetworkPluginServer::handleBuddyRemoved(Buddy *b) {
buddy.set_username(user->getJID().toBare());
buddy.set_buddyname(b->getName());
buddy.set_alias(b->getAlias());
buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
BOOST_FOREACH(const std::string &g, b->getGroups()) {
buddy.add_group(g);
}
buddy.set_status(pbnetwork::STATUS_NONE);
std::string message;
@ -1189,7 +1193,9 @@ void NetworkPluginServer::handleBuddyUpdated(Buddy *b, const Swift::RosterItemPa
buddy.set_username(user->getJID().toBare());
buddy.set_buddyname(b->getName());
buddy.set_alias(b->getAlias());
buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
BOOST_FOREACH(const std::string &g, b->getGroups()) {
buddy.add_group(g);
}
buddy.set_status(pbnetwork::STATUS_NONE);
std::string message;
@ -1215,7 +1221,9 @@ void NetworkPluginServer::handleBlockToggled(Buddy *b) {
buddy.set_username(user->getJID().toBare());
buddy.set_buddyname(b->getName());
buddy.set_alias(b->getAlias());
buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
BOOST_FOREACH(const std::string &g, b->getGroups()) {
buddy.add_group(g);
}
buddy.set_status(pbnetwork::STATUS_NONE);
buddy.set_blocked(!b->isBlocked());

View file

@ -21,6 +21,7 @@
#ifdef WITH_SQLITE
#include "transport/sqlite3backend.h"
#include "transport/util.h"
#include <boost/bind.hpp>
#include "log4cxx/logger.h"
@ -254,7 +255,7 @@ long SQLite3Backend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
BIND_INT(m_addBuddy, userId);
BIND_STR(m_addBuddy, buddyInfo.legacyName);
BIND_STR(m_addBuddy, buddyInfo.subscription);
BIND_STR(m_addBuddy, buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]); // TODO: serialize groups
BIND_STR(m_addBuddy, Util::serializeGroups(buddyInfo.groups));
BIND_STR(m_addBuddy, buddyInfo.alias);
BIND_INT(m_addBuddy, buddyInfo.flags);
@ -280,7 +281,7 @@ long SQLite3Backend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
void SQLite3Backend::updateBuddy(long userId, const BuddyInfo &buddyInfo) {
// UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?
BEGIN(m_updateBuddy);
BIND_STR(m_updateBuddy, buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]); // TODO: serialize groups
BIND_STR(m_updateBuddy, Util::serializeGroups(buddyInfo.groups));
BIND_STR(m_updateBuddy, buddyInfo.alias);
BIND_INT(m_updateBuddy, buddyInfo.flags);
BIND_STR(m_updateBuddy, buddyInfo.subscription);
@ -321,7 +322,8 @@ bool SQLite3Backend::getBuddies(long id, std::list<BuddyInfo> &roster) {
b.legacyName = GET_STR(m_getBuddies);
b.subscription = GET_STR(m_getBuddies);
b.alias = GET_STR(m_getBuddies);
b.groups.push_back(GET_STR(m_getBuddies));
std::string groups = GET_STR(m_getBuddies);
b.groups = Util::deserializeGroups(groups);
b.flags = GET_INT(m_getBuddies);
if (buddy_id == b.id) {

View file

@ -24,6 +24,7 @@
#include <iterator>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
using namespace boost::filesystem;
@ -103,6 +104,30 @@ std::string decryptPassword(std::string &encrypted, const std::string &key) {
return password;
}
std::string serializeGroups(const std::vector<std::string> &groups) {
std::string ret;
BOOST_FOREACH(const std::string &group, groups) {
ret += group + "\n";
}
if (!ret.empty()) {
ret.erase(ret.end() - 1);
}
return ret;
}
std::vector<std::string> deserializeGroups(std::string &groups) {
std::vector<std::string> ret;
if (groups.empty()) {
return ret;
}
boost::split(ret, groups, boost::is_any_of("\n"));
if (ret.back().empty()) {
ret.erase(ret.end() - 1);
}
return ret;
}
}
}