From e08c803ffd3d6b0bb4b202eaac9e305eb978f04e Mon Sep 17 00:00:00 2001 From: Aleteoryx Date: Sat, 26 Jul 2025 17:37:32 -0400 Subject: [PATCH] basic batch support Implements: https://todo.amehut.dev/~aleteoryx/sexchat/2 --- src/common/hexchat.h | 21 +++++++++--------- src/common/inbound.c | 1 + src/common/meson.build | 3 ++- src/common/outbound.c | 4 ++-- src/common/proto-irc.c | 50 ++++++++++++++++++++++++++++++------------ src/common/proto-irc.h | 2 ++ 6 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index edaae58eb8489f9e06ca952779903e27da5c20ab..de8958afebc68b5a16dae82a27f9d22f14c8c30b 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -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; diff --git a/src/common/inbound.c b/src/common/inbound.c index 2eb52a443dc90793d4382259037ac99c52b9248a..1c7cfe9361cee1ddfa8c69470b1b1d6fbd9fc054 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1716,6 +1716,7 @@ static const char * const supported_caps[] = { "extended-monitor", "message-tags", "echo-message", + "batch", /* ZNC */ "znc.in/server-time-iso", diff --git a/src/common/meson.build b/src/common/meson.build index 35db2c27329e361acd6bb327eb79a7aeba34c541..5d99588cbffdc59ce3f218fa40c27539f834a14d 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -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', diff --git a/src/common/outbound.c b/src/common/outbound.c index 4d1993c6b51744f85d2b74df89862ed2a6660c79..a52625f6a09c87f152ee09e308257691e9b3cc3c 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -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; diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index d807e008b29e12df5b6bc4be3d40b3af190133f4..7d708c3090570118bf513f7caf7a26196220b9e0 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -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; } diff --git a/src/common/proto-irc.h b/src/common/proto-irc.h index 7467d8dc912d1b8d85d73f3f2a7d75f34a20cbc0..fad32d5e29d59475fd40fecd52a7f7a2dfd33791 100644 --- a/src/common/proto-irc.h +++ b/src/common/proto-irc.h @@ -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;