X-Git-Url: https://git.cworth.org/git?p=loudgame;a=blobdiff_plain;f=loudgame.c;h=7c9114e4fffd7783763e9c1af8f3aee0d54832e3;hp=f09910f3611aa8e8866879cdec8cff597c870c1f;hb=88c5b7fb802cd1eab050dc67289d86dcb37dec6c;hpb=39f777396572d1b1a28648687d4e030fbfd007bc diff --git a/loudgame.c b/loudgame.c index f09910f..7c9114e 100644 --- a/loudgame.c +++ b/loudgame.c @@ -71,7 +71,7 @@ static void connection_open_cb (LmConnection *connection, gboolean result, loudgame_t *lg) { lm_connection_authenticate (connection, - lg->name, lg->passwd, "TestLM", + lg->name, lg->passwd, "loudgame", authentication_cb, lg, FALSE, NULL); } @@ -128,22 +128,104 @@ loudgame_sendf (loudgame_t *lg, va_end (va); } +typedef struct _loudgame_broadcast_data +{ + loudgame_t *lg; + const char *message; +} loudgame_broadcast_data_t; + static void -handle_command (LmConnection *connection, - const char *peer, - const char *command, - loudgame_t *lg) +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 *error; + 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 (loudgame_t *lg, + const char *peer, + const char *command) +{ if (strcmp (command, "quit") == 0) { loudgame_quit (lg, 0); return; } - error = g_strdup_printf ("Unknown command: '%s'", command); - loudgame_send (lg, peer, error); - free (error); + loudgame_sendf (lg, "Unknown command: '%s'", command); +} + +static void +handle_say (loudgame_t *lg, + const char *peer, + const char *message) +{ + loudgame_broadcastf (lg, "%s: %s", peer, message); +} + +static void +handle_whisper (loudgame_t *lg, + const char *peer, + const char *body) +{ + const char *recipient, *space, *message; + + space = strchr (body, ' '); + if (space == NULL) { + loudgame_sendf (lg, peer, + "Error: whisper should be of the form 'user message'"); + return; + } + + recipient = g_strndup (body, space - body); + + message = space + 1; + + loudgame_sendf (lg, recipient, "*%s*: %s", peer, message); } static LmHandlerResult @@ -160,13 +242,28 @@ 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 (! 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); + if (body_str) { + if (body_str[0] == '%') + handle_command (lg, peer, body_str + 1); + else if (strncmp (body_str, "say ", 4) == 0) + handle_say (lg, peer, body_str + 4); + else if (strncmp (body_str, "whisper ", 8) == 0) + handle_whisper (lg, peer, body_str + 8); else if (lg->handle_message) - (lg->handle_message) (lg, peer, body_str); + (lg->handle_message) (lg, peer, body_str); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; @@ -229,6 +326,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; @@ -241,6 +341,7 @@ static void loudgame_fini (loudgame_t *lg) { g_main_loop_unref (lg->main_loop); + g_hash_table_destroy (lg->players); } int