--- a/src/spasm-chat.c Sun Apr 19 17:22:00 2020 -0500
+++ b/src/spasm-chat.c Mon Apr 20 00:42:50 2020 -0500
@@ -48,6 +48,10 @@
+/****************************************************************************** + *****************************************************************************/ +static void spasm_chat_read(SpasmChatService *chat); /******************************************************************************
@@ -98,7 +102,7 @@
buffer = g_strdup_vprintf(format, vargs);
- purple_debug_info("spasm-chat", "send buffer: %s\n", buffer);
+ purple_debug_info("spasm-chat", "send buffer: '%s'\n", buffer); success = g_output_stream_printf(
@@ -141,22 +145,111 @@
spasm_chat_service_handle_join(SpasmChatService *chat, const gchar *prefix,
const gchar *middle, const gchar *trailing)
+ PurpleAccount *account = spasm_account_get_account(chat->sa); + PurpleConnection *connection = NULL; + PurpleConversation *conversation = NULL; + gchar *nick= NULL, *target = NULL; + if(!g_regex_match(chat->regex_target, middle, 0, &info)) { + purple_debug_misc("spasm-chat", "JOIN failed to find a target"); - if(g_regex_match(chat->regex_target, middle, 0, &info)) {
- gchar *target = g_match_info_fetch_named(info, "target");
+ g_match_info_unref(info); + target = g_match_info_fetch_named(info, "target"); + g_match_info_unref(info); + connection = spasm_account_get_connection(chat->sa); + nick = spasm_chat_service_nick_from_mask(prefix);
- PurpleConnection *connection = NULL;
+ if(purple_utf8_strcasecmp(nick, purple_account_get_username(account)) == 0) { + /* We initiated the join. */ + serv_got_joined_chat(connection, chat->id++, target); + /* Someone else is joining a channel we're in. */ + PurpleConvChat *chat = NULL; - connection = spasm_account_get_connection(chat->sa);
- serv_got_joined_chat(connection, chat->id++, target);
+ conversation = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, + if(conversation == NULL) { + purple_debug_misc("spasm-chat", + "ignoring JOIN for non-existant channel %s\n", + chat = PURPLE_CONV_CHAT(conversation); + purple_conv_chat_add_user(chat, nick, NULL, PURPLE_CBFLAGS_NONE, TRUE); +spasm_chat_service_handle_part(SpasmChatService *chat, const gchar *prefix, + const gchar *middle, const gchar *trailing) + PurpleAccount *account = spasm_account_get_account(chat->sa); + PurpleConnection *connection = NULL; + PurpleConvChat *chat_conversation = NULL; + PurpleConversation *conversation = NULL; + GMatchInfo *info = NULL; + gchar *nick= NULL, *target = NULL; + if(!g_regex_match(chat->regex_target, middle, 0, &info)) { + purple_debug_misc("spasm-chat", "PART failed to find a target"); + g_match_info_unref(info); + target = g_match_info_fetch_named(info, "target"); g_match_info_unref(info);
+ connection = spasm_account_get_connection(chat->sa); + nick = spasm_chat_service_nick_from_mask(prefix); + conversation = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, + if(conversation == NULL) { + purple_debug_misc("spasm-chat", + "Ignoring PART for non-existent channel %s\n", + chat_conversation = PURPLE_CONV_CHAT(conversation); + if(purple_utf8_strcasecmp(nick, purple_account_get_username(account)) == 0) { + /* We initiated the part. */ + serv_got_chat_left(connection, + purple_conv_chat_get_id(chat_conversation)); + /* Someone else is parting a channel we're in. */ + purple_conv_chat_remove_user(chat_conversation, nick, NULL); @@ -194,6 +287,19 @@
g_match_info_unref(info);
+spasm_chat_service_handle_cap(SpasmChatService *chat, const gchar *prefix, + const gchar *middle, const gchar *trailing) + if(g_ascii_strcasecmp(middle, "ACK") == 0) { + spasm_chat_service_real_send(chat, "CAP END"); + //spasm_chat_read(chat); + purple_debug_misc("spasm-chat", "cap-middle: '%s'\n", middle); + purple_debug_misc("spasm-chat", "cap-trailing: '%s'\n", trailing); spasm_chat_service_init_handlers(void) {
GHashTable *handlers = NULL;
@@ -204,13 +310,15 @@
g_hash_table_insert(handlers, "002", NULL); /* Ignore RPL_YOURHOST */
g_hash_table_insert(handlers, "003", NULL); /* Ignore RPL_CREATED */
g_hash_table_insert(handlers, "004", NULL); /* Ignore RPL_MYINFO */
- g_hash_table_insert(handlers, "353", NULL); /* Ignore RPL_NAMREPLY */
+// g_hash_table_insert(handlers, "353", NULL); /* Ignore RPL_NAMREPLY */ g_hash_table_insert(handlers, "366", NULL); /* Ignore RPL_ENDOFNAMES */
g_hash_table_insert(handlers, "372", NULL); /* Ignore RPL_MOTD */
g_hash_table_insert(handlers, "375", NULL); /* Ignore RPL_MOTDSTART */
g_hash_table_insert(handlers, "376", NULL); /* Ignore RPL_ENDOFMOTD */
+ g_hash_table_insert(handlers, "CAP", spasm_chat_service_handle_cap); g_hash_table_insert(handlers, "JOIN", spasm_chat_service_handle_join);
+ g_hash_table_insert(handlers, "PART", spasm_chat_service_handle_part); g_hash_table_insert(handlers, "PING", spasm_chat_service_handle_ping);
g_hash_table_insert(handlers, "PRIVMSG",
spasm_chat_service_handle_privmsg);
@@ -272,8 +380,6 @@
-static void spasm_chat_read(SpasmChatService *chat);
spasm_chat_read_cb(GObject *obj, GAsyncResult *res, gpointer data) {
@@ -362,6 +468,9 @@
chat->output_stream = g_io_stream_get_output_stream(G_IO_STREAM(chat->socket_connection));
+ /* first check that we have the right capabilities */ + spasm_chat_service_real_send(chat, "CAP REQ :twitch.tv/membership"); spasm_chat_service_real_send(
@@ -486,7 +595,18 @@
spasm_chat_service_leave(PurpleConnection *connection, gint id) {
+ PurpleConversation *conversation = NULL; + const gchar *channel = NULL; + conversation = purple_find_chat(connection, id); + if(conversation != NULL) { + SpasmAccount *sa = purple_connection_get_protocol_data(connection); + SpasmChatService *chat = spasm_account_get_chat_service(sa); + channel = purple_conversation_get_name(conversation); + spasm_chat_service_real_send(chat, "PART #%s", channel);