grim/purple-spasm

99c8b92f6aaf
Basic chat auth working, need to implement ping's yet
/*
* PurpleSpasm - A Twitch Protocol Plugin
* Copyright (C) 2017 Gary Kramlich <grim@reaperworld.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "spasm-chat.h"
#include "spasm-const.h"
#include "debug.h"
/******************************************************************************
* read loop
*****************************************************************************/
static void _purple_spasm_chat_read(PurpleSpasmAccount *sa);
static void
_purple_spasm_chat_read_cb(GObject *obj, GAsyncResult *res, gpointer data) {
GError *error = NULL;
gchar *buffer = NULL;
gsize buffer_len;
PurpleSpasmAccount *sa = (PurpleSpasmAccount *)data;
buffer = g_data_input_stream_read_line_finish(
G_DATA_INPUT_STREAM(obj),
res,
&buffer_len,
&error
);
/* g_data_input_stream_read_line_finish, will return null with error set
* on connection error. It will also return null with error not set if
* there is no content to read.
*/
if(buffer == NULL) {
gchar *error_msg = NULL;
if(error != NULL) {
error_msg = g_strdup_printf(
"spasm lost connection with server : %s",
error->message
);
} else {
error_msg = g_strdup_printf("spasm server closed connection");
}
purple_connection_error(
purple_spasm_account_get_connection(sa),
error_msg
);
g_free(error_msg);
return;
}
purple_debug_info("spasm", "chat buffer: %s\n", buffer);
g_free(buffer);
_purple_spasm_chat_read(sa);
}
static void
_purple_spasm_chat_read(PurpleSpasmAccount *sa) {
g_data_input_stream_read_line_async(
purple_spasm_account_get_input_stream(sa),
G_PRIORITY_DEFAULT,
purple_spasm_account_get_cancellable(sa),
_purple_spasm_chat_read_cb,
sa
);
}
/******************************************************************************
* chat login flow
*****************************************************************************/
static void
_purple_spasm_chat_login_cb(GObject *obj, GAsyncResult *res, gpointer data) {
GCancellable *cancellable = NULL;
GError *error = NULL;
GOutputStream *output = NULL;
GSocketConnection *socket_connection = NULL;
PurpleConnection *purple_connection = NULL;
PurpleSpasmAccount *sa = (PurpleSpasmAccount *)data;
gboolean success = FALSE;
cancellable = purple_spasm_account_get_cancellable(sa);
purple_connection = purple_spasm_account_get_connection(sa);
socket_connection = g_socket_client_connect_to_host_finish(
G_SOCKET_CLIENT(obj),
res,
&error
);
if(socket_connection == NULL) {
if(error) {
g_prefix_error(&error, "failed to connect: ");
purple_connection_error(purple_connection, error->message);
g_error_free(error);
} else {
purple_connection_error(purple_connection, "unknown error");
}
return;
}
purple_spasm_account_set_socket_connection(sa, socket_connection);
output = g_io_stream_get_output_stream(G_IO_STREAM(socket_connection));
/* now do the login */
success = g_output_stream_printf(
output,
NULL,
cancellable,
&error,
"PASS oauth:%s\r\n",
purple_spasm_account_get_access_token(sa)
);
if(!success) {
if(error) {
g_prefix_error(&error, "failed to set password: ");
purple_connection_error(purple_connection, error->message);
g_error_free(error);
} else {
purple_connection_error(purple_connection, "unknown error");
}
return;
}
g_output_stream_flush(output, NULL, NULL);
/* now try to use our nick */
success = g_output_stream_printf(
output,
NULL,
cancellable,
&error,
"NICK %s\r\n",
purple_spasm_account_get_name(sa)
);
if(!success) {
if(error) {
g_prefix_error(&error, "failed to set nick : ");
purple_connection_error(purple_connection, error->message);
g_error_free(error);
} else {
purple_connection_error(purple_connection, "unknown error");
}
return;
}
g_output_stream_flush(output, NULL, NULL);
purple_spasm_account_set_input_stream(
sa,
g_data_input_stream_new(
g_io_stream_get_input_stream(G_IO_STREAM(socket_connection))
)
);
_purple_spasm_chat_read(sa);
}
void
purple_spasm_chat_login(PurpleSpasmAccount *sa) {
GSocketClient *socket_client = NULL;
socket_client = g_socket_client_new();
g_socket_client_connect_to_host_async(
socket_client,
PURPLE_SPASM_CHAT_HOSTNAME,
PURPLE_SPASM_CHAT_PORT,
purple_spasm_account_get_cancellable(sa),
_purple_spasm_chat_login_cb,
sa
);
}