X-Git-Url: https://git.cworth.org/git?p=loudgame;a=blobdiff_plain;f=loudgame.c;h=aaeea5f7cec620f8531683e56cc25e0f3c0b4421;hp=53b392b1b0d9440f97da8162b204cae85b8e3123;hb=197c1ca4317efc2c685708a248fa42da3aac60f5;hpb=a812ce8bebf9c5a2408537626e1a8bb593fe9879 diff --git a/loudgame.c b/loudgame.c index 53b392b..aaeea5f 100644 --- a/loudgame.c +++ b/loudgame.c @@ -33,11 +33,16 @@ loudgame_quit (loudgame_t *lg, int return_value) lg->return_value = return_value; - if (! lm_connection_close (lg->connection, &error)) - g_print ("An error occurred during lm_connection_close: %s\n", - error->message); - - lm_connection_unref (lg->connection); + if (lg->connection) + { + if (! lm_connection_close (lg->connection, &error)) + { + g_print ("An error occurred during lm_connection_close: %s\n", + error->message); + } + lm_connection_unref (lg->connection); + lg->connection = NULL; + } g_main_loop_quit (lg->main_loop); } @@ -70,11 +75,10 @@ connection_open_cb (LmConnection *connection, gboolean result, loudgame_t *lg) authentication_cb, lg, FALSE, NULL); } -static void -send_reply (LmConnection *connection, - const char *peer, - const char *message, - loudgame_t *lg) +void +loudgame_send (loudgame_t *lg, + const char *peer, + const char *message) { LmMessage *reply; gboolean result; @@ -84,15 +88,104 @@ send_reply (LmConnection *connection, lm_message_node_add_child (reply->node, "body", message); - result = lm_connection_send (connection, reply, &error); + result = lm_connection_send (lg->connection, reply, &error); lm_message_unref (reply); if (! result) { - g_error ("lm_connection_send failed: error->message"); + g_error ("lm_connection_send failed: %s\n", + error->message); loudgame_quit (lg, 1); } } +void +loudgame_vsendf (loudgame_t *lg, + const char *peer, + const char *format, + va_list va) +{ + char *str; + + str = g_strdup_vprintf (format, va); + + loudgame_send (lg, peer, str); + + free (str); +} + +void +loudgame_sendf (loudgame_t *lg, + const char *peer, + const char *format, + ...) +{ + va_list va; + + va_start (va, format); + + loudgame_vsendf (lg, peer, format, va); + + va_end (va); +} + +typedef struct _loudgame_broadcast_data +{ + loudgame_t *lg; + const char *message; +} loudgame_broadcast_data_t; + +static void +loudgame_broadcast_cb (void *key, + void *data, + void *closure) +{ + loudgame_broadcast_data_t *lbd = closure; + char *peer = key; + + loudgame_send (lbd->lg, peer, lbd->message); +} + +void +loudgame_broadcast (loudgame_t *lg, + const char *message) +{ + loudgame_broadcast_data_t lbd; + + lbd.lg = lg; + lbd.message = message; + + g_hash_table_foreach (lg->players, + loudgame_broadcast_cb, &lbd); +} + +void +loudgame_vbroadcastf (loudgame_t *lg, + const char *format, + va_list va) +{ + char *str; + + str = g_strdup_vprintf (format, va); + + loudgame_broadcast (lg, str); + + free (str); +} + +void +loudgame_broadcastf (loudgame_t *lg, + const char *format, + ...) +{ + va_list va; + + va_start (va,format); + + loudgame_vbroadcastf (lg, format, va); + + va_end (va); +} + static void handle_command (LmConnection *connection, const char *peer, @@ -107,7 +200,7 @@ handle_command (LmConnection *connection, } error = g_strdup_printf ("Unknown command: '%s'", command); - send_reply (connection, peer, error, lg); + loudgame_send (lg, peer, error); free (error); } @@ -125,14 +218,23 @@ handle_messages (LmMessageHandler *handler, peer = lm_message_node_get_attribute (m->node, "from"); body = lm_message_node_get_child (m->node, "body"); - if (body) { - body_str = lm_message_node_get_value (body); + if (! body) + return LM_HANDLER_RESULT_REMOVE_MESSAGE; - if (body_str && body_str[0] == '%') - handle_command (connection, peer, body_str + 1, lg); - else if (lg->handle_message) - (lg->handle_message) (lg, peer, body_str); + if (! g_hash_table_lookup_extended (lg->players, peer, + NULL, NULL)) + { + char *peer_copy = g_strdup (peer); + g_hash_table_insert (lg->players, peer_copy, NULL); + loudgame_broadcastf (lg, "%s has joined the game", peer); } + + body_str = lm_message_node_get_value (body); + + if (body_str && body_str[0] == '%') + handle_command (connection, peer, body_str + 1, lg); + else if (lg->handle_message) + (lg->handle_message) (lg, peer, body_str); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } @@ -170,6 +272,11 @@ make_connection (gpointer closure) loudgame_quit (lg, 1); } + /* It seems to be necessary to explicitly tell the server we're + * still here. Let's see if one keep-alive every 60 seconds is + * sufficient. */ + lm_connection_set_keep_alive_rate (lg->connection, 60); + /* Return false to not schedule another call. */ return 0; } @@ -189,6 +296,9 @@ loudgame_init (loudgame_t *lg, int argc, char **argv) lg->connection = NULL; lg->main_loop = g_main_loop_new (NULL, FALSE); + lg->players = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, /* key_destroy */ + NULL /*value_destroy */); lg->return_value = 0; @@ -197,6 +307,13 @@ loudgame_init (loudgame_t *lg, int argc, char **argv) return 0; } +static void +loudgame_fini (loudgame_t *lg) +{ + g_main_loop_unref (lg->main_loop); + g_hash_table_destroy (lg->players); +} + int loudgame_run (loudgame_t *lg) { @@ -204,7 +321,7 @@ loudgame_run (loudgame_t *lg) g_main_loop_run (lg->main_loop); - g_main_loop_unref (lg->main_loop); + loudgame_fini (lg); return lg->return_value; }