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

110 lines
3.9 KiB

/* $Id: pkgcache.c,v 1.10 2006/08/13 21:26:50 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"
struct _resend_cache rscache;
/* reset the counter for the resendcache */
void rscache_init () {
rscache.count = 0;
};
/* add a new packet to the list
struct _rscache_entry {
Uint32 timestamp; // pointer to the timestamp
signed char retry; // retry's how many times we tryed this
_net_addr addr; // the address
char packet[MAX_UDPDATA]; // the packet
} __attribute__((packed));
*/
void rscache_add (_net_addr *addr, struct pkg *packet) {
int len;
d_printf ("rscache_add: addr %p, pkg %p\n", addr, packet);
/* check if there is still some free space left. */
if (rscache.count >= PKG_RESENDCACHE_SIZE) {
d_printf ("rscache_add no free rscache entry left.\n");
return;
}
/* copy all the data we need. */
rscache.entry[rscache.count].timestamp = timestamp;
rscache.entry[rscache.count].retry = 0;
memcpy (&rscache.entry[rscache.count].addr, addr, sizeof (_net_addr));
len = NTOH16 (packet->h.len);
if (MAX_UDPDATA < len) len = MAX_UDPDATA;
memcpy (&rscache.entry[rscache.count].packet, packet, MAX_UDPDATA);
rscache.count ++;
};
/* delete the packet from the cache */
void rscache_del (_net_addr *addr, unsigned char typ, short unsigned int id) {
int i;
d_printf ("rscache_del: addr %p\n", addr);
for (i = 0; (i < rscache.count) && (i < PKG_RESENDCACHE_SIZE); i++) {
if (rscache.entry[i].addr.pl_nr == addr->pl_nr &&
NTOH16(rscache.entry[i].packet.h.id) == id &&
((struct pkg)rscache.entry[i].packet).h.typ == typ) { // found element
int a;
for (a = i; a < rscache.count - 1; a++)
rscache.entry[i] = rscache.entry[i+1];
rscache.count--;
break;
}
}
};
/* test for old packets where we haven't got a ackreq packet for.
* If the timeout is up resend the packet again until RESENDCACHE_RETRY
* has reached then delete the packet. */
void rscache_loop () {
int i;
int timeout;
if (bman.state==GS_running) timeout = RESENDCACHE_TIMEOUT; else timeout=RESENDCACHE_TIMEOUT_MENU;
for (i = 0; (i < rscache.count) && (i < PKG_RESENDCACHE_SIZE); i++) {
if (timestamp - rscache.entry[i].timestamp >= timeout
&& rscache.entry[i].retry < RESENDCACHE_RETRY) {
/* send it again */
d_printf
("Data Send Timeout (%s:%s) Resend now Package Fill %d, Pos %d\n",
rscache.entry[i].addr.host, rscache.entry[i].addr.port, rscache.count,i);
udp_send (bman.sock, (char *) &rscache.entry[i].packet,
NTOH16 (rscache.entry[i].packet.h.len),
&rscache.entry[i].addr.sAddr,
bman.net_ai_family);
rscache.entry[i].timestamp = timestamp;
rscache.entry[i].retry++;
if (rscache.entry[i].addr.pl_nr >= 0 && rscache.entry[i].addr.pl_nr < MAX_PLAYERS)
players[rscache.entry[i].addr.pl_nr].net.pkgopt.to_2sec++;
}
if (timestamp - rscache.entry[i].timestamp >= timeout
&& rscache.entry[i].retry >= RESENDCACHE_RETRY) {
d_printf ("Data Send Timeout (%s:%s) Delete now Package Fill %d, Pos %d\n",
rscache.entry[i].addr.host, rscache.entry[i].addr.port, rscache.count, i);
if (rscache.entry[i].addr.pl_nr >= 0 && rscache.entry[i].addr.pl_nr < MAX_PLAYERS)
players[rscache.entry[i].addr.pl_nr].net.pkgopt.to_2sec++;
rscache_del (&rscache.entry[i].addr, rscache.entry[i].packet.h.typ,
NTOH16(rscache.entry[i].packet.h.id));
}
}
};