From 197c1ca4317efc2c685708a248fa42da3aac60f5 Mon Sep 17 00:00:00 2001
From: Carl Worth <cworth@cworth.org>
Date: Thu, 24 Jan 2008 06:09:51 -0800
Subject: [PATCH] Add loudgame_broadcast and a simple hash table to announce
 new users to each other.

---
 loudgame.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 loudgame.h |  3 ++
 2 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/loudgame.c b/loudgame.c
index f09910f..aaeea5f 100644
--- a/loudgame.c
+++ b/loudgame.c
@@ -128,6 +128,64 @@ 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
+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,
@@ -160,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;
 }
@@ -229,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;
 
@@ -241,6 +311,7 @@ static void
 loudgame_fini (loudgame_t *lg)
 {
     g_main_loop_unref (lg->main_loop);
+    g_hash_table_destroy (lg->players);
 }
 
 int
diff --git a/loudgame.h b/loudgame.h
index 11e74df..7aedd79 100644
--- a/loudgame.h
+++ b/loudgame.h
@@ -34,7 +34,10 @@ struct _loudgame {
     gchar		*name;
     gchar		*passwd;
     LmConnection	*connection;
+
     GMainLoop		*main_loop;
+    GHashTable		*players;
+
     int			 return_value;
 
     /* Callbacks */
-- 
2.45.2