You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bomberclone/src/broadcast.c

185 lines
5.7 KiB

/* $Id: broadcast.c,v 1.5 2005/04/08 00:18:29 stpohle Exp $
* find broadcasted games and also hold in this list
* all games which the ogc reports us */
#include "bomberclone.h"
#include "network.h"
#include "packets.h"
#include "ogcache-client.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;
}
/* delete entry from the broadcasted list */
void broadcast_del (int nr) {
if (nr < (BC_MAXENTRYS -1))
memcpy (&broadcast_list[nr], &broadcast_list[nr+1], sizeof (struct broadcast_entry) * (BC_MAXENTRYS - (nr+1)));
broadcast_list[BC_MAXENTRYS-1].host[0] = 0;
}
/* check for old not seen games */
void broadcast_check () {
int i, j;
/* check for a new update request on a single game and if a game had timed
* out */
for (i = 0; i < BC_MAXENTRYS; i++) {
while (broadcast_list[i].host[0] != 0
&& ((broadcast_list[i].try > BC_MAXREQUEST && broadcast_list[i].lan == 0)
|| (timestamp - broadcast_list[i].timestamp > BC_REQUESTTIMEOUT && broadcast_list[i].lan == 1)))
broadcast_del (i);
if (timestamp - broadcast_list[i].timestamp > BC_REQUESTTIME
&& broadcast_list[i].lan == 0 && broadcast_list[i].host[0] != 0) {
broadcast_send (broadcast_list[i].host, broadcast_list[i].port);
broadcast_list[i].timestamp = timestamp;
broadcast_list[i].try++;
}
if (((broadcast_list[i].timestamp < 0) || (timestamp - broadcast_list[i].timestamp < 0))
&& broadcast_list[i].host[0] != 0 && broadcast_list[i].lan == 0) {
broadcast_send (broadcast_list[i].host, broadcast_list[i].port);
broadcast_list[i].timestamp = timestamp;
}
}
/* check for games in the OGC list which are not in the broadcast_list */
for (i = 0; i < MAX_OGC_ENTRYS; i++)
if ((ogc_array[i].serial != -1) && (broadcast_find (ogc_array[i].host, ogc_array[i].port) == -1)) {
j = broadcast_findfree ();
if ((check_version (0,11,6, ogc_array[i].version) >= 0) && j >= 0) {
strncpy (broadcast_list[j].host, ogc_array[i].host, LEN_SERVERNAME);
strncpy (broadcast_list[j].port, ogc_array[i].port, LEN_PORT);
strncpy (broadcast_list[j].version, ogc_array[i].version, LEN_VERSION);
strncpy (broadcast_list[j].gamename, ogc_array[i].gamename, LEN_GAMENAME);
d_printf ("broadcast_check: Add: nr:%d game:%s %s:%s\n", j,
broadcast_list[j].gamename, broadcast_list[j].host, broadcast_list[j].port);
broadcast_list[j].timestamp = timestamp;
broadcast_list[j].ping = -1;
broadcast_list[j].lan = 0;
broadcast_list[j].try = 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;
if (bman.broadcast)
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 (bman.broadcast && (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->h.typ == PKG_gameinfo && pgi->gamename[0] != 0) {
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 (lan:%d)\n", nr,
broadcast_list[nr].gamename, broadcast_list[nr].host,
broadcast_list[nr].port, pgi->broadcast);
broadcast_list[nr].timestamp = timestamp;
broadcast_list[nr].ping = timestamp - pgi->timestamp;
broadcast_list[nr].lan = pgi->broadcast;
}
}
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 ();
};