grim/purple-spasm

Parents 7388a4c9a1b3
Children cffbcb39672a
Properly implement JOIN's as they come from other users too (duh) as well as PART's
  • +130 -10
    src/spasm-chat.c
  • --- 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 @@
    const gchar *prefix,
    const gchar *middle,
    const gchar *trailing);
    +/******************************************************************************
    + * Prototypes
    + *****************************************************************************/
    +static void spasm_chat_read(SpasmChatService *chat);
    /******************************************************************************
    * Helpers
    @@ -98,7 +102,7 @@
    buffer = g_strdup_vprintf(format, vargs);
    va_end(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(
    chat->output_stream,
    @@ -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;
    GMatchInfo *info = 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);
    +
    + return;
    + }
    +
    + 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);
    - if(target != NULL) {
    - 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);
    +
    + g_free(nick);
    + g_free(target);
    +
    + return;
    + } else {
    + /* 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,
    + target, account);
    + if(conversation == NULL) {
    + purple_debug_misc("spasm-chat",
    + "ignoring JOIN for non-existant channel %s\n",
    + target);
    +
    + g_free(nick);
    + g_free(target);
    +
    + return;
    }
    + chat = PURPLE_CONV_CHAT(conversation);
    +
    + purple_conv_chat_add_user(chat, nick, NULL, PURPLE_CBFLAGS_NONE, TRUE);
    +
    + g_free(nick);
    g_free(target);
    }
    +}
    +static void
    +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);
    +
    + return;
    + }
    +
    + 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,
    + target, account);
    + if(conversation == NULL) {
    + purple_debug_misc("spasm-chat",
    + "Ignoring PART for non-existent channel %s\n",
    + target);
    +
    + g_free(nick);
    + g_free(target);
    +
    + return;
    + }
    +
    + g_free(target);
    + 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));
    + } else {
    + /* Someone else is parting a channel we're in. */
    + purple_conv_chat_remove_user(chat_conversation, nick, NULL);
    + }
    +
    + g_free(nick);
    }
    static void
    @@ -194,6 +287,19 @@
    g_match_info_unref(info);
    }
    +static void
    +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);
    + } else {
    + purple_debug_misc("spasm-chat", "cap-middle: '%s'\n", middle);
    + purple_debug_misc("spasm-chat", "cap-trailing: '%s'\n", trailing);
    + }
    +}
    +
    static GHashTable *
    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 @@
    g_free(trailing);
    }
    -static void spasm_chat_read(SpasmChatService *chat);
    -
    static void
    spasm_chat_read_cb(GObject *obj, GAsyncResult *res, gpointer data) {
    GError *error = NULL;
    @@ -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");
    +
    /* now do the login */
    spasm_chat_service_real_send(
    chat,
    @@ -486,7 +595,18 @@
    void
    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);
    + }
    }
    gint