~ubuntu-branches/ubuntu/gutsy/ggz-client-libs/gutsy

« back to all changes in this revision

Viewing changes to ggz-wrapper/server.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Eisentraut, Josef Spillner, Peter Eisentraut
  • Date: 2006-09-09 13:37:14 UTC
  • mfrom: (2.1.2 edgy)
  • Revision ID: james.westby@ubuntu.com-20060909133714-q49a9kvjfkc0wcc3
Tags: 0.0.13-3
[ Josef Spillner ]
* Change ggzcore-bin dependency from ggzmod to recommends from ggzcore
  (closes: #384671).

[ Peter Eisentraut ]
* Make package dependencies binNMU-safe through use of ${binary:Version}
  (closes: #386126)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * File: server.c
 
3
 * Author: Brent Hendricks
 
4
 * Project: GGZ Text Client 
 
5
 * Date: 9/26/00
 
6
 * $Id: server.c 7147 2005-04-24 06:36:47Z josef $
 
7
 *
 
8
 * Functions for handling server events
 
9
 *
 
10
 * Copyright (C) 2000 Brent Hendricks.
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or modify
 
13
 * it under the terms of the GNU General Public License as published by
 
14
 * the Free Software Foundation; either version 2 of the License, or
 
15
 * (at your option) any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 * GNU General Public License for more details.
 
21
 *
 
22
 * You should have received a copy of the GNU General Public License
 
23
 * along with this program; if not, write to the Free Software
 
24
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
25
 */
 
26
 
 
27
#ifdef HAVE_CONFIG_H
 
28
#  include <config.h>   /* Site-specific config */
 
29
#endif
 
30
 
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
#include <unistd.h>
 
35
 
 
36
#include <ggz.h>
 
37
 
 
38
#include "ggzcore.h"
 
39
 
 
40
#include "server.h"
 
41
#include "loop.h"
 
42
#include "game.h"
 
43
 
 
44
#define _(x) x
 
45
 
 
46
extern char *dst_nick;
 
47
extern char *game_name;
 
48
 
 
49
static void server_register(GGZServer * server);
 
50
static void server_process(void);
 
51
 
 
52
static void checkplayer(void);
 
53
 
 
54
/* Hooks for server events */
 
55
static GGZHookReturn server_connected(GGZServerEvent id, const void *,
 
56
                                      const void *);
 
57
static GGZHookReturn server_connect_fail(GGZServerEvent id, const void *,
 
58
                                         const void *);
 
59
static GGZHookReturn server_negotiated(GGZServerEvent id, const void *,
 
60
                                       const void *);
 
61
static GGZHookReturn server_login_ok(GGZServerEvent id, const void *,
 
62
                                     const void *);
 
63
static GGZHookReturn server_login_fail(GGZServerEvent id, const void *,
 
64
                                       const void *);
 
65
static GGZHookReturn server_list_rooms(GGZServerEvent id, const void *,
 
66
                                       const void *);
 
67
static GGZHookReturn server_list_types(GGZServerEvent id, const void *,
 
68
                                       const void *);
 
69
static GGZHookReturn server_enter_ok(GGZServerEvent id, const void *,
 
70
                                     const void *);
 
71
static GGZHookReturn server_enter_fail(GGZServerEvent id, const void *,
 
72
                                       const void *);
 
73
static GGZHookReturn server_loggedout(GGZServerEvent id, const void *,
 
74
                                      const void *);
 
75
 
 
76
#ifdef GGZ_ENABLE_DEPRECATED
 
77
static GGZHookReturn server_channel_connected(GGZServerEvent id,
 
78
                                              const void *, const void *);
 
79
static GGZHookReturn server_channel_ready(GGZServerEvent id, const void *,
 
80
                                          const void *);
 
81
 
 
82
#endif
 
83
static GGZHookReturn server_net_error(GGZServerEvent id, const void *,
 
84
                                      const void *);
 
85
static GGZHookReturn server_protocol_error(GGZServerEvent id, const void *,
 
86
                                           const void *);
 
87
 
 
88
static GGZHookReturn room_list_players(GGZRoomEvent id, const void *,
 
89
                                       const void *);
 
90
static GGZHookReturn room_list_tables(GGZRoomEvent id, const void *,
 
91
                                      const void *);
 
92
static GGZHookReturn room_enter(GGZRoomEvent id, const void *,
 
93
                                const void *);
 
94
static GGZHookReturn room_leave(GGZRoomEvent id, const void *,
 
95
                                const void *);
 
96
static GGZHookReturn room_table_launched(GGZRoomEvent id, const void *,
 
97
                                         const void *);
 
98
static GGZHookReturn room_table_launch_fail(GGZRoomEvent id, const void *,
 
99
                                            const void *);
 
100
static GGZHookReturn room_table_joined(GGZRoomEvent id, const void *,
 
101
                                       const void *);
 
102
static GGZHookReturn room_table_join_fail(GGZRoomEvent id, const void *,
 
103
                                          const void *);
 
104
static GGZHookReturn room_table_left(GGZRoomEvent id, const void *,
 
105
                                     const void *);
 
106
static GGZHookReturn room_table_leave_fail(GGZRoomEvent id, const void *,
 
107
                                           const void *);
 
108
static GGZHookReturn room_table_update(GGZRoomEvent id, const void *,
 
109
                                       const void *);
 
110
 
 
111
GGZServer *server = NULL;
 
112
static int fd;
 
113
static int playing = 0;
 
114
 
 
115
extern GGZGame *game;
 
116
 
 
117
int server_init(char *host, int port, GGZLoginType type, char *login,
 
118
                char *password)
 
119
{
 
120
        GGZOptions opt;
 
121
        opt.flags = GGZ_OPT_PARSER | GGZ_OPT_MODULES;
 
122
        ggzcore_init(opt);
 
123
 
 
124
        server = ggzcore_server_new();
 
125
        ggzcore_server_set_hostinfo(server, host, port, 0);
 
126
        ggzcore_server_set_logininfo(server, type, login, password, NULL);
 
127
        server_register(server);
 
128
 
 
129
        return ggzcore_server_connect(server);
 
130
}
 
131
 
 
132
static void server_process(void)
 
133
{
 
134
        if (server) {
 
135
                int fd = ggzcore_server_get_fd(server);
 
136
                ggzcore_server_read_data(server, fd);
 
137
        }
 
138
}
 
139
 
 
140
static void server_register(GGZServer * server)
 
141
{
 
142
        ggzcore_server_add_event_hook(server, GGZ_CONNECTED,
 
143
                                      server_connected);
 
144
        ggzcore_server_add_event_hook(server, GGZ_CONNECT_FAIL,
 
145
                                      server_connect_fail);
 
146
        ggzcore_server_add_event_hook(server, GGZ_NEGOTIATED,
 
147
                                      server_negotiated);
 
148
        ggzcore_server_add_event_hook(server, GGZ_NEGOTIATE_FAIL,
 
149
                                      server_connect_fail);
 
150
        ggzcore_server_add_event_hook(server, GGZ_LOGGED_IN,
 
151
                                      server_login_ok);
 
152
        ggzcore_server_add_event_hook(server, GGZ_LOGIN_FAIL,
 
153
                                      server_login_fail);
 
154
        ggzcore_server_add_event_hook(server, GGZ_ROOM_LIST,
 
155
                                      server_list_rooms);
 
156
        ggzcore_server_add_event_hook(server, GGZ_TYPE_LIST,
 
157
                                      server_list_types);
 
158
        ggzcore_server_add_event_hook(server, GGZ_ENTERED,
 
159
                                      server_enter_ok);
 
160
        ggzcore_server_add_event_hook(server, GGZ_ENTER_FAIL,
 
161
                                      server_enter_fail);
 
162
        ggzcore_server_add_event_hook(server, GGZ_LOGOUT,
 
163
                                      server_loggedout);
 
164
        ggzcore_server_add_event_hook(server, GGZ_NET_ERROR,
 
165
                                      server_net_error);
 
166
        ggzcore_server_add_event_hook(server, GGZ_PROTOCOL_ERROR,
 
167
                                      server_protocol_error);
 
168
#ifdef GGZ_ENABLE_DEPRECATED
 
169
        ggzcore_server_add_event_hook(server, GGZ_CHANNEL_CONNECTED,
 
170
                                      server_channel_connected);
 
171
        ggzcore_server_add_event_hook(server, GGZ_CHANNEL_READY,
 
172
                                      server_channel_ready);
 
173
#endif
 
174
}
 
175
 
 
176
static void room_register(GGZRoom * room)
 
177
{
 
178
        ggzcore_room_add_event_hook(room, GGZ_PLAYER_LIST,
 
179
                                    room_list_players);
 
180
        ggzcore_room_add_event_hook(room, GGZ_TABLE_LIST,
 
181
                                    room_list_tables);
 
182
        ggzcore_room_add_event_hook(room, GGZ_ROOM_ENTER, room_enter);
 
183
        ggzcore_room_add_event_hook(room, GGZ_ROOM_LEAVE, room_leave);
 
184
        ggzcore_room_add_event_hook(room, GGZ_TABLE_LAUNCHED,
 
185
                                    room_table_launched);
 
186
        ggzcore_room_add_event_hook(room, GGZ_TABLE_LAUNCH_FAIL,
 
187
                                    room_table_launch_fail);
 
188
        ggzcore_room_add_event_hook(room, GGZ_TABLE_JOINED,
 
189
                                    room_table_joined);
 
190
        ggzcore_room_add_event_hook(room, GGZ_TABLE_JOIN_FAIL,
 
191
                                    room_table_join_fail);
 
192
        ggzcore_room_add_event_hook(room, GGZ_TABLE_LEFT, room_table_left);
 
193
        ggzcore_room_add_event_hook(room, GGZ_TABLE_LEAVE_FAIL,
 
194
                                    room_table_leave_fail);
 
195
        ggzcore_room_add_event_hook(room, GGZ_TABLE_UPDATE,
 
196
                                    room_table_update);
 
197
}
 
198
 
 
199
static GGZHookReturn server_connected(GGZServerEvent id,
 
200
                                      const void *event_data,
 
201
                                      const void *user_data)
 
202
{
 
203
 
 
204
        fd = ggzcore_server_get_fd(server);
 
205
        loop_add_fd(fd, server_process, NULL);
 
206
 
 
207
        return GGZ_HOOK_OK;
 
208
}
 
209
 
 
210
static GGZHookReturn server_connect_fail(GGZServerEvent id,
 
211
                                         const void *event_data,
 
212
                                         const void *user_data)
 
213
{
 
214
        const char *msg = event_data;
 
215
 
 
216
        fprintf(stderr, _("Connection failed: %s\n"), msg);
 
217
 
 
218
        return GGZ_HOOK_OK;
 
219
}
 
220
 
 
221
static GGZHookReturn server_negotiated(GGZServerEvent id,
 
222
                                       const void *event_data,
 
223
                                       const void *user_data)
 
224
{
 
225
        ggzcore_server_login(server);
 
226
        return GGZ_HOOK_OK;
 
227
}
 
228
 
 
229
static GGZHookReturn server_login_ok(GGZServerEvent id,
 
230
                                     const void *event_data,
 
231
                                     const void *user_data)
 
232
{
 
233
        ggzcore_server_list_rooms(server, -1, 1);
 
234
 
 
235
        return GGZ_HOOK_OK;
 
236
}
 
237
 
 
238
static GGZHookReturn server_login_fail(GGZServerEvent id,
 
239
                                       const void *event_data,
 
240
                                       const void *user_data)
 
241
{
 
242
        const char *msg = event_data;
 
243
 
 
244
        fprintf(stderr, _("Login failed: %s\n"), msg);
 
245
 
 
246
        /* For the time being disconnect at not to confuse us */
 
247
        ggzcore_server_logout(server);
 
248
        exit(0);
 
249
        return GGZ_HOOK_OK;
 
250
}
 
251
 
 
252
static GGZModule *pick_module(GGZGameType * gt)
 
253
{
 
254
        const char *name = ggzcore_gametype_get_name(gt);
 
255
        const char *engine = ggzcore_gametype_get_prot_engine(gt);
 
256
        const char *version = ggzcore_gametype_get_prot_version(gt);
 
257
        int num;
 
258
 
 
259
        num = ggzcore_module_get_num_by_type(name, engine, version);
 
260
 
 
261
        if (num == 0) {
 
262
                fprintf(stderr, _("Game is not installed!\n"));
 
263
                return NULL;
 
264
        }
 
265
 
 
266
        return ggzcore_module_get_nth_by_type(name, engine, version, 0);
 
267
}
 
268
 
 
269
static GGZHookReturn server_enter_ok(GGZServerEvent id,
 
270
                                     const void *event_data,
 
271
                                     const void *user_data)
 
272
{
 
273
        GGZRoom *room;
 
274
 
 
275
        room = ggzcore_server_get_cur_room(server);
 
276
        if (ggzcore_room_get_num_players(room) > 0) {
 
277
        } else {        /* Get list from server */
 
278
                ggzcore_room_list_players(room);
 
279
        }
 
280
 
 
281
        return GGZ_HOOK_OK;
 
282
}
 
283
 
 
284
static GGZHookReturn server_enter_fail(GGZServerEvent id,
 
285
                                       const void *event_data,
 
286
                                       const void *user_data)
 
287
{
 
288
        const char *msg = event_data;
 
289
 
 
290
        fprintf(stderr, _("Enter failed: %s\n"), msg);
 
291
 
 
292
        return GGZ_HOOK_OK;
 
293
}
 
294
 
 
295
static GGZHookReturn server_loggedout(GGZServerEvent id,
 
296
                                      const void *event_data,
 
297
                                      const void *user_data)
 
298
{
 
299
        exit(0);
 
300
        return GGZ_HOOK_OK;
 
301
}
 
302
 
 
303
static GGZHookReturn server_net_error(GGZServerEvent id,
 
304
                                      const void *event_data,
 
305
                                      const void *user_data)
 
306
{
 
307
        exit(0);
 
308
        return GGZ_HOOK_OK;
 
309
}
 
310
 
 
311
static GGZHookReturn server_protocol_error(GGZServerEvent id,
 
312
                                           const void *event_data,
 
313
                                           const void *user_data)
 
314
{
 
315
        const char *msg = event_data;
 
316
 
 
317
        fprintf(stderr, _("Server error: %s disconnected\n"), msg);
 
318
        exit(0);
 
319
 
 
320
        return GGZ_HOOK_OK;
 
321
}
 
322
 
 
323
static GGZHookReturn room_list_players(GGZRoomEvent id,
 
324
                                       const void *event_data,
 
325
                                       const void *user_data)
 
326
{
 
327
        GGZRoom *room;
 
328
        room = ggzcore_server_get_cur_room(server);
 
329
        ggzcore_room_list_tables(room, 0, 0);
 
330
        return GGZ_HOOK_OK;
 
331
}
 
332
 
 
333
static GGZHookReturn room_list_tables(GGZRoomEvent id,
 
334
                                      const void *event_data,
 
335
                                      const void *user_data)
 
336
{
 
337
        checkplayer();
 
338
        return GGZ_HOOK_OK;
 
339
}
 
340
 
 
341
static void checkplayer()
 
342
{
 
343
        GGZRoom *room;
 
344
        GGZPlayer *player = NULL;
 
345
        GGZTable *table;
 
346
        GGZGameType *gt;
 
347
        GGZModule *module;
 
348
        int i, table_id, found;
 
349
        int bot;
 
350
 
 
351
        if (playing)
 
352
                return;
 
353
#ifdef HAVE_ALARM
 
354
        alarm(15);
 
355
#else
 
356
        /* FIXME */
 
357
#endif
 
358
 
 
359
        bot = 0;
 
360
        room = ggzcore_server_get_cur_room(server);
 
361
 
 
362
        if (!dst_nick) {
 
363
                table_id = -1;
 
364
        } else if (!strcmp(dst_nick, "")) {
 
365
                table_id = -1;
 
366
                bot = 1;
 
367
        } else {
 
368
                found = 0;
 
369
                for (i = 0; i < ggzcore_room_get_num_players(room); i++) {
 
370
                        player = ggzcore_room_get_nth_player(room, i);
 
371
                        if (strcmp
 
372
                            (ggzcore_player_get_name(player),
 
373
                             dst_nick) == 0) {
 
374
                                found = 1;
 
375
                                break;
 
376
                        }
 
377
                }
 
378
                if (!found) {
 
379
                        printf(_
 
380
                               ("checkplayer: The player %s could not be found.\n"),
 
381
                               dst_nick);
 
382
                        return;
 
383
                }
 
384
                found = 0;
 
385
                table = ggzcore_player_get_table(player);
 
386
                if (!table) {
 
387
                        printf(_("checkplayer: %s not at a table?\n"),
 
388
                               dst_nick);
 
389
                        return;
 
390
                }
 
391
                table_id = ggzcore_table_get_id(table);
 
392
        }
 
393
 
 
394
        gt = ggzcore_room_get_gametype(room);
 
395
        if (!gt) {
 
396
                printf(_("checkplayer: room without gametype?\n"));
 
397
                return;
 
398
        }
 
399
        module = pick_module(gt);
 
400
        if (!module) {
 
401
                return;
 
402
        }
 
403
        printf(_("checkplayer: We're playing...\n"));
 
404
#ifdef HAVE_ALARM
 
405
        alarm(0);
 
406
#else
 
407
        /* FIXME */
 
408
#endif
 
409
        playing = 1;
 
410
        game_init(module, gt, table_id, NULL, bot);
 
411
        return;
 
412
}
 
413
 
 
414
static GGZHookReturn room_enter(GGZRoomEvent id, const void *event_data,
 
415
                                const void *user_data)
 
416
{
 
417
        checkplayer();
 
418
        return GGZ_HOOK_OK;
 
419
}
 
420
 
 
421
static GGZHookReturn room_leave(GGZRoomEvent id, const void *event_data,
 
422
                                const void *user_data)
 
423
{
 
424
        return GGZ_HOOK_OK;
 
425
}
 
426
 
 
427
static GGZHookReturn room_table_launched(GGZRoomEvent id,
 
428
                                         const void *event_data,
 
429
                                         const void *user_data)
 
430
{
 
431
        checkplayer();
 
432
        return GGZ_HOOK_OK;
 
433
}
 
434
 
 
435
static GGZHookReturn room_table_launch_fail(GGZRoomEvent id,
 
436
                                            const void *event_data,
 
437
                                            const void *user_data)
 
438
{
 
439
        const char *err_msg = event_data;
 
440
 
 
441
        fprintf(stderr, _("Table launch failed: %s\n"), err_msg);
 
442
        game_quit();
 
443
 
 
444
        return GGZ_HOOK_OK;
 
445
}
 
446
 
 
447
static GGZHookReturn room_table_joined(GGZRoomEvent id,
 
448
                                       const void *event_data,
 
449
                                       const void *user_data)
 
450
{
 
451
        return GGZ_HOOK_OK;
 
452
}
 
453
 
 
454
static GGZHookReturn room_table_join_fail(GGZRoomEvent id,
 
455
                                          const void *event_data,
 
456
                                          const void *user_data)
 
457
{
 
458
        const char *err_msg = event_data;
 
459
 
 
460
        fprintf(stderr, _("Table join failed: %s\n"), err_msg);
 
461
        game_quit();
 
462
        return GGZ_HOOK_OK;
 
463
}
 
464
 
 
465
static GGZHookReturn room_table_left(GGZRoomEvent id,
 
466
                                     const void *event_data,
 
467
                                     const void *user_data)
 
468
{
 
469
        exit(0);
 
470
        return GGZ_HOOK_OK;
 
471
}
 
472
 
 
473
static GGZHookReturn room_table_update(GGZRoomEvent id,
 
474
                                       const void *event_data,
 
475
                                       const void *user_data)
 
476
{
 
477
        checkplayer();
 
478
        return GGZ_HOOK_OK;
 
479
}
 
480
 
 
481
static GGZHookReturn room_table_leave_fail(GGZRoomEvent id,
 
482
                                           const void *event_data,
 
483
                                           const void *user_data)
 
484
{
 
485
        fprintf(stderr, _("Table leave failed\n"));
 
486
        return GGZ_HOOK_OK;
 
487
}
 
488
 
 
489
static GGZHookReturn server_list_rooms(GGZServerEvent id,
 
490
                                       const void *event_data,
 
491
                                       const void *user_data)
 
492
{
 
493
        int i, num;
 
494
 
 
495
        /* Register callbacks for all rooms */
 
496
        num = ggzcore_server_get_num_rooms(server);
 
497
        for (i = 0; i < num; i++)
 
498
                room_register(ggzcore_server_get_nth_room(server, i));
 
499
        ggzcore_server_list_gametypes(server, 0);
 
500
        return GGZ_HOOK_OK;
 
501
}
 
502
 
 
503
static GGZHookReturn server_list_types(GGZServerEvent id,
 
504
                                       const void *event_data,
 
505
                                       const void *user_data)
 
506
{
 
507
        int i, num;
 
508
        GGZRoom *room;
 
509
        GGZGameType *type;
 
510
        const char *name;
 
511
        int found;
 
512
 
 
513
        num = ggzcore_server_get_num_rooms(server);
 
514
        found = 0;
 
515
        for (i = 0; i < num; i++) {
 
516
                room = ggzcore_server_get_nth_room(server, i);
 
517
                type = ggzcore_room_get_gametype(room);
 
518
                if (type) {
 
519
                        name = ggzcore_gametype_get_name(type);
 
520
                        if (name && game_name
 
521
                            && strcmp(name, game_name) == 0) {
 
522
                                ggzcore_server_join_room(server, i);
 
523
                                found = 1;
 
524
                                break;
 
525
                        }
 
526
                }
 
527
        }
 
528
        if (!found) {
 
529
                fprintf(stderr,
 
530
                        _("Game type %s not found on the server\n"),
 
531
                        game_name);
 
532
                exit(0);
 
533
        }
 
534
#ifdef GGZ_ENABLE_DEPRECATED
 
535
        return GGZ_HOOK_OK;
 
536
}
 
537
 
 
538
static GGZHookReturn server_channel_connected(GGZServerEvent id,
 
539
                                              const void *event_data,
 
540
                                              const void *user_data)
 
541
{
 
542
        game_channel_connected(ggzcore_server_get_channel(server));
 
543
        return GGZ_HOOK_OK;
 
544
}
 
545
 
 
546
static GGZHookReturn server_channel_ready(GGZServerEvent id,
 
547
                                          const void *event_data,
 
548
                                          const void *user_data)
 
549
{
 
550
        game_channel_ready(ggzcore_server_get_channel(server));
 
551
#endif
 
552
        return GGZ_HOOK_OK;
 
553
}