--- a/src/spasm-account.c Sun Apr 19 06:50:19 2020 -0500
+++ b/src/spasm-account.c Sun Apr 19 13:55:45 2020 -0500
@@ -219,7 +219,6 @@
account = spasm_account_get_account(sa);
connection = purple_account_get_connection(account);
username = purple_account_get_username(account);
state = g_strdup_printf("%s,%s", SPASM_PLUGIN_ID, username);
@@ -389,3 +388,10 @@
+spasm_account_get_chat_service(SpasmAccount *sa) { + g_return_val_if_fail(sa != NULL, NULL); --- a/src/spasm-account.h Sun Apr 19 06:50:19 2020 -0500
+++ b/src/spasm-account.h Sun Apr 19 13:55:45 2020 -0500
@@ -61,6 +61,8 @@
gboolean spasm_account_get_partnered(const SpasmAccount *sa);
gboolean spasm_account_get_twitter_connected(const SpasmAccount *sa);
+SpasmChatService *spasm_account_get_chat_service(SpasmAccount *sa); #endif /* SPASM_ACCOUNT_H */
--- a/src/spasm-chat.c Sun Apr 19 06:50:19 2020 -0500
+++ b/src/spasm-chat.c Sun Apr 19 13:55:45 2020 -0500
@@ -36,8 +36,95 @@
GSocketConnection *socket_connection;
GOutputStream *output_stream;
GDataInputStream *input_stream;
+ gint id; /* used to track ids for this service */ + void (*callback)(SpasmChatService *sa, const gchar *from, gchar **args); +} SpasmChatMessageHandler; +/****************************************************************************** + *****************************************************************************/ +spasm_chat_service_nick_from_mask(const gchar *mask) { + gchar *nick = NULL, *bang = NULL; + bang = strchr(mask, '!'); + nick = g_strndup(mask, bang - mask); /* eww pointer math... */ +/****************************************************************************** + *****************************************************************************/ +spasm_chat_service_handle_join(SpasmChatService *chat, const gchar *from, + PurpleConnection *connection = NULL; + const gchar *name = args[0] + 1; /* we want to ignore the leading # */ + connection = spasm_account_get_connection(chat->sa); + serv_got_joined_chat(connection, chat->id++, name); +spasm_chat_service_handle_privmsg(SpasmChatService *chat, const gchar *from, + PurpleAccount *account = NULL; + PurpleConversation *conversation = NULL; + gchar *nick = spasm_chat_service_nick_from_mask(from); + account = spasm_account_get_account(chat->sa); + conversation = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, + if(conversation != NULL) { + id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conversation)); + serv_got_chat_in(spasm_account_get_connection(chat->sa), id, nick, 0, + args[1] + 1, time(NULL)); +spasm_chat_service_init_handlers(void) { + static SpasmChatMessageHandler handlers[] = { + { "001", 0, NULL }, /* ignore RPL_WELCOME */ + { "002", 0, NULL }, /* ignore RPL_YOURHOST */ + { "003", 0, NULL }, /* ignore RPL_CREATED */ + { "004", 0, NULL }, /* ignore RPL_MYINFO */ + { "353", 0, NULL }, /* ignore RPL_NAMREPLY */ + { "366", 0, NULL }, /* ignore RPL_ENDOFNAMES */ + { "372", 0, NULL }, /* ignore RPL_MOTD */ + { "375", 0, NULL }, /* ignore RPL_MOTDSTART */ + { "376", 0, NULL }, /* ignore RPL_ENDOFMOTD */ + { "JOIN", 1, spasm_chat_service_handle_join }, + { "PRIVMSG", 2, spasm_chat_service_handle_privmsg }, + GHashTable *ret = NULL; + ret = g_hash_table_new(g_str_hash, g_str_equal); + for(i = 0; i < G_N_ELEMENTS(handlers); i++) { + g_hash_table_insert(ret, handlers[i].name, &handlers[i]); /******************************************************************************
*****************************************************************************/
@@ -57,6 +144,8 @@
buffer = g_strdup_vprintf(format, vargs);
+ purple_debug_info("spasm-chat", "send buffer: %s\n", buffer); success = g_output_stream_printf(
@@ -90,11 +179,56 @@
spasm_chat_service_parse(SpasmChatService *chat,
+ SpasmChatMessageHandler *handler = NULL; + g_return_if_fail(buffer != NULL); + /* special case message parsing */ if(purple_str_has_prefix(buffer, "PING ")) {
- purple_debug_misc("spasm", "PING? PONG!\n");
+ purple_debug_misc("spasm-chat", "PING? PONG!\n"); spasm_chat_service_real_send(chat, "PONG %s\r\n", buffer + 5);
+ /* handle basic message parsing */ + purple_debug_warning("spasm", "failed to parse message \"%s\"\n", + parts = g_strsplit(buffer, " ", 3); + /* look up the command handler */ + handler = g_hash_table_lookup(chat->handlers, parts[1]); + purple_debug_misc("spasm-chat", "unknown message type %s\n", parts[1]); + purple_debug_misc("spasm-chat", "from: %s\n", parts[0]); + purple_debug_misc("spasm-chat", "command: %s\n", parts[1]); + purple_debug_misc("spasm-chat", "args: %s\n", parts[2]); + purple_debug_misc("spasm-chat", "-----\n"); + if(handler->callback != NULL) { + gchar **args = g_strsplit(g_strstrip(parts[2]), " ", + gchar *from = parts[0]; + if(from && *from == ':') { + from++; /* increment past the : */ + handler->callback(chat, from, args); static void spasm_chat_read(SpasmChatService *chat);
@@ -137,8 +271,6 @@
- purple_debug_info("spasm", "chat buffer: %s\n", buffer);
spasm_chat_service_parse(chat, buffer);
@@ -219,7 +351,9 @@
g_return_val_if_fail(sa, NULL);
chat = g_slice_new0(SpasmChatService);
+ chat->handlers = spasm_chat_service_init_handlers(); @@ -252,8 +386,17 @@
-GList *_spasm_chat_service_info(PurpleConnection *connection) {
+spasm_chat_service_info(PurpleConnection *connection) { + struct proto_chat_entry *pce = NULL; + pce = g_new0(struct proto_chat_entry, 1); + pce->label = _("Channel"); + pce->identifier = "channel"; + entries = g_list_append(entries, pce); @@ -278,7 +421,16 @@
spasm_chat_service_join(PurpleConnection *connection,
+ SpasmAccount *sa = NULL; + SpasmChatService *chat = NULL; + const gchar *channel = NULL; + channel = g_hash_table_lookup(components, "channel"); + sa = purple_connection_get_protocol_data(connection); + chat = spasm_account_get_chat_service(sa); + spasm_chat_service_real_send(chat, "JOIN #%s\r\n", channel); @@ -297,7 +449,24 @@
PurpleMessageFlags flags)
+ SpasmAccount *sa = NULL; + SpasmChatService *chat = NULL; + PurpleConversation *conversation = purple_find_chat(connection, id); + if(conversation == NULL) { + sa = purple_connection_get_protocol_data(connection); + chat = spasm_account_get_chat_service(sa); + spasm_chat_service_real_send(chat, "PRIVMSG #%s :%s\r\n", + purple_conversation_get_name(conversation), + serv_got_chat_in(connection, id, spasm_account_get_display_name(sa), flags, --- a/src/spasm-plugin.c Sun Apr 19 06:50:19 2020 -0500
+++ b/src/spasm-plugin.c Sun Apr 19 13:55:45 2020 -0500
@@ -78,7 +78,6 @@
.status_types = spasm_status_types,
.chat_info = spasm_chat_service_info,
.chat_info_defaults = spasm_chat_service_info_default,
.join_chat = spasm_chat_service_join,
@@ -86,7 +85,6 @@
.chat_leave = spasm_chat_service_leave,
.chat_send = spasm_chat_service_send,
.set_chat_topic = spasm_chat_service_set_topic,
static PurplePluginInfo info = {