From e072547df636eccfd8a9c77f2d6b32328f0c0f0f Mon Sep 17 00:00:00 2001 From: stpohle Date: Sun, 27 Mar 2005 01:31:46 +0000 Subject: [PATCH] Put broadcast support into the game. So it is able to find local running games on its own. Fixed some list element problem in netsrvlst routines. --- ChangeLog | 18 ++++- bomberclone.prj | 6 +- configure.in | 2 +- include/Makefile.am | 3 +- include/basic.h | 3 +- include/broadcast.h | 26 ++++++++ include/ogcache-client.h | 8 ++- include/packets.h | 20 +++++- include/udp.h | 3 +- src/Makefile.am | 3 +- src/broadcast.c | 138 +++++++++++++++++++++++++++++++++++++++ src/menu.c | 5 +- src/menulists.c | 6 +- src/netsrvlist.c | 111 ++++++++++++++++++++----------- src/packets.c | 46 +++++++++++++ src/udp.c | 14 +++- 16 files changed, 355 insertions(+), 57 deletions(-) create mode 100644 include/broadcast.h create mode 100644 src/broadcast.c diff --git a/ChangeLog b/ChangeLog index 4028fab..a4cf6e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,27 @@ -$Id: ChangeLog,v 1.95 2005/01/30 16:54:03 stpohle Exp $ +$Id: ChangeLog,v 1.96 2005/03/27 01:31:46 stpohle Exp $ Version 0.11.6 ============== -2005-01-30 -- Fixed: Crash on IRIX in function ai_bombpoints. +2005-03-27 + +- Added: Network Join will find Local games without OGC. + Broadcasted UDP Packets will be send to find games. + +2005-02-20 + +- Fixed: Network Player died in a game. All network + players will controll thier own dead. (needed on slow networks) + +- Added: 1600x1280 Resolution + +2005-01-30 - Fixed: Makefile.am in datadir. Pixmap for the icon was not installed. 2004-12-27 + - Fixed: moving and liquid bombs where not working right. we checked the wrong map.bfield value. diff --git a/bomberclone.prj b/bomberclone.prj index b34d690..411cd04 100644 --- a/bomberclone.prj +++ b/bomberclone.prj @@ -104,7 +104,8 @@ module.include.files=\ keyb.h\ bomb.h\ player.h\ - single.h + single.h\ + broadcast.h module.source.name=src module.source.type= @@ -148,7 +149,8 @@ module.source.files=\ menuimages.c\ playerinput.c\ keyb.c\ - playermenu.c + playermenu.c\ + broadcast.c module.pixmap.name=pixmaps module.pixmap.type= diff --git a/configure.in b/configure.in index afc0809..d36193d 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl Please disable it in the Anjuta project configuration AC_INIT(configure.in) AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE(bomberclone, 0.11.6) +AM_INIT_AUTOMAKE(bomberclone, 0.11.6a) AM_CONFIG_HEADER(config.h) diff --git a/include/Makefile.am b/include/Makefile.am index ad55491..1e6f4fa 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,6 +26,7 @@ bomberclone_include = \ keyb.h \ player.h \ bomb.h \ - single.h + single.h \ + broadcast.h noinst_HEADERS = $(bomberclone_include) diff --git a/include/basic.h b/include/basic.h index 5740915..66ccfed 100644 --- a/include/basic.h +++ b/include/basic.h @@ -1,4 +1,4 @@ -/* $Id: basic.h,v 1.29 2004/12/26 04:19:21 stpohle Exp $ */ +/* $Id: basic.h,v 1.30 2005/03/27 01:31:49 stpohle Exp $ */ /* basic types which we need everywhere */ #ifndef _BC_BASIC_H_ @@ -70,6 +70,7 @@ #define LEN_TILESETNAME 32 #define LEN_CHARENTRY 256 #define LEN_PASSWORD 16 +#define LEN_VERSION 20 #define DEFAULT_UDPPORT 11000 #define DEFAULT_GAMECACHEPORT "11111" diff --git a/include/broadcast.h b/include/broadcast.h new file mode 100644 index 0000000..49c5dde --- /dev/null +++ b/include/broadcast.h @@ -0,0 +1,26 @@ +/* $id:$ */ + +#define BC_MAXENTRYS 64 +#define BC_REQUESTTIME 2500 +#define BC_REQUESTTIMEOUT 7500 + +struct broadcast_entry { + char port[LEN_PORT]; + char host[LEN_SERVERNAME]; + char gamename[LEN_GAMENAME]; + char version[LEN_VERSION]; + int ping; + int password; + int curplayers; + int maxplayers; + int timestamp; +}; + +extern struct broadcast_entry broadcast_list []; + +extern void broadcast_send (char *host, char *port); +void broadcast_init (); +void broadcast_loop (); +int broadcast_find (char *host, char *port); +int broadcast_findfree (); +void broadcast_check (); diff --git a/include/ogcache-client.h b/include/ogcache-client.h index b59cbb9..72cb0c9 100644 --- a/include/ogcache-client.h +++ b/include/ogcache-client.h @@ -1,4 +1,4 @@ -/* $Id: ogcache-client.h,v 1.1 2003/12/24 02:42:05 stpohle Exp $ +/* $Id: ogcache-client.h,v 1.2 2005/03/27 01:31:50 stpohle Exp $ * include file for the opengamesrv.c file */ @@ -10,7 +10,11 @@ #define LEN_OGCHOST 64 #define LEN_OGCPORT 10 #define LEN_GAME 32 -#define LEN_VERSION 12 + +#ifndef LEN_VERSION + #define LEN_VERSION 20 +#endif + #define LEN_STATUS 6 #define LEN_GAMENAME 32 #define BUF_SIZE 1024 diff --git a/include/packets.h b/include/packets.h index 7f1261f..dfebd7e 100644 --- a/include/packets.h +++ b/include/packets.h @@ -1,4 +1,4 @@ -/* $Id: packets.h,v 1.31 2004/12/26 04:19:21 stpohle Exp $ +/* $Id: packets.h,v 1.32 2005/03/27 01:31:50 stpohle Exp $ * network packets.. */ #ifndef _PACKETS_H_ @@ -14,6 +14,7 @@ * are between all clients so they will be forwarded. */ enum _network_data { PKG_error = 0, + PKG_gameinfo, PKG_joingame, // every packet below here will checked // if it comes from a orginal player PKG_contest, @@ -332,6 +333,19 @@ struct pkg_mapinfo { }; +/* this packet type is also used in netsrvlist.c */ +struct pkg_gameinfo { + struct pkgheader h; + Uint32 timestamp; + unsigned char curplayers; + unsigned char maxplayers; + char gamename[LEN_GAMENAME]; + char version[LEN_VERSION]; + char broadcast; + signed char password; /* if password == -1, we do a game request */ +}; + + struct _rscache_entry { signed char pl_nr; // playernumber to whom this data should go Sint16 len; // size of the entry @@ -383,7 +397,8 @@ extern void do_dropitems (struct pkg_dropitem *di_pkg, _net_addr *addr); extern void do_respawn (struct pkg_respawn *r_pkg, _net_addr *addr); extern void do_contest (struct pkg_contest *ct_pkg, _net_addr *addr); extern void do_teamdata (struct pkg_teamdata *td, _net_addr * addr); - +extern void do_gameinfo (struct pkg_gameinfo *pgi, _net_addr *addr); + extern void send_pkg (struct pkg *packet, _net_addr *addr); extern void send_playerid (_net_addr *addr, char *name, char *pladdr, char *plport, int p_nr, int gfx_nr, int team_nr, signed char netflags); extern void send_servermode (_net_addr *addr, int pl_nr); @@ -410,6 +425,7 @@ extern void send_dropitems (_net_addr *addr, int pl_nr, _flyingitem **fitems, in extern void send_respawn (_net_addr * addr, int plnr); extern void send_contest (_net_addr * addr, int from, int to, int ackreq); extern void send_teamdata (_net_addr * addr, int team_nr); +extern void send_gameinfo (_net_addr * addr, int sock, int broadcast); extern void fwd_pkg (struct pkg *packet, _net_addr *addr); diff --git a/include/udp.h b/include/udp.h index 49fe309..9c8c049 100644 --- a/include/udp.h +++ b/include/udp.h @@ -1,4 +1,4 @@ -/* $Id: udp.h,v 1.1 2003/12/24 02:42:05 stpohle Exp $ +/* $Id: udp.h,v 1.2 2005/03/27 01:31:50 stpohle Exp $ * UDP Network */ #ifndef _UDP_H @@ -34,6 +34,7 @@ extern int dns_filladdr (char *host, int hostlen, char *port, int portlen, int a extern int udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family); extern int udp_server (char *port, int ai_family); extern void udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family); +extern void udp_sendbroadcast (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family); extern void udp_close (int sock); #endif diff --git a/src/Makefile.am b/src/Makefile.am index 2a212f6..a726257 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,7 @@ bomberclone_SOURCES = \ help.c\ playerinput.c\ keyb.c\ - playermenu.c + playermenu.c\ + broadcast.c ## bomberclone_LDADD = diff --git a/src/broadcast.c b/src/broadcast.c new file mode 100644 index 0000000..81bfb74 --- /dev/null +++ b/src/broadcast.c @@ -0,0 +1,138 @@ +/* $id:$ + * find broadcasted games */ +#include "bomberclone.h" +#include "network.h" +#include "packets.h" +#include "broadcast.h" + +static int bc_lastrequest; +struct broadcast_entry broadcast_list [BC_MAXENTRYS]; + + +/* find a game on the same server and port */ +int broadcast_find (char *host, char *port) { + int i; + + for (i = 0; ((strncmp (host, broadcast_list[i].host, LEN_SERVERNAME) != 0) + && (strncmp (port, broadcast_list[i].port, LEN_PORT) != 0) + && (i < BC_MAXENTRYS)); i++); + + if (i >= BC_MAXENTRYS) + i = -1; + return i; +}; + + +/* find next free game */ +int broadcast_findfree () { + int i; + + for (i = 0; (broadcast_list[i].host[0] != 0) && (i < BC_MAXENTRYS); i++); + + return i; +} + + +/* check for old not seen games */ +void broadcast_check () { + int i; + + for (i = 0; i < BC_MAXENTRYS; i++) { + while ((broadcast_list[i].host[0] != 0) + && (timestamp - broadcast_list[i].timestamp > BC_REQUESTTIMEOUT)) { + /* delete entry */ + if (i < (BC_MAXENTRYS -1)) + memcpy (&broadcast_list[i], &broadcast_list[i+1], sizeof (struct broadcast_entry) * (BC_MAXENTRYS - (i+1))); + + broadcast_list[BC_MAXENTRYS-1].host[0] = 0; + } + } +} + + + +/* open and send the first broadcast request */ +void broadcast_init () { + int i; + + for (i = 0; i < BC_MAXENTRYS; i++) + broadcast_list[i].host[0] = 0; + + broadcast_send (NULL, NULL); + bc_lastrequest = timestamp; +}; + + +/* send the broadcast information */ +void broadcast_send (char *host, char *port) { + _net_addr addr; + + + if (host != NULL && port != NULL) { + strncpy (addr.host, host, LEN_SERVERNAME); + strncpy (addr.port, port, LEN_PORT); + d_printf ("broadcast_send (%s:%s)\n", addr.host, addr.port); + dns_filladdr (addr.host, LEN_SERVERNAME, addr.port, LEN_PORT, bman.net_ai_family, &addr.sAddr); + send_gameinfo (&addr, bman.sock, 0); + } + else { + sprintf (addr.port, "%d", DEFAULT_UDPPORT); + strncpy (addr.host, "255.255.255.255", LEN_SERVERNAME); + d_printf ("broadcast_send (%s:%s)\n", addr.host, addr.port); + dns_filladdr (addr.host, LEN_SERVERNAME, addr.port, LEN_PORT, bman.net_ai_family, &addr.sAddr); + send_gameinfo (&addr, bman.sock, 1); + } +}; + + +void broadcast_loop () { + int inlen; + char indata [MAX_UDPDATA]; + struct pkg_gameinfo *pgi; + _net_addr addr; + + if ((timestamp - bc_lastrequest) > BC_REQUESTTIME) { + broadcast_send (NULL, NULL); + bc_lastrequest = timestamp; + } + + pgi = (struct pkg_gameinfo*) &indata; + pgi->gamename[0] = 0; + addr.port[0] = addr.host[0] = 0; + inlen = udp_get (bman.sock, indata, MAX_UDPDATA, &addr.sAddr, bman.net_ai_family); + if (inlen > 0) + dns_filladdr (addr.host, LEN_SERVERNAME, addr.port, LEN_PORT, bman.net_ai_family, + &addr.sAddr); + + while (inlen > 0) { + + if (pgi->gamename[0] != 0 && pgi->broadcast) { + int nr; + + nr = broadcast_find (addr.host, addr.port); + if (nr == -1) + nr = broadcast_findfree (); + if (nr < BC_MAXENTRYS) { + strncpy (broadcast_list[nr].host, addr.host, LEN_SERVERNAME); + strncpy (broadcast_list[nr].port, addr.port, LEN_PORT); + strncpy (broadcast_list[nr].version, pgi->version, LEN_VERSION); + strncpy (broadcast_list[nr].gamename, pgi->gamename, LEN_GAMENAME); + + d_printf ("broadcast_loop: Add: nr:%d game:%s %s:%s\n", nr, + broadcast_list[nr].gamename, broadcast_list[nr].host, + broadcast_list[nr].port); + broadcast_list[nr].timestamp = timestamp; + } + } + + pgi->gamename[0] = 0; + addr.port[0] = addr.host[0] = 0; + inlen = udp_get (bman.sock, indata, MAX_UDPDATA, &addr.sAddr, bman.net_ai_family); + if (inlen > 0) + dns_filladdr (addr.host, LEN_SERVERNAME, addr.port, LEN_PORT, bman.net_ai_family, + &addr.sAddr); + } + + broadcast_check (); + +}; diff --git a/src/menu.c b/src/menu.c index de122fc..d41a2e3 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1,4 +1,4 @@ -/* $Id: menu.c,v 1.49 2004/09/13 22:04:24 stpohle Exp $ +/* $Id: menu.c,v 1.50 2005/03/27 01:31:50 stpohle Exp $ * Menuhandling */ #include "basic.h" @@ -206,8 +206,9 @@ menu_draw (_menu * menu) menu_draw_border (menu); - for (m = menu->items; m != NULL; m = m->next) + for (m = menu->items; m != NULL; m = m->next) { menu_draw_menuitem (m); + } }; diff --git a/src/menulists.c b/src/menulists.c index c2ebe0e..e4ed589 100644 --- a/src/menulists.c +++ b/src/menulists.c @@ -1,4 +1,4 @@ -/* $Id: menulists.c,v 1.5 2004/09/12 21:35:32 stpohle Exp $ +/* $Id: menulists.c,v 1.6 2005/03/27 01:31:50 stpohle Exp $ * Menuhandling: lists */ @@ -225,7 +225,8 @@ void menu_draw_list (_menuitem *mi) { dest.w = mi->pos.w; dest.h = menulistimages[0][0]->h; - if (mi->changed) menu_draw_background ((((_menu *)mi->menu)),&dest); + if (mi->changed) + menu_draw_background ((((_menu *)mi->menu)),&dest); /* check the focus of the button */ if (((_menu *)mi->menu)->focusvis && mi == ((_menu *)mi->menu)->focus) @@ -270,6 +271,7 @@ void menu_draw_list (_menuitem *mi) { dest.x = MENUOFFSET_X(((_menu *)mi->menu)) + mi->pos.x + mi->pos.w - menulistimages[focus][5]->w; gfx_blit (menulistimages[focus][5], NULL, gfx.screen, &dest, 10000); } + if (mi->changed) { menu_draw_listbackground (mi, NULL); menu_draw_listtext (mi); diff --git a/src/netsrvlist.c b/src/netsrvlist.c index 762687f..614686e 100644 --- a/src/netsrvlist.c +++ b/src/netsrvlist.c @@ -1,4 +1,4 @@ -/* $Id: netsrvlist.c,v 1.10 2004/05/20 17:50:09 stpohle Exp $ +/* $Id: netsrvlist.c,v 1.11 2005/03/27 01:31:50 stpohle Exp $ * netsrvlist.c - shows a list of possible servers.*/ #include "basic.h" @@ -8,45 +8,60 @@ #include "network.h" #include "menu.h" #include "ogcache-client.h" +#include "broadcast.h" + +#define SRVLST_TIMEREBUILD 2000 _charlist srvlst_text[MAX_SRVLIST]; struct __srvlst_entry { char host[LEN_SERVERNAME]; char port[LEN_PORT]; char gamename[LEN_GAMENAME]; + char version[LEN_VERSION]; int maxplayers; int curplayers; int ai_family; } srvlst_dat[MAX_SRVLIST]; int srvlst_cnt = 0; - - /* will build up our srvlst list with * all servers we have in there */ void srvlist_rebuildlist () { int ogclst, i; char text[255]; - d_printf ("srvlist_rebuildlist\n"); - /* delete the whole list */ for (i = 0; i < MAX_SRVLIST; i++) { srvlst_text[i].text[0] = 0; srvlst_text[i].next = NULL; srvlst_dat[i].host[0] = 0; srvlst_dat[i].port[0] = 0; + srvlst_dat[i].version[0] = 0; srvlst_dat[i].gamename[0] = 0; } srvlst_cnt = 0; - + + /* add broadcasted list */ + for (i = 0; i < BC_MAXENTRYS; i++) { + if (broadcast_list[i].host[0] != 0) { + strncpy (srvlst_dat[srvlst_cnt].host, broadcast_list[i].host, LEN_SERVERNAME); + strncpy (srvlst_dat[srvlst_cnt].port, broadcast_list[i].port, LEN_PORT); + strncpy (srvlst_dat[srvlst_cnt].version, broadcast_list[i].version, LEN_VERSION); + strncpy (srvlst_dat[srvlst_cnt].gamename, broadcast_list[i].gamename, LEN_GAMENAME); + srvlst_dat[srvlst_cnt].ai_family = bman.net_ai_family; + + srvlst_cnt++; + } + } + /* add the OpenGameCache Entrys */ if (bman.notifygamemaster) { for (ogclst = 0; (ogclst < MAX_OGC_ENTRYS && srvlst_cnt < MAX_SRVLIST); ogclst++) if (ogc_array[ogclst].serial != -1) { srvlst_dat[srvlst_cnt].host[0] = 0; srvlst_dat[srvlst_cnt].port[0] = 0; + srvlst_dat[srvlst_cnt].version[0] = 0; srvlst_dat[srvlst_cnt].gamename[0] = 0; srvlst_dat[srvlst_cnt].ai_family = ogc_array[ogclst].ai_family; @@ -59,70 +74,90 @@ void srvlist_rebuildlist () { if (srvlst_cnt >= MAX_SRVLIST) d_fatal ("srvlist_rebuildlist : srvlst_cnt >= MAX_SRVLIST\n"); - /* add local server list - * - this will have to be finished later -*/ - - - /* add broadcasted list - * - this will have to be finished later -*/ - /* make the list viewable */ for (i = 0; i < srvlst_cnt; i++) { if (srvlst_dat[i].gamename[0] != 0) /* gamename is present */ - sprintf (text, "%s", srvlst_dat[i].gamename); + sprintf (text, "%s(%s)", srvlst_dat[i].gamename, srvlst_dat[i].version); else - sprintf (text, "%s:%s", srvlst_dat[i].host, srvlst_dat[i].port); + sprintf (text, "%s:%s(%s)", srvlst_dat[i].host, srvlst_dat[i].port, srvlst_dat[i].version); strncpy (srvlst_text[i].text, text, LEN_CHARENTRY); } if (srvlst_cnt == 0) strcpy (srvlst_text[0].text, "No Servers Found"); charlist_fillarraypointer (srvlst_text, srvlst_cnt); - }; /* show a list of servers you can select */ void net_getserver () { - int menuselect = 0, entry = 0; + int menuselect = 0, entry = 0, eventstate, done, srvlst_lastrebuild = 0; _charlist *sel_entry = &srvlst_text[0]; _menu *menu; + _menuitem *srvlst_listmenu; + SDL_Event event; d_printf ("net_getserver\n"); - + + broadcast_init (); if (bman.servername[0] != 0) return; // a server has already been selected if (bman.notifygamemaster) ogc_browsestart (); menu = menu_new ("Join a Game", 500, 400); - menu_create_list (menu, "Host a Game", -1, 50, 475, 250, srvlst_text, &sel_entry, 1); + srvlst_listmenu = menu_create_list (menu, "Host a Game", -1, 50, 475, 250, srvlst_text, &sel_entry, 1); menu_create_entry (menu, "IP :", -1, 320, 475, bman.servername, LEN_SERVERNAME+LEN_PORT + 2, MENU_entrytext, 2); menu_create_button (menu, "OK", -1, 350, 150, 0); menu_focus_id (menu, 1); + + menu->looprunning = 1; + menu_draw (menu); while (menuselect != -1 && bman.state != GS_quit) { - srvlist_rebuildlist (); - menu_reload (menu); - menuselect = menu_loop (menu); + + broadcast_loop (); + if (bman.notifygamemaster) + ogc_loop (); + + if ((timestamp - srvlst_lastrebuild) > SRVLST_TIMEREBUILD) { + srvlist_rebuildlist (); + srvlst_lastrebuild = timestamp; + menu_reload (menu); + srvlst_listmenu->changed = 1; + menu_draw (menu); + } - switch (menuselect) { - case (0): // Ok Join Selected Game + eventstate = SDL_PollEvent (&event); + gfx_blitdraw (); + + done = menu_event_loop (menu, &event, eventstate); + menuselect = menu->focus->id; + if (done) { + switch (menuselect) { + case (0): // Ok Join Selected Game + menuselect = -1; + break; + case (1): // Join a Game + entry = sel_entry - &srvlst_text[0]; + d_printf ("Selected Entry (%d) %s:%s Game:%s\n", entry, srvlst_dat[entry].host, srvlst_dat[entry].port, srvlst_dat[entry].gamename); + if (srvlst_dat[entry].host[0] != 0 + && srvlst_dat[entry].port[0] != 0 + && srvlst_dat[entry].gamename[0] != 0) { /* test if there was a selection */ + bman.net_ai_family = srvlst_dat[entry].ai_family; + sprintf (bman.servername, "%s:%s", srvlst_dat[entry].host, srvlst_dat[entry].port); + menu_focus_id (menu, 0); + } + break; + } + } + if (done == -1) { menuselect = -1; - break; - case (1): // Join a Game - entry = sel_entry - &srvlst_text[0]; - d_printf ("Selected Entry (%d) %s:%s Game:%s\n", entry, srvlst_dat[entry].host, srvlst_dat[entry].port, srvlst_dat[entry].gamename); - if (srvlst_dat[entry].host[0] != 0 - && srvlst_dat[entry].port[0] != 0 - && srvlst_dat[entry].gamename[0] != 0) { /* test if there was a selection */ - bman.net_ai_family = srvlst_dat[entry].ai_family; - sprintf (bman.servername, "%s:%s", srvlst_dat[entry].host, srvlst_dat[entry].port); - menu_focus_id (menu, 0); - } - break; - } - } + bman.servername[0] = 0; + } + + s_calctimesync (); + } if (bman.notifygamemaster) ogc_browsestop (); diff --git a/src/packets.c b/src/packets.c index 5b37d08..89110f1 100644 --- a/src/packets.c +++ b/src/packets.c @@ -1634,6 +1634,49 @@ void do_respawn (struct pkg_respawn *r_pkg, _net_addr *addr) { +/*** + *** gameinfo packet is used to get some data from a running game + *** just fill in the informations we need and send this packet back. + ***/ +void do_gameinfo (struct pkg_gameinfo *pgi, _net_addr *addr) { + if (GT_MP_PTPM && pgi->password == -1) { + d_printf ("do_gameinfo (from: %s:%s)\n", addr->host, addr->port); + + strncpy (pgi->version, VERSION, LEN_VERSION); + pgi->maxplayers = bman.maxplayer; + pgi->curplayers = bman.players_nr_s; + strncpy (pgi->gamename, bman.gamename, LEN_GAMENAME); + send_pkg ((struct pkg*) pgi, addr); + } + else if (pgi->password != -1) + d_printf ("do_gameinfo (from: %s:%s) ** NO REQUEST **\n", addr->host, addr->port); + else + d_printf ("do_gameinfo (from: %s:%s) ** WE ARE NOT THE MASTER OF THIS GAME **\n", addr->host, addr->port); + +} + + +void send_gameinfo (_net_addr * addr, int sock, int broadcast) { + struct pkg_gameinfo pgi; + + pgi.h.typ = PKG_gameinfo; + pgi.h.len = HTON16 (sizeof (struct pkg_gameinfo)); + pgi.h.flags = 0; + pgi.timestamp = timestamp; + pgi.gamename[0] = 0; + pgi.version[0] = 0; + pgi.password = -1; + pgi.broadcast = broadcast; + + if (bman.net_ai_family != PF_INET) + pgi.h.flags = pgi.h.flags | PKGF_ipv6; + if (broadcast) + udp_sendbroadcast (sock, (char *) &pgi, NTOH16 (pgi.h.len), &addr->sAddr, bman.net_ai_family); + else + udp_send (sock, (char *) &pgi, NTOH16 (pgi.h.len), &addr->sAddr, bman.net_ai_family); +}; + + /*** *** general packet handling, like check for double recived packets *** network type. Autoreply on PKGF_ackreq and such things. @@ -1788,6 +1831,9 @@ do_pkg (struct pkg *packet, _net_addr * addr) if (do_error ((struct pkg_error *) packet, addr) < 0) return -1; break; + case (PKG_gameinfo): + do_gameinfo ((struct pkg_gameinfo *) packet, addr); + break; case (PKG_playerid): do_playerid ((struct pkg_playerid *) packet, addr); break; diff --git a/src/udp.c b/src/udp.c index 9dbc106..350fc8f 100644 --- a/src/udp.c +++ b/src/udp.c @@ -1,4 +1,4 @@ -/* $Id: udp.c,v 1.12 2004/11/29 09:45:53 stpohle Exp $ */ +/* $Id: udp.c,v 1.13 2005/03/27 01:31:50 stpohle Exp $ */ /* udp.c code for the network File Version 0.2 */ @@ -156,6 +156,18 @@ udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family) }; +/* send udp broadcasted message */ +void udp_sendbroadcast (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family) +{ + int value; + + value = 1; + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof (value)); + udp_send (sock, text, len, sAddr, ai_family); + value = 0; + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof (value)); +}; + int udp_server (char *port, int ai_family) {