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/pkgcache.c

169 lines
5.1 KiB

/* $Id: pkgcache.c,v 1.7 2003/11/08 06:27:59 stpohle Exp $
* Resendcache work, We need this to resend lost packets over the network.
* we will keep every packet with the PKGF_ackreq flag as long as we haven't
* got any answer from the destination host. And resend the packet after a givin
* time. The maximum time for a resend is 10 times if we haven't got any reply
* by then we delete the packet from the cache. By doing this the game will not
* anymore sync. with all clients.
*/
#include "bomberclone.h"
#include "network.h"
#include "packets.h"
/*
set pointers at the giving pos
*/
void
rscache_setpointer (int pos)
{
resend_cache.entry = (struct _rscache_entry *) (((char *) resend_cache.data) + pos);
};
/*
add a packet to the cache and sets the timestamp
*/
int
rscache_add (_net_addr * addr, struct pkg *packet)
{
int newlen;
if (resend_cache.fill + sizeof (struct _rscache_entry) > PKG_RESENDCACHE_SIZE)
return -1;
rscache_setpointer (resend_cache.fill);
resend_cache.entry->retry = 0;
resend_cache.entry->timestamp = timestamp;
memcpy (&resend_cache.entry->addr, addr, sizeof (_net_addr));
memcpy (&resend_cache.entry->packet, packet, NTOH16 (packet->h.len));
newlen = resend_cache.fill + rscache_getcurlen ();
resend_cache.fill = newlen;
return 0;
};
/*
deletes the packet at current pointer in the cache
*/
void
rscache_del ()
{
int len,
size;
char *pos1;
/* check if we are able to delete */
if ((char *) resend_cache.data > (char *) resend_cache.entry ||
(char *) resend_cache.entry > (char *) resend_cache.data + resend_cache.fill ||
resend_cache.fill == -1 || resend_cache.data == NULL) {
d_printf ("rscache_del: something wrong with the cache\n");
exit (1);
return;
}
/* newlen = size of the cacheentry we are going to delete */
len = rscache_getcurlen ();
if (resend_cache.fill <= len) /* something went wrong, fill is smaler as the cacheentry, delete the cache */
resend_cache.fill = 0;
else {
pos1 = (char *) resend_cache.entry + len;
size = PKG_RESENDCACHE_SIZE - (pos1 - resend_cache.data);
if (resend_cache.fill < PKG_RESENDCACHE_SIZE) {
memmove (resend_cache.entry, pos1, size);
resend_cache.fill = resend_cache.fill - len;
}
}
};
/*
get the position in the cache where our needed packet is
*/
int
rscache_getpos (_net_addr * addr, unsigned char typ, short int id)
{
int len,
pos,
done = 0;
for (pos = 0; (pos < resend_cache.fill && done == 0);) {
rscache_setpointer (pos);
/* get size of the cacheentry */
len = rscache_getcurlen ();
if (strcmp (addr->host, resend_cache.entry->addr.host) == 0 &&
strcmp (addr->port, resend_cache.entry->addr.port) == 0 &&
typ == resend_cache.entry->packet.h.typ && id == NTOH16 (resend_cache.entry->packet.h.id))
done = 1; /* we have found the old packet */
else
pos = pos + len;
}
if (done == 0) /* we have found nothing */
return -1;
return pos;
};
/* get the len of the current entry */
int
rscache_getcurlen ()
{
int len;
len = sizeof (struct _rscache_entry) - sizeof (struct pkg) + NTOH16 (resend_cache.entry->packet.h.len);
return len;
};
/*
the loop for the cache.. to see what will have to be resend
*/
void
rscache_loop ()
{
int len,
pos,
timeout;
if (bman.state==GS_running) timeout = RESENDCACHE_TIMEOUT; else timeout=RESENDCACHE_TIMEOUT_MENU;
for (pos = 0; pos < resend_cache.fill && pos < PKG_RESENDCACHE_SIZE && pos >= 0;) {
rscache_setpointer (pos);
len = rscache_getcurlen ();
if (timestamp - resend_cache.entry->timestamp >= timeout
&& resend_cache.entry->retry < RESENDCACHE_RETRY) {
/* send it again */
d_printf
("Data Send Timeout (%s:%s) Resend now Package Fill %d, Pos %d\n",
resend_cache.entry->addr.host, resend_cache.entry->addr.port, resend_cache.fill,pos);
udp_send (bman.sock, (char *) &resend_cache.entry->packet,
NTOH16 (resend_cache.entry->packet.h.len), &resend_cache.entry->addr.sAddr,
bman.net_ai_family);
resend_cache.entry->timestamp = timestamp;
resend_cache.entry->retry++;
if (resend_cache.entry->addr.pl_nr >= 0 && resend_cache.entry->addr.pl_nr < MAX_PLAYERS)
players[resend_cache.entry->addr.pl_nr].net.pkgopt.to_2sec++;
}
if (timestamp - resend_cache.entry->timestamp >= timeout
&& resend_cache.entry->retry >= RESENDCACHE_RETRY) {
d_printf ("Data Send Timeout (%s:%s) Delete now Package Fill %d, Pos %d\n",
resend_cache.entry->addr.host, resend_cache.entry->addr.port,
resend_cache.fill, pos);
if (resend_cache.entry->addr.pl_nr >= 0 && resend_cache.entry->addr.pl_nr < MAX_PLAYERS)
players[resend_cache.entry->addr.pl_nr].net.pkgopt.to_2sec++;
rscache_del ();
}
else
pos = pos + len;
}
};