]> git.cworth.org Git - loudgame/blob - loudgame.c
Add a call to lm_connection_set_keep_alive_rate
[loudgame] / loudgame.c
1 /*
2  * Copyright (C) 2003-2004 Imendio AB
3  * Copyright (C) 2008 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see http://www.gnu.org/licenses/ .
17  *
18  * Authors: Imendio AB
19  *          Carl Worth <cworth@cworth.org>
20  */
21
22 #include "loudgame.h"
23  
24 #include <glib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28  
29 void
30 loudgame_quit (loudgame_t *lg, int return_value)
31 {
32     GError *error = NULL;
33
34     lg->return_value = return_value;
35
36     if (! lm_connection_close (lg->connection, &error))
37         g_print ("An error occurred during lm_connection_close: %s\n",
38                  error->message);
39
40     lm_connection_unref (lg->connection);
41
42     g_main_loop_quit (lg->main_loop);
43 }
44  
45 static void
46 authentication_cb (LmConnection *connection, gboolean result, gpointer closure)
47 {
48     LmMessage *m;
49     loudgame_t *lg = closure;
50
51     if (! result) {
52         g_print ("Authentication for %s failed\n", lg->name);
53         loudgame_quit (lg, 1);
54         return;
55     }
56                  
57     m = lm_message_new_with_sub_type (NULL,
58                                       LM_MESSAGE_TYPE_PRESENCE,
59                                       LM_MESSAGE_SUB_TYPE_AVAILABLE);
60
61     lm_connection_send (connection, m, NULL);
62     lm_message_unref (m);
63 }
64  
65 static void
66 connection_open_cb (LmConnection *connection, gboolean result, loudgame_t *lg)
67 {
68     lm_connection_authenticate (connection,
69                                 lg->name, lg->passwd, "TestLM",
70                                 authentication_cb, lg, FALSE,  NULL);
71 }
72
73 void
74 loudgame_send (loudgame_t       *lg,
75                const char       *peer,
76                const char       *message)
77 {
78     LmMessage *reply;
79     gboolean result;
80     GError *error = NULL;
81
82     reply = lm_message_new (peer, LM_MESSAGE_TYPE_MESSAGE);
83
84     lm_message_node_add_child (reply->node, "body", message);
85
86     result = lm_connection_send (lg->connection, reply, &error);
87     lm_message_unref (reply);
88
89     if (! result) {
90         g_error ("lm_connection_send failed: %s\n",
91                  error->message);
92         loudgame_quit (lg, 1);
93     }
94 }
95
96 void
97 loudgame_vsendf (loudgame_t     *lg,
98                  const char     *peer,
99                  const char     *format,
100                  va_list         va)
101 {
102     char *str;
103
104     str = g_strdup_vprintf (format, va);
105
106     loudgame_send (lg, peer, str);
107
108     free (str);
109 }
110
111 void
112 loudgame_sendf (loudgame_t      *lg,
113                 const char      *peer,
114                 const char      *format,
115                 ...)
116 {
117     va_list va;
118
119     va_start (va, format);
120
121     loudgame_vsendf (lg, peer, format, va);
122
123     va_end (va);
124 }
125
126 static void
127 handle_command (LmConnection    *connection,
128                 const char      *peer,
129                 const char      *command,
130                 loudgame_t      *lg)
131 {
132     char *error;
133
134     if (strcmp (command, "quit") == 0) {
135         loudgame_quit (lg, 0);
136         return;
137     }
138
139     error = g_strdup_printf ("Unknown command: '%s'", command);
140     loudgame_send (lg, peer, error);
141     free (error);
142 }
143  
144 static LmHandlerResult
145 handle_messages (LmMessageHandler *handler,
146                  LmConnection     *connection,
147                  LmMessage        *m,
148                  gpointer          closure)
149 {
150     loudgame_t *lg = closure;
151     LmMessageNode *body;
152     const char *peer;
153     const char *body_str;
154
155     peer = lm_message_node_get_attribute (m->node, "from");
156
157     body = lm_message_node_get_child (m->node, "body");
158     if (body) {
159         body_str = lm_message_node_get_value (body);
160
161         if (body_str && body_str[0] == '%')
162             handle_command (connection, peer, body_str + 1, lg);
163         else if (lg->handle_message)
164             (lg->handle_message) (lg, peer, body_str);
165     }
166         
167     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
168 }
169
170 static gboolean
171 make_connection (gpointer closure)
172 {
173     loudgame_t       *lg;
174     LmMessageHandler *handler;
175     gchar            *jid;
176     GError           *error = NULL;
177
178     lg = closure;
179                                                                                 
180     lg->connection = lm_connection_new (lg->server);
181
182     jid = g_strdup_printf ("%s@%s", lg->name, lg->server);
183     lm_connection_set_jid (lg->connection, jid);
184     g_free (jid);
185
186     handler = lm_message_handler_new (handle_messages, lg, NULL);
187     lm_connection_register_message_handler (lg->connection,
188                                             handler,
189                                             LM_MESSAGE_TYPE_MESSAGE,
190                                             LM_HANDLER_PRIORITY_NORMAL);
191                                                                                 
192     lm_message_handler_unref (handler);
193                                                                                 
194     if (! lm_connection_open (lg->connection,
195                               (LmResultFunction) connection_open_cb,
196                               lg, NULL, &error))
197     {
198         g_print ("Failed to open connection to %s: %s.\n",
199                  lg->server, error->message);
200         loudgame_quit (lg, 1);
201     }
202
203     /* It seems to be necessary to explicitly tell the server we're
204      * still here. Let's see if one keep-alive every 60 seconds is
205      * sufficient. */
206     lm_connection_set_keep_alive_rate (lg->connection, 60);
207
208     /* Return false to not schedule another call. */
209     return 0;
210 }
211
212 int
213 loudgame_init (loudgame_t *lg, int argc, char **argv)
214 {
215     if (argc != 4) {
216         g_print ("Usage: %s <server> <username> <password>\n", argv[0]);
217         return 1;
218     }
219
220     lg->server = argv[1];
221     lg->name = argv[2];
222     lg->passwd = argv[3];
223
224     lg->connection = NULL;
225
226     lg->main_loop = g_main_loop_new (NULL, FALSE);
227
228     lg->return_value = 0;
229
230     lg->handle_message = NULL;
231
232     return 0;
233 }
234
235 int
236 loudgame_run (loudgame_t *lg)
237 {
238     g_idle_add (make_connection, lg);
239
240     g_main_loop_run (lg->main_loop);
241
242     g_main_loop_unref (lg->main_loop);
243                                                                                 
244     return lg->return_value;
245 }