pinging backends
This commit is contained in:
parent
7ac55eba24
commit
e8b61aa9b6
17 changed files with 173 additions and 601 deletions
|
@ -82,6 +82,7 @@ ADD_SUBDIRECTORY(src)
|
|||
ADD_SUBDIRECTORY(include)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
ADD_SUBDIRECTORY(spectrum)
|
||||
ADD_SUBDIRECTORY(backends)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
message("Docs : yes")
|
||||
|
|
|
@ -222,7 +222,7 @@ static void buddyListNewNode(PurpleBlistNode *node) {
|
|||
std::string message;
|
||||
getStatus(buddy, status, message);
|
||||
|
||||
np->handleBuddyCreated(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy));
|
||||
np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy));
|
||||
}
|
||||
|
||||
static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status_, PurpleStatus *old_status) {
|
||||
|
|
|
@ -81,6 +81,36 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
|
|||
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(PROTOBUF_GENERATE_PY SRCS HDRS)
|
||||
if(NOT ARGN)
|
||||
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
|
||||
return()
|
||||
endif(NOT ARGN)
|
||||
|
||||
set(${SRCS})
|
||||
set(${HDRS})
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
||||
|
||||
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
|
||||
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
|
||||
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
|
||||
ARGS --python_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR} ${ABS_FIL}
|
||||
DEPENDS ${ABS_FIL}
|
||||
COMMENT "Running Py protocol buffer compiler on ${FIL}"
|
||||
VERBATIM )
|
||||
endforeach()
|
||||
|
||||
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
|
||||
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
||||
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
find_path(PROTOBUF_INCLUDE_DIR google/protobuf/service.h)
|
||||
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
ADD_SUBDIRECTORY(server_connect)
|
||||
ADD_SUBDIRECTORY(usermanager)
|
||||
|
||||
if (PROTOBUF_FOUND)
|
||||
ADD_SUBDIRECTORY(external_network_plugin)
|
||||
endif()
|
||||
|
|
|
@ -70,11 +70,14 @@ class Config {
|
|||
return m_variables[key];
|
||||
}
|
||||
|
||||
const std::string &getConfigFile() { return m_file; }
|
||||
|
||||
/// This signal is emitted when config is loaded/reloaded.
|
||||
boost::signal<void ()> onConfigReloaded;
|
||||
|
||||
private:
|
||||
Variables m_variables;
|
||||
std::string m_file;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ class NetworkPlugin {
|
|||
void handleDisconnected();
|
||||
|
||||
void send(const std::string &data);
|
||||
void sendPong();
|
||||
|
||||
std::string m_data;
|
||||
std::string m_host;
|
||||
|
|
|
@ -58,12 +58,17 @@ class NetworkPluginServer {
|
|||
|
||||
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
|
||||
|
||||
void pingTimeout();
|
||||
void sendPing();
|
||||
|
||||
std::string m_command;
|
||||
std::string m_data;
|
||||
UserManager *m_userManager;
|
||||
Config *m_config;
|
||||
boost::shared_ptr<Swift::ConnectionServer> m_server;
|
||||
boost::shared_ptr<Swift::Connection> m_client;
|
||||
bool m_pongReceived;
|
||||
Swift::Timer::ref m_pingTimer;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,583 +1,39 @@
|
|||
#include "glib.h"
|
||||
#include "purple.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "transport/config.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/logger.h"
|
||||
#include "transport/sqlite3backend.h"
|
||||
#include "transport/userregistration.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/storagebackend.h"
|
||||
#include "transport/rostermanager.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "spectrumeventloop.h"
|
||||
#include "spectrumbuddy.h"
|
||||
#include "spectrumconversation.h"
|
||||
#include "geventloop.h"
|
||||
|
||||
#define Log(X, STRING) std::cout << "[SPECTRUM] " << X << " " << STRING << "\n";
|
||||
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
Logger *_logger;
|
||||
|
||||
static gboolean nodaemon = FALSE;
|
||||
static gchar *logfile = NULL;
|
||||
static gchar *lock_file = NULL;
|
||||
static gboolean ver = FALSE;
|
||||
static gboolean upgrade_db = FALSE;
|
||||
static gboolean check_db_version = FALSE;
|
||||
static gboolean list_purple_settings = FALSE;
|
||||
|
||||
static GOptionEntry options_entries[] = {
|
||||
{ "nodaemon", 'n', 0, G_OPTION_ARG_NONE, &nodaemon, "Disable background daemon mode", NULL },
|
||||
{ "logfile", 'l', 0, G_OPTION_ARG_STRING, &logfile, "Set file to log", NULL },
|
||||
{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &lock_file, "File where to write transport PID", NULL },
|
||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Shows Spectrum version", NULL },
|
||||
{ "list-purple-settings", 's', 0, G_OPTION_ARG_NONE, &list_purple_settings, "Lists purple settings which can be used in config file", NULL },
|
||||
{ "upgrade-db", 'u', 0, G_OPTION_ARG_NONE, &upgrade_db, "Upgrades Spectrum database", NULL },
|
||||
{ "check-db-GlooxMessageHandler::version", 'c', 0, G_OPTION_ARG_NONE, &check_db_version, "Checks Spectrum database version", NULL },
|
||||
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL }
|
||||
};
|
||||
|
||||
static void buddyListNewNode(PurpleBlistNode *node) {
|
||||
if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
|
||||
return;
|
||||
PurpleBuddy *buddy = (PurpleBuddy *) node;
|
||||
PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
User *user = (User *) account->ui_data;
|
||||
|
||||
if (!user)
|
||||
return;
|
||||
|
||||
SpectrumBuddy *s_buddy = NULL;
|
||||
GSList *list = purple_find_buddies(account, purple_buddy_get_name(buddy));
|
||||
while (list) {
|
||||
PurpleBuddy *b = (PurpleBuddy *) list->data;
|
||||
if (b->node.ui_data)
|
||||
s_buddy = (SpectrumBuddy *) b->node.ui_data;
|
||||
list = g_slist_delete_link(list, list);
|
||||
}
|
||||
|
||||
if (s_buddy) {
|
||||
buddy->node.ui_data = s_buddy;
|
||||
s_buddy->addBuddy(buddy);
|
||||
}
|
||||
else {
|
||||
buddy->node.ui_data = (void *) new SpectrumBuddy(user->getRosterManager(), -1, buddy);
|
||||
SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
|
||||
s_buddy->setFlags(BUDDY_JID_ESCAPING);
|
||||
}
|
||||
}
|
||||
|
||||
static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status, PurpleStatus *old_status) {
|
||||
SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
|
||||
PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
User *user = (User *) account->ui_data;
|
||||
|
||||
if (!user || !s_buddy)
|
||||
return;
|
||||
|
||||
s_buddy->buddyChanged();
|
||||
}
|
||||
|
||||
static void buddySignedOn(PurpleBuddy *buddy) {
|
||||
SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
|
||||
PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
User *user = (User *) account->ui_data;
|
||||
|
||||
if (!user || !s_buddy)
|
||||
return;
|
||||
|
||||
s_buddy->buddyChanged();
|
||||
}
|
||||
|
||||
static void buddySignedOff(PurpleBuddy *buddy) {
|
||||
SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
|
||||
PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
User *user = (User *) account->ui_data;
|
||||
|
||||
if (!user || !s_buddy)
|
||||
return;
|
||||
|
||||
s_buddy->buddyChanged();
|
||||
}
|
||||
|
||||
static void NodeRemoved(PurpleBlistNode *node, void *data) {
|
||||
if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
|
||||
return;
|
||||
PurpleBuddy *buddy = (PurpleBuddy *) node;
|
||||
|
||||
// PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
// User *user = (User *) account->ui_data;
|
||||
if (buddy->node.ui_data) {
|
||||
SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
|
||||
s_buddy->removeBuddy(buddy);
|
||||
buddy->node.ui_data = NULL;
|
||||
if (s_buddy->getBuddiesCount() == 0) {
|
||||
delete s_buddy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PurpleBlistUiOps blistUiOps =
|
||||
{
|
||||
NULL,
|
||||
buddyListNewNode,
|
||||
NULL,
|
||||
NULL, // buddyListUpdate,
|
||||
NULL, //NodeRemoved,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // buddyListAddBuddy,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, //buddyListSaveNode,
|
||||
NULL, //buddyListRemoveNode,
|
||||
NULL, //buddyListSaveAccount,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void conv_new(PurpleConversation *conv) {
|
||||
PurpleAccount *account = purple_conversation_get_account(conv);
|
||||
User *user = (User *) account->ui_data;
|
||||
|
||||
if (!user)
|
||||
return;
|
||||
|
||||
std::string name = purple_conversation_get_name(conv);
|
||||
size_t pos = name.find("/");
|
||||
if (pos != std::string::npos)
|
||||
name.erase((int) pos, name.length() - (int) pos);
|
||||
|
||||
SpectrumConversation *s_conv = new SpectrumConversation(user->getConversationManager(), name, conv);
|
||||
conv->ui_data = s_conv;
|
||||
}
|
||||
|
||||
static void conv_destroy(PurpleConversation *conv) {
|
||||
SpectrumConversation *s_conv = (SpectrumConversation *) conv->ui_data;
|
||||
if (s_conv) {
|
||||
delete s_conv;
|
||||
}
|
||||
}
|
||||
|
||||
static void conv_write_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime) {
|
||||
// Don't forwards our own messages.
|
||||
if (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)
|
||||
return;
|
||||
SpectrumConversation *s_conv = (SpectrumConversation *) conv->ui_data;
|
||||
if (!s_conv)
|
||||
return;
|
||||
|
||||
boost::shared_ptr<Swift::Message> msg(new Swift::Message());
|
||||
|
||||
char *striped = purple_markup_strip_html(message);
|
||||
msg->setBody(message);
|
||||
g_free(striped);
|
||||
|
||||
s_conv->handleMessage(msg);
|
||||
}
|
||||
|
||||
static PurpleConversationUiOps conversation_ui_ops =
|
||||
{
|
||||
conv_new,
|
||||
conv_destroy,
|
||||
NULL,//conv_write_chat, /* write_chat */
|
||||
conv_write_im, /* write_im */
|
||||
NULL,//conv_write_conv, /* write_conv */
|
||||
NULL,//conv_chat_add_users, /* chat_add_users */
|
||||
NULL,//conv_chat_rename_user, /* chat_rename_user */
|
||||
NULL,//conv_chat_remove_users, /* chat_remove_users */
|
||||
NULL,//pidgin_conv_chat_update_user, /* chat_update_user */
|
||||
NULL,//pidgin_conv_present_conversation, /* present */
|
||||
NULL,//pidgin_conv_has_focus, /* has_focus */
|
||||
NULL,//pidgin_conv_custom_smiley_add, /* custom_smiley_add */
|
||||
NULL,//pidgin_conv_custom_smiley_write, /* custom_smiley_write */
|
||||
NULL,//pidgin_conv_custom_smiley_close, /* custom_smiley_close */
|
||||
NULL,//pidgin_conv_send_confirm, /* send_confirm */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void connection_report_disconnect(PurpleConnection *gc, PurpleConnectionError reason, const char *text){
|
||||
PurpleAccount *account = purple_connection_get_account(gc);
|
||||
User *user = (User *) account->ui_data;
|
||||
|
||||
if (!user)
|
||||
return;
|
||||
user->handleDisconnected(text);
|
||||
}
|
||||
|
||||
static PurpleConnectionUiOps conn_ui_ops =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,//connection_disconnected,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
connection_report_disconnect,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void transport_core_ui_init(void)
|
||||
{
|
||||
purple_blist_set_ui_ops(&blistUiOps);
|
||||
// purple_accounts_set_ui_ops(&accountUiOps);
|
||||
// purple_notify_set_ui_ops(¬ifyUiOps);
|
||||
// purple_request_set_ui_ops(&requestUiOps);
|
||||
// purple_xfers_set_ui_ops(getXferUiOps());
|
||||
purple_connections_set_ui_ops(&conn_ui_ops);
|
||||
purple_conversations_set_ui_ops(&conversation_ui_ops);
|
||||
// #ifndef WIN32
|
||||
// purple_dnsquery_set_ui_ops(getDNSUiOps());
|
||||
// #endif
|
||||
}
|
||||
|
||||
static PurpleCoreUiOps coreUiOps =
|
||||
{
|
||||
NULL,
|
||||
// debug_init,
|
||||
NULL,
|
||||
transport_core_ui_init,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) {
|
||||
std::string c("[LIBPURPLE");
|
||||
|
||||
if (category) {
|
||||
c.push_back('/');
|
||||
c.append(category);
|
||||
}
|
||||
|
||||
c.push_back(']');
|
||||
|
||||
std::cout << c << " " << arg_s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ops....
|
||||
*/
|
||||
static PurpleDebugUiOps debugUiOps =
|
||||
{
|
||||
printDebug,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static bool initPurple(Config &cfg) {
|
||||
bool ret;
|
||||
|
||||
purple_util_set_user_dir("./");
|
||||
remove("./accounts.xml");
|
||||
remove("./blist.xml");
|
||||
|
||||
// if (m_configuration.logAreas & LOG_AREA_PURPLE)
|
||||
purple_debug_set_ui_ops(&debugUiOps);
|
||||
|
||||
purple_core_set_ui_ops(&coreUiOps);
|
||||
purple_eventloop_set_ui_ops(getEventLoopUiOps());
|
||||
|
||||
ret = purple_core_init("spectrum");
|
||||
if (ret) {
|
||||
static int conversation_handle;
|
||||
static int conn_handle;
|
||||
static int blist_handle;
|
||||
|
||||
purple_set_blist(purple_blist_new());
|
||||
purple_blist_load();
|
||||
|
||||
purple_prefs_load();
|
||||
|
||||
/* Good default preferences */
|
||||
/* The combination of these two settings mean that libpurple will never
|
||||
* (of its own accord) set all the user accounts idle.
|
||||
*/
|
||||
purple_prefs_set_bool("/purple/away/away_when_idle", false);
|
||||
/*
|
||||
* This must be set to something not "none" for idle reporting to work
|
||||
* for, e.g., the OSCAR prpl. We don't implement the UI ops, so this is
|
||||
* okay for now.
|
||||
*/
|
||||
purple_prefs_set_string("/purple/away/idle_reporting", "system");
|
||||
|
||||
/* Disable all logging */
|
||||
purple_prefs_set_bool("/purple/logging/log_ims", false);
|
||||
purple_prefs_set_bool("/purple/logging/log_chats", false);
|
||||
purple_prefs_set_bool("/purple/logging/log_system", false);
|
||||
|
||||
|
||||
// purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", &conversation_handle, PURPLE_CALLBACK(newMessageReceived), NULL);
|
||||
// purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL);
|
||||
// purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL);
|
||||
// purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL);
|
||||
// purple_signal_connect(purple_connections_get_handle(), "signed-on", &conn_handle,PURPLE_CALLBACK(signed_on), NULL);
|
||||
// purple_signal_connect(purple_blist_get_handle(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL);
|
||||
purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL);
|
||||
purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL);
|
||||
purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL);
|
||||
purple_signal_connect(purple_blist_get_handle(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL);
|
||||
// purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL);
|
||||
//
|
||||
// purple_commands_init();
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void handleUserReadyToConnect(User *user) {
|
||||
PurpleAccount *account = (PurpleAccount *) user->getData();
|
||||
purple_account_set_enabled(account, "spectrum", TRUE);
|
||||
|
||||
const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE);
|
||||
if (status_type != NULL) {
|
||||
purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void handleUserCreated(User *user, UserManager *userManager, Config *config) {
|
||||
UserInfo userInfo = user->getUserInfo();
|
||||
PurpleAccount *account = NULL;
|
||||
const char *protocol = CONFIG_STRING(config, "service.protocol").c_str();
|
||||
if (purple_accounts_find(userInfo.uin.c_str(), protocol) != NULL){
|
||||
Log(userInfo.jid, "this account already exists");
|
||||
account = purple_accounts_find(userInfo.uin.c_str(), protocol);
|
||||
User *u = (User *) account->ui_data;
|
||||
if (u && u != user) {
|
||||
Log(userInfo.jid, "This account is already connected by another jid " << user->getJID());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log(userInfo.jid, "creating new account");
|
||||
account = purple_account_new(userInfo.uin.c_str(), protocol);
|
||||
|
||||
purple_accounts_add(account);
|
||||
}
|
||||
// Transport::instance()->collector()->stopCollecting(m_account);
|
||||
|
||||
// PurplePlugin *plugin = purple_find_prpl(protocol);
|
||||
// PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
|
||||
// for (GList *l = prpl_info->protocol_options; l != NULL; l = l->next) {
|
||||
// PurpleAccountOption *option = (PurpleAccountOption *) l->data;
|
||||
// purple_account_remove_setting(account, purple_account_option_get_setting(option));
|
||||
// }
|
||||
//
|
||||
// std::map <std::string, PurpleAccountSettingValue> &settings = Transport::instance()->getConfiguration().purple_account_settings;
|
||||
// for (std::map <std::string, PurpleAccountSettingValue>::iterator it = settings.begin(); it != settings.end(); it++) {
|
||||
// PurpleAccountSettingValue v = (*it).second;
|
||||
// std::string key((*it).first);
|
||||
// switch (v.type) {
|
||||
// case PURPLE_PREF_BOOLEAN:
|
||||
// purple_account_set_bool(m_account, key.c_str(), v.b);
|
||||
// break;
|
||||
//
|
||||
// case PURPLE_PREF_INT:
|
||||
// purple_account_set_int(m_account, key.c_str(), v.i);
|
||||
// break;
|
||||
//
|
||||
// case PURPLE_PREF_STRING:
|
||||
// if (v.str)
|
||||
// purple_account_set_string(m_account, key.c_str(), v.str);
|
||||
// else
|
||||
// purple_account_remove_setting(m_account, key.c_str());
|
||||
// break;
|
||||
//
|
||||
// case PURPLE_PREF_STRING_LIST:
|
||||
// // TODO:
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
purple_account_set_string(account, "encoding", userInfo.encoding.empty() ? CONFIG_STRING(config, "registration.encoding").c_str() : userInfo.encoding.c_str());
|
||||
purple_account_set_bool(account, "use_clientlogin", false);
|
||||
// purple_account_set_bool(account, "require_tls", Transport::instance()->getConfiguration().require_tls);
|
||||
// purple_account_set_bool(account, "use_ssl", Transport::instance()->getConfiguration().require_tls);
|
||||
purple_account_set_bool(account, "direct_connect", false);
|
||||
// purple_account_set_bool(account, "check-mail", purple_value_get_boolean(getSetting("enable_notify_email")));
|
||||
|
||||
account->ui_data = user;
|
||||
user->setData(account);
|
||||
|
||||
user->onReadyToConnect.connect(boost::bind(&handleUserReadyToConnect, user));
|
||||
_logger->setRosterManager(user->getRosterManager());
|
||||
|
||||
// Transport::instance()->protocol()->onPurpleAccountCreated(m_account);
|
||||
|
||||
// m_loadingBuddiesFromDB = true;
|
||||
// loadRoster();
|
||||
// m_loadingBuddiesFromDB = false;
|
||||
|
||||
// m_connectionStart = time(NULL);
|
||||
// m_readyForConnect = false;
|
||||
purple_account_set_password(account, userInfo.password.c_str());
|
||||
// Log(m_jid, "UIN:" << m_username << " USER_ID:" << m_userID);
|
||||
}
|
||||
|
||||
static void handleUserDestroyed(User *user, UserManager *userManager, Config *config) {
|
||||
PurpleAccount *account = (PurpleAccount *) user->getData();
|
||||
if (account) {
|
||||
purple_account_set_enabled(account, "spectrum", FALSE);
|
||||
|
||||
// Remove conversations.
|
||||
// This has to be called before m_account->ui_data = NULL;, because it uses
|
||||
// ui_data to call SpectrumMessageHandler::purpleConversationDestroyed() callback.
|
||||
GList *iter;
|
||||
for (iter = purple_get_conversations(); iter; ) {
|
||||
PurpleConversation *conv = (PurpleConversation*) iter->data;
|
||||
iter = iter->next;
|
||||
if (purple_conversation_get_account(conv) == account)
|
||||
purple_conversation_destroy(conv);
|
||||
}
|
||||
|
||||
account->ui_data = NULL;
|
||||
// Transport::instance()->collector()->collect(m_account);
|
||||
}
|
||||
}
|
||||
|
||||
class SpectrumFactory : public Factory {
|
||||
public:
|
||||
Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
|
||||
PurpleConversation *conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, (PurpleAccount *) conversationManager->getUser()->getData() , legacyName.c_str());
|
||||
return (Conversation *) conv->ui_data;
|
||||
}
|
||||
|
||||
Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
|
||||
PurpleAccount *account = (PurpleAccount *) rosterManager->getUser()->getData();
|
||||
std::string group = buddyInfo.groups[0];
|
||||
PurpleGroup *g = purple_find_group(group.c_str());
|
||||
if (!g) {
|
||||
g = purple_group_new(group.c_str());
|
||||
purple_blist_add_group(g, NULL);
|
||||
}
|
||||
|
||||
PurpleBuddy *buddy = purple_find_buddy_in_group(account, buddyInfo.legacyName.c_str(), g);
|
||||
if (!buddy) {
|
||||
// create contact
|
||||
PurpleContact *contact = purple_contact_new();
|
||||
purple_blist_add_contact(contact, g, NULL);
|
||||
|
||||
// create buddy
|
||||
buddy = purple_buddy_new(account, buddyInfo.legacyName.c_str(), buddyInfo.alias.c_str());
|
||||
purple_blist_add_buddy(buddy, contact, g, NULL);
|
||||
purple_blist_server_alias_buddy(buddy, buddyInfo.alias.c_str());
|
||||
}
|
||||
return (Buddy *) buddy->node.ui_data;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
context = g_option_context_new("config_file_name or profile name");
|
||||
g_option_context_add_main_entries(context, options_entries, "");
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||
std::cout << "option parsing failed: " << error->message << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ver) {
|
||||
// std::cout << VERSION << "\n";
|
||||
std::cout << "verze\n";
|
||||
g_option_context_free(context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
#ifdef WIN32
|
||||
std::cout << "Usage: spectrum.exe <configuration_file.cfg>\n";
|
||||
#else
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,14,0)
|
||||
std::cout << g_option_context_get_help(context, FALSE, NULL);
|
||||
#else
|
||||
std::cout << "Usage: spectrum <configuration_file.cfg>\n";
|
||||
std::cout << "See \"man spectrum\" for more info.\n";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifndef WIN32
|
||||
// signal(SIGPIPE, SIG_IGN);
|
||||
//
|
||||
// if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
|
||||
// std::cout << "SIGCHLD handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// if (signal(SIGINT, spectrum_sigint_handler) == SIG_ERR) {
|
||||
// std::cout << "SIGINT handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// if (signal(SIGTERM, spectrum_sigterm_handler) == SIG_ERR) {
|
||||
// std::cout << "SIGTERM handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// struct sigaction sa;
|
||||
// memset(&sa, 0, sizeof(sa));
|
||||
// sa.sa_handler = spectrum_sighup_handler;
|
||||
// if (sigaction(SIGHUP, &sa, NULL)) {
|
||||
// std::cout << "SIGHUP handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
#endif
|
||||
Config config;
|
||||
if (!config.load(argv[1])) {
|
||||
std::cout << "Can't open " << argv[1] << " configuration file.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
initPurple(config);
|
||||
|
||||
SpectrumEventLoop eventLoop;
|
||||
SpectrumFactory factory;
|
||||
Component transport(&eventLoop, &config, &factory);
|
||||
Logger logger(&transport);
|
||||
_logger = &logger;
|
||||
|
||||
SQLite3Backend sql(&config);
|
||||
logger.setStorageBackend(&sql);
|
||||
if (!sql.connect()) {
|
||||
std::cout << "Can't connect to database.\n";
|
||||
}
|
||||
|
||||
UserManager userManager(&transport, &sql);
|
||||
userManager.onUserCreated.connect(boost::bind(&handleUserCreated, _1, &userManager, &config));
|
||||
userManager.onUserDestroyed.connect(boost::bind(&handleUserDestroyed, _1, &userManager, &config));
|
||||
|
||||
UserRegistration userRegistration(&transport, &userManager, &sql);
|
||||
logger.setUserRegistration(&userRegistration);
|
||||
logger.setUserManager(&userManager);
|
||||
|
||||
transport.connect();
|
||||
eventLoop.run();
|
||||
}
|
||||
|
||||
g_option_context_free(context);
|
||||
}
|
||||
#include "transport/config.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/logger.h"
|
||||
#include "transport/sqlite3backend.h"
|
||||
#include "transport/userregistration.h"
|
||||
#include "transport/networkpluginserver.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Config config;
|
||||
if (!config.load("sample.cfg")) {
|
||||
std::cout << "Can't open sample.cfg configuration file.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
Component transport(&eventLoop, &config, NULL);
|
||||
Logger logger(&transport);
|
||||
|
||||
SQLite3Backend sql(&config);
|
||||
logger.setStorageBackend(&sql);
|
||||
if (!sql.connect()) {
|
||||
std::cout << "Can't connect to database.\n";
|
||||
}
|
||||
|
||||
UserManager userManager(&transport, &sql);
|
||||
UserRegistration userRegistration(&transport, &userManager, &sql);
|
||||
logger.setUserRegistration(&userRegistration);
|
||||
logger.setUserManager(&userManager);
|
||||
|
||||
NetworkPluginServer plugin(&transport, &config, &userManager);
|
||||
|
||||
transport.connect();
|
||||
eventLoop.run();
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@ jid = icq.localhost
|
|||
password = secret
|
||||
server = 127.0.0.1
|
||||
port = 5222
|
||||
server_mode = 1
|
||||
backend=../../backends/libpurple/libpurple_backend
|
||||
protocol=prpl-jabber
|
||||
server_mode=1
|
||||
|
||||
[database]
|
||||
database = test.sql
|
||||
|
|
|
@ -2,12 +2,16 @@ cmake_minimum_required(VERSION 2.6)
|
|||
FILE(GLOB SRC *.cpp *.h)
|
||||
FILE(GLOB HEADERS ../../include/transport/*.h)
|
||||
|
||||
if (PROTOBUF_FOUND)
|
||||
PROTOBUF_GENERATE_CPP(PROTOBUF_SRC PROTOBUF_HDRS "pbnetwork.proto")
|
||||
endif()
|
||||
|
||||
# SOURCE_GROUP(headers FILES ${HEADERS})
|
||||
|
||||
ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC})
|
||||
ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS})
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
|
||||
TARGET_LINK_LIBRARIES(transport -lresolv -lidn -lz -lpthread -lexpat -lidn -lz -lssl -lcrypto -lexpat -lresolv -lc -lxml2 ${Boost_LIBRARIES} ${SQLITE3_LIBRARIES} ${SWIFTEN_LIBRARY})
|
||||
TARGET_LINK_LIBRARIES(transport -lresolv -lidn -lz -lpthread -lexpat -lidn -lz -lssl -lcrypto -lexpat -lresolv -lc -lxml2 ${Boost_LIBRARIES} ${SQLITE3_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
|
||||
|
||||
SET_TARGET_PROPERTIES(transport PROPERTIES
|
||||
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
namespace Transport {
|
||||
|
||||
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_online(false), m_subscription("ask"), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){
|
||||
m_rosterManager->setBuddy(this);
|
||||
// m_rosterManager->setBuddy(this);
|
||||
}
|
||||
|
||||
Buddy::~Buddy() {
|
||||
|
|
|
@ -35,6 +35,7 @@ bool Config::load(const std::string &configfile, boost::program_options::options
|
|||
("service.server", value<std::string>()->default_value(""), "Server to connect to")
|
||||
("service.password", value<std::string>()->default_value(""), "Password used to auth the server")
|
||||
("service.port", value<int>()->default_value(0), "Port the server is listening on")
|
||||
("service.backend", value<std::string>()->default_value("libpurple_backend"), "Backend")
|
||||
("service.protocol", value<std::string>()->default_value(""), "Protocol")
|
||||
("service.allowed_servers", value<std::string>()->default_value(""), "Only users from these servers can connect")
|
||||
("service.server_mode", value<bool>()->default_value(false), "True if Spectrum should behave as server")
|
||||
|
@ -51,6 +52,8 @@ bool Config::load(const std::string &configfile, boost::program_options::options
|
|||
store(parse_config_file(ifs, opts), m_variables);
|
||||
notify(m_variables);
|
||||
|
||||
m_file = configfile;
|
||||
|
||||
onConfigReloaded();
|
||||
|
||||
return true;
|
||||
|
|
|
@ -160,6 +160,9 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) {
|
|||
case pbnetwork::WrapperMessage_Type_TYPE_LOGOUT:
|
||||
handleLogoutPayload(wrapper.payload());
|
||||
break;
|
||||
case pbnetwork::WrapperMessage_Type_TYPE_PING:
|
||||
sendPong();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -178,4 +181,14 @@ void NetworkPlugin::send(const std::string &data) {
|
|||
m_conn->write(Swift::ByteArray(header + data));
|
||||
}
|
||||
|
||||
void NetworkPlugin::sendPong() {
|
||||
std::string message;
|
||||
pbnetwork::WrapperMessage wrap;
|
||||
wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PONG);
|
||||
wrap.SerializeToString(&message);
|
||||
|
||||
send(message);
|
||||
std::cout << "SENDING PONG\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,9 +73,13 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
|
|||
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager) {
|
||||
m_userManager = userManager;
|
||||
m_config = config;
|
||||
m_pongReceived = false;
|
||||
m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1));
|
||||
m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1));
|
||||
|
||||
m_pingTimer = component->getFactories()->getTimerFactory()->createTimer(10000);
|
||||
m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this));
|
||||
|
||||
m_server = component->getFactories()->getConnectionFactory()->createConnectionServer(10000);
|
||||
m_server->onNewConnection.connect(boost::bind(&NetworkPluginServer::handleNewClientConnection, this, _1));
|
||||
m_server->start();
|
||||
|
@ -86,7 +90,7 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
|
|||
}
|
||||
|
||||
NetworkPluginServer::~NetworkPluginServer() {
|
||||
|
||||
m_pingTimer->stop();
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Connection> c) {
|
||||
|
@ -94,15 +98,21 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Con
|
|||
c->disconnect();
|
||||
}
|
||||
m_client = c;
|
||||
m_pongReceived = false;
|
||||
|
||||
|
||||
c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, c));
|
||||
c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, c, _1));
|
||||
sendPing();
|
||||
m_pingTimer->start();
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleSessionFinished(boost::shared_ptr<Swift::Connection> c) {
|
||||
if (c == m_client) {
|
||||
m_client.reset();
|
||||
}
|
||||
m_pingTimer->stop();
|
||||
exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str());
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleConnectedPayload(const std::string &data) {
|
||||
|
@ -187,6 +197,9 @@ void NetworkPluginServer::handleDataRead(boost::shared_ptr<Swift::Connection> c,
|
|||
case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED:
|
||||
handleBuddyChangedPayload(wrapper.payload());
|
||||
break;
|
||||
case pbnetwork::WrapperMessage_Type_TYPE_PONG:
|
||||
m_pongReceived = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -201,6 +214,17 @@ void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const st
|
|||
c->write(Swift::ByteArray(header + data));
|
||||
}
|
||||
|
||||
void NetworkPluginServer::pingTimeout() {
|
||||
std::cout << "pingtimeout\n";
|
||||
if (m_pongReceived) {
|
||||
sendPing();
|
||||
m_pingTimer->start();
|
||||
}
|
||||
else {
|
||||
exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleUserCreated(User *user) {
|
||||
// UserInfo userInfo = user->getUserInfo();
|
||||
user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user));
|
||||
|
@ -233,8 +257,20 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
|
|||
logout.SerializeToString(&message);
|
||||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGOUT);
|
||||
|
||||
|
||||
send(m_client, message);
|
||||
}
|
||||
|
||||
void NetworkPluginServer::sendPing() {
|
||||
|
||||
std::string message;
|
||||
pbnetwork::WrapperMessage wrap;
|
||||
wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PING);
|
||||
wrap.SerializeToString(&message);
|
||||
|
||||
send(m_client, message);
|
||||
m_pongReceived = false;
|
||||
std::cout << "SENDING PING\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,8 +55,10 @@ message WrapperMessage {
|
|||
TYPE_CONV_CREATED = 8;
|
||||
TYPE_CONV_WRITE = 9;
|
||||
TYPE_CONV_REMOVED = 10;
|
||||
TYPE_PING = 11;
|
||||
TYPE_PONG = 12;
|
||||
}
|
||||
required Type type = 1;
|
||||
required bytes payload = 2;
|
||||
optional bytes payload = 2;
|
||||
}
|
||||
;
|
|
@ -37,20 +37,25 @@ RosterManager::RosterManager(User *user, Component *component){
|
|||
m_user = user;
|
||||
m_component = component;
|
||||
m_setBuddyTimer = m_component->getFactories()->getTimerFactory()->createTimer(1000);
|
||||
m_RIETimer = m_component->getFactories()->getTimerFactory()->createTimer(3000);
|
||||
m_RIETimer = m_component->getFactories()->getTimerFactory()->createTimer(5000);
|
||||
m_RIETimer->onTick.connect(boost::bind(&RosterManager::sendRIE, this));
|
||||
}
|
||||
|
||||
RosterManager::~RosterManager() {
|
||||
m_setBuddyTimer->stop();
|
||||
m_RIETimer->stop();
|
||||
for (std::map<std::string, Buddy *>::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
|
||||
Buddy *buddy = (*it).second;
|
||||
delete buddy;
|
||||
}
|
||||
if (m_rosterStorage)
|
||||
delete m_rosterStorage;
|
||||
}
|
||||
|
||||
void RosterManager::setBuddy(Buddy *buddy) {
|
||||
m_setBuddyTimer->onTick.connect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
|
||||
m_setBuddyTimer->start();
|
||||
// m_setBuddyTimer->onTick.connect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
|
||||
// m_setBuddyTimer->start();
|
||||
setBuddyCallback(buddy);
|
||||
}
|
||||
|
||||
void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
|
||||
|
@ -70,6 +75,7 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
|
|||
void RosterManager::setBuddyCallback(Buddy *buddy) {
|
||||
m_setBuddyTimer->onTick.disconnect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
|
||||
|
||||
std::cout << "ADDING " << buddy->getName() << "\n";
|
||||
m_buddies[buddy->getName()] = buddy;
|
||||
onBuddySet(buddy);
|
||||
|
||||
|
@ -79,13 +85,11 @@ void RosterManager::setBuddyCallback(Buddy *buddy) {
|
|||
sendBuddyRosterPush(buddy);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
if (m_setBuddyTimer->onTick.empty()) {
|
||||
m_setBuddyTimer->stop();
|
||||
if (true /*&& rie_is_supported*/) {
|
||||
m_RIETimer->start();
|
||||
if (m_setBuddyTimer->onTick.empty()) {
|
||||
m_setBuddyTimer->stop();
|
||||
if (true /*&& rie_is_supported*/) {
|
||||
m_RIETimer->start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,15 @@ SQLite3Backend::~SQLite3Backend(){
|
|||
// But requires SQLite3 >= 3.6.0 beta
|
||||
|
||||
FINALIZE_STMT(m_setUser);
|
||||
FINALIZE_STMT(m_getUser);
|
||||
FINALIZE_STMT(m_removeUser);
|
||||
FINALIZE_STMT(m_removeUserBuddies);
|
||||
FINALIZE_STMT(m_removeUserSettings);
|
||||
FINALIZE_STMT(m_removeUserBuddiesSettings);
|
||||
FINALIZE_STMT(m_addBuddy);
|
||||
FINALIZE_STMT(m_updateBuddy);
|
||||
FINALIZE_STMT(m_getBuddies);
|
||||
FINALIZE_STMT(m_getBuddiesSettings);
|
||||
sqlite3_close(m_db);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue