diff options
-rwxr-xr-x | configure | 27 | ||||
-rw-r--r-- | source/bsp.c | 216 | ||||
-rw-r--r-- | source/bsp.h | 8 | ||||
-rw-r--r-- | source/cl_main.c | 6 | ||||
-rw-r--r-- | source/mvd_client.c | 7 | ||||
-rw-r--r-- | source/mvd_game.c | 2 | ||||
-rw-r--r-- | source/q_shared.h | 11 | ||||
-rw-r--r-- | source/ref_public.h | 3 | ||||
-rw-r--r-- | source/sv_ccmds.c | 47 | ||||
-rw-r--r-- | source/sv_ents.c | 79 | ||||
-rw-r--r-- | source/sv_init.c | 1 | ||||
-rw-r--r-- | source/sv_local.h | 6 | ||||
-rw-r--r-- | source/sv_main.c | 8 | ||||
-rw-r--r-- | source/sv_user.c | 17 | ||||
-rw-r--r-- | source/sw_main.c | 3 |
15 files changed, 249 insertions, 192 deletions
@@ -22,7 +22,7 @@ # ----------------------------- # build directories -sources=$(dirname $0) +sources=`dirname $0` if [ "$sources" = "." ]; then sources=`pwd` fi @@ -35,8 +35,8 @@ if [ ! -f $sources/REVISION ] ; then echo "You can create it by running 'svnversion > REVISION' at the root of source tree." exit 1 fi -version=$(cat $sources/REVISION) -revision=$(cat $sources/REVISION | tr -d -c [:digit:]) +version=`< $sources/REVISION` +revision=`tr -d -c [:digit:] < $sources/REVISION` outdir=`pwd` tmpc="/tmp/q2pro-${RANDOM}.c" tmpo="/tmp/q2pro-${RANDOM}.o" @@ -58,6 +58,7 @@ wince="no" if [ -z "$CFLAGS" ]; then CFLAGS="-O2 -g -Wall -Wstrict-prototypes" fi +have_endian_h="no" # build tools cross_prefix="" @@ -236,24 +237,25 @@ fi if [ -z "$cpu" ] ; then cpu=`uname -m` fi + case $cpu in -i386|i486|i586|i686) +i?86) cpu="i386" if [ "$use_asm" != "no" ] ; then use_asm="yes" fi ;; -ia64) -cpu="ia64" -;; -x86_64|amd64) +amd64) cpu="x86_64" ;; arm*) cpu="arm" ;; -*) -cpu="unknown" +ppc*) +cpu="powerpc" +;; +mips*) +cpu="mips" ;; esac @@ -272,6 +274,7 @@ make="gmake" ;; Linux) use_dl="yes" +have_endian_h="yes" ;; esac @@ -609,6 +612,10 @@ fi echo "#define USE_MAPCHECKSUM 1" >> $config_h echo "#define USE_AUTOREPLY 1" >> $config_h +if [ "$have_endian_h" = "yes" ]; then + echo "#define HAVE_ENDIAN_H 1" >> $config_h +fi + for t in $targets ; do mkdir -p .$t ; done diff --git a/source/bsp.c b/source/bsp.c index baa1f57..0d522cc 100644 --- a/source/bsp.c +++ b/source/bsp.c @@ -65,7 +65,7 @@ LOAD( Visibility ) { numclusters = LittleLong( bsp->vis->numclusters ); if( numclusters > ( count - 4 ) / 8 ) { - BSP_SetError( "%s: bad numclusters", __func__ ); + BSP_SetError( "%s: bad numclusters", __func__ ); } bsp->vis->numclusters = numclusters; bsp->visrowsize = ( numclusters + 7 ) >> 3; @@ -73,7 +73,7 @@ LOAD( Visibility ) { for( j = 0; j < 2; j++ ) { bitofs = LittleLong( bsp->vis->bitofs[i][j] ); if( bitofs >= count ) { - BSP_SetError( "%s: bad bitofs", __func__ ); + BSP_SetError( "%s: bad bitofs", __func__ ); return qfalse; } bsp->vis->bitofs[i][j] = bitofs; @@ -114,31 +114,31 @@ LOAD( Texinfo ) { #if USE_REF for( j = 0; j < 2; j++ ) { for( k = 0; k < 3; k++ ) { - out->axis[j][k] = LittleFloat( in->vecs[j][k] ); + out->axis[j][k] = LittleFloat( in->vecs[j][k] ); } - out->offset[j] = LittleFloat( in->vecs[j][k] ); + out->offset[j] = LittleFloat( in->vecs[j][k] ); } - next = LittleLong( in->nexttexinfo ); - if( next > 0 ) { - if( next >= count ) { - BSP_SetError( "%s: bad anim chain", __func__ ); + next = LittleLong( in->nexttexinfo ); + if( next > 0 ) { + if( next >= count ) { + BSP_SetError( "%s: bad anim chain", __func__ ); return qfalse; - } - out->next = bsp->texinfo + next; - } else { - out->next = NULL; - } + } + out->next = bsp->texinfo + next; + } else { + out->next = NULL; + } #endif } #if USE_REF - // count animation frames + // count animation frames out = bsp->texinfo; - for( i = 0; i < count; i++, out++ ) { - out->numframes = 1; - for( step = out->next; step && step != out; step = step->next ) { - out->numframes++; + for( i = 0; i < count; i++, out++ ) { + out->numframes = 1; + for( step = out->next; step && step != out; step = step->next ) { + out->numframes++; } } #endif @@ -295,14 +295,14 @@ LOAD( Lightmap ) { // by taking the brightest component in = base; out = bsp->lightmap; - for( i = 0; i < count; i++, in += 3, out++ ) { - if( in[0] > in[1] && in[0] > in[2] ) - *out = in[0]; - else if( in[1] > in[0] && in[1] > in[2] ) - *out = in[1]; - else - *out = in[2]; - } + for( i = 0; i < count; i++, in += 3, out++ ) { + if( in[0] > in[1] && in[0] > in[2] ) + *out = in[0]; + else if( in[1] > in[0] && in[1] > in[2] ) + *out = in[1]; + else + *out = in[2]; + } #else memcpy( bsp->lightmap, base, count ); #endif @@ -326,7 +326,7 @@ LOAD( Vertices ) { out = bsp->vertices; for( i = 0; i < count; i++, out++, in++ ) { for( j = 0; j < 3; j++ ) { - out->point[j] = LittleFloat( in->point[j] ); + out->point[j] = LittleFloat( in->point[j] ); } } return qtrue; @@ -350,7 +350,7 @@ LOAD( Edges ) { out = bsp->edges; for( i = 0; i < count; i++, out++, in++ ) { for( j = 0; j < 2; j++ ) { - vertnum = LittleShort( in->v[j] ); + vertnum = LittleShort( in->v[j] ); if( vertnum >= bsp->numvertices ) { BSP_SetError( "%s: bad vertnum", __func__ ); return qfalse; @@ -380,15 +380,15 @@ LOAD( SurfEdges ) { for( i = 0; i < count; i++, out++, in++ ) { index = ( signed int )LittleLong( *in ); - vert = 0; - if( index < 0 ) { - index = -index; - vert = 1; - } + vert = 0; + if( index < 0 ) { + index = -index; + vert = 1; + } - if( index >= bsp->numedges ) { + if( index >= bsp->numedges ) { BSP_SetError( "%s: bad edgenum", __func__ ); - } + } out->edge = bsp->edges + index; out->vert = vert; @@ -402,14 +402,14 @@ Faces ================= */ LOAD( Faces ) { - dface_t *in; - mface_t *out; - int i; + dface_t *in; + mface_t *out; + int i; #if USE_REF == REF_SOFT - int j; + int j; #endif - unsigned texinfo, lightofs; - unsigned firstedge, numedges, lastedge; + unsigned texinfo, lightofs; + unsigned firstedge, numedges, lastedge; unsigned planenum, side; bsp->numfaces = count; @@ -418,13 +418,13 @@ LOAD( Faces ) { in = base; out = bsp->faces; for( i = 0; i < count; i++, in++, out++ ) { - firstedge = LittleLong( in->firstedge ); - numedges = LittleShort( in->numedges ); + firstedge = LittleLong( in->firstedge ); + numedges = LittleShort( in->numedges ); lastedge = firstedge + numedges; - if( numedges < 3 || lastedge < firstedge || lastedge > bsp->numsurfedges ) { - BSP_SetError( "%s: bad surfedges", __func__ ); + if( numedges < 3 || lastedge < firstedge || lastedge > bsp->numsurfedges ) { + BSP_SetError( "%s: bad surfedges", __func__ ); return qfalse; - } + } out->firstsurfedge = bsp->surfedges + firstedge; out->numsurfedges = numedges; @@ -435,16 +435,16 @@ LOAD( Faces ) { } out->plane = bsp->planes + planenum; - texinfo = LittleShort( in->texinfo ); - if( texinfo >= bsp->numtexinfo ) { - BSP_SetError( "%s: bad texinfo", __func__ ); + texinfo = LittleShort( in->texinfo ); + if( texinfo >= bsp->numtexinfo ) { + BSP_SetError( "%s: bad texinfo", __func__ ); return qfalse; - } + } out->texinfo = bsp->texinfo + texinfo; #if USE_REF == REF_SOFT - for( j = 0; j < MAX_LIGHTMAPS; j++ ) { - out->styles[j] = in->styles[j]; + for( j = 0; j < MAX_LIGHTMAPS; j++ ) { + out->styles[j] = in->styles[j]; } #endif @@ -453,7 +453,7 @@ LOAD( Faces ) { out->lightmap = NULL; } else { #if USE_REF == REF_SOFT - // lighting info is converted from 24 bit on disk to 8 bit + // lighting info is converted from 24 bit on disk to 8 bit lightofs /= 3; #endif if( lightofs >= bsp->numlightmapbytes ) { @@ -465,7 +465,7 @@ LOAD( Faces ) { side = LittleShort( in->side ); out->drawflags = side & DSURF_PLANEBACK; - } + } return qtrue; } @@ -555,13 +555,13 @@ LOAD( Leafs ) { out->firstleafface = bsp->leaffaces + firstleafface; out->numleaffaces = numleaffaces; - for( j = 0; j < 3; j++ ) { + for( j = 0; j < 3; j++ ) { out->mins[j] = ( signed short )LittleShort( in->mins[j] ); out->maxs[j] = ( signed short )LittleShort( in->maxs[j] ); } - out->parent = NULL; - out->visframe = -1; + out->parent = NULL; + out->visframe = -1; #endif } @@ -624,23 +624,23 @@ LOAD( Nodes ) { } #if USE_REF - firstface = LittleLong( in->firstface ); - numfaces = LittleLong( in->numfaces ); + firstface = LittleShort( in->firstface ); + numfaces = LittleShort( in->numfaces ); lastface = firstface + numfaces; - if( lastface < firstface || lastface > bsp->numfaces ) { - BSP_SetError( "%s: bad faces", __func__ ); + if( lastface < firstface || lastface > bsp->numfaces ) { + BSP_SetError( "%s: bad faces", __func__ ); return qfalse; - } - out->firstface = bsp->faces + firstface; - out->numfaces = numfaces; + } + out->firstface = bsp->faces + firstface; + out->numfaces = numfaces; - for( j = 0; j < 3; j++ ) { + for( j = 0; j < 3; j++ ) { out->mins[j] = ( signed short )LittleShort( in->mins[j] ); out->maxs[j] = ( signed short )LittleShort( in->maxs[j] ); } - out->parent = NULL; - out->visframe = -1; + out->parent = NULL; + out->visframe = -1; #endif } return qtrue; @@ -681,17 +681,17 @@ LOAD( Submodels ) { out->headnode = bsp->nodes + headnode; } #if USE_REF - firstface = LittleLong( in->firstface ); - numfaces = LittleLong( in->numfaces ); + firstface = LittleLong( in->firstface ); + numfaces = LittleLong( in->numfaces ); lastface = firstface + numfaces; - if( lastface < firstface || lastface > bsp->numfaces ) { - BSP_SetError( "%s: bad faces", __func__ ); + if( lastface < firstface || lastface > bsp->numfaces ) { + BSP_SetError( "%s: bad faces", __func__ ); return qfalse; - } - out->firstface = bsp->faces + firstface; - out->numfaces = numfaces; + } + out->firstface = bsp->faces + firstface; + out->numfaces = numfaces; - out->radius = RadiusFromBounds( out->mins, out->maxs ); + out->radius = RadiusFromBounds( out->mins, out->maxs ); #endif } return qtrue; @@ -817,12 +817,12 @@ static const lump_info_t bsp_lumps[] = { LUMP( AreaPortals, AREAPORTALS, dareaportal_t ), LUMP( Areas, AREAS, darea_t ), #if USE_REF - LUMP( Lightmap, LIGHTING, byte ), - LUMP( Vertices, VERTEXES, dvertex_t ), - LUMP( Edges, EDGES, dedge_t ), - LUMP( SurfEdges, SURFEDGES, uint32_t ), - LUMP( Faces, FACES, dface_t ), - LUMP( LeafFaces, LEAFFACES, uint16_t ), + LUMP( Lightmap, LIGHTING, byte ), + LUMP( Vertices, VERTEXES, dvertex_t ), + LUMP( Edges, EDGES, dedge_t ), + LUMP( SurfEdges, SURFEDGES, uint32_t ), + LUMP( Faces, FACES, dface_t ), + LUMP( LeafFaces, LEAFFACES, uint16_t ), #endif LUMP( Leafs, LEAFS, dleaf_t ), LUMP( Nodes, NODES, dnode_t ), @@ -843,7 +843,7 @@ static void BSP_List_f( void ) { return; } - Com_Printf( "------------------\n"); + Com_Printf( "------------------\n"); bytes = 0; LIST_FOR_EACH( bsp_t, bsp, &bsp_cache, entry ) { @@ -851,7 +851,7 @@ static void BSP_List_f( void ) { bsp->pool.mapped, bsp->name, bsp->refcount ); bytes += bsp->pool.mapped; } - Com_Printf( "Total resident: %"PRIz"\n", bytes ); + Com_Printf( "Total resident: %"PRIz"\n", bytes ); } static bsp_t *BSP_Find( const char *name ) { @@ -866,23 +866,23 @@ static bsp_t *BSP_Find( const char *name ) { } static qboolean BSP_SetParent( mnode_t *node ) { - mnode_t *child; - - while( node->plane ) { - child = node->children[0]; + mnode_t *child; + + while( node->plane ) { + child = node->children[0]; if( child->parent ) { return qfalse; } - child->parent = node; - BSP_SetParent( child ); - - child = node->children[1]; + child->parent = node; + BSP_SetParent( child ); + + child = node->children[1]; if( child->parent ) { return qfalse; } - child->parent = node; - node = child; - } + child->parent = node; + node = child; + } return qtrue; } @@ -912,11 +912,11 @@ static qboolean BSP_ValidateAreaPortals( bsp_t *bsp ) { void BSP_SetError( const char *fmt, ... ) { - va_list argptr; + va_list argptr; - va_start( argptr, fmt ); - Q_vsnprintf( bsp_error, sizeof( bsp_error ), fmt, argptr ); - va_end( argptr ); + va_start( argptr, fmt ); + Q_vsnprintf( bsp_error, sizeof( bsp_error ), fmt, argptr ); + va_end( argptr ); } const char *BSP_GetError( void ) { @@ -959,7 +959,7 @@ bsp_t *BSP_Load( const char *name ) { BSP_SetError( "no error" ); if( ( bsp = BSP_Find( name ) ) != NULL ) { - Com_PageInMemory( bsp->pool.base, bsp->pool.cursize ); + Com_PageInMemory( bsp->pool.base, bsp->pool.cursize ); bsp->refcount++; return bsp; } @@ -1058,16 +1058,16 @@ HELPER FUNCTIONS #if USE_REF mface_t *BSP_LightPoint( mnode_t *node, vec3_t start, vec3_t end, int *ps, int *pt ) { - vec_t startFrac, endFrac, midFrac; - vec3_t _start, mid; - int side; - mface_t *surf; - mtexinfo_t *texinfo; - int i; - int s, t; + vec_t startFrac, endFrac, midFrac; + vec3_t _start, mid; + int side; + mface_t *surf; + mtexinfo_t *texinfo; + int i; + int s, t; VectorCopy( start, _start ); - while( node->plane ) { + while( node->plane ) { // calculate distancies startFrac = PlaneDiffFast( _start, node->plane ); endFrac = PlaneDiffFast( end, node->plane ); @@ -1120,7 +1120,7 @@ mface_t *BSP_LightPoint( mnode_t *node, vec3_t start, vec3_t end, int *ps, int * node = node->children[side^1]; } - return NULL; + return NULL; } #endif diff --git a/source/bsp.h b/source/bsp.h index ce7c29d..868ab20 100644 --- a/source/bsp.h +++ b/source/bsp.h @@ -45,13 +45,13 @@ typedef struct mtexinfo_s { // used internally due to name len probs //ZOID #if USE_REF typedef struct { - vec3_t point; + vec3_t point; } mvertex_t; typedef struct { - mvertex_t *v[2]; + mvertex_t *v[2]; #if USE_REF == REF_SOFT - unsigned cachededgeoffset; + unsigned cachededgeoffset; #endif } medge_t; @@ -85,7 +85,7 @@ typedef struct mface_s { int texnum[2]; int firstvert; #else - struct surfcache_s *cachespots[MIPLEVELS]; // surface generation data + struct surfcache_s *cachespots[MIPLEVELS]; // surface generation data #endif int drawframe; diff --git a/source/cl_main.c b/source/cl_main.c index cc04be8..afd4fed 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -614,6 +614,12 @@ void CL_Disconnect( comErrorType_t type, const char *text ) { EXEC_TRIGGER( cl_disconnectcmd ); } +#if USE_REF == REF_SOFT + if( cls.ref_initialized ) { + R_CinematicSetPalette( NULL ); + } +#endif + cls.connect_time = 0; cls.connect_count = 0; cls.passive = qfalse; diff --git a/source/mvd_client.c b/source/mvd_client.c index 64d491a..013dc11 100644 --- a/source/mvd_client.c +++ b/source/mvd_client.c @@ -1620,7 +1620,7 @@ void MVD_StreamedRecord_f( void ) { while( ( c = Cmd_ParseOptions( o_record ) ) != -1 ) { switch( c ) { case 'h': - Cmd_PrintUsage( o_record, "[/]<filename> [chanid]" ); + Cmd_PrintUsage( o_record, "<filename> [chanid]" ); Com_Printf( "Begin MVD recording on the specified channel.\n" ); Cmd_PrintHelp( o_record ); return; @@ -1644,7 +1644,8 @@ void MVD_StreamedRecord_f( void ) { } if( mvd->demorecording ) { - Com_Printf( "[%s] Already recording.\n", mvd->name ); + Com_Printf( "[%s] Already recording into %s.\n", + mvd->name, mvd->demoname ); return; } @@ -1660,7 +1661,7 @@ void MVD_StreamedRecord_f( void ) { FS_FOpenFile( buffer, &f, FS_MODE_WRITE ); if( !f ) { - Com_EPrintf( "Couldn't open %s for writing\n", buffer ); + Com_EPrintf( "Couldn't open %s for writing.\n", buffer ); return; } diff --git a/source/mvd_game.c b/source/mvd_game.c index 270c00a..c0b015c 100644 --- a/source/mvd_game.c +++ b/source/mvd_game.c @@ -790,7 +790,7 @@ static void MVD_Say_f( mvd_client_t *client, int argnum ) { *p |= 128; } - MVD_BroadcastPrintf( mvd, PRINT_MEDIUM, client->admin ? + MVD_BroadcastPrintf( mvd, PRINT_HIGH, client->admin ? 0 : UF_MUTE_OBSERVERS, "%s\n", text ); } diff --git a/source/q_shared.h b/source/q_shared.h index a69c5a3..b63cca7 100644 --- a/source/q_shared.h +++ b/source/q_shared.h @@ -577,9 +577,9 @@ static inline float FloatSwap( float f ) { #define MakeLong(b1,b2,b3,b4) (((b4)<<24)|((b3)<<16)|((b2)<<8)|(b1)) #define MakeShort(b1,b2) (((b2)<<8)|(b1)) #elif __BYTE_ORDER == __BIG_ENDIAN -#define BigShort ((uint16_t)(x)) -#define BigLong ((uint32_t)(x)) -#define BigFloat ((float)(x)) +#define BigShort(x) ((uint16_t)(x)) +#define BigLong(x) ((uint32_t)(x)) +#define BigFloat(x) ((float)(x)) #define LittleShort ShortSwap #define LittleLong LongSwap #define LittleFloat FloatSwap @@ -589,7 +589,10 @@ static inline float FloatSwap( float f ) { #error Unknown byte order #endif -#define LittleVector(a,b) ((b)[0]=LittleFloat((a)[0]),(b)[1]=LittleFloat((a)[1]),(b)[2]=LittleFloat((a)[2])) +#define LittleVector(a,b) \ + ((b)[0]=LittleFloat((a)[0]),\ + (b)[1]=LittleFloat((a)[1]),\ + (b)[2]=LittleFloat((a)[2])) //============================================= diff --git a/source/ref_public.h b/source/ref_public.h index f49aa8e..b6e5bf3 100644 --- a/source/ref_public.h +++ b/source/ref_public.h @@ -227,5 +227,8 @@ void R_BeginFrame( void ); void R_EndFrame( void ); void R_ModeChanged( int width, int height, int flags, int rowbytes, void *pixels ); void R_GetConfig( glconfig_t *dest ); +#if USE_REF == REF_SOFT +void R_CinematicSetPalette( const byte *palette ); +#endif #endif // __REF_H diff --git a/source/sv_ccmds.c b/source/sv_ccmds.c index 64b8f52..1a0a41d 100644 --- a/source/sv_ccmds.c +++ b/source/sv_ccmds.c @@ -467,6 +467,34 @@ static void dump_time( void ) { } } +static void dump_lag( void ) { + client_t *cl; + +#ifdef USE_PACKETDUP +#define PD1 " dup" +#define PD2 " ---" +#define PD3 " %3d" +#else +#define PD1 +#define PD2 +#define PD3 +#endif + + Com_Printf( +"num name PLs2c PLc2s Rmin Ravg Rmax"PD1"\n" +"--- --------------- ----- ----- ---- ---- ----"PD2"\n" ); + + FOR_EACH_CLIENT( cl ) { + Com_Printf( "%3i %-15.15s %5.2f %5.2f %4d %4d %4d"PD3"\n", + cl->number, cl->name, PL_S2C( cl ), PL_C2S( cl ), + cl->min_ping, AVG_PING( cl ), cl->max_ping +#ifdef USE_PACKETDUP + , cl->netchan->numpackets - 1 +#endif + ); + } +} + /* ================ SV_Status_f @@ -487,12 +515,11 @@ static void SV_Status_f( void ) { } else { if( Cmd_Argc() > 1 ) { char *w = Cmd_Argv( 1 ); - if( *w == 't' ) { - dump_time(); - } else if( *w == 'd' ) { - dump_downloads(); - } else { - dump_versions(); + switch( *w ) { + case 't': dump_time(); break; + case 'd': dump_downloads(); break; + case 'l': dump_lag(); break; + default: dump_versions(); break; } } else { dump_clients(); @@ -595,16 +622,20 @@ static void SV_DumpUser_f( void ) { Com_Printf( "--------\n" ); Com_Printf( "version %s\n", sv_client->versionString ? sv_client->versionString : "-" ); - Com_Printf( "protocol %d/%d\n", + Com_Printf( "protocol (min/maj) %d/%d\n", sv_client->protocol, sv_client->version ); Com_Printf( "ping %d\n", sv_client->ping ); Com_Printf( "fps %d\n", sv_client->fps ); + Com_Printf( "RTT (min/avg/max) %d/%d/%d ms\n", + sv_client->min_ping, AVG_PING( sv_client ), sv_client->max_ping ); + Com_Printf( "PL server to client %.2f%% (approx)\n", PL_S2C( sv_client ) ); + Com_Printf( "PL client to server %.2f%%\n", PL_C2S( sv_client ) ); #ifdef USE_PACKETDUP Com_Printf( "packetdup %d\n", sv_client->numpackets - 1 ); #endif Com_TimeDiff( buffer, sizeof( buffer ), sv_client->connect_time, time( NULL ) ); - Com_Printf( "time %s\n", buffer ); + Com_Printf( "connection time %s\n", buffer ); sv_client = NULL; sv_player = NULL; diff --git a/source/sv_ents.c b/source/sv_ents.c index 1f1622a..d8a4032 100644 --- a/source/sv_ents.c +++ b/source/sv_ents.c @@ -129,6 +129,33 @@ static void SV_EmitPacketEntities( client_t *client, MSG_WriteShort( 0 ); // end of packetentities } +static client_frame_t *get_last_frame( client_t *client ) { + client_frame_t *frame; + + if( client->lastframe <= 0 ) { + // client is asking for a retransmit + client->frames_nodelta++; + return NULL; + } + client->frames_nodelta = 0; + + if( sv.framenum - client->lastframe > UPDATE_BACKUP - 1 ) { + // client hasn't gotten a good message through in a long time + Com_DPrintf( "%s: delta request from out-of-date packet.\n", client->name ); + return NULL; + } + + // we have a valid message to delta from + frame = &client->frames[client->lastframe & UPDATE_MASK]; + if( svs.nextEntityStates - frame->firstEntity > svs.numEntityStates ) { + // but entities are too old + Com_DPrintf( "%s: delta request from out-of-date entities.\n", client->name ); + return NULL; + } + + return frame; +} + /* ================== SV_WriteFrameToClient_Default @@ -142,28 +169,14 @@ void SV_WriteFrameToClient_Default( client_t *client ) { // this is the frame we are creating frame = &client->frames[sv.framenum & UPDATE_MASK]; - if( client->lastframe <= 0 ) { - // client is asking for a retransmit - oldframe = NULL; - oldstate = NULL; - lastframe = -1; - } else if( sv.framenum - client->lastframe > UPDATE_BACKUP - 1 ) { - // client hasn't gotten a good message through in a long time - Com_DPrintf( "%s: delta request from out-of-date packet.\n", client->name ); - oldframe = NULL; - oldstate = NULL; - lastframe = -1; - } else { - // we have a valid message to delta from - oldframe = &client->frames[client->lastframe & UPDATE_MASK]; + // this is the frame we are delta'ing from + oldframe = get_last_frame( client ); + if( oldframe ) { oldstate = &oldframe->ps; lastframe = client->lastframe; - if( svs.nextEntityStates - oldframe->firstEntity > svs.numEntityStates ) { - Com_DPrintf( "%s: delta request from out-of-date entities.\n", client->name ); - oldframe = NULL; - oldstate = NULL; - lastframe = -1; - } + } else { + oldstate = NULL; + lastframe = -1; } MSG_WriteByte( svc_frame ); @@ -204,28 +217,14 @@ void SV_WriteFrameToClient_Enhanced( client_t *client ) { // this is the frame we are creating frame = &client->frames[sv.framenum & UPDATE_MASK]; - if( client->lastframe <= 0 ) { - // client is asking for a retransmit - oldframe = NULL; - oldstate = NULL; - delta = 31; - } else if( sv.framenum - client->lastframe > UPDATE_BACKUP - 1 ) { - // client hasn't gotten a good message through in a long time - Com_DPrintf( "%s: delta request from out-of-date packet.\n", client->name ); - oldframe = NULL; - oldstate = NULL; - delta = 31; - } else { - // we have a valid message to delta from - oldframe = &client->frames[client->lastframe & UPDATE_MASK]; + // this is the frame we are delta'ing from + oldframe = get_last_frame( client ); + if( oldframe ) { oldstate = &oldframe->ps; delta = sv.framenum - client->lastframe; - if( svs.nextEntityStates - oldframe->firstEntity > svs.numEntityStates ) { - Com_DPrintf( "%s: delta request from out-of-date entities.\n", client->name ); - oldframe = NULL; - oldstate = NULL; - delta = 31; - } + } else { + oldstate = NULL; + delta = 31; } // first byte to be patched diff --git a/source/sv_init.c b/source/sv_init.c index dbfaccf..cdeff2f 100644 --- a/source/sv_init.c +++ b/source/sv_init.c @@ -31,6 +31,7 @@ void SV_ClientReset( client_t *client ) { // any partially connected client will be restarted client->state = cs_connected; client->lastframe = -1; + client->frames_nodelta = 0; client->send_delta = 0; client->surpressCount = 0; memset( &client->lastcmd, 0, sizeof( client->lastcmd ) ); diff --git a/source/sv_local.h b/source/sv_local.h index 9d14238..7cbd85c 100644 --- a/source/sv_local.h +++ b/source/sv_local.h @@ -168,6 +168,10 @@ typedef struct { #define FOR_EACH_CLIENT( client ) \ LIST_FOR_EACH( client_t, client, &svs.udp_client_list, entry ) +#define PL_S2C(cl) ((1.0f-(float)cl->frames_acked/cl->frames_sent)*100.0f) +#define PL_C2S(cl) (((float)cl->netchan->total_dropped/cl->netchan->total_received)*100.0f) +#define AVG_PING(cl) (cl->avg_ping_count?cl->avg_ping_time/cl->avg_ping_count:cl->ping) + typedef enum { CF_RECONNECTED = ( 1 << 0 ), CF_NODATA = ( 1 << 1 ), @@ -216,7 +220,7 @@ typedef struct client_s { clientSetting_t settings[CLS_MAX]; client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here - unsigned frames_sent, frames_acked; + unsigned frames_sent, frames_acked, frames_nodelta; byte *download; // file being downloaded int downloadsize; // total bytes (can't use EOF because of paks) diff --git a/source/sv_main.c b/source/sv_main.c index 22890b6..47d232a 100644 --- a/source/sv_main.c +++ b/source/sv_main.c @@ -32,6 +32,7 @@ LIST_DECL( sv_filterlist ); client_t *sv_client; // current client cvar_t *sv_enforcetime; +cvar_t *sv_allow_nodelta; #if USE_FPS cvar_t *sv_fps; #endif @@ -1309,6 +1310,12 @@ static void SV_CheckTimeouts( void ) { if( delta > drop_time || ( client->state == cs_assigned && delta > ghost_time ) ) { SV_DropClient( client, "connection timed out" ); SV_RemoveClient( client ); // don't bother with zombie state + continue; + } + + if( client->frames_nodelta > 64 && !sv_allow_nodelta->integer ) { + SV_DropClient( client, "too many nodelta frames" ); + continue; } } } @@ -1760,6 +1767,7 @@ void SV_Init( void ) { sv_ghostime = Cvar_Get( "sv_ghostime", "6", 0 ); sv_showclamp = Cvar_Get( "showclamp", "0", 0 ); sv_enforcetime = Cvar_Get( "sv_enforcetime", "1", 0 ); + sv_allow_nodelta = Cvar_Get( "sv_allow_nodelta", "1", 0 ); #if USE_FPS sv_fps = Cvar_Get( "sv_fps", "10", CVAR_LATCH ); #endif diff --git a/source/sv_user.c b/source/sv_user.c index 0145eb1..4dece07 100644 --- a/source/sv_user.c +++ b/source/sv_user.c @@ -757,8 +757,6 @@ static void SV_NoGameData_f( void ) { static void SV_Lag_f( void ) { client_t *cl; - float c2s, s2c; - int avg_ping; if( Cmd_Argc() > 1 ) { SV_BeginRedirect( RD_CLIENT ); @@ -771,19 +769,13 @@ static void SV_Lag_f( void ) { cl = sv_client; } - avg_ping = cl->avg_ping_count ? - cl->avg_ping_time / cl->avg_ping_count : cl->ping; - - s2c = ( 1.0f - (float)cl->frames_acked / cl->frames_sent ) * 100.0f; - c2s = ( (float)cl->netchan->total_dropped / - cl->netchan->total_received ) * 100.0f; - SV_ClientPrintf( sv_client, PRINT_HIGH, "Lag stats for: %s\n" "RTT (min/avg/max): %d/%d/%d ms\n" "Server to client PL: %.2f%% (approx)\n" "Client to server PL: %.2f%%\n", - cl->name, cl->min_ping, avg_ping, cl->max_ping, s2c, c2s ); + cl->name, cl->min_ping, AVG_PING( cl ), cl->max_ping, + PL_S2C( cl ), PL_C2S( cl ) ); } #if USE_PACKETDUP @@ -989,8 +981,11 @@ static inline void SV_SetLastFrame( int lastframe ) { unsigned sentTime; if( lastframe > 0 ) { + if( lastframe > sv.framenum ) { + return; // ignore bogus acks + } if( lastframe <= sv_client->lastframe ) { - return; + return; // ignore duplicate acks } sentTime = sv_client->frames[lastframe & UPDATE_MASK].sentTime; diff --git a/source/sw_main.c b/source/sw_main.c index b8caeaf..165a524 100644 --- a/source/sw_main.c +++ b/source/sw_main.c @@ -329,7 +329,7 @@ void R_Shutdown( qboolean total ) { D_FlushCaches(); - MOD_FreeAll(); + MOD_Shutdown(); R_ShutdownImages(); @@ -364,7 +364,6 @@ void R_Shutdown( qboolean total ) { R_UnRegister(); IMG_Shutdown(); - MOD_Shutdown(); VID_Shutdown(); } |