relay: add message "_nicklist_diff" (differences between old and current nicklist)

This is an experimental feature, that must be explicitely enabled by clients
(for weechat protocol) in the init command with option "nicklistdiff", for example:

  init password=mypasswd,nicklistdiff=1

This option will be removed when clients will handle nicklist diff.
v2.8-utf8proc
Sebastien Helleu 2013-03-09 09:04:49 +01:00
parent 9fdeef247e
commit d2ff46fa69
14 changed files with 488 additions and 152 deletions

View File

@ -1,7 +1,7 @@
WeeChat ChangeLog
=================
Sébastien Helleu <flashcode@flashtux.org>
v0.4.1-dev, 2013-03-08
v0.4.1-dev, 2013-03-09
This document lists all changes for each version.
@ -52,6 +52,8 @@ Version 0.4.1 (under dev!)
* irc: add color in output of /names when result is on server buffer (channel
not joined) (bug #38070)
* perl: simplify code to load scripts
* relay: add message "_nicklist_diff" (differences between old and current
nicklist)
* relay: add support of multiple servers on same port for irc protocol (the
client must send the server in the "PASS" command)
* relay: add websocket server support (RFC 6455) for irc and weechat protocols,

View File

@ -241,6 +241,7 @@ Plugins
| weechat/ | Relay for remote interface
| relay-weechat.c | Relay for remote interface (main functions)
| relay-weechat-msg.c | Send binary messages to clients
| relay-weechat-nicklist.c | Nicklist functions
| relay-weechat-protocol.c | Read commands from clients
| rmodifier/ | Rmodifier plugin
| rmodifier.c | Main rmodifier functions

View File

@ -215,6 +215,8 @@
./src/plugins/relay/weechat/relay-weechat.h
./src/plugins/relay/weechat/relay-weechat-msg.c
./src/plugins/relay/weechat/relay-weechat-msg.h
./src/plugins/relay/weechat/relay-weechat-nicklist.c
./src/plugins/relay/weechat/relay-weechat-nicklist.h
./src/plugins/relay/weechat/relay-weechat-protocol.c
./src/plugins/relay/weechat/relay-weechat-protocol.h
./src/plugins/rmodifier/rmodifier.c

View File

@ -208,6 +208,8 @@ SET(WEECHAT_SOURCES
./src/plugins/relay/weechat/relay-weechat.h
./src/plugins/relay/weechat/relay-weechat-msg.c
./src/plugins/relay/weechat/relay-weechat-msg.h
./src/plugins/relay/weechat/relay-weechat-nicklist.c
./src/plugins/relay/weechat/relay-weechat-nicklist.h
./src/plugins/relay/weechat/relay-weechat-protocol.c
./src/plugins/relay/weechat/relay-weechat-protocol.h
./src/plugins/rmodifier/rmodifier.c

View File

@ -24,6 +24,7 @@ relay-client.c relay-client.h
irc/relay-irc.c irc/relay-irc.h
weechat/relay-weechat.c weechat/relay-weechat.h
weechat/relay-weechat-msg.c weechat/relay-weechat-msg.h
weechat/relay-weechat-nicklist.c weechat/relay-weechat-nicklist.h
weechat/relay-weechat-protocol.c weechat/relay-weechat-protocol.h
relay-command.c relay-command.h
relay-completion.c relay-completion.h

View File

@ -35,6 +35,8 @@ relay_la_SOURCES = relay.c \
weechat/relay-weechat.h \
weechat/relay-weechat-msg.c \
weechat/relay-weechat-msg.h \
weechat/relay-weechat-nicklist.c \
weechat/relay-weechat-nicklist.h \
weechat/relay-weechat-protocol.c \
weechat/relay-weechat-protocol.h \
relay-command.c \

View File

@ -34,6 +34,7 @@
#include "../relay.h"
#include "relay-weechat.h"
#include "relay-weechat-msg.h"
#include "relay-weechat-nicklist.h"
#include "../relay-buffer.h"
#include "../relay-client.h"
#include "../relay-config.h"
@ -823,85 +824,108 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg,
/*
* Adds nicklist for a buffer, as hdata object.
*
* Argument "nicklist" contains nicklist diffs. If it is NULL or don't have
* items inside, full nicklist is sent.
*
* Returns the number of nicks+groups added to message.
*/
int
relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg,
struct t_gui_buffer *buffer)
struct t_gui_buffer *buffer,
struct t_relay_weechat_nicklist *nicklist)
{
int count;
int count, i;
struct t_hdata *ptr_hdata_group, *ptr_hdata_nick;
struct t_gui_nick_group *ptr_group;
struct t_gui_nick *ptr_nick;
count = 0;
ptr_hdata_group = weechat_hdata_get ("nick_group");
ptr_hdata_nick = weechat_hdata_get ("nick");
ptr_group = NULL;
ptr_nick = NULL;
weechat_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick);
while (ptr_group || ptr_nick)
if (nicklist)
{
if (ptr_nick)
/* send nicklist diffs */
for (i = 0; i < nicklist->items_count; i++)
{
relay_weechat_msg_add_pointer (msg, buffer);
relay_weechat_msg_add_pointer (msg, ptr_nick);
relay_weechat_msg_add_char (msg, 0); /* group */
relay_weechat_msg_add_char (msg,
(char)weechat_hdata_integer(ptr_hdata_nick,
ptr_nick,
"visible"));
relay_weechat_msg_add_int (msg,
weechat_hdata_integer (ptr_hdata_nick,
ptr_nick,
"level"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"name"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"color"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"prefix"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"prefix_color"));
count++;
}
else
{
relay_weechat_msg_add_pointer (msg, buffer);
relay_weechat_msg_add_pointer (msg, ptr_group);
relay_weechat_msg_add_char (msg, 1); /* group */
relay_weechat_msg_add_char (msg,
(char)weechat_hdata_integer(ptr_hdata_group,
ptr_group,
"visible"));
relay_weechat_msg_add_int (msg,
weechat_hdata_integer (ptr_hdata_group,
ptr_group,
"level"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_group,
ptr_group,
"name"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_group,
ptr_group,
"color"));
relay_weechat_msg_add_string (msg, NULL); /* prefix */
relay_weechat_msg_add_string (msg, NULL); /* prefix_color */
relay_weechat_msg_add_pointer (msg, nicklist->items[i].pointer);
relay_weechat_msg_add_char (msg, nicklist->items[i].diff);
relay_weechat_msg_add_char (msg, nicklist->items[i].group);
relay_weechat_msg_add_char (msg, nicklist->items[i].visible);
relay_weechat_msg_add_int (msg, nicklist->items[i].level);
relay_weechat_msg_add_string (msg, nicklist->items[i].name);
relay_weechat_msg_add_string (msg, nicklist->items[i].color);
relay_weechat_msg_add_string (msg, nicklist->items[i].prefix);
relay_weechat_msg_add_string (msg, nicklist->items[i].prefix_color);
count++;
}
}
else
{
/* send full nicklist */
ptr_hdata_group = weechat_hdata_get ("nick_group");
ptr_hdata_nick = weechat_hdata_get ("nick");
ptr_group = NULL;
ptr_nick = NULL;
weechat_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick);
while (ptr_group || ptr_nick)
{
if (ptr_nick)
{
relay_weechat_msg_add_pointer (msg, buffer);
relay_weechat_msg_add_pointer (msg, ptr_nick);
relay_weechat_msg_add_char (msg, 0); /* group */
relay_weechat_msg_add_char (msg,
(char)weechat_hdata_integer(ptr_hdata_nick,
ptr_nick,
"visible"));
relay_weechat_msg_add_int (msg, 0); /* level */
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"name"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"color"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"prefix"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_nick,
ptr_nick,
"prefix_color"));
count++;
}
else
{
relay_weechat_msg_add_pointer (msg, buffer);
relay_weechat_msg_add_pointer (msg, ptr_group);
relay_weechat_msg_add_char (msg, 1); /* group */
relay_weechat_msg_add_char (msg,
(char)weechat_hdata_integer(ptr_hdata_group,
ptr_group,
"visible"));
relay_weechat_msg_add_int (msg,
weechat_hdata_integer (ptr_hdata_group,
ptr_group,
"level"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_group,
ptr_group,
"name"));
relay_weechat_msg_add_string (msg,
weechat_hdata_string (ptr_hdata_group,
ptr_group,
"color"));
relay_weechat_msg_add_string (msg, NULL); /* prefix */
relay_weechat_msg_add_string (msg, NULL); /* prefix_color */
count++;
}
weechat_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick);
}
}
return count;
@ -909,23 +933,31 @@ relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg,
/*
* Adds nicklist for one or all buffers, as hdata object.
*
* Argument "nicklist" contains nicklist diffs. If it is NULL or don't have
* items inside, full nicklist is sent.
*/
void
relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg,
struct t_gui_buffer *buffer)
struct t_gui_buffer *buffer,
struct t_relay_weechat_nicklist *nicklist)
{
char str_vars[512];
struct t_hdata *ptr_hdata;
struct t_gui_buffer *ptr_buffer;
int pos_count, count;
uint32_t count32;
snprintf (str_vars, sizeof (str_vars),
"%sgroup:chr,visible:chr,level:int,"
"name:str,color:str,"
"prefix:str,prefix_color:str",
(nicklist) ? "_diff:chr," : "");
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HDATA);
relay_weechat_msg_add_string (msg, "buffer/nicklist_item");
relay_weechat_msg_add_string (msg,
"group:chr,visible:chr,level:int,"
"name:str,color:str,"
"prefix:str,prefix_color:str");
relay_weechat_msg_add_string (msg, str_vars);
/* "count" will be set later, with number of objects in hdata */
pos_count = msg->data_size;
@ -933,14 +965,16 @@ relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg,
relay_weechat_msg_add_int (msg, 0);
if (buffer)
count += relay_weechat_msg_add_nicklist_buffer (msg, buffer);
{
count += relay_weechat_msg_add_nicklist_buffer (msg, buffer, nicklist);
}
else
{
ptr_hdata = weechat_hdata_get ("buffer");
ptr_buffer = weechat_hdata_get_list (ptr_hdata, "gui_buffers");
while (ptr_buffer)
{
count += relay_weechat_msg_add_nicklist_buffer (msg, ptr_buffer);
count += relay_weechat_msg_add_nicklist_buffer (msg, ptr_buffer, NULL);
ptr_buffer = weechat_hdata_move (ptr_hdata, ptr_buffer, 1);
}
}

View File

@ -20,6 +20,8 @@
#ifndef __WEECHAT_RELAY_WEECHAT_MSG_H
#define __WEECHAT_RELAY_WEECHAT_MSG_H 1
struct t_relay_weechat_nicklist;
#define RELAY_WEECHAT_MSG_INITIAL_ALLOC 4096
/* object ids in binary messages */
@ -73,7 +75,8 @@ extern void relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg,
void *pointer,
const char *arguments);
extern void relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg,
struct t_gui_buffer *buffer);
struct t_gui_buffer *buffer,
struct t_relay_weechat_nicklist *nicklist);
extern void relay_weechat_msg_send (struct t_relay_client *client,
struct t_relay_weechat_msg *msg);
extern void relay_weechat_msg_free (struct t_relay_weechat_msg *msg);

View File

@ -0,0 +1,155 @@
/*
* relay-weechat-nicklist.c - nicklist functions for WeeChat protocol
*
* Copyright (C) 2003-2013 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "../../weechat-plugin.h"
#include "../relay.h"
#include "relay-weechat.h"
#include "relay-weechat-nicklist.h"
/*
* Builds a new nicklist structure (to store nicklist diffs).
*
* Returns pointer to new nicklist structure, NULL if error.
*/
struct t_relay_weechat_nicklist *
relay_weechat_nicklist_new ()
{
struct t_relay_weechat_nicklist *new_nicklist;
new_nicklist = malloc (sizeof (*new_nicklist));
if (!new_nicklist)
return NULL;
new_nicklist->nicklist_count = 0;
new_nicklist->items_count = 0;
new_nicklist->items = NULL;
return new_nicklist;
}
/*
* Adds a nicklist item in nicklist structure.
*/
void
relay_weechat_nicklist_add_item (struct t_relay_weechat_nicklist *nicklist,
char diff, struct t_gui_nick_group *group,
struct t_gui_nick *nick)
{
struct t_relay_weechat_nicklist_item *new_items, *ptr_item;
struct t_hdata *hdata;
const char *str;
int i;
/*
* check if the last "parent_group" (with diff = '^') of items is the same
* as this one: if yes, don't add this parent group
*/
if ((diff == RELAY_WEECHAT_NICKLIST_DIFF_PARENT)
&& (nicklist->items_count > 0))
{
for (i = nicklist->items_count - 1; i >= 0; i--)
{
if (nicklist->items[i].diff == RELAY_WEECHAT_NICKLIST_DIFF_PARENT)
{
if (nicklist->items[i].pointer == group)
return;
break;
}
}
}
new_items = realloc (nicklist->items,
(nicklist->items_count + 1) * sizeof (new_items[0]));
if (!new_items)
return;
nicklist->items = new_items;
ptr_item = &(nicklist->items[nicklist->items_count]);
if (group)
{
hdata = weechat_hdata_get ("nick_group");
ptr_item->pointer = group;
}
else
{
hdata = weechat_hdata_get ("nick");
ptr_item->pointer = nick;
}
ptr_item->diff = diff;
ptr_item->group = (group) ? 1 : 0;
ptr_item->visible = weechat_hdata_integer (hdata, ptr_item->pointer, "visible");
ptr_item->level = (group) ? weechat_hdata_integer (hdata, ptr_item->pointer, "level") : 0;
str = weechat_hdata_string (hdata, ptr_item->pointer, "name");
ptr_item->name = (str) ? strdup (str) : NULL;
str = weechat_hdata_string (hdata, ptr_item->pointer, "color");
ptr_item->color = (str) ? strdup (str) : NULL;
str = weechat_hdata_string (hdata, ptr_item->pointer, "prefix");
ptr_item->prefix = (str) ? strdup (str) : NULL;
str = weechat_hdata_string (hdata, ptr_item->pointer, "prefix_color");
ptr_item->prefix_color = (str) ? strdup (str) : NULL;
nicklist->items_count++;
}
/*
* Frees a nicklist_item structure.
*/
void
relay_weechat_nicklist_item_free (struct t_relay_weechat_nicklist_item *item)
{
if (item->name)
free (item->name);
if (item->color)
free (item->color);
if (item->prefix)
free (item->prefix);
if (item->prefix_color)
free (item->prefix_color);
}
/*
* Frees a new nicklist structure.
*/
void
relay_weechat_nicklist_free (struct t_relay_weechat_nicklist *nicklist)
{
int i;
/* free items */
if (nicklist->items_count > 0)
{
for (i = 0; i < nicklist->items_count; i++)
{
relay_weechat_nicklist_item_free (&(nicklist->items[i]));
}
free (nicklist->items);
}
free (nicklist);
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2003-2013 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_WEECHAT_NICKLIST_H
#define __WEECHAT_RELAY_WEECHAT_NICKLIST_H 1
#define RELAY_WEECHAT_NICKLIST_DIFF_UNKNOWN ' '
#define RELAY_WEECHAT_NICKLIST_DIFF_PARENT '^'
#define RELAY_WEECHAT_NICKLIST_DIFF_ADDED '+'
#define RELAY_WEECHAT_NICKLIST_DIFF_REMOVED '-'
#define RELAY_WEECHAT_NICKLIST_DIFF_CHANGED '*'
struct t_relay_weechat_nicklist_item
{
void *pointer; /* pointer on group/nick */
char diff; /* type of diff (see constants above)*/
char group; /* 1=group, 0=nick */
char visible; /* 1=visible, 0=not visible */
int level; /* level */
char *name; /* name of group/nick */
char *color; /* color for name */
char *prefix; /* prefix */
char *prefix_color; /* color for prefix */
};
struct t_relay_weechat_nicklist
{
int nicklist_count; /* number of nicks in nicklist */
/* before receiving first diff */
int items_count; /* number of nicklist items */
struct t_relay_weechat_nicklist_item *items; /* nicklist items */
};
extern struct t_relay_weechat_nicklist *relay_weechat_nicklist_new ();
extern void relay_weechat_nicklist_add_item (struct t_relay_weechat_nicklist *nicklist,
char diff,
struct t_gui_nick_group *group,
struct t_gui_nick *nick);
extern void relay_weechat_nicklist_free (struct t_relay_weechat_nicklist *nicklist);
#endif /* __WEECHAT_RELAY_WEECHAT_NICKLIST_H */

View File

@ -28,6 +28,7 @@
#include "relay-weechat.h"
#include "relay-weechat-protocol.h"
#include "relay-weechat-msg.h"
#include "relay-weechat-nicklist.h"
#include "../relay-client.h"
#include "../relay-config.h"
#include "../relay-raw.h"
@ -193,6 +194,10 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(init)
if (compression >= 0)
RELAY_WEECHAT_DATA(client, compression) = compression;
}
else if (strcmp (options[i], "nicklistdiff") == 0)
{
RELAY_WEECHAT_DATA(client, nicklist_diff) = 1;
}
}
}
weechat_string_free_split (options);
@ -320,7 +325,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(nicklist)
msg = relay_weechat_msg_new (id);
if (msg)
{
relay_weechat_msg_add_nicklist (msg, ptr_buffer);
relay_weechat_msg_add_nicklist (msg, ptr_buffer, NULL);
relay_weechat_msg_send (client, msg);
relay_weechat_msg_free (msg);
}
@ -605,7 +610,7 @@ relay_weechat_protocol_signal_buffer_cb (void *data, const char *signal,
snprintf (cmd_hdata, sizeof (cmd_hdata),
"buffer:0x%lx", (long unsigned int)ptr_buffer);
weechat_hashtable_remove (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist),
cmd_hdata + 7);
ptr_buffer);
relay_weechat_msg_add_hdata (msg, cmd_hdata,
"number,full_name");
relay_weechat_msg_send (ptr_client, msg);
@ -629,35 +634,52 @@ relay_weechat_protocol_nicklist_map_cb (void *data,
const void *value)
{
struct t_relay_client *ptr_client;
int rc;
long unsigned int buffer;
struct t_gui_buffer *ptr_buffer;
struct t_relay_weechat_nicklist *ptr_nicklist;
struct t_hdata *ptr_hdata;
struct t_relay_weechat_msg *msg;
/* make C compiler happy */
(void) hashtable;
(void) value;
ptr_client = (struct t_relay_client *)data;
ptr_buffer = (struct t_gui_buffer *)key;
ptr_nicklist = (struct t_relay_weechat_nicklist *)value;
rc = sscanf (key, "%lx", &buffer);
if ((rc != EOF) && (rc != 0))
ptr_hdata = weechat_hdata_get ("buffer");
if (ptr_hdata)
{
ptr_hdata = weechat_hdata_get ("buffer");
if (ptr_hdata)
if (weechat_hdata_check_pointer (ptr_hdata,
weechat_hdata_get_list (ptr_hdata, "gui_buffers"),
ptr_buffer))
{
if (weechat_hdata_check_pointer (ptr_hdata,
weechat_hdata_get_list (ptr_hdata, "gui_buffers"),
(void *)buffer))
if (RELAY_WEECHAT_DATA(ptr_client, nicklist_diff))
{
msg = relay_weechat_msg_new ("_nicklist");
if (msg)
/*
* if no diff at all, or if diffs are bigger than nicklist:
* send whole nicklist
*/
if (ptr_nicklist
&& ((ptr_nicklist->items_count == 0)
|| (ptr_nicklist->items_count >= weechat_buffer_get_integer (ptr_buffer, "nicklist_count") + 1)))
{
relay_weechat_msg_add_nicklist (msg, (struct t_gui_buffer *)buffer);
relay_weechat_msg_send (ptr_client, msg);
relay_weechat_msg_free (msg);
ptr_nicklist = NULL;
}
}
else
{
/* it will be removed soon (when clients will handle nicklist diff) */
ptr_nicklist = NULL;
}
/* send nicklist diffs or full nicklist */
msg = relay_weechat_msg_new ((ptr_nicklist) ? "_nicklist_diff" : "_nicklist");
if (msg)
{
relay_weechat_msg_add_nicklist (msg, ptr_buffer, ptr_nicklist);
relay_weechat_msg_send (ptr_client, msg);
relay_weechat_msg_free (msg);
}
}
}
}
@ -690,54 +712,94 @@ relay_weechat_protocol_timer_nicklist_cb (void *data, int remaining_calls)
}
/*
* Callback for signals "nicklist_*".
* Callback for hsignals "nicklist_*".
*/
int
relay_weechat_protocol_signal_nicklist_cb (void *data, const char *signal,
const char *type_data,
void *signal_data)
relay_weechat_protocol_hsignal_nicklist_cb (void *data, const char *signal,
struct t_hashtable *hashtable)
{
struct t_relay_client *ptr_client;
char *pos, *str_buffer;
int rc;
long unsigned int buffer;
/* make C compiler happy */
(void) signal;
(void) type_data;
struct t_gui_nick_group *parent_group, *group;
struct t_gui_nick *nick;
struct t_gui_buffer *ptr_buffer;
struct t_relay_weechat_nicklist *ptr_nicklist;
char diff;
ptr_client = (struct t_relay_client *)data;
if (!ptr_client || !relay_client_valid (ptr_client))
return WEECHAT_RC_OK;
pos = strchr ((char *)signal_data, ',');
if (!pos)
/* check if buffer is synchronized with flag "nicklist" */
ptr_buffer = weechat_hashtable_get (hashtable, "buffer");
if (!relay_weechat_protocol_is_sync (ptr_client, ptr_buffer,
RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST))
return WEECHAT_RC_OK;
str_buffer = weechat_strndup (signal_data, pos - (char *)signal_data);
if (!str_buffer)
parent_group = weechat_hashtable_get (hashtable, "parent_group");
group = weechat_hashtable_get (hashtable, "group");
nick = weechat_hashtable_get (hashtable, "nick");
/* if there is no parent group (for example "root" group), ignore the signal */
if (!parent_group)
return WEECHAT_RC_OK;
rc = sscanf (str_buffer, "%lx", &buffer);
if ((rc != EOF) && (rc != 0))
ptr_nicklist = weechat_hashtable_get (RELAY_WEECHAT_DATA(ptr_client,
buffers_nicklist),
ptr_buffer);
if (!ptr_nicklist)
{
/* send nicklist only if buffer is synchronized with flag "nicklist" */
if (relay_weechat_protocol_is_sync (ptr_client, (void *)buffer,
RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST))
{
weechat_hashtable_set (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist),
str_buffer, "1");
if (RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist))
{
weechat_unhook (RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist));
RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist) = NULL;
}
relay_weechat_hook_timer_nicklist (ptr_client);
}
ptr_nicklist = relay_weechat_nicklist_new ();
if (!ptr_nicklist)
return WEECHAT_RC_OK;
ptr_nicklist->nicklist_count = weechat_buffer_get_integer (ptr_buffer,
"nicklist_count");
weechat_hashtable_set (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist),
ptr_buffer,
ptr_nicklist);
}
free (str_buffer);
/* set diff type */
diff = RELAY_WEECHAT_NICKLIST_DIFF_UNKNOWN;
if ((strcmp (signal, "nicklist_group_added") == 0)
|| (strcmp (signal, "nicklist_nick_added") == 0))
{
diff = RELAY_WEECHAT_NICKLIST_DIFF_ADDED;
}
else if ((strcmp (signal, "nicklist_group_removing") == 0)
|| (strcmp (signal, "nicklist_nick_removing") == 0))
{
diff = RELAY_WEECHAT_NICKLIST_DIFF_REMOVED;
}
else if ((strcmp (signal, "nicklist_group_changed") == 0)
|| (strcmp (signal, "nicklist_nick_changed") == 0))
{
diff = RELAY_WEECHAT_NICKLIST_DIFF_CHANGED;
}
if (diff != RELAY_WEECHAT_NICKLIST_DIFF_UNKNOWN)
{
/*
* add items if nicklist was not empty or very small (otherwise we will
* send full nicklist)
*/
if (ptr_nicklist->nicklist_count > 1)
{
/* add nicklist item for parent group and group/nick */
relay_weechat_nicklist_add_item (ptr_nicklist,
RELAY_WEECHAT_NICKLIST_DIFF_PARENT,
parent_group, NULL);
relay_weechat_nicklist_add_item (ptr_nicklist, diff, group, nick);
}
/* add timer to send nicklist */
if (RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist))
{
weechat_unhook (RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist));
RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist) = NULL;
}
relay_weechat_hook_timer_nicklist (ptr_client);
}
return WEECHAT_RC_OK;
}

View File

@ -89,6 +89,9 @@ extern int relay_weechat_protocol_signal_nicklist_cb (void *data,
const char *signal,
const char *type_data,
void *signal_data);
extern int relay_weechat_protocol_hsignal_nicklist_cb (void *data,
const char *signal,
struct t_hashtable *hashtable);
extern int relay_weechat_protocol_signal_upgrade_cb (void *data,
const char *signal,
const char *type_data,

View File

@ -33,6 +33,7 @@
#include "../../weechat-plugin.h"
#include "../relay.h"
#include "relay-weechat.h"
#include "relay-weechat-nicklist.h"
#include "relay-weechat-protocol.h"
#include "../relay-client.h"
#include "../relay-config.h"
@ -76,10 +77,10 @@ relay_weechat_hook_signals (struct t_relay_client *client)
weechat_hook_signal ("buffer_*",
&relay_weechat_protocol_signal_buffer_cb,
client);
RELAY_WEECHAT_DATA(client, hook_signal_nicklist) =
weechat_hook_signal ("nicklist_*",
&relay_weechat_protocol_signal_nicklist_cb,
client);
RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist) =
weechat_hook_hsignal ("nicklist_*",
&relay_weechat_protocol_hsignal_nicklist_cb,
client);
RELAY_WEECHAT_DATA(client, hook_signal_upgrade) =
weechat_hook_signal ("upgrade*",
&relay_weechat_protocol_signal_upgrade_cb,
@ -98,10 +99,10 @@ relay_weechat_unhook_signals (struct t_relay_client *client)
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_buffer));
RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL;
}
if (RELAY_WEECHAT_DATA(client, hook_signal_nicklist))
if (RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist))
{
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_nicklist));
RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = NULL;
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist));
RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist) = NULL;
}
if (RELAY_WEECHAT_DATA(client, hook_signal_upgrade))
{
@ -143,6 +144,21 @@ relay_weechat_close_connection (struct t_relay_client *client)
relay_weechat_unhook_signals (client);
}
/*
* Frees a value of hashtable "buffers_nicklist".
*/
void
relay_weechat_free_buffers_nicklist (struct t_hashtable *hashtable,
const void *key, void *value)
{
/* make C compiler happy */
(void) hashtable;
(void) key;
relay_weechat_nicklist_free ((struct t_relay_weechat_nicklist *)value);
}
/*
* Initializes relay data specific to WeeChat protocol.
*/
@ -160,6 +176,7 @@ relay_weechat_alloc (struct t_relay_client *client)
{
RELAY_WEECHAT_DATA(client, password_ok) = (password && password[0]) ? 0 : 1;
RELAY_WEECHAT_DATA(client, compression) = 1;
RELAY_WEECHAT_DATA(client, nicklist_diff) = 0;
RELAY_WEECHAT_DATA(client, buffers_sync) =
weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
@ -167,14 +184,17 @@ relay_weechat_alloc (struct t_relay_client *client)
NULL,
NULL);
RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL;
RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = NULL;
RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist) = NULL;
RELAY_WEECHAT_DATA(client, hook_signal_upgrade) = NULL;
RELAY_WEECHAT_DATA(client, buffers_nicklist) =
weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
WEECHAT_HASHTABLE_POINTER,
NULL,
NULL);
weechat_hashtable_set_pointer (RELAY_WEECHAT_DATA(client, buffers_nicklist),
"callback_free_value",
&relay_weechat_free_buffers_nicklist);
RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL;
relay_weechat_hook_signals (client);
@ -194,7 +214,7 @@ relay_weechat_alloc_with_infolist (struct t_relay_client *client,
struct t_relay_weechat_data *weechat_data;
int index, value;
char name[64];
const char *key, *str_value;
const char *key;
client->protocol_data = malloc (sizeof (*weechat_data));
if (client->protocol_data)
@ -202,6 +222,7 @@ relay_weechat_alloc_with_infolist (struct t_relay_client *client,
/* general stuff */
RELAY_WEECHAT_DATA(client, password_ok) = weechat_infolist_integer (infolist, "password_ok");
RELAY_WEECHAT_DATA(client, compression) = weechat_infolist_integer (infolist, "compression");
RELAY_WEECHAT_DATA(client, nicklist_diff) = weechat_infolist_integer (infolist, "nicklist_diff");
/* sync of buffers */
RELAY_WEECHAT_DATA(client, buffers_sync) = weechat_hashtable_new (32,
@ -224,28 +245,17 @@ relay_weechat_alloc_with_infolist (struct t_relay_client *client,
index++;
}
RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL;
RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = NULL;
RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist) = NULL;
RELAY_WEECHAT_DATA(client, hook_signal_upgrade) = NULL;
RELAY_WEECHAT_DATA(client, buffers_nicklist) =
weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
WEECHAT_HASHTABLE_POINTER,
NULL,
NULL);
index = 0;
while (1)
{
snprintf (name, sizeof (name), "buffers_nicklist_name_%05d", index);
key = weechat_infolist_string (infolist, name);
if (!key)
break;
snprintf (name, sizeof (name), "buffers_nicklist_value_%05d", index);
str_value = weechat_infolist_string (infolist, name);
weechat_hashtable_set (RELAY_WEECHAT_DATA(client, buffers_nicklist),
key,
str_value);
index++;
}
weechat_hashtable_set_pointer (RELAY_WEECHAT_DATA(client, buffers_nicklist),
"callback_free_value",
&relay_weechat_free_buffers_nicklist);
RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL;
relay_weechat_hook_signals (client);
@ -265,8 +275,8 @@ relay_weechat_free (struct t_relay_client *client)
weechat_hashtable_free (RELAY_WEECHAT_DATA(client, buffers_sync));
if (RELAY_WEECHAT_DATA(client, hook_signal_buffer))
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_buffer));
if (RELAY_WEECHAT_DATA(client, hook_signal_nicklist))
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_nicklist));
if (RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist))
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist));
if (RELAY_WEECHAT_DATA(client, hook_signal_upgrade))
weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_upgrade));
if (RELAY_WEECHAT_DATA(client, buffers_nicklist))
@ -297,9 +307,9 @@ relay_weechat_add_to_infolist (struct t_infolist_item *item,
return 0;
if (!weechat_infolist_new_var_integer (item, "compression", RELAY_WEECHAT_DATA(client, compression)))
return 0;
if (!weechat_hashtable_add_to_infolist (RELAY_WEECHAT_DATA(client, buffers_sync), item, "buffers_sync"))
if (!weechat_infolist_new_var_integer (item, "nicklist_diff", RELAY_WEECHAT_DATA(client, nicklist_diff)))
return 0;
if (!weechat_hashtable_add_to_infolist (RELAY_WEECHAT_DATA(client, buffers_nicklist), item, "buffers_nicklist"))
if (!weechat_hashtable_add_to_infolist (RELAY_WEECHAT_DATA(client, buffers_sync), item, "buffers_sync"))
return 0;
return 1;
@ -316,12 +326,13 @@ relay_weechat_print_log (struct t_relay_client *client)
{
weechat_log_printf (" password_ok. . . . . . : %d", RELAY_WEECHAT_DATA(client, password_ok));
weechat_log_printf (" compression. . . . . . : %d", RELAY_WEECHAT_DATA(client, compression));
weechat_log_printf (" nicklist_diff. . . . . : %d", RELAY_WEECHAT_DATA(client, nicklist_diff));
weechat_log_printf (" buffers_sync . . . . . : 0x%lx (hashtable: '%s')",
RELAY_WEECHAT_DATA(client, buffers_sync),
weechat_hashtable_get_string (RELAY_WEECHAT_DATA(client, buffers_sync),
"keys_values"));
weechat_log_printf (" hook_signal_buffer . . : 0x%lx", RELAY_WEECHAT_DATA(client, hook_signal_buffer));
weechat_log_printf (" hook_signal_nicklist . : 0x%lx", RELAY_WEECHAT_DATA(client, hook_signal_nicklist));
weechat_log_printf (" hook_hsignal_nicklist. : 0x%lx", RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist));
weechat_log_printf (" hook_signal_upgrade. . : 0x%lx", RELAY_WEECHAT_DATA(client, hook_signal_upgrade));
weechat_log_printf (" buffers_nicklist . . . : 0x%lx (hashtable: '%s')",
RELAY_WEECHAT_DATA(client, buffers_nicklist),

View File

@ -37,12 +37,13 @@ struct t_relay_weechat_data
{
int password_ok; /* password received and ok? */
int compression; /* compression type */
int nicklist_diff; /* (TEMPORARY) nicklist diff enabled?*/
/* sync of buffers */
struct t_hashtable *buffers_sync; /* buffers synchronized (events */
/* received for these buffers) */
struct t_hook *hook_signal_buffer; /* hook for signals "buffer_*" */
struct t_hook *hook_signal_nicklist; /* hook for signals "nicklist_*" */
struct t_hook *hook_hsignal_nicklist; /* hook for hsignals "nicklist_*" */
struct t_hook *hook_signal_upgrade; /* hook for signals "upgrade*" */
struct t_hashtable *buffers_nicklist; /* send nicklist for these buffers*/
struct t_hook *hook_timer_nicklist; /* timer for sending nicklist */