~aleteoryx/sexchat

e08c803ffd3d6b0bb4b202eaac9e305eb978f04e — Aleteoryx 4 months ago a1d5bb4
basic batch support

Implements: https://todo.amehut.dev/~aleteoryx/sexchat/2
M src/common/hexchat.h => src/common/hexchat.h +11 -10
@@ 530,24 530,25 @@ typedef struct server
	struct session *front_session;	/* front-most window/tab */
	struct session *server_session;	/* server window/tab */

	struct server_gui *gui;		  /* initialized by fe_new_server */
	struct server_gui *gui;		/* initialized by fe_new_server */

	unsigned int ctcp_counter;	  /*flood */
	unsigned int ctcp_counter;	/*flood */
	time_t ctcp_last_time;

	unsigned int msg_counter;	  /*counts the msg tab opened in a certain time */
	unsigned int msg_counter;	/*counts the msg tab opened in a certain time */
	time_t msg_last_time;

	/*time_t connect_time;*/				/* when did it connect? */
	unsigned long lag_sent;   /* we are still waiting for this ping response*/
	time_t ping_recv;					/* when we last got a ping reply */
	time_t away_time;					/* when we were marked away */
	unsigned long lag_sent;		/* we are still waiting for this ping response*/
	time_t ping_recv;		/* when we last got a ping reply */
	time_t away_time;		/* when we were marked away */

	char *encoding;
	GIConv read_converter;  /* iconv converter for converting from server encoding to UTF-8. */
	GIConv write_converter; /* iconv converter for converting from UTF-8 to server encoding. */
	GIConv read_converter;  	/* iconv converter for converting from server encoding to UTF-8. */
	GIConv write_converter; 	/* iconv converter for converting from UTF-8 to server encoding. */

	GSList *favlist;			/* list of channels & keys to join */
	GSList *favlist;		/* list of channels & keys to join */

	GSList *batches;		/* list of batches */

	unsigned int motd_skipped:1;
	unsigned int connected:1;

M src/common/inbound.c => src/common/inbound.c +1 -0
@@ 1716,6 1716,7 @@ static const char * const supported_caps[] = {
	"extended-monitor",
	"message-tags",
	"echo-message",
	"batch",

	/* ZNC */
	"znc.in/server-time-iso",

M src/common/meson.build => src/common/meson.build +2 -1
@@ 1,4 1,5 @@
common_sources = [
  'batch.c',
  'cfgfiles.c',
  'chanopt.c',
  'ctcp.c',


@@ 18,7 19,7 @@ common_sources = [
  'scram.c',
  'server.c',
  'servlist.c',
	'text.c',
  'text.c',
  'tree.c',
  'url.c',
  'userlist.c',

M src/common/outbound.c => src/common/outbound.c +2 -2
@@ 151,8 151,8 @@ server_sendquit (session * sess)

void
process_data_init (char *buf, char *cmd, char *word[],
						 char *word_eol[], gboolean handle_quotes,
						 gboolean allow_escape_quotes)
		   char *word_eol[], gboolean handle_quotes,
		   gboolean allow_escape_quotes)
{
	int wordcount = 2;
	int space = FALSE;

M src/common/proto-irc.c => src/common/proto-irc.c +36 -14
@@ 44,6 44,7 @@
#include "hexchatc.h"
#include "url.h"
#include "servlist.h"
#include "batch.h"

static void
irc_login (server *serv, char *user, char *realname)


@@ 1103,14 1104,14 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
			}
			return;

		case WORDL('P', 'I', 'N', 'G'):
		case WORDL('P','I','N','G'):
			tcp_sendf (sess->server, "PONG %s\r\n", word_eol[3]);
			return;

		case WORDL('P','O','N','G'):
			inbound_ping_reply (serv->server_session,
									  (word[4][0] == ':') ? word[4] + 1 : word[4],
									  word[3], tags_data);
					    (word[4][0] == ':') ? word[4] + 1 : word[4],
					    word[3], tags_data);
			return;

		case WORDL('Q','U','I','T'):


@@ 1175,16 1176,16 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
			inbound_account (serv, nick, STRIP_COLON(word, word_eol, 3), tags_data);
			return;

		case WORDL('A', 'U', 'T', 'H'):
		case WORDL('A','U','T','H'):
			inbound_sasl_authenticate (sess->server, word_eol[3]);
			return;

		case WORDL('C', 'H', 'G', 'H'):
		case WORDL('C','H','G','H'):
			inbound_user_info (sess, NULL, word[3], STRIP_COLON(word, word_eol, 4), NULL, nick, NULL,
							   NULL, 0xff, tags_data);
			return;

		case WORDL('S', 'E', 'T', 'N'):
		case WORDL('S','E','T','N'):
			inbound_user_info (sess, NULL, NULL, NULL, NULL, nick, STRIP_COLON(word, word_eol, 3),
							   NULL, 0xff, tags_data);
			return;


@@ 1310,8 1311,8 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],

		case WORDL('T','O','P','I'):
			inbound_topicnew (serv, nick, word[3],
									(word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4],
									tags_data);
					  (word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4],
					  tags_data);
			return;

		case WORDL('W','A','L','L'):


@@ 1320,6 1321,13 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
				text++;
			EMIT_SIGNAL_TAGS (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0, tags_data);
			return;
		
		case WORDL('B','A','T','C'):
			if (word[3][0] == '-')
				batch_finalize (serv, word[3]+1);
			else
				batch_new (serv, word[3]+1, word[4], word+5);
			return;
		}
	}



@@ 1372,8 1380,8 @@ garbage:
/* handle named messages that DON'T start with a ':' */

static void
process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol[],
								 const message_tags_data *tags_data)
process_named_servermsg (session *sess, char *buf, char *rawname, char *word[], char *word_eol[],
			 const message_tags_data *tags_data)
{
	sess = sess->server->server_session;



@@ 1400,6 1408,14 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol
		inbound_sasl_authenticate (sess->server, word_eol[2]);
		return;
	}
	if (!strncmp (buf, "BATCH ", 6))
	{
		if (word[3][0] == '-')
			batch_finalize (sess->server, word[3]+1);
		else
			batch_new (sess->server, word[3]+1, word[4], word+5);
		return;
	}

	EMIT_SIGNAL_TAGS (XP_TE_SERVTEXT, sess, buf, sess->server->servername, rawname, NULL, 0, tags_data);
}


@@ 1503,7 1519,7 @@ handle_message_tag_time (const char *time, message_tags_data *tags_data)
 */
static void
handle_message_tags (server *serv, const char *tags_str,
							message_tags_data *tags_data)
		     message_tags_data *tags_data)
{
	char **tags;
	int i;


@@ 1527,8 1543,11 @@ handle_message_tags (server *serv, const char *tags_str,
		if (serv->have_account_tag && !strcmp (key, "account"))
			tags_data->account = g_strdup (value);
		
		if (serv->have_message_tags && !strcmp (key, "msgid"))
		if (!strcmp (key, "msgid"))
			tags_data->msgid = g_strdup (value);
		
		if (!strcmp (key, "batch"))
			tags_data->batchref = g_strdup (value);

		if (serv->have_idmsg && strcmp (key, "solanum.chat/identified"))
			tags_data->identified = TRUE;


@@ 1577,6 1596,9 @@ irc_inline (server *serv, char *buf, int len)

	/* split line into words and words_to_end_of_line */
	process_data_init (pdibuf, buf, word, word_eol, FALSE, FALSE);
	
	if (tags_data.batchref && batch_event (serv, tags_data.batchref, buf, word, word_eol))
		goto xit;

	if (buf[0] == ':')
	{


@@ 1595,7 1617,7 @@ irc_inline (server *serv, char *buf, int len)
		word_eol[1] = buf;	/* keep the ":" for plugins */

		if (plugin_emit_server (sess, type, word, word_eol,
								tags_data.timestamp))
					tags_data.timestamp))
			goto xit;

		word[1]++;


@@ 1612,7 1634,7 @@ irc_inline (server *serv, char *buf, int len)

	if (buf[0] != ':')
	{
		process_named_servermsg (sess, buf, word[0], word_eol, &tags_data);
		process_named_servermsg (sess, buf, word[0], word, word_eol, &tags_data);
		goto xit;
	}


M src/common/proto-irc.h => src/common/proto-irc.h +2 -0
@@ 27,6 27,7 @@
	{					\
		NULL, /* account name */	\
		NULL, /* message id */		\
		NULL, /* batch ref */		\
		FALSE, /* identified to nick */ \
		(time_t)0, /* timestamp */	\
	}


@@ 41,6 42,7 @@ typedef struct
{
	char *account;
	char *msgid;
	char *batchref;
	gboolean identified;
	time_t timestamp;
} message_tags_data;