From 81ccc527ea0d190e63b7a2b9d1c1752d3af19dc7 Mon Sep 17 00:00:00 2001 From: stpohle Date: Sun, 1 Feb 2004 02:47:33 +0000 Subject: [PATCH] major network packages problem fixed --- ChangeLog | 8 ++++- include/network.h | 7 ++-- include/packets.h | 6 ++-- src/network.c | 5 +-- src/packets.c | 85 ++++++++++++++++++++++++++--------------------- 5 files changed, 64 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a1a77d..e26549c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -$Id: ChangeLog,v 1.61 2004/02/01 01:15:03 stpohle Exp $ +$Id: ChangeLog,v 1.62 2004/02/01 02:52:01 stpohle Exp $ - Added: Deathmatch mode. @@ -42,6 +42,12 @@ $Id: ChangeLog,v 1.61 2004/02/01 01:15:03 stpohle Exp $ - Fixed: player_move had a problem with the speed of the player on slow systems. +- Fixed: Major networking and packet handling problem. inpkg_check + fixed, strange crash fixed was reading from players[addr->pl_nr].* + where addr->pl_nr was set to -1. Function inpkg_delplayer added + so all inconig indexdata for double packets can be deleted. This + made a big problem when someone disconnected and tryed to rejoin + Version 0.11.0 ============== diff --git a/include/network.h b/include/network.h index e074a6f..da968a3 100644 --- a/include/network.h +++ b/include/network.h @@ -1,4 +1,4 @@ -/* $Id: network.h,v 1.13 2004/01/27 21:58:05 stpohle Exp $ +/* $Id: network.h,v 1.14 2004/02/01 02:47:33 stpohle Exp $ * network.h file... for everything what have to do with the network stuff */ @@ -28,9 +28,6 @@ #define GS_WAITRUNNING (bman.state == GS_wait || bman.state == GS_ready || bman.state == GS_running) #define GS_RUNNING (bman.state == GS_ready || bman.state == GS_running) -/* check if we can send to the player */ -#define NET_CANSEND(__pl) ( __pl == bman.p_servnr || GT_MP_PTPM || (((players[__pl].net.flags & NETF_firewall) == 0) && !bman.firewall)) - /* Little / Big Endian Convert */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN #define NTOH16(__i) s_swap16(__i) @@ -136,5 +133,7 @@ extern void mw_draw_chat (); extern void net_getserver (); extern void srvlist_rebuildlist (); +/* check if we can send to the player */ +#define NET_CANSEND(__pl) ( GT_MP_PTPM || __pl == bman.p_servnr || (((players[__pl].net.flags & NETF_firewall) == 0) && !bman.firewall)) #endif diff --git a/include/packets.h b/include/packets.h index cb222f7..200378c 100644 --- a/include/packets.h +++ b/include/packets.h @@ -9,7 +9,6 @@ enum _network_data { PKG_playerid, PKG_servermode, PKG_joingame, - PKG_quit, PKG_field, PKG_playerdata, PKG_bombdata, @@ -25,7 +24,8 @@ enum _network_data { PKG_mapinfo, PKG_tunneldata, PKG_dropitem, - PKG_respawn + PKG_respawn, + PKG_quit // always the last known type }; @@ -363,7 +363,7 @@ extern void fwd_pkg (struct pkg *packet, _net_addr *addr); extern int get_player_nr (char *host, char *port); extern int inpkg_check (unsigned char typ, short int id, _net_addr *addr); - +extern void inpkg_delplayer (int pl_nr); /* this functions will be defined in pkgcache.c */ extern int rscache_add (_net_addr *addr, struct pkg *packet); diff --git a/src/network.c b/src/network.c index ce36fdd..1a80a12 100644 --- a/src/network.c +++ b/src/network.c @@ -1,4 +1,4 @@ -/* $Id: network.c,v 1.58 2004/02/01 00:20:29 stpohle Exp $ */ +/* $Id: network.c,v 1.59 2004/02/01 02:47:34 stpohle Exp $ */ /* network routines. */ @@ -652,13 +652,14 @@ net_delplayer (int pl_nr) } } - if (GT_MP_PTPS && pl_nr == 0) /* server quit */ + if (GT_MP_PTPS && pl_nr == bman.p_servnr) /* server quit */ bman.state = GS_startup; if (GT_MP_PTPM && bman.notifygamemaster) send_ogc_update (); d_playerdetail (" Player Left ... Playerlist\n"); + inpkg_delplayer (pl_nr); }; diff --git a/src/packets.c b/src/packets.c index abee47e..8d76e5b 100644 --- a/src/packets.c +++ b/src/packets.c @@ -10,9 +10,9 @@ extern _point debug_field; extern int debug_lastping; -static short int pkg_lastid; /* the packet id, this will only counted - up nothing more.. if we are at 0x10000 - we will start at 0 */ +static short int pkg_lastid; /* the packet id, this will only counted + * up nothing more.. if we are at 0x10000 + * we will start at 0 */ struct _resend_cache resend_cache; struct _inpkg_index inpkg_index[PKG_IN_INDEX_NUM]; @@ -1379,11 +1379,17 @@ inpkg_check (unsigned char typ, short int id, _net_addr * addr) int i, pos; + /* check if the player is still connected */ + if (!PS_IS_used (players[addr->pl_nr].state)) + return -1; + /* find packet */ - for (i = 0, pos = -1; (i < PKG_IN_INDEX_NUM && pos == -1); i++) - if (inpkg_index[i].pl_nr == addr->pl_nr && - inpkg_index[i].typ == typ && inpkg_index[i].id == id) + for (i = 0, pos = -1; (i < PKG_IN_INDEX_NUM && pos == -1); i++) + if (inpkg_index[i].pl_nr == addr->pl_nr + && inpkg_index[i].typ == typ + && inpkg_index[i].id == id) pos = i; + if (pos == -1) { /* add to index */ if (++inpkg_index_pos >= PKG_IN_INDEX_NUM) @@ -1397,6 +1403,16 @@ inpkg_check (unsigned char typ, short int id, _net_addr * addr) }; +/* delete all old pkg indexes about a player */ +void +inpkg_delplayer (int pl_nr) { + int i; + + for (i = 0; i < PKG_IN_INDEX_NUM; i++) + if (inpkg_index[i].pl_nr == pl_nr) inpkg_index[i].pl_nr = -1; +} + + /* sends the packet and if PKGF_ackreq is set add packet to the resendcache */ void send_pkg (struct pkg *packet, _net_addr * addr) @@ -1427,15 +1443,11 @@ fwd_pkg (struct pkg *packet, _net_addr * addr) if (GT_MP_PTPS) /* clients don't forward anything */ return; - if (packet->h.typ == PKG_field || packet->h.typ == PKG_playerdata - || packet->h.typ == PKG_playermove || packet->h.typ == PKG_ill - || packet->h.typ == PKG_bombdata || packet->h.typ == PKG_chat - || packet->h.typ == PKG_special) - for (pl = 1; pl < MAX_PLAYERS; pl++) + if (packet->h.typ <= PKG_quit) + for (pl = 0; pl < MAX_PLAYERS; pl++) if ((!PS_IS_aiplayer (players[pl].state)) && PS_IS_netplayer (players[pl].state) - && ((players[pl].net.flags & NETF_firewall) == NETF_firewall - || (players[addr->pl_nr].net.flags & NETF_firewall) == - NETF_firewall) && pl != addr->pl_nr) + && (players[addr->pl_nr].net.flags & NETF_firewall) == NETF_firewall + && pl != addr->pl_nr) send_pkg (packet, &players[pl].net.addr); }; @@ -1452,31 +1464,30 @@ do_pkg (struct pkg *packet, _net_addr * addr) d_printf ("do_pkg: packet comes from the wrong network type\n"); return 0; } + /* get the addr and set the ping timeout value */ addr->pl_nr = get_player_nr (addr->host, addr->port); - players[addr->pl_nr].net.timestamp = timestamp; - players[addr->pl_nr].net.pingreq = players[addr->pl_nr].net.pingack + 5; - - /* test if we have any important packet */ - if (packet->h.flags & PKGF_ackreq) - send_pkgack (addr, packet->h.typ, NTOH16 (packet->h.id)); - - /* check the packet with the index */ - if (inpkg_check (packet->h.typ, NTOH16 (packet->h.id), addr) != -1) { - /* we have got this packet already */ - d_printf ("do_pkg: double packet ignoring\n"); - if (addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) - players[addr->pl_nr].net.pkgopt.to_2sec++; - return 0; - } - - /* check if the incoming packet have the right size */ - if (packet->h.typ == PKG_servermode && NTOH16 (packet->h.len) != sizeof (struct pkg_servermode)) - send_error (addr, "pkg_servermode: packetsize incorrect."); - - /* forward packet */ - if (GT_MP_PTPM) - fwd_pkg (packet, addr); + if (addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) { + players[addr->pl_nr].net.timestamp = timestamp; + players[addr->pl_nr].net.pingreq = players[addr->pl_nr].net.pingack + 5; + + /* test if we have any important packet */ + if (packet->h.flags & PKGF_ackreq) + send_pkgack (addr, packet->h.typ, NTOH16 (packet->h.id)); + + /* check the packet with the index */ + if (inpkg_check (packet->h.typ, NTOH16 (packet->h.id), addr) != -1) { + /* we have got this packet already */ + d_printf ("do_pkg: double packet ignoring addr->pl_nr=%d\n", addr->pl_nr); + if (addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) + players[addr->pl_nr].net.pkgopt.to_2sec++; + return 0; + } + + /* forward packet */ + if (GT_MP_PTPM) + fwd_pkg (packet, addr); + } switch (packet->h.typ) { case (PKG_error):