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.
169 lines
5.1 KiB
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;
|
|
}
|
|
};
|