diff options
author | Andrey Nazarov <skuller@skuller.net> | 2008-10-25 16:43:39 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2008-10-25 16:43:39 +0000 |
commit | 8a4e5f5516e94fe901a332bce7eef9b824f225c6 (patch) | |
tree | 93d64ca93047c6b1c1b59658e950ab0062544fe9 | |
parent | b7d3939f3f68617f80d74d0a2bf6ea34ddea1065 (diff) |
Progress meter now works for local MVDs again.
Implemented `mvdskip' command which allows one jump to the next map in a MVD.
Removed `mvd_shownet' debugging stuff from dedicated server build.
Dropped packets no longer have maximum height on the lagometer.
-rw-r--r-- | source/cl_demo.c | 4 | ||||
-rw-r--r-- | source/cl_draw.c | 11 | ||||
-rw-r--r-- | source/cl_scrn.c | 17 | ||||
-rw-r--r-- | source/files.c | 136 | ||||
-rw-r--r-- | source/files.h | 4 | ||||
-rw-r--r-- | source/mvd_client.c | 193 | ||||
-rw-r--r-- | source/mvd_game.c | 485 | ||||
-rw-r--r-- | source/mvd_local.h | 5 | ||||
-rw-r--r-- | source/mvd_parse.c | 818 | ||||
-rw-r--r-- | source/q_msg.c | 14 | ||||
-rw-r--r-- | source/q_msg.h | 6 | ||||
-rw-r--r-- | source/q_shared.c | 48 | ||||
-rw-r--r-- | source/r_images.c | 98 | ||||
-rw-r--r-- | source/sv_local.h | 7 | ||||
-rw-r--r-- | source/sv_main.c | 1406 | ||||
-rw-r--r-- | source/sv_mvd.c | 4 | ||||
-rw-r--r-- | source/sv_null.c | 8 | ||||
-rw-r--r-- | source/sv_public.h | 5 | ||||
-rw-r--r-- | source/sv_user.c | 26 | ||||
-rw-r--r-- | source/sv_world.c | 784 | ||||
-rw-r--r-- | source/ui_atoms.c | 3 | ||||
-rw-r--r-- | source/vid_sdl.c | 4 |
22 files changed, 2113 insertions, 1973 deletions
diff --git a/source/cl_demo.c b/source/cl_demo.c index a007f74..1e08789 100644 --- a/source/cl_demo.c +++ b/source/cl_demo.c @@ -235,7 +235,7 @@ void CL_Stop_f( void ) { FS_Write( &msglen, 4, cls.demo.recording ); FS_Flush( cls.demo.recording ); - msglen = FS_RawTell( cls.demo.recording ); + msglen = FS_Tell( cls.demo.recording ); // close demofile FS_FCloseFile( cls.demo.recording ); @@ -571,7 +571,7 @@ static void CL_ParseNextDemoMessage( void ) { CL_ParseServerMessage(); if( cls.demo.file_size ) { - pos = FS_RawTell( cls.demo.playback ) - cls.demo.file_offset; + pos = FS_Tell( cls.demo.playback ) - cls.demo.file_offset; if( pos < 0 ) { pos = 0; } diff --git a/source/cl_draw.c b/source/cl_draw.c index cc58474..ab0b888 100644 --- a/source/cl_draw.c +++ b/source/cl_draw.c @@ -107,8 +107,8 @@ LAGOMETER #define LAG_CRIT 0xF2 static struct { - int samples[LAG_WIDTH]; - int head; + unsigned samples[LAG_WIDTH]; + unsigned head; } lag; void SCR_LagClear( void ) { @@ -118,15 +118,16 @@ void SCR_LagClear( void ) { void SCR_LagSample( void ) { int i = cls.netchan->incoming_acknowledged & CMD_MASK; client_history_t *h = &cl.history[i]; - int ping = cls.realtime - h->sent; + unsigned ping; h->rcvd = cls.realtime; - if( !h->cmdNumber ) { + if( !h->cmdNumber || h->rcvd < h->sent ) { return; } + ping = h->rcvd - h->sent; for( i = 0; i < cls.netchan->dropped; i++ ) { - lag.samples[lag.head % LAG_WIDTH] = LAG_MAX | LAG_CRIT_BIT; + lag.samples[lag.head % LAG_WIDTH] = ping | LAG_CRIT_BIT; lag.head++; } diff --git a/source/cl_scrn.c b/source/cl_scrn.c index e3dd6ca..18f4602 100644 --- a/source/cl_scrn.c +++ b/source/cl_scrn.c @@ -194,7 +194,7 @@ static void SCR_DrawPercentBar( int percent ) { R_DrawFill( 0, scr_hudHeight, w, CHAR_HEIGHT, 4 ); R_DrawFill( w, scr_hudHeight, scr_hudWidth - w, CHAR_HEIGHT, 0 ); - length = sprintf( buffer, "%d%%", percent ); + length = Q_snprintf( buffer, sizeof( buffer ), "%d%%", percent ); x = ( scr_hudWidth - length * CHAR_WIDTH ) / 2; R_DrawString( x, scr_hudHeight, 0, MAX_STRING_CHARS, buffer, scr_font ); } @@ -205,7 +205,7 @@ SCR_DrawDemoBar ================ */ static void SCR_DrawDemoBar( void ) { - //int percent, bufferPercent; + int percent; if( !scr_demobar->integer ) { return; @@ -217,23 +217,18 @@ static void SCR_DrawDemoBar( void ) { } return; } -#if 0 + +#if USE_MVD_CLIENT if( sv_running->integer != ss_broadcast ) { return; } - if( !MVD_GetDemoPercent( &percent, &bufferPercent ) ) { + if( ( percent = MVD_GetDemoPercent() ) == -1 ) { return; } - if( scr_demobar->integer & 1 ) { - SCR_DrawPercentBar( percent ); - } - if( scr_demobar->integer & 2 ) { - SCR_DrawPercentBar( bufferPercent ); - } + SCR_DrawPercentBar( percent ); #endif - } /* diff --git a/source/files.c b/source/files.c index 6289d52..a8eb100 100644 --- a/source/files.c +++ b/source/files.c @@ -342,9 +342,10 @@ char *FS_ReplaceSeparators( char *s, int separator ) { ================ FS_GetFileLength -Returns current length for files opened for writing. -Returns cached length for files opened for reading. -Returns compressed length for GZIP files. +Returns: +- current length for files opened for writing. +- cached length for files opened for reading. +- INVALID_LENGTH for gzip-compressed files. ================ */ size_t FS_GetFileLength( fileHandle_t f ) { @@ -358,10 +359,11 @@ size_t FS_GetFileLength( fileHandle_t f ) { } return info.size; case FS_PAK: - return file->length; #if USE_ZLIB case FS_PK2: +#endif return file->length; +#if USE_ZLIB case FS_GZIP: return INVALID_LENGTH; #endif @@ -374,6 +376,69 @@ size_t FS_GetFileLength( fileHandle_t f ) { /* ============ +FS_Tell +============ +*/ +size_t FS_Tell( fileHandle_t f ) { + fsFile_t *file = FS_FileForHandle( f ); + int length; + + switch( file->type ) { + case FS_REAL: + length = ftell( file->fp ); + break; + case FS_PAK: + length = ftell( file->fp ) - file->pak->filepos; + break; +#if USE_ZLIB + case FS_PK2: + length = unztell( file->zfp ); + break; + case FS_GZIP: + return INVALID_LENGTH; +#endif + default: + Com_Error( ERR_FATAL, "%s: bad file type", __func__ ); + } + + return length; +} + +/* +============ +FS_Seek +============ +*/ +qboolean FS_Seek( fileHandle_t f, size_t offset ) { + fsFile_t *file = FS_FileForHandle( f ); + + switch( file->type ) { + case FS_REAL: + case FS_PAK: + if( fseek( file->fp, offset, SEEK_CUR ) == -1 ) { + return qfalse; + } + break; +#if USE_ZLIB + case FS_GZIP: + if( gzseek( file->zfp, offset, SEEK_CUR ) == -1 ) { + return qfalse; + } + break; + //case FS_PK2: + // length = unztell( file->zfp ); + // break; +#endif + default: + return qfalse; + } + + return qtrue; +} + + +/* +============ FS_CreatePath Creates any directories needed to store the given filename. @@ -966,69 +1031,6 @@ size_t FS_FOpenFile( const char *name, fileHandle_t *f, int mode ) { } -/* -============ -FS_Tell -============ -*/ -int FS_Tell( fileHandle_t f ) { - fsFile_t *file = FS_FileForHandle( f ); - int length; - - switch( file->type ) { - case FS_REAL: - length = ftell( file->fp ); - break; - case FS_PAK: - length = ftell( file->fp ) - file->pak->filepos; - break; -#if USE_ZLIB - case FS_GZIP: - length = gztell( file->zfp ); - break; - case FS_PK2: - length = unztell( file->zfp ); - break; -#endif - default: - length = -1; - break; - } - - return length; -} - -/* -============ -FS_RawTell -============ -*/ -int FS_RawTell( fileHandle_t f ) { - fsFile_t *file = FS_FileForHandle( f ); - int length; - - switch( file->type ) { - case FS_REAL: - length = ftell( file->fp ); - break; - case FS_PAK: - length = ftell( file->fp ) - file->pak->filepos; - break; -#if USE_ZLIB - case FS_GZIP: - length = ftell( file->fp ); - break; - case FS_PK2: - length = unztell( file->zfp ); - break; -#endif - default: - length = -1; - break; - } - - return length; -} #define MAX_LOAD_BUFFER 0x100000 // 1 MiB diff --git a/source/files.h b/source/files.h index 319e5e7..6fdf983 100644 --- a/source/files.h +++ b/source/files.h @@ -107,8 +107,8 @@ size_t FS_ReadLine( fileHandle_t f, char *buffer, int size ); void FS_Flush( fileHandle_t f ); -int FS_Tell( fileHandle_t f ); -int FS_RawTell( fileHandle_t f ); +size_t FS_Tell( fileHandle_t f ); +qboolean FS_Seek( fileHandle_t f, size_t offset ); size_t FS_GetFileLength( fileHandle_t f ); diff --git a/source/mvd_client.c b/source/mvd_client.c index 6b6c45d..859227e 100644 --- a/source/mvd_client.c +++ b/source/mvd_client.c @@ -22,9 +22,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // mvd_client.c -- MVD/GTV client // -#include "sv_local.h" #include "mvd_local.h" #include "mvd_gtv.h" +#include "net_stream.h" #include <setjmp.h> #define GTV_DEFAULT_BACKOFF (5*1000) // 5 seconds @@ -74,8 +74,9 @@ typedef struct gtv_s { // demo related variables fileHandle_t demoplayback; - int demoloop; + int demoloop, demoskip; string_entry_t *demohead, *demoentry; + size_t demosize, demopos; } gtv_t; static const char *const gtv_states[GTV_NUM_STATES] = { @@ -104,7 +105,9 @@ int mvd_chanid; jmp_buf mvd_jmpbuf; +#if USE_CLIENT cvar_t *mvd_shownet; +#endif static qboolean mvd_active; @@ -181,6 +184,22 @@ void MVD_Destroyf( mvd_t *mvd, const char *fmt, ... ) { longjmp( mvd_jmpbuf, -1 ); } +#if USE_CLIENT +static mvd_t *find_local_channel( void ) { + mvd_client_t *client; + mvd_t *mvd; + + LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { + LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { + if( NET_IsLocalAddress( &client->cl->netchan->remote_address ) ) { + return mvd; + } + } + } + return NULL; +} +#endif + mvd_t *MVD_SetChannel( int arg ) { char *s = Cmd_Argv( arg ); mvd_t *mvd; @@ -199,18 +218,15 @@ mvd_t *MVD_SetChannel( int arg ) { return NULL; } +#if USE_CLIENT // special value of @@ returns the channel local client is on - if( !Com_IsDedicated() && !strcmp( s, "@@" ) ) { - LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { - mvd_client_t *client; - - LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { - if( NET_IsLocalAddress( &client->cl->netchan->remote_address ) ) { - return mvd; - } - } + if( !dedicated->integer && !strcmp( s, "@@" ) ) { + if( ( mvd = find_local_channel() ) != NULL ) { + return mvd; } - } else if( COM_IsUint( s ) ) { + } else +#endif + if( COM_IsUint( s ) ) { id = atoi( s ); LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { if( mvd->id == id ) { @@ -254,7 +270,6 @@ void MVD_CheckActive( mvd_t *mvd ) { } } - /* ==================================================================== @@ -372,8 +387,8 @@ int MVD_Frame( void ) { Com_DPrintf( "Resuming MVD streams.\n" ); mvd_active = qtrue; } - } else if( svs.realtime - prevtime > delta ) { - if( mvd_active ) { + } else if( mvd_active ) { + if( svs.realtime - prevtime > delta ) { Com_DPrintf( "Suspending MVD streams.\n" ); mvd_active = qfalse; } @@ -383,6 +398,7 @@ int MVD_Frame( void ) { // run all GTV connections (but not demos) LIST_FOR_EACH_SAFE( gtv_t, gtv, next, &mvd_gtv_list, entry ) { if( setjmp( mvd_jmpbuf ) ) { + SZ_Clear( &msg_write ); continue; } @@ -394,6 +410,27 @@ int MVD_Frame( void ) { return connections; } +#if USE_CLIENT +int MVD_GetDemoPercent( void ) { + mvd_t *mvd; + gtv_t *gtv; + + if( ( mvd = find_local_channel() ) == NULL ) { + return -1; + } + if( ( gtv = mvd->gtv ) == NULL ) { + return -1; + } + + if( !gtv->demoplayback ) { + return -1; + } + if( !gtv->demosize ) { + return -1; + } + return gtv->demopos * 100 / gtv->demosize; +} +#endif /* ==================================================================== @@ -405,23 +442,58 @@ DEMO PLAYER static void demo_play_next( gtv_t *gtv, string_entry_t *entry ); -static qboolean demo_read_message( fileHandle_t f ) { - size_t ret; +static size_t demo_read_msglen( fileHandle_t f ) { uint16_t msglen; - ret = FS_Read( &msglen, 2, f ); - if( ret != 2 ) { - return qfalse; + if( FS_Read( &msglen, 2, f ) != 2 ) { + return 0; } if( !msglen ) { - return qfalse; + return 0; } msglen = LittleShort( msglen ); if( msglen > MAX_MSGLEN ) { + return 0; + } + return msglen; +} + +static qboolean demo_skip_map( fileHandle_t f ) { + size_t msglen; + + while( 1 ) { + if( ( msglen = demo_read_msglen( f ) ) == 0 ) { + return qfalse; + } + if( FS_Read( msg_read_buffer, 1, f ) != 1 ) { + return qfalse; + } + if( msg_read_buffer[0] == mvd_serverdata ) { + break; + } + if( !FS_Seek( f, msglen - 1 ) ) { + return qfalse; + } + } + + if( FS_Read( msg_read_buffer + 1, msglen - 1, f ) != msglen - 1 ) { return qfalse; } - ret = FS_Read( msg_read_buffer, msglen, f ); - if( ret != msglen ) { + + SZ_Init( &msg_read, msg_read_buffer, sizeof( msg_read_buffer ) ); + msg_read.cursize = msglen; + + return qtrue; +} + +static qboolean demo_read_message( fileHandle_t f ) { + size_t msglen; + + if( ( msglen = demo_read_msglen( f ) ) == 0 ) { + return qfalse; + } + + if( FS_Read( msg_read_buffer, msglen, f ) != msglen ) { return qfalse; } @@ -433,6 +505,7 @@ static qboolean demo_read_message( fileHandle_t f ) { static qboolean demo_read_frame( mvd_t *mvd ) { gtv_t *gtv = mvd->gtv; + int count; if( mvd->state == MVD_WAITING ) { return qfalse; // paused by user @@ -441,13 +514,31 @@ static qboolean demo_read_frame( mvd_t *mvd ) { MVD_Destroyf( mvd, "End of MVD stream reached" ); } - if( !demo_read_message( gtv->demoplayback ) ) { - demo_play_next( gtv, gtv->demoentry->next ); - return qtrue; + count = gtv->demoskip; + gtv->demoskip = 0; + + if( count ) { + do { + if( !demo_skip_map( gtv->demoplayback ) ) { + goto next; + } + } while( --count ); + } else { + if( !demo_read_message( gtv->demoplayback ) ) { + goto next; + } + } + + if( gtv->demosize ) { + gtv->demopos = FS_Tell( gtv->demoplayback ); } MVD_ParseMessage( mvd ); return qtrue; + +next: + demo_play_next( gtv, gtv->demoentry->next ); + return qtrue; } static void demo_play_next( gtv_t *gtv, string_entry_t *entry ) { @@ -501,6 +592,8 @@ static void demo_play_next( gtv_t *gtv, string_entry_t *entry ) { gtv->mvd->read_frame = demo_read_frame; } + Com_Printf( "[%s] -=- Reading from %s\n", gtv->name, entry->string ); + // parse gamestate MVD_ParseMessage( gtv->mvd ); if( !gtv->mvd->state ) { @@ -509,13 +602,17 @@ static void demo_play_next( gtv_t *gtv, string_entry_t *entry ) { gtv->mvd->state = MVD_READING; - Com_Printf( "[%s] Reading from %s\n", gtv->name, entry->string ); - // reset state gtv->demoentry = entry; // set channel address Q_strlcpy( gtv->address, COM_SkipPath( entry->string ), sizeof( gtv->address ) ); + + gtv->demosize = FS_GetFileLength( gtv->demoplayback ); + if( gtv->demosize == INVALID_LENGTH ) { + gtv->demosize = 0; + } + gtv->demopos = FS_Tell( gtv->demoplayback ); } static void demo_free_playlist( gtv_t *gtv ) { @@ -633,7 +730,8 @@ static void gtv_wait_start( mvd_t *mvd ) { // send ping to force server to flush write_message( gtv, GTC_PING ); } else { - // this is a `normal' underflow, reset delay to default + // channel is expected to underflow after suspend, + // reset delay to default mvd->min_packets = tr; mvd->underflows = 0; } @@ -693,17 +791,17 @@ static qboolean gtv_forward_cmd( mvd_client_t *client ) { size_t len; if( !gtv || gtv->state < GTV_CONNECTED ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Not connected to the game server.\n" ); return qfalse; } if( !( gtv->flags & GTF_STRINGCMDS ) ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Game server does not allow command forwarding.\n" ); return qfalse; } if( FIFO_Usage( >v->stream.send ) ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Send buffer not empty, please wait.\n" ); return qfalse; } @@ -889,7 +987,7 @@ static void parse_stream_data( gtv_t *gtv ) { return; } - // non-empty data part act as stream resume marker + // non-empty data part acts as stream resume marker if( gtv->state == GTV_WAITING ) { Com_Printf( "[%s] -=- Stream resumed by server.\n", gtv->name ); gtv->state = GTV_READING; @@ -1138,12 +1236,14 @@ static neterr_t run_stream( gtv_t *gtv ) { count++; } +#if USE_CLIENT if( mvd_shownet->integer == -1 ) { size_t total = usage - FIFO_Usage( >v->stream.recv ); Com_Printf( "[%s] %"PRIz" bytes, %d msgs\n", gtv->name, total, count ); } +#endif return NET_OK; } @@ -1712,6 +1812,29 @@ static void MVD_Pause_f( void ) { } } +static void MVD_Skip_f( void ) { + mvd_t *mvd; + int count; + + mvd = MVD_SetChannel( 1 ); + if( !mvd ) { + Com_Printf( "Usage: %s [chan_id] [count]\n", Cmd_Argv( 0 ) ); + return; + } + + count = atoi( Cmd_Argv( 2 ) ); + if( count < 1 ) { + count = 1; + } + + if( !mvd->gtv || !mvd->gtv->demoplayback ) { + Com_Printf( "[%s] Maps can be skipped only on demo channels.\n", mvd->name ); + return; + } + + mvd->gtv->demoskip = count; +} + static void MVD_Control_f( void ) { static const cmd_option_t options[] = { { "h", "help", "display this message" }, @@ -1896,7 +2019,6 @@ static void MVD_Play_f( void ) { // set new playlist gtv->demohead = head; - gtv->demoloop = loop; demo_play_next( gtv, head ); } @@ -1940,6 +2062,7 @@ static const cmdreg_t c_mvd[] = { { "mvdservers", MVD_ListServers_f }, { "mvdcontrol", MVD_Control_f }, { "mvdpause", MVD_Pause_f }, + { "mvdskip", MVD_Skip_f }, { NULL } }; @@ -1951,7 +2074,9 @@ MVD_Register ============== */ void MVD_Register( void ) { +#if USE_CLIENT mvd_shownet = Cvar_Get( "mvd_shownet", "0", 0 ); +#endif mvd_timeout = Cvar_Get( "mvd_timeout", "90", 0 ); mvd_suspend_time = Cvar_Get( "mvd_suspend_time", "5", 0 ); mvd_wait_delay = Cvar_Get( "mvd_wait_delay", "20", 0 ); diff --git a/source/mvd_game.c b/source/mvd_game.c index f795bbc..9fc5e5f 100644 --- a/source/mvd_game.c +++ b/source/mvd_game.c @@ -22,20 +22,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // mvd_game.c // -#include "sv_local.h" #include "mvd_local.h" #include <setjmp.h> -static cvar_t *mvd_admin_password; -static cvar_t *mvd_flood_msgs; -static cvar_t *mvd_flood_persecond; -static cvar_t *mvd_flood_waitdelay; -static cvar_t *mvd_flood_mute; -static cvar_t *mvd_filter_version; -static cvar_t *mvd_stats_score; -static cvar_t *mvd_stats_hack; -static cvar_t *mvd_freeze_hack; -static cvar_t *mvd_chase_prefix; +static cvar_t *mvd_admin_password; +static cvar_t *mvd_flood_msgs; +static cvar_t *mvd_flood_persecond; +static cvar_t *mvd_flood_waitdelay; +static cvar_t *mvd_flood_mute; +static cvar_t *mvd_filter_version; +static cvar_t *mvd_stats_score; +static cvar_t *mvd_stats_hack; +static cvar_t *mvd_freeze_hack; +static cvar_t *mvd_chase_prefix; mvd_client_t *mvd_clients; @@ -56,13 +55,13 @@ LAYOUTS static void MVD_LayoutClients( mvd_client_t *client ) { static const char header[] = "xv 16 yv 0 string2 \" Name RTT Status\""; - char layout[MAX_STRING_CHARS]; - char buffer[MAX_QPATH]; - char status[MAX_QPATH]; - size_t len, total; - mvd_client_t *cl; + char layout[MAX_STRING_CHARS]; + char buffer[MAX_QPATH]; + char status[MAX_QPATH]; + size_t len, total; + mvd_client_t *cl; mvd_t *mvd = client->mvd; - int y, i, prestep, flags; + int y, i, prestep, flags; // calculate prestep if( client->layout_cursor < 0 ) { @@ -77,36 +76,36 @@ static void MVD_LayoutClients( mvd_client_t *client ) { prestep = client->layout_cursor * 10; memcpy( layout, header, sizeof( header ) - 1 ); - total = sizeof( header ) - 1; + total = sizeof( header ) - 1; - y = 8; + y = 8; i = 0; LIST_FOR_EACH( mvd_client_t, cl, &mvd->clients, entry ) { if( ++i < prestep ) { continue; } - if( cl->cl->state < cs_spawned ) { + if( cl->cl->state < cs_spawned ) { continue; } if( cl->target ) { - strcpy( status, "-> " ); + strcpy( status, "-> " ); strcpy( status + 3, cl->target->name ); } else { strcpy( status, "observing" ); } - len = Q_snprintf( buffer, sizeof( buffer ), - "yv %d string \"%3d %-15.15s %3d %s\"", - y, i, cl->cl->name, cl->ping, status ); + len = Q_snprintf( buffer, sizeof( buffer ), + "yv %d string \"%3d %-15.15s %3d %s\"", + y, i, cl->cl->name, cl->ping, status ); if( len >= sizeof( buffer ) ) { continue; } - if( total + len >= sizeof( layout ) ) { - break; - } - memcpy( layout + total, buffer, len ); - total += len; - y += 8; - } + if( total + len >= sizeof( layout ) ) { + break; + } + memcpy( layout + total, buffer, len ); + total += len; + y += 8; + } layout[total] = 0; @@ -117,11 +116,11 @@ static void MVD_LayoutClients( mvd_client_t *client ) { } // send the layout - MSG_WriteByte( svc_layout ); - MSG_WriteData( layout, total + 1 ); - SV_ClientAddMessage( client->cl, flags ); + MSG_WriteByte( svc_layout ); + MSG_WriteData( layout, total + 1 ); + SV_ClientAddMessage( client->cl, flags ); - client->layout_time = svs.realtime; + client->layout_time = svs.realtime; } static void MVD_LayoutChannels( mvd_client_t *client ) { @@ -136,11 +135,11 @@ static void MVD_LayoutChannels( mvd_client_t *client ) { "yv 80 string \" Please wait until players\"" "yv 88 string \" connect.\"" ; - char layout[MAX_STRING_CHARS]; - char buffer[MAX_QPATH]; + char layout[MAX_STRING_CHARS]; + char buffer[MAX_QPATH]; mvd_t *mvd; - size_t len, total; - int cursor, y; + size_t len, total; + int cursor, y; memcpy( layout, header, sizeof( header ) - 1 ); total = sizeof( header ) - 1; @@ -188,11 +187,11 @@ static void MVD_LayoutChannels( mvd_client_t *client ) { layout[total] = 0; // send the layout - MSG_WriteByte( svc_layout ); - MSG_WriteData( layout, total + 1 ); - SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); + MSG_WriteByte( svc_layout ); + MSG_WriteData( layout, total + 1 ); + SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); - client->layout_time = svs.realtime; + client->layout_time = svs.realtime; } #define MENU_ITEMS 10 @@ -215,7 +214,7 @@ static void MVD_LayoutMenu( mvd_client_t *client ) { "yv 128 string \" (use 'set uf %d u' in cfg)\"" "yv 144 string2 \"%cExit menu\"" "xv 240 yv 172 string2 " VERSION; - char layout[MAX_STRING_CHARS]; + char layout[MAX_STRING_CHARS]; char cur[MENU_ITEMS]; size_t total; @@ -240,11 +239,11 @@ static void MVD_LayoutMenu( mvd_client_t *client ) { cur[9] ); // send the layout - MSG_WriteByte( svc_layout ); - MSG_WriteData( layout, total + 1 ); - SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); + MSG_WriteByte( svc_layout ); + MSG_WriteData( layout, total + 1 ); + SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); - client->layout_time = svs.realtime; + client->layout_time = svs.realtime; } static void MVD_LayoutScores( mvd_client_t *client, const char *layout ) { @@ -261,11 +260,11 @@ static void MVD_LayoutScores( mvd_client_t *client, const char *layout ) { } // send the layout - MSG_WriteByte( svc_layout ); + MSG_WriteByte( svc_layout ); MSG_WriteString( layout ); - SV_ClientAddMessage( client->cl, flags ); + SV_ClientAddMessage( client->cl, flags ); - client->layout_time = svs.realtime; + client->layout_time = svs.realtime; } static void MVD_LayoutFollow( mvd_client_t *client ) { @@ -282,25 +281,25 @@ static void MVD_LayoutFollow( mvd_client_t *client ) { } // send the layout - MSG_WriteByte( svc_layout ); + MSG_WriteByte( svc_layout ); MSG_WriteData( layout, total + 1 ); - SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); + SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); - client->layout_time = svs.realtime; + client->layout_time = svs.realtime; } static void MVD_SetDefaultLayout( mvd_client_t *client ) { mvd_t *mvd = client->mvd; - if( mvd == &mvd_waitingRoom ) { - client->layout_type = LAYOUT_CHANNELS; - } else if( mvd->intermission ) { + if( mvd == &mvd_waitingRoom ) { + client->layout_type = LAYOUT_CHANNELS; + } else if( mvd->intermission ) { client->layout_type = LAYOUT_SCORES; - } else if( client->target ) { + } else if( client->target ) { client->layout_type = LAYOUT_FOLLOW; } else { - client->layout_type = LAYOUT_NONE; - } + client->layout_type = LAYOUT_NONE; + } // force an update client->layout_time = 0; @@ -320,7 +319,7 @@ static void MVD_UpdateLayouts( mvd_t *mvd ) { mvd_client_t *client; LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { - if( client->cl->state != cs_spawned ) { + if( client->cl->state != cs_spawned ) { continue; } client->ps.stats[STAT_LAYOUTS] = client->layout_type ? 1 : 0; @@ -382,21 +381,21 @@ CHASE CAMERA static void MVD_FollowStop( mvd_client_t *client ) { mvd_t *mvd = client->mvd; mvd_cs_t *cs; - int i; + int i; - client->ps.viewangles[ROLL] = 0; + client->ps.viewangles[ROLL] = 0; - for( i = 0; i < 3; i++ ) { - client->ps.pmove.delta_angles[i] = ANGLE2SHORT( + for( i = 0; i < 3; i++ ) { + client->ps.pmove.delta_angles[i] = ANGLE2SHORT( client->ps.viewangles[i] ) - client->lastcmd.angles[i]; - } + } - VectorClear( client->ps.kick_angles ); + VectorClear( client->ps.kick_angles ); Vector4Clear( client->ps.blend ); - client->ps.pmove.pm_flags = 0; - client->ps.pmove.pm_type = mvd->pm_type; - client->ps.rdflags = 0; - client->ps.gunindex = 0; + client->ps.pmove.pm_flags = 0; + client->ps.pmove.pm_type = mvd->pm_type; + client->ps.rdflags = 0; + client->ps.gunindex = 0; client->ps.fov = client->fov; for( cs = mvd->dummy->configstrings; cs; cs = cs->next ) { @@ -420,20 +419,20 @@ static void MVD_FollowStop( mvd_client_t *client ) { static void MVD_FollowStart( mvd_client_t *client, mvd_player_t *target ) { mvd_cs_t *cs; - if( client->target == target ) { - return; - } + if( client->target == target ) { + return; + } client->oldtarget = client->target; - client->target = target; + client->target = target; - // send delta configstrings + // send delta configstrings for( cs = target->configstrings; cs; cs = cs->next ) { MSG_WriteByte( svc_configstring ); MSG_WriteShort( cs->index ); MSG_WriteString( cs->string ); SV_ClientAddMessage( client->cl, MSG_RELIABLE|MSG_CLEAR ); - } + } SV_ClientPrintf( client->cl, PRINT_LOW, "[MVD] Chasing %s.\n", target->name ); @@ -443,8 +442,8 @@ static void MVD_FollowStart( mvd_client_t *client, mvd_player_t *target ) { static void MVD_FollowFirst( mvd_client_t *client ) { mvd_t *mvd = client->mvd; - mvd_player_t *target; - int i; + mvd_player_t *target; + int i; // pick up the first active player for( i = 0; i < mvd->maxclients; i++ ) { @@ -460,8 +459,8 @@ static void MVD_FollowFirst( mvd_client_t *client ) { static void MVD_FollowLast( mvd_client_t *client ) { mvd_t *mvd = client->mvd; - mvd_player_t *target; - int i; + mvd_player_t *target; + int i; // pick up the last active player for( i = 0; i < mvd->maxclients; i++ ) { @@ -477,7 +476,7 @@ static void MVD_FollowLast( mvd_client_t *client ) { static void MVD_FollowNext( mvd_client_t *client ) { mvd_t *mvd = client->mvd; - mvd_player_t *target = client->target; + mvd_player_t *target = client->target; if( !target ) { MVD_FollowFirst( client ); @@ -495,12 +494,12 @@ static void MVD_FollowNext( mvd_client_t *client ) { } } while( !target->inuse || target == mvd->dummy ); - MVD_FollowStart( client, target ); + MVD_FollowStart( client, target ); } static void MVD_FollowPrev( mvd_client_t *client ) { mvd_t *mvd = client->mvd; - mvd_player_t *target = client->target; + mvd_player_t *target = client->target; if( !target ) { MVD_FollowLast( client ); @@ -518,7 +517,7 @@ static void MVD_FollowPrev( mvd_client_t *client ) { } } while( !target->inuse || target == mvd->dummy ); - MVD_FollowStart( client, target ); + MVD_FollowStart( client, target ); } static mvd_player_t *MVD_MostFollowed( mvd_t *mvd ) { @@ -601,15 +600,15 @@ SPECTATOR COMMANDS */ void MVD_BroadcastPrintf( mvd_t *mvd, int level, int mask, const char *fmt, ... ) { - va_list argptr; - char text[MAX_STRING_CHARS]; + va_list argptr; + char text[MAX_STRING_CHARS]; size_t len; mvd_client_t *other; client_t *cl; - va_start( argptr, fmt ); - len = Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); + va_start( argptr, fmt ); + len = Q_vsnprintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); if( len >= sizeof( text ) ) { Com_WPrintf( "%s: overflow\n", __func__ ); @@ -632,14 +631,14 @@ void MVD_BroadcastPrintf( mvd_t *mvd, int level, int mask, const char *fmt, ... if( cl->state < cs_spawned ) { continue; } - if( level < cl->messagelevel ) { - continue; + if( level < cl->messagelevel ) { + continue; } if( other->uf & mask ) { continue; } - SV_ClientAddMessage( cl, MSG_RELIABLE ); - } + SV_ClientAddMessage( cl, MSG_RELIABLE ); + } SZ_Clear( &msg_write ); } @@ -658,7 +657,7 @@ static void MVD_SetServerState( client_t *cl, mvd_t *mvd ) { void MVD_SwitchChannel( mvd_client_t *client, mvd_t *mvd ) { client_t *cl = client->cl; - List_Remove( &client->entry ); + List_Remove( &client->entry ); List_Append( &mvd->clients, &client->entry ); client->mvd = mvd; client->begin_time = 0; @@ -700,7 +699,7 @@ static void MVD_Admin_f( mvd_client_t *client ) { if( client->admin ) { client->admin = qfalse; - SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Lost admin status.\n" ); + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Lost admin status.\n" ); return; } @@ -716,20 +715,20 @@ static void MVD_Admin_f( mvd_client_t *client ) { } client->admin = qtrue; - SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Granted admin status.\n" ); + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] Granted admin status.\n" ); } static void MVD_Forward_f( mvd_client_t *client ) { mvd_t *mvd = client->mvd; if( !client->admin ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] You don't have admin status.\n" ); return; } if( !mvd->forward_cmd ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "[MVD] This channel does not support command forwarding.\n" ); return; } @@ -909,14 +908,14 @@ static void MVD_Invuse_f( mvd_client_t *client ) { MVD_Observe_f( client ); return; case 1: - client->layout_type = LAYOUT_SCORES; + client->layout_type = LAYOUT_SCORES; break; case 2: - client->layout_type = LAYOUT_CLIENTS; + client->layout_type = LAYOUT_CLIENTS; client->layout_cursor = 0; break; case 3: - client->layout_type = LAYOUT_CHANNELS; + client->layout_type = LAYOUT_CHANNELS; client->layout_cursor = 0; break; case 4: @@ -959,9 +958,9 @@ static void MVD_Invuse_f( mvd_client_t *client ) { static void MVD_Join_f( mvd_client_t *client ) { mvd_t *mvd; - SV_BeginRedirect( RD_CLIENT ); + SV_BeginRedirect( RD_CLIENT ); mvd = MVD_SetChannel( 1 ); - Com_EndRedirect(); + Com_EndRedirect(); if( !mvd ) { return; @@ -1013,21 +1012,21 @@ static void mvd_channel_list_f( mvd_client_t *client ) { if( Cmd_Argc() > 1 ) { if( LIST_EMPTY( &mvd_channel_list ) ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "No ready channels.\n" ); return; } } else { if( LIST_EMPTY( &mvd_active_list ) ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "No active channels.\n" ); return; } } - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "id name map spc plr who is playing\n" - "-- ------------ -------- --- --- --------------\n" ); + "-- ------------ -------- --- --- --------------\n" ); if( Cmd_Argc() > 1 ) { LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { @@ -1048,7 +1047,7 @@ static void MVD_Clients_f( mvd_client_t *client ) { } static void MVD_Commands_f( mvd_client_t *client ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, + SV_ClientPrintf( client->cl, PRINT_HIGH, "chase [player_id] toggle chasecam mode\n" "observe toggle observer mode\n" "menu show main menu\n" @@ -1061,46 +1060,46 @@ static void MVD_Commands_f( mvd_client_t *client ) { } static void MVD_GameClientCommand( edict_t *ent ) { - mvd_client_t *client = EDICT_MVDCL( ent ); - char *cmd; + mvd_client_t *client = EDICT_MVDCL( ent ); + char *cmd; if( client->cl->state < cs_spawned ) { return; } - cmd = Cmd_Argv( 0 ); + cmd = Cmd_Argv( 0 ); - if( !strcmp( cmd, "!mvdadmin" ) ) { + if( !strcmp( cmd, "!mvdadmin" ) ) { MVD_Admin_f( client ); - return; - } - if( !strcmp( cmd, "fwd" ) ) { + return; + } + if( !strcmp( cmd, "fwd" ) ) { MVD_Forward_f( client ); return; } - if( !strcmp( cmd, "say" ) || !strcmp( cmd, "say_team" ) ) { + if( !strcmp( cmd, "say" ) || !strcmp( cmd, "say_team" ) ) { MVD_Say_f( client, 1 ); - return; - } - if( !strcmp( cmd, "follow" ) || !strcmp( cmd, "chase" ) ) { + return; + } + if( !strcmp( cmd, "follow" ) || !strcmp( cmd, "chase" ) ) { MVD_Follow_f( client ); - return; - } - if( !strcmp( cmd, "observe" ) ) { + return; + } + if( !strcmp( cmd, "observe" ) ) { MVD_Observe_f( client ); - return; - } - if( !strcmp( cmd, "inven" ) || !strcmp( cmd, "menu" ) ) { - if( client->layout_type == LAYOUT_MENU ) { - MVD_SetDefaultLayout( client ); - } else { - client->layout_type = LAYOUT_MENU; + return; + } + if( !strcmp( cmd, "inven" ) || !strcmp( cmd, "menu" ) ) { + if( client->layout_type == LAYOUT_MENU ) { + MVD_SetDefaultLayout( client ); + } else { + client->layout_type = LAYOUT_MENU; client->layout_time = 0; - } - return; - } - if( !strcmp( cmd, "invnext" ) ) { - if( client->layout_type >= LAYOUT_MENU ) { + } + return; + } + if( !strcmp( cmd, "invnext" ) ) { + if( client->layout_type >= LAYOUT_MENU ) { client->layout_cursor++; client->layout_time = 0; } else if( !client->mvd->intermission ) { @@ -1108,8 +1107,8 @@ static void MVD_GameClientCommand( edict_t *ent ) { } return; } - if( !strcmp( cmd, "invprev" ) ) { - if( client->layout_type >= LAYOUT_MENU ) { + if( !strcmp( cmd, "invprev" ) ) { + if( client->layout_type >= LAYOUT_MENU ) { client->layout_cursor--; client->layout_time = 0; } else if( !client->mvd->intermission ) { @@ -1117,49 +1116,49 @@ static void MVD_GameClientCommand( edict_t *ent ) { } return; } - if( !strcmp( cmd, "invuse" ) ) { + if( !strcmp( cmd, "invuse" ) ) { MVD_Invuse_f( client ); return; } - if( !strcmp( cmd, "help" ) || !strcmp( cmd, "score" ) ) { - if( client->layout_type == LAYOUT_SCORES ) { - MVD_SetDefaultLayout( client ); - } else { - client->layout_type = LAYOUT_SCORES; + if( !strcmp( cmd, "help" ) || !strcmp( cmd, "score" ) ) { + if( client->layout_type == LAYOUT_SCORES ) { + MVD_SetDefaultLayout( client ); + } else { + client->layout_type = LAYOUT_SCORES; client->layout_time = 0; - } - return; - } - if( !strcmp( cmd, "oldscore" ) ) { - if( client->layout_type == LAYOUT_OLDSCORES ) { - MVD_SetDefaultLayout( client ); - } else { - client->layout_type = LAYOUT_OLDSCORES; + } + return; + } + if( !strcmp( cmd, "oldscore" ) ) { + if( client->layout_type == LAYOUT_OLDSCORES ) { + MVD_SetDefaultLayout( client ); + } else { + client->layout_type = LAYOUT_OLDSCORES; client->layout_time = 0; - } + } return; } - if( !strcmp( cmd, "putaway" ) ) { - MVD_SetDefaultLayout( client ); - return; - } - if( !strcmp( cmd, "channels" ) ) { + if( !strcmp( cmd, "putaway" ) ) { + MVD_SetDefaultLayout( client ); + return; + } + if( !strcmp( cmd, "channels" ) ) { mvd_channel_list_f( client ); - return; - } - if( !strcmp( cmd, "clients" ) || !strcmp( cmd, "players" ) ) { + return; + } + if( !strcmp( cmd, "clients" ) || !strcmp( cmd, "players" ) ) { MVD_Clients_f( client ); - return; - } - if( !strcmp( cmd, "join" ) ) { + return; + } + if( !strcmp( cmd, "join" ) ) { MVD_Join_f( client ); return; } - if( !strcmp( cmd, "leave" ) ) { + if( !strcmp( cmd, "leave" ) ) { MVD_TrySwitchChannel( client, &mvd_waitingRoom ); return; } - if( !strcmp( cmd, "commands" ) ) { + if( !strcmp( cmd, "commands" ) ) { MVD_Commands_f( client ); return; } @@ -1176,13 +1175,13 @@ MISC GAME FUNCTIONS */ void MVD_RemoveClient( client_t *client ) { - int index = client - svs.udp_client_pool; - mvd_client_t *cl = &mvd_clients[index]; + int index = client - svs.udp_client_pool; + mvd_client_t *cl = &mvd_clients[index]; List_Remove( &cl->entry ); - memset( cl, 0, sizeof( *cl ) ); - cl->cl = client; + memset( cl, 0, sizeof( *cl ) ); + cl->cl = client; } static void MVD_GameInit( void ) { @@ -1192,16 +1191,16 @@ static void MVD_GameInit( void ) { char buffer[MAX_QPATH]; unsigned checksum; bsp_t *bsp; - int i; + int i; - Com_Printf( "----- MVD_GameInit -----\n" ); + Com_Printf( "----- MVD_GameInit -----\n" ); - mvd_admin_password = Cvar_Get( "mvd_admin_password", "", CVAR_PRIVATE ); - mvd_flood_msgs = Cvar_Get( "flood_msgs", "4", 0 ); - mvd_flood_persecond = Cvar_Get( "flood_persecond", "4", 0 ); // FIXME: rename this - mvd_flood_waitdelay = Cvar_Get( "flood_waitdelay", "10", 0 ); - mvd_flood_mute = Cvar_Get( "flood_mute", "0", 0 ); - mvd_filter_version = Cvar_Get( "mvd_filter_version", "0", 0 ); + mvd_admin_password = Cvar_Get( "mvd_admin_password", "", CVAR_PRIVATE ); + mvd_flood_msgs = Cvar_Get( "flood_msgs", "4", 0 ); + mvd_flood_persecond = Cvar_Get( "flood_persecond", "4", 0 ); // FIXME: rename this + mvd_flood_waitdelay = Cvar_Get( "flood_waitdelay", "10", 0 ); + mvd_flood_mute = Cvar_Get( "flood_mute", "0", 0 ); + mvd_filter_version = Cvar_Get( "mvd_filter_version", "0", 0 ); mvd_default_map = Cvar_Get( "mvd_default_map", "q2dm1", CVAR_LATCH ); mvd_stats_score = Cvar_Get( "mvd_stats_score", "0", 0 ); mvd_stats_hack = Cvar_Get( "mvd_stats_hack", "0", 0 ); @@ -1212,15 +1211,15 @@ static void MVD_GameInit( void ) { Z_TagReserve( ( sizeof( edict_t ) + sizeof( mvd_client_t ) ) * sv_maxclients->integer + sizeof( edict_t ), TAG_MVD ); - mvd_clients = Z_ReservedAllocz( sizeof( mvd_client_t ) * + mvd_clients = Z_ReservedAllocz( sizeof( mvd_client_t ) * sv_maxclients->integer ); edicts = Z_ReservedAllocz( sizeof( edict_t ) * ( sv_maxclients->integer + 1 ) ); - for( i = 0; i < sv_maxclients->integer; i++ ) { - mvd_clients[i].cl = &svs.udp_client_pool[i]; + for( i = 0; i < sv_maxclients->integer; i++ ) { + mvd_clients[i].cl = &svs.udp_client_pool[i]; edicts[i + 1].client = ( gclient_t * )&mvd_clients[i]; - } + } mvd_ge.edicts = edicts; mvd_ge.edict_size = sizeof( edict_t ); @@ -1261,15 +1260,15 @@ static void MVD_GameInit( void ) { mvd->servercount = sv.spawncount; // set serverinfo variables - SV_InfoSet( "mapname", mvd->mapname ); -// SV_InfoSet( "gamedir", "gtv" ); - SV_InfoSet( "gamename", "gtv" ); - SV_InfoSet( "gamedate", __DATE__ ); + SV_InfoSet( "mapname", mvd->mapname ); +// SV_InfoSet( "gamedir", "gtv" ); + SV_InfoSet( "gamename", "gtv" ); + SV_InfoSet( "gamedate", __DATE__ ); MVD_InfoSet( "channels", "0" ); } static void MVD_GameShutdown( void ) { - Com_Printf( "----- MVD_GameShutdown -----\n" ); + Com_Printf( "----- MVD_GameShutdown -----\n" ); MVD_Shutdown(); @@ -1293,7 +1292,7 @@ static void MVD_GameReadLevel( const char *filename ) { } static qboolean MVD_GameClientConnect( edict_t *ent, char *userinfo ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); mvd_t *mvd; int count; @@ -1311,34 +1310,34 @@ static qboolean MVD_GameClientConnect( edict_t *ent, char *userinfo ) { // override server state MVD_SetServerState( client->cl, mvd ); - return qtrue; + return qtrue; } static void MVD_GameClientBegin( edict_t *ent ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); mvd_t *mvd = client->mvd; mvd_player_t *target; - client->floodTime = 0; - client->floodHead = 0; - memset( &client->lastcmd, 0, sizeof( client->lastcmd ) ); - memset( &client->ps, 0, sizeof( client->ps ) ); + client->floodTime = 0; + client->floodHead = 0; + memset( &client->lastcmd, 0, sizeof( client->lastcmd ) ); + memset( &client->ps, 0, sizeof( client->ps ) ); client->jump_held = 0; client->layout_type = LAYOUT_NONE; client->layout_time = 0; client->layout_cursor = 0; - - if( !client->begin_time ) { - MVD_BroadcastPrintf( mvd, PRINT_MEDIUM, UF_MUTE_MISC, + + if( !client->begin_time ) { + MVD_BroadcastPrintf( mvd, PRINT_MEDIUM, UF_MUTE_MISC, "[MVD] %s entered the channel\n", client->cl->name ); target = MVD_MostFollowed( mvd ); - } else { + } else { target = client->target; } client->oldtarget = NULL; - client->begin_time = svs.realtime; + client->begin_time = svs.realtime; - MVD_SetDefaultLayout( client ); + MVD_SetDefaultLayout( client ); if( mvd->intermission ) { // force them to chase dummy MVD client @@ -1357,28 +1356,28 @@ static void MVD_GameClientBegin( edict_t *ent ) { } static void MVD_GameClientUserinfoChanged( edict_t *ent, char *userinfo ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); char *s; - float fov; + float fov; s = Info_ValueForKey( userinfo, "uf" ); client->uf = atoi( s ); s = Info_ValueForKey( userinfo, "fov" ); - fov = atof( s ); - if( fov < 1 ) { - fov = 90; - } else if( fov > 160 ) { - fov = 160; - } - client->fov = fov; + fov = atof( s ); + if( fov < 1 ) { + fov = 90; + } else if( fov > 160 ) { + fov = 160; + } + client->fov = fov; if( client->uf & UF_LOCALFOV ) { - client->ps.fov = fov; + client->ps.fov = fov; } } void MVD_GameClientNameChanged( edict_t *ent, const char *name ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); client_t *cl = client->cl; if( client->begin_time ) { @@ -1389,7 +1388,7 @@ void MVD_GameClientNameChanged( edict_t *ent, const char *name ) { // called early from SV_Drop to prevent multiple disconnect messages void MVD_GameClientDrop( edict_t *ent, const char *reason ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); client_t *cl = client->cl; if( client->begin_time ) { @@ -1400,13 +1399,13 @@ void MVD_GameClientDrop( edict_t *ent, const char *reason ) { } static void MVD_GameClientDisconnect( edict_t *ent ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); client_t *cl = client->cl; if( client->begin_time ) { - MVD_BroadcastPrintf( client->mvd, PRINT_MEDIUM, UF_MUTE_MISC, + MVD_BroadcastPrintf( client->mvd, PRINT_MEDIUM, UF_MUTE_MISC, "[MVD] %s disconnected\n", cl->name ); - client->begin_time = 0; + client->begin_time = 0; } } @@ -1426,33 +1425,33 @@ static int MVD_PointContents( vec3_t p ) { } static void MVD_GameClientThink( edict_t *ent, usercmd_t *cmd ) { - mvd_client_t *client = EDICT_MVDCL( ent ); + mvd_client_t *client = EDICT_MVDCL( ent ); usercmd_t *old = &client->lastcmd; - pmove_t pm; + pmove_t pm; - if( ( cmd->buttons & ~old->buttons ) & BUTTON_ATTACK ) { + if( ( cmd->buttons & ~old->buttons ) & BUTTON_ATTACK ) { MVD_Observe_f( client ); - } + } - if( client->target ) { - if( cmd->upmove >= 10 ) { + if( client->target ) { + if( cmd->upmove >= 10 ) { if( client->jump_held < 1 ) { if( !client->mvd->intermission ) { - MVD_FollowNext( client ); + MVD_FollowNext( client ); } client->jump_held = 1; } } else if( cmd->upmove <= -10 ) { if( client->jump_held > -1 ) { if( !client->mvd->intermission ) { - MVD_FollowPrev( client ); + MVD_FollowPrev( client ); } client->jump_held = -1; } - } else { + } else { client->jump_held = 0; } - } else { + } else { memset( &pm, 0, sizeof( pm ) ); pm.trace = MVD_Trace; pm.pointcontents = MVD_PointContents; @@ -1467,7 +1466,7 @@ static void MVD_GameClientThink( edict_t *ent, usercmd_t *cmd ) { } } - *old = *cmd; + *old = *cmd; } static void MVD_IntermissionStart( mvd_t *mvd ) { @@ -1562,7 +1561,7 @@ static void MVD_GameRunFrame( void ) { // write this message to demofile if( mvd->demorecording ) { uint16_t length = LittleShort( msg_read.cursize ); - FS_Write( &length, 2, mvd->demorecording ); + FS_Write( &length, 2, mvd->demorecording ); FS_Write( msg_read.data, msg_read.cursize, mvd->demorecording ); } @@ -1602,22 +1601,22 @@ void MVD_PrepWorldFrame( void ) { game_export_t mvd_ge = { - GAME_API_VERSION, - - MVD_GameInit, - MVD_GameShutdown, - MVD_GameSpawnEntities, - MVD_GameWriteGame, - MVD_GameReadGame, - MVD_GameWriteLevel, - MVD_GameReadLevel, - MVD_GameClientConnect, - MVD_GameClientBegin, - MVD_GameClientUserinfoChanged, - MVD_GameClientDisconnect, - MVD_GameClientCommand, - MVD_GameClientThink, - MVD_GameRunFrame, - MVD_GameServerCommand + GAME_API_VERSION, + + MVD_GameInit, + MVD_GameShutdown, + MVD_GameSpawnEntities, + MVD_GameWriteGame, + MVD_GameReadGame, + MVD_GameWriteLevel, + MVD_GameReadLevel, + MVD_GameClientConnect, + MVD_GameClientBegin, + MVD_GameClientUserinfoChanged, + MVD_GameClientDisconnect, + MVD_GameClientCommand, + MVD_GameClientThink, + MVD_GameRunFrame, + MVD_GameServerCommand }; diff --git a/source/mvd_local.h b/source/mvd_local.h index 2442a1d..c6821a8 100644 --- a/source/mvd_local.h +++ b/source/mvd_local.h @@ -18,6 +18,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "sv_local.h" +#include "q_fifo.h" + #define MVD_Malloc( size ) Z_TagMalloc( size, TAG_MVD ) #define MVD_Mallocz( size ) Z_TagMallocz( size, TAG_MVD ) #define MVD_CopyString( s ) Z_TagCopyString( s, TAG_MVD ) @@ -158,7 +161,9 @@ extern list_t mvd_active_list; extern mvd_t mvd_waitingRoom; extern qboolean mvd_dirty; +#if USE_CLIENT extern cvar_t *mvd_shownet; +#endif void MVD_Destroyf( mvd_t *mvd, const char *fmt, ... ) q_noreturn q_printf( 2, 3 ); diff --git a/source/mvd_parse.c b/source/mvd_parse.c index a0f9070..2f6dd83 100644 --- a/source/mvd_parse.c +++ b/source/mvd_parse.c @@ -22,11 +22,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // mvd_parse.c // -#include "sv_local.h" #include "mvd_local.h" +#if USE_CLIENT + #define MVD_ShowSVC( cmd ) \ - Com_Printf( "%3"PRIz":%s\n", msg_read.readcount - 1, \ + Com_Printf( "%3"PRIz":%s\n", msg_read.readcount - 1, \ MVD_ServerCommandString( cmd ) ) static const char mvd_strings[mvd_num_types][20] = { @@ -38,14 +39,14 @@ static const char mvd_strings[mvd_num_types][20] = { "mvd_configstring", "mvd_frame", "mvd_frame_nodelta", - "mvd_unicast", + "mvd_unicast", "mvd_unicast_r", - "mvd_multicast_all", - "mvd_multicast_pvs", - "mvd_multicast_phs", - "mvd_multicast_all_r", - "mvd_multicast_pvs_r", - "mvd_multicast_phs_r", + "mvd_multicast_all", + "mvd_multicast_pvs", + "mvd_multicast_phs", + "mvd_multicast_all_r", + "mvd_multicast_pvs_r", + "mvd_multicast_phs_r", "mvd_sound", "mvd_print", "mvd_stufftext" @@ -59,214 +60,216 @@ static const char *MVD_ServerCommandString( int cmd ) { } else if( cmd >= 0 && cmd < mvd_num_types ) { s = mvd_strings[cmd]; } else { - s = "UNKNOWN COMMAND"; - } + s = "UNKNOWN COMMAND"; + } return s; } +#endif // USE_CLIENT + static void MVD_LinkEdict( mvd_t *mvd, edict_t *ent ) { - int index; - mmodel_t *cm; - int x, zd, zu; - bsp_t *cache = mvd->cm.cache; + int index; + mmodel_t *cm; + int x, zd, zu; + bsp_t *cache = mvd->cm.cache; - if( !cache ) { - return; - } + if( !cache ) { + return; + } - if( ent->s.solid == 31 ) { - index = ent->s.modelindex; - if( index < 1 || index > cache->nummodels ) { - Com_WPrintf( "%s: entity %d: bad inline model index: %d\n", - __func__, ent->s.number, index ); - return; - } - cm = &cache->models[ index - 1 ]; - VectorCopy( cm->mins, ent->mins ); - VectorCopy( cm->maxs, ent->maxs ); + if( ent->s.solid == 31 ) { + index = ent->s.modelindex; + if( index < 1 || index > cache->nummodels ) { + Com_WPrintf( "%s: entity %d: bad inline model index: %d\n", + __func__, ent->s.number, index ); + return; + } + cm = &cache->models[ index - 1 ]; + VectorCopy( cm->mins, ent->mins ); + VectorCopy( cm->maxs, ent->maxs ); ent->solid = SOLID_BSP; - } else if( ent->s.solid ) { - x = 8 * ( ent->s.solid & 31 ); - zd = 8 * ( ( ent->s.solid >> 5 ) & 31 ); - zu = 8 * ( ( ent->s.solid >> 10 ) & 63 ) - 32; - - ent->mins[0] = ent->mins[1] = -x; - ent->maxs[0] = ent->maxs[1] = x; - ent->mins[2] = -zd; - ent->maxs[2] = zu; + } else if( ent->s.solid ) { + x = 8 * ( ent->s.solid & 31 ); + zd = 8 * ( ( ent->s.solid >> 5 ) & 31 ); + zu = 8 * ( ( ent->s.solid >> 10 ) & 63 ) - 32; + + ent->mins[0] = ent->mins[1] = -x; + ent->maxs[0] = ent->maxs[1] = x; + ent->mins[2] = -zd; + ent->maxs[2] = zu; ent->solid = SOLID_BBOX; - } else { - VectorClear( ent->mins ); - VectorClear( ent->maxs ); + } else { + VectorClear( ent->mins ); + VectorClear( ent->maxs ); ent->solid = SOLID_NOT; - } + } SV_LinkEdict( &mvd->cm, ent ); } void MVD_ParseEntityString( mvd_t *mvd, const char *data ) { - const char *p; - char key[MAX_STRING_CHARS]; - char value[MAX_STRING_CHARS]; - char classname[MAX_QPATH]; - vec3_t origin; - vec3_t angles; - - while( data ) { - p = COM_Parse( &data ); - if( !p[0] ) { - break; - } - if( p[0] != '{' ) { - Com_Error( ERR_DROP, "expected '{', found '%s'", p ); - } - - classname[0] = 0; - VectorClear( origin ); - VectorClear( angles ); - while( 1 ) { - p = COM_Parse( &data ); - if( p[0] == '}' ) { - break; - } - if( p[0] == '{' ) { - Com_Error( ERR_DROP, "expected key, found '{'" ); - } - - Q_strlcpy( key, p, sizeof( key ) ); - - p = COM_Parse( &data ); - if( !data ) { - Com_Error( ERR_DROP, "expected key/value pair, found EOF" ); - } - if( p[0] == '}' || p[0] == '{' ) { - Com_Error( ERR_DROP, "expected value, found '%s'", p ); - } - - if( !strcmp( key, "classname" ) ) { - Q_strlcpy( classname, p, sizeof( classname ) ); - continue; - } - - Q_strlcpy( value, p, sizeof( value ) ); - - p = value; - if( !strcmp( key, "origin" ) ) { - origin[0] = atof( COM_Parse( &p ) ); - origin[1] = atof( COM_Parse( &p ) ); - origin[2] = atof( COM_Parse( &p ) ); - } else if( !strncmp( key, "angle", 5 ) ) { - if( key[5] == 0 ) { - angles[0] = 0; - angles[1] = atof( COM_Parse( &p ) ); - angles[2] = 0; - } else if( key[5] == 's' && key[6] == 0 ) { - angles[0] = atof( COM_Parse( &p ) ); - angles[1] = atof( COM_Parse( &p ) ); - angles[2] = atof( COM_Parse( &p ) ); - } - } - } - - if( !classname[0] ) { - Com_Error( ERR_DROP, "entity with no classname" ); - } - - if( strncmp( classname, "info_player_", 12 ) ) { - continue; - } - - if( !strcmp( classname + 12, "intermission" ) ) { - VectorCopy( origin, mvd->spawnOrigin ); - VectorCopy( angles, mvd->spawnAngles ); + const char *p; + char key[MAX_STRING_CHARS]; + char value[MAX_STRING_CHARS]; + char classname[MAX_QPATH]; + vec3_t origin; + vec3_t angles; + + while( data ) { + p = COM_Parse( &data ); + if( !p[0] ) { + break; + } + if( p[0] != '{' ) { + Com_Error( ERR_DROP, "expected '{', found '%s'", p ); + } + + classname[0] = 0; + VectorClear( origin ); + VectorClear( angles ); + while( 1 ) { + p = COM_Parse( &data ); + if( p[0] == '}' ) { + break; + } + if( p[0] == '{' ) { + Com_Error( ERR_DROP, "expected key, found '{'" ); + } + + Q_strlcpy( key, p, sizeof( key ) ); + + p = COM_Parse( &data ); + if( !data ) { + Com_Error( ERR_DROP, "expected key/value pair, found EOF" ); + } + if( p[0] == '}' || p[0] == '{' ) { + Com_Error( ERR_DROP, "expected value, found '%s'", p ); + } + + if( !strcmp( key, "classname" ) ) { + Q_strlcpy( classname, p, sizeof( classname ) ); + continue; + } + + Q_strlcpy( value, p, sizeof( value ) ); + + p = value; + if( !strcmp( key, "origin" ) ) { + origin[0] = atof( COM_Parse( &p ) ); + origin[1] = atof( COM_Parse( &p ) ); + origin[2] = atof( COM_Parse( &p ) ); + } else if( !strncmp( key, "angle", 5 ) ) { + if( key[5] == 0 ) { + angles[0] = 0; + angles[1] = atof( COM_Parse( &p ) ); + angles[2] = 0; + } else if( key[5] == 's' && key[6] == 0 ) { + angles[0] = atof( COM_Parse( &p ) ); + angles[1] = atof( COM_Parse( &p ) ); + angles[2] = atof( COM_Parse( &p ) ); + } + } + } + + if( !classname[0] ) { + Com_Error( ERR_DROP, "entity with no classname" ); + } + + if( strncmp( classname, "info_player_", 12 ) ) { + continue; + } + + if( !strcmp( classname + 12, "intermission" ) ) { + VectorCopy( origin, mvd->spawnOrigin ); + VectorCopy( angles, mvd->spawnAngles ); break; - } - - if( !strcmp( classname + 12, "start" ) || + } + + if( !strcmp( classname + 12, "start" ) || !strcmp( classname + 12, "deathmatch" ) ) { - VectorCopy( origin, mvd->spawnOrigin ); - VectorCopy( angles, mvd->spawnAngles ); - } + VectorCopy( origin, mvd->spawnOrigin ); + VectorCopy( angles, mvd->spawnAngles ); + } - } + } } static void MVD_ParseMulticast( mvd_t *mvd, mvd_ops_t op, int extrabits ) { - mvd_client_t *client; + mvd_client_t *client; client_t *cl; - byte mask[MAX_MAP_VIS]; - mleaf_t *leaf1, *leaf2; - vec3_t org; + byte mask[MAX_MAP_VIS]; + mleaf_t *leaf1, *leaf2; + vec3_t org; qboolean reliable = qfalse; - player_state_t *ps; + player_state_t *ps; byte *data; - int length, leafnum; + int length, leafnum; - length = MSG_ReadByte(); + length = MSG_ReadByte(); length |= extrabits << 8; - switch( op ) { - case mvd_multicast_all_r: - reliable = qtrue; + switch( op ) { + case mvd_multicast_all_r: + reliable = qtrue; // intentional fallthrough - case mvd_multicast_all: - leaf1 = NULL; - break; - case mvd_multicast_phs_r: - reliable = qtrue; + case mvd_multicast_all: + leaf1 = NULL; + break; + case mvd_multicast_phs_r: + reliable = qtrue; // intentional fallthrough - case mvd_multicast_phs: + case mvd_multicast_phs: leafnum = MSG_ReadShort(); - leaf1 = CM_LeafNum( &mvd->cm, leafnum ); - BSP_ClusterVis( mvd->cm.cache, mask, leaf1->cluster, DVIS_PHS ); - break; - case mvd_multicast_pvs_r: - reliable = qtrue; + leaf1 = CM_LeafNum( &mvd->cm, leafnum ); + BSP_ClusterVis( mvd->cm.cache, mask, leaf1->cluster, DVIS_PHS ); + break; + case mvd_multicast_pvs_r: + reliable = qtrue; // intentional fallthrough - case mvd_multicast_pvs: + case mvd_multicast_pvs: leafnum = MSG_ReadShort(); - leaf1 = CM_LeafNum( &mvd->cm, leafnum ); - BSP_ClusterVis( mvd->cm.cache, mask, leaf1->cluster, DVIS_PVS ); - break; - default: - MVD_Destroyf( mvd, "bad op" ); - } + leaf1 = CM_LeafNum( &mvd->cm, leafnum ); + BSP_ClusterVis( mvd->cm.cache, mask, leaf1->cluster, DVIS_PVS ); + break; + default: + MVD_Destroyf( mvd, "bad op" ); + } // skip data payload - data = msg_read.data + msg_read.readcount; - msg_read.readcount += length; - if( msg_read.readcount > msg_read.cursize ) { - MVD_Destroyf( mvd, "read past end of message" ); - } + data = msg_read.data + msg_read.readcount; + msg_read.readcount += length; + if( msg_read.readcount > msg_read.cursize ) { + MVD_Destroyf( mvd, "read past end of message" ); + } - // send the data to all relevent clients + // send the data to all relevent clients LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { cl = client->cl; if( cl->state < cs_primed ) { continue; } - // do not send unreliables to connecting clients - if( !reliable && ( cl->state != cs_spawned || cl->download || ( cl->flags & CF_NODATA ) ) ) { - continue; - } - - if( leaf1 ) { - // find the client's PVS - ps = &client->ps; - VectorMA( ps->viewoffset, 0.125f, ps->pmove.origin, org ); - leaf2 = CM_PointLeaf( &mvd->cm, org ); - if( !CM_AreasConnected( &mvd->cm, leaf1->area, leaf2->area ) ) - continue; - if( !Q_IsBitSet( mask, leaf2->cluster ) ) { - continue; - } - } - - cl->AddMessage( cl, data, length, reliable ); - } + // do not send unreliables to connecting clients + if( !reliable && ( cl->state != cs_spawned || cl->download || ( cl->flags & CF_NODATA ) ) ) { + continue; + } + + if( leaf1 ) { + // find the client's PVS + ps = &client->ps; + VectorMA( ps->viewoffset, 0.125f, ps->pmove.origin, org ); + leaf2 = CM_PointLeaf( &mvd->cm, org ); + if( !CM_AreasConnected( &mvd->cm, leaf1->area, leaf2->area ) ) + continue; + if( !Q_IsBitSet( mask, leaf2->cluster ) ) { + continue; + } + } + + cl->AddMessage( cl, data, length, reliable ); + } } static void MVD_UnicastSend( mvd_t *mvd, qboolean reliable, byte *data, size_t length, mvd_player_t *player ) { @@ -274,17 +277,17 @@ static void MVD_UnicastSend( mvd_t *mvd, qboolean reliable, byte *data, size_t l mvd_client_t *client; client_t *cl; - // send to all relevant clients + // send to all relevant clients LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { cl = client->cl; if( cl->state < cs_spawned ) { continue; } target = client->target ? client->target : mvd->dummy; - if( target == player ) { - cl->AddMessage( cl, data, length, reliable ); - } - } + if( target == player ) { + cl->AddMessage( cl, data, length, reliable ); + } + } } static void MVD_UnicastLayout( mvd_t *mvd, qboolean reliable, mvd_player_t *player ) { @@ -297,15 +300,15 @@ static void MVD_UnicastLayout( mvd_t *mvd, qboolean reliable, mvd_player_t *play MSG_ReadString( mvd->layout, sizeof( mvd->layout ) ); - // force an update to all relevant clients + // force an update to all relevant clients LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { if( client->cl->state < cs_spawned ) { continue; } - if( client->layout_type == LAYOUT_SCORES ) { + if( client->layout_type == LAYOUT_SCORES ) { client->layout_time = 0; - } - } + } + } } static void MVD_UnicastString( mvd_t *mvd, qboolean reliable, mvd_player_t *player ) { @@ -315,7 +318,7 @@ static void MVD_UnicastString( mvd_t *mvd, qboolean reliable, mvd_player_t *play byte *data; size_t readcount, length; - data = msg_read.data + msg_read.readcount - 1; + data = msg_read.data + msg_read.readcount - 1; readcount = msg_read.readcount - 1; index = MSG_ReadShort(); @@ -359,7 +362,7 @@ static void MVD_UnicastPrint( mvd_t *mvd, qboolean reliable, mvd_player_t *playe client_t *cl; mvd_player_t *target; - data = msg_read.data + msg_read.readcount - 1; + data = msg_read.data + msg_read.readcount - 1; readcount = msg_read.readcount - 1; level = MSG_ReadByte(); @@ -367,14 +370,14 @@ static void MVD_UnicastPrint( mvd_t *mvd, qboolean reliable, mvd_player_t *playe length = msg_read.readcount - readcount; - // send to all relevant clients + // send to all relevant clients LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { cl = client->cl; if( cl->state < cs_spawned ) { continue; } - if( level < cl->messagelevel ) { - continue; + if( level < cl->messagelevel ) { + continue; } if( level == PRINT_CHAT && ( client->uf & UF_MUTE_PLAYERS ) ) { continue; @@ -382,10 +385,10 @@ static void MVD_UnicastPrint( mvd_t *mvd, qboolean reliable, mvd_player_t *playe // decide if message should be routed or not target = ( mvd->flags & MVF_NOMSGS ) ? mvd->dummy : client->target ? client->target : mvd->dummy; - if( target == player ) { - cl->AddMessage( cl, data, length, reliable ); - } - } + if( target == player ) { + cl->AddMessage( cl, data, length, reliable ); + } + } } static void MVD_UnicastStuff( mvd_t *mvd, qboolean reliable, mvd_player_t *player ) { @@ -393,7 +396,7 @@ static void MVD_UnicastStuff( mvd_t *mvd, qboolean reliable, mvd_player_t *playe byte *data; size_t readcount, length; - data = msg_read.data + msg_read.readcount - 1; + data = msg_read.data + msg_read.readcount - 1; readcount = msg_read.readcount - 1; MSG_ReadString( string, sizeof( string ) ); @@ -412,64 +415,70 @@ Attempt to parse the datagram and find custom configstrings, layouts, etc. Give up as soon as unknown command byte is encountered. */ static void MVD_ParseUnicast( mvd_t *mvd, mvd_ops_t op, int extrabits ) { - int clientNum; - size_t length, last; - mvd_player_t *player; + int clientNum; + size_t length, last; + mvd_player_t *player; byte *data; qboolean reliable; - int cmd; + int cmd; - length = MSG_ReadByte(); + length = MSG_ReadByte(); length |= extrabits << 8; - clientNum = MSG_ReadByte(); + clientNum = MSG_ReadByte(); - if( clientNum < 0 || clientNum >= mvd->maxclients ) { - MVD_Destroyf( mvd, "%s: bad number: %d", __func__, clientNum ); - } + if( clientNum < 0 || clientNum >= mvd->maxclients ) { + MVD_Destroyf( mvd, "%s: bad number: %d", __func__, clientNum ); + } - last = msg_read.readcount + length; - if( last > msg_read.cursize ) { - MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); - } + last = msg_read.readcount + length; + if( last > msg_read.cursize ) { + MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); + } - player = &mvd->players[clientNum]; + player = &mvd->players[clientNum]; reliable = op == mvd_unicast_r ? qtrue : qfalse; - while( msg_read.readcount < last ) { + while( msg_read.readcount < last ) { cmd = MSG_ReadByte(); - if( mvd_shownet->integer > 1 ) { - MSG_ShowSVC( cmd ); - } - switch( cmd ) { - case svc_layout: +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + MSG_ShowSVC( cmd ); + } +#endif + switch( cmd ) { + case svc_layout: MVD_UnicastLayout( mvd, reliable, player ); - break; - case svc_configstring: + break; + case svc_configstring: MVD_UnicastString( mvd, reliable, player ); - break; - case svc_print: + break; + case svc_print: MVD_UnicastPrint( mvd, reliable, player ); - break; - case svc_stufftext: + break; + case svc_stufftext: MVD_UnicastStuff( mvd, reliable, player ); - break; - default: + break; + default: +#if USE_CLIENT if( mvd_shownet->integer > 1 ) { Com_Printf( "%"PRIz":SKIPPING UNICAST\n", msg_read.readcount - 1 ); } - // send remaining data and return +#endif + // send remaining data and return data = msg_read.data + msg_read.readcount - 1; length = last - msg_read.readcount + 1; MVD_UnicastSend( mvd, reliable, data, length, player ); - msg_read.readcount = last; - return; - } - } + msg_read.readcount = last; + return; + } + } - if( mvd_shownet->integer > 1 ) { - Com_Printf( "%"PRIz":END OF UNICAST\n", msg_read.readcount - 1 ); - } +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + Com_Printf( "%"PRIz":END OF UNICAST\n", msg_read.readcount - 1 ); + } +#endif if( msg_read.readcount > last ) { MVD_Destroyf( mvd, "%s: read past end of unicast", __func__ ); @@ -486,36 +495,36 @@ are able to postition sounds on BSP models properly. FIXME: this duplicates code in sv_game.c */ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) { - int flags, index; - int volume, attenuation, offset, sendchan; - int entnum; - vec3_t origin; - mvd_client_t *client; - client_t *cl; - byte mask[MAX_MAP_VIS]; - mleaf_t *leaf; - int area; - player_state_t *ps; - message_packet_t *msg; + int flags, index; + int volume, attenuation, offset, sendchan; + int entnum; + vec3_t origin; + mvd_client_t *client; + client_t *cl; + byte mask[MAX_MAP_VIS]; + mleaf_t *leaf; + int area; + player_state_t *ps; + message_packet_t *msg; edict_t *entity; int i; - flags = MSG_ReadByte(); - index = MSG_ReadByte(); + flags = MSG_ReadByte(); + index = MSG_ReadByte(); volume = attenuation = offset = 0; if( flags & SND_VOLUME ) - volume = MSG_ReadByte(); + volume = MSG_ReadByte(); if( flags & SND_ATTENUATION ) - attenuation = MSG_ReadByte(); + attenuation = MSG_ReadByte(); if( flags & SND_OFFSET ) - offset = MSG_ReadByte(); + offset = MSG_ReadByte(); - // entity relative - sendchan = MSG_ReadShort(); + // entity relative + sendchan = MSG_ReadShort(); entnum = sendchan >> 3; if( entnum < 0 || entnum >= MAX_EDICTS ) { - MVD_Destroyf( mvd, "%s: bad entnum: %d", __func__, entnum ); + MVD_Destroyf( mvd, "%s: bad entnum: %d", __func__, entnum ); } entity = &mvd->edicts[entnum]; @@ -527,10 +536,10 @@ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) { LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { cl = client->cl; - // do not send unreliables to connecting clients - if( cl->state != cs_spawned || cl->download || ( cl->flags & CF_NODATA ) ) { - continue; - } + // do not send unreliables to connecting clients + if( cl->state != cs_spawned || cl->download || ( cl->flags & CF_NODATA ) ) { + continue; + } // PHS cull this sound if( !( extrabits & 1 ) ) { @@ -543,10 +552,10 @@ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) { // doors can legally straddle two areas, so // we may need to check another one if( !entity->areanum2 || !CM_AreasConnected( &mvd->cm, area, entity->areanum2 ) ) { - continue; // blocked by a door + continue; // blocked by a door } } - BSP_ClusterVis( mvd->cm.cache, mask, leaf->cluster, DVIS_PHS ); + BSP_ClusterVis( mvd->cm.cache, mask, leaf->cluster, DVIS_PHS ); if( !SV_EdictPV( &mvd->cm, entity, mask ) ) { continue; // not in PHS } @@ -608,7 +617,7 @@ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) { List_Remove( &msg->entry ); List_Append( &cl->msg_used[0], &msg->entry ); cl->msg_bytes += MAX_SOUND_PACKET; - } + } } void MVD_FreePlayer( mvd_player_t *player ) { @@ -631,27 +640,27 @@ static void set_player_name( mvd_player_t *player, const char *string ) { } static void MVD_ParseConfigstring( mvd_t *mvd ) { - int index; - size_t len, maxlen; - char *string; - mvd_client_t *client; + int index; + size_t len, maxlen; + char *string; + mvd_client_t *client; mvd_player_t *player; mvd_cs_t *cs, **pcs; int i; - index = MSG_ReadShort(); - if( index < 0 || index >= MAX_CONFIGSTRINGS ) { - MVD_Destroyf( mvd, "%s: bad index: %d", __func__, index ); - } + index = MSG_ReadShort(); + if( index < 0 || index >= MAX_CONFIGSTRINGS ) { + MVD_Destroyf( mvd, "%s: bad index: %d", __func__, index ); + } string = mvd->configstrings[index]; maxlen = CS_SIZE( index ); len = MSG_ReadString( string, maxlen ); if( len >= maxlen ) { - MVD_Destroyf( mvd, "%s: index %d overflowed", __func__, index ); + MVD_Destroyf( mvd, "%s: index %d overflowed", __func__, index ); } - if( index >= CS_PLAYERSKINS && index < CS_PLAYERSKINS + mvd->maxclients ) { + if( index >= CS_PLAYERSKINS && index < CS_PLAYERSKINS + mvd->maxclients ) { // update player name player = &mvd->players[ index - CS_PLAYERSKINS ]; set_player_name( player, string ); @@ -680,19 +689,19 @@ static void MVD_ParseConfigstring( mvd_t *mvd ) { } } - MSG_WriteByte( svc_configstring ); - MSG_WriteShort( index ); - MSG_WriteData( string, len + 1 ); - + MSG_WriteByte( svc_configstring ); + MSG_WriteShort( index ); + MSG_WriteData( string, len + 1 ); + // broadcast configstring change LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { if( client->cl->state < cs_primed ) { continue; } - SV_ClientAddMessage( client->cl, MSG_RELIABLE ); - } + SV_ClientAddMessage( client->cl, MSG_RELIABLE ); + } - SZ_Clear( &msg_write ); + SZ_Clear( &msg_write ); } static void MVD_ParsePrint( mvd_t *mvd ) { @@ -713,7 +722,7 @@ extracting data from player state. static void MVD_PlayerToEntityStates( mvd_t *mvd ) { mvd_player_t *player; edict_t *edict; - int i; + int i; mvd->numplayers = 0; for( i = 1, player = mvd->players; i <= mvd->maxclients; i++, player++ ) { @@ -732,7 +741,7 @@ static void MVD_PlayerToEntityStates( mvd_t *mvd ) { continue; // not present in this frame } - VectorCopy( edict->s.origin, edict->s.old_origin ); + VectorCopy( edict->s.origin, edict->s.old_origin ); VectorScale( player->ps.pmove.origin, 0.125f, edict->s.origin ); VectorCopy( player->ps.viewangles, edict->s.angles ); @@ -747,8 +756,7 @@ static void MVD_PlayerToEntityStates( mvd_t *mvd ) { } } -#define RELINK_MASK (U_MODEL|U_ORIGIN1|U_ORIGIN2|U_ORIGIN3|U_SOLID) - +#define RELINK_MASK (U_MODEL|U_ORIGIN1|U_ORIGIN2|U_ORIGIN3|U_SOLID) /* ================== @@ -756,32 +764,34 @@ MVD_ParsePacketEntities ================== */ static void MVD_ParsePacketEntities( mvd_t *mvd ) { - int number; - int bits; - edict_t *ent; + int number; + int bits; + edict_t *ent; - while( 1 ) { - if( msg_read.readcount > msg_read.cursize ) { - MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); - } + while( 1 ) { + if( msg_read.readcount > msg_read.cursize ) { + MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); + } - number = MSG_ParseEntityBits( &bits ); - if( number < 0 || number >= MAX_EDICTS ) { - MVD_Destroyf( mvd, "%s: bad number: %d", __func__, number ); - } + number = MSG_ParseEntityBits( &bits ); + if( number < 0 || number >= MAX_EDICTS ) { + MVD_Destroyf( mvd, "%s: bad number: %d", __func__, number ); + } - if( !number ) { - break; - } + if( !number ) { + break; + } ent = &mvd->edicts[number]; +#if USE_CLIENT if( mvd_shownet->integer > 2 ) { - Com_Printf( " %s: %d ", ent->inuse ? + Com_Printf( " %s: %d ", ent->inuse ? "delta" : "baseline", number ); MSG_ShowDeltaEntityBits( bits ); Com_Printf( "\n" ); } +#endif MSG_ParseDeltaEntity( &ent->s, &ent->s, number, bits ); @@ -790,19 +800,21 @@ static void MVD_ParsePacketEntities( mvd_t *mvd ) { MVD_LinkEdict( mvd, ent ); } - if( bits & U_REMOVE ) { - if( mvd_shownet->integer > 2 ) { - Com_Printf( " remove: %d\n", number ); - } + if( bits & U_REMOVE ) { +#if USE_CLIENT + if( mvd_shownet->integer > 2 ) { + Com_Printf( " remove: %d\n", number ); + } +#endif ent->inuse = qfalse; - continue; - } + continue; + } ent->inuse = qtrue; if( number >= mvd->pool.num_edicts ) { mvd->pool.num_edicts = number + 1; } - } + } } /* @@ -811,44 +823,48 @@ MVD_ParsePacketPlayers ================== */ static void MVD_ParsePacketPlayers( mvd_t *mvd ) { - int number; - int bits; + int number; + int bits; mvd_player_t *player; - while( 1 ) { - if( msg_read.readcount > msg_read.cursize ) { - MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); - } + while( 1 ) { + if( msg_read.readcount > msg_read.cursize ) { + MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); + } - number = MSG_ReadByte(); - if( number == CLIENTNUM_NONE ) { - break; - } + number = MSG_ReadByte(); + if( number == CLIENTNUM_NONE ) { + break; + } - if( number < 0 || number >= mvd->maxclients ) { - MVD_Destroyf( mvd, "%s: bad number: %d", __func__, number ); - } + if( number < 0 || number >= mvd->maxclients ) { + MVD_Destroyf( mvd, "%s: bad number: %d", __func__, number ); + } player = &mvd->players[number]; - bits = MSG_ReadShort(); + bits = MSG_ReadShort(); +#if USE_CLIENT if( mvd_shownet->integer > 2 ) { - Com_Printf( " %s: %d ", player->inuse ? + Com_Printf( " %s: %d ", player->inuse ? "delta" : "baseline", number ); MSG_ShowDeltaPlayerstateBits_Packet( bits ); Com_Printf( "\n" ); } +#endif MSG_ParseDeltaPlayerstate_Packet( &player->ps, &player->ps, bits ); - if( bits & PPS_REMOVE ) { - if( mvd_shownet->integer > 2 ) { - Com_Printf( " remove: %d\n", number ); - } + if( bits & PPS_REMOVE ) { +#if USE_CLIENT + if( mvd_shownet->integer > 2 ) { + Com_Printf( " remove: %d\n", number ); + } +#endif player->inuse = qfalse; - continue; - } + continue; + } player->inuse = qtrue; } @@ -860,41 +876,47 @@ MVD_ParseFrame ================ */ static void MVD_ParseFrame( mvd_t *mvd ) { - int length; + int length; - // read portalbits - length = MSG_ReadByte(); - if( length ) { - if( length < 0 || msg_read.readcount + length > msg_read.cursize ) { + // read portalbits + length = MSG_ReadByte(); + if( length ) { + if( length < 0 || msg_read.readcount + length > msg_read.cursize ) { MVD_Destroyf( mvd, "%s: read past end of message", __func__ ); - } - if( length > MAX_MAP_AREAS/8 ) { + } + if( length > MAX_MAP_AREAS/8 ) { MVD_Destroyf( mvd, "%s: bad portalbits length: %d", __func__, length ); - } + } CM_SetPortalStates( &mvd->cm, msg_read.data + msg_read.readcount, length ); msg_read.readcount += length; - } else { + } else { CM_SetPortalStates( &mvd->cm, NULL, 0 ); - } + } - if( mvd_shownet->integer > 1 ) { - Com_Printf( "%3"PRIz":playerinfo\n", msg_read.readcount - 1 ); - } +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + Com_Printf( "%3"PRIz":playerinfo\n", msg_read.readcount - 1 ); + } +#endif - MVD_ParsePacketPlayers( mvd ); + MVD_ParsePacketPlayers( mvd ); - if( mvd_shownet->integer > 1 ) { - Com_Printf( "%3"PRIz":packetentities\n", msg_read.readcount - 1 ); - } +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + Com_Printf( "%3"PRIz":packetentities\n", msg_read.readcount - 1 ); + } +#endif - MVD_ParsePacketEntities( mvd ); + MVD_ParsePacketEntities( mvd ); - if( mvd_shownet->integer > 1 ) { - Com_Printf( "%3"PRIz":frame:%u\n", msg_read.readcount - 1, mvd->framenum ); - } +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + Com_Printf( "%3"PRIz":frame:%u\n", msg_read.readcount - 1, mvd->framenum ); + } +#endif - MVD_PlayerToEntityStates( mvd ); + MVD_PlayerToEntityStates( mvd ); mvd->framenum++; } @@ -962,18 +984,18 @@ static void MVD_ChangeLevel( mvd_t *mvd ) { } static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { - int protocol; + int protocol; size_t len, maxlen; - char *string; + char *string; int i, index; mvd_player_t *player; // clear the leftover from previous level MVD_ClearState( mvd ); - // parse major protocol version - protocol = MSG_ReadLong(); - if( protocol != PROTOCOL_VERSION_MVD ) { + // parse major protocol version + protocol = MSG_ReadLong(); + if( protocol != PROTOCOL_VERSION_MVD ) { MVD_Destroyf( mvd, "Unsupported protocol: %d", protocol ); } @@ -984,7 +1006,7 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { "Current version is %d.\n", protocol, PROTOCOL_VERSION_MVD_CURRENT ); } - mvd->servercount = MSG_ReadLong(); + mvd->servercount = MSG_ReadLong(); len = MSG_ReadString( mvd->gamedir, sizeof( mvd->gamedir ) ); if( len >= sizeof( mvd->gamedir ) ) { MVD_Destroyf( mvd, "Oversize gamedir string" ); @@ -993,7 +1015,7 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { mvd->flags = extrabits; #if 0 - // change gamedir unless playing a demo + // change gamedir unless playing a demo Cvar_UserSet( "game", mvd->gamedir ); if( FS_NeedRestart() ) { FS_Restart(); @@ -1061,7 +1083,7 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { memcpy( mvd->mapname, string + 5, len - 9 ); // skip "maps/" mvd->mapname[len - 9] = 0; // cut off ".bsp" - // load the world model (we are only interesed in visibility info) + // load the world model (we are only interesed in visibility info) Com_Printf( "[%s] -=- Loading %s...\n", mvd->name, string ); if( !CM_LoadMap( &mvd->cm, string ) ) { MVD_Destroyf( mvd, "Couldn't load %s: %s", string, BSP_GetError() ); @@ -1108,70 +1130,76 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { } void MVD_ParseMessage( mvd_t *mvd ) { - int cmd, extrabits; + int cmd, extrabits; - if( mvd_shownet->integer == 1 ) { - Com_Printf( "%"PRIz" ", msg_read.cursize ); - } else if( mvd_shownet->integer > 1 ) { - Com_Printf( "------------------\n" ); - } +#if USE_CLIENT + if( mvd_shownet->integer == 1 ) { + Com_Printf( "%"PRIz" ", msg_read.cursize ); + } else if( mvd_shownet->integer > 1 ) { + Com_Printf( "------------------\n" ); + } +#endif // // parse the message // - while( 1 ) { - if( msg_read.readcount > msg_read.cursize ) { + while( 1 ) { + if( msg_read.readcount > msg_read.cursize ) { MVD_Destroyf( mvd, "Read past end of message" ); - } - if( msg_read.readcount == msg_read.cursize ) { - if( mvd_shownet->integer > 1 ) { - Com_Printf( "%3"PRIz":END OF MESSAGE\n", msg_read.readcount - 1 ); - } - break; - } - - cmd = MSG_ReadByte(); + } + if( msg_read.readcount == msg_read.cursize ) { +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + Com_Printf( "%3"PRIz":END OF MESSAGE\n", msg_read.readcount - 1 ); + } +#endif + break; + } + + cmd = MSG_ReadByte(); extrabits = cmd >> SVCMD_BITS; cmd &= SVCMD_MASK; - if( mvd_shownet->integer > 1 ) { - MVD_ShowSVC( cmd ); - } +#if USE_CLIENT + if( mvd_shownet->integer > 1 ) { + MVD_ShowSVC( cmd ); + } +#endif - switch( cmd ) { - case mvd_serverdata: - MVD_ParseServerData( mvd, extrabits ); - break; - case mvd_multicast_all: - case mvd_multicast_pvs: + switch( cmd ) { + case mvd_serverdata: + MVD_ParseServerData( mvd, extrabits ); + break; + case mvd_multicast_all: + case mvd_multicast_pvs: case mvd_multicast_phs: - case mvd_multicast_all_r: + case mvd_multicast_all_r: case mvd_multicast_pvs_r: case mvd_multicast_phs_r: - MVD_ParseMulticast( mvd, cmd, extrabits ); - break; - case mvd_unicast: - case mvd_unicast_r: - MVD_ParseUnicast( mvd, cmd, extrabits ); - break; - case mvd_configstring: - MVD_ParseConfigstring( mvd ); - break; - case mvd_frame: - MVD_ParseFrame( mvd ); - break; - case mvd_sound: - MVD_ParseSound( mvd, extrabits ); - break; + MVD_ParseMulticast( mvd, cmd, extrabits ); + break; + case mvd_unicast: + case mvd_unicast_r: + MVD_ParseUnicast( mvd, cmd, extrabits ); + break; + case mvd_configstring: + MVD_ParseConfigstring( mvd ); + break; + case mvd_frame: + MVD_ParseFrame( mvd ); + break; + case mvd_sound: + MVD_ParseSound( mvd, extrabits ); + break; case mvd_print: MVD_ParsePrint( mvd ); break; case mvd_nop: break; - default: + default: MVD_Destroyf( mvd, "Illegible command at %"PRIz": %d", msg_read.readcount - 1, cmd ); - } - } + } + } } diff --git a/source/q_msg.c b/source/q_msg.c index c1ca775..16985dd 100644 --- a/source/q_msg.c +++ b/source/q_msg.c @@ -2359,6 +2359,8 @@ void MSG_ParseDeltaPlayerstate_Packet( const player_state_t *from, } +#if USE_CLIENT + #define SHOWBITS( data ) \ do { Com_Printf( "%s ", data ); } while( 0 ) @@ -2437,11 +2439,8 @@ void MSG_ShowDeltaEntityBits( int bits ) { if( bits & U_SOLID ) { SHOWBITS( "solid" ); } - } -#if USE_CLIENT - void MSG_ShowDeltaPlayerstateBits_Default( int flags ) { if( flags & PS_M_TYPE ) { SHOWBITS( "pmove.pm_type" ); @@ -2502,7 +2501,6 @@ void MSG_ShowDeltaPlayerstateBits_Default( int flags ) { if( flags & PS_RDFLAGS ) { SHOWBITS( "rdflags" ); } - } void MSG_ShowDeltaPlayerstateBits_Enhanced( int flags ) { @@ -2596,8 +2594,6 @@ void MSG_ShowDeltaPlayerstateBits_Enhanced( int flags ) { } } -#endif // USE_CLIENT - void MSG_ShowDeltaPlayerstateBits_Packet( int flags ) { if( flags & PPS_M_TYPE ) { SHOWBITS( "pmove.pm_type" ); @@ -2660,8 +2656,6 @@ void MSG_ShowDeltaPlayerstateBits_Packet( int flags ) { } } -#if USE_CLIENT - void MSG_ShowDeltaUsercmdBits_Enhanced( int bits ) { if( !bits ) { SHOWBITS( "<none>" ); @@ -2687,8 +2681,6 @@ void MSG_ShowDeltaUsercmdBits_Enhanced( int bits ) { SHOWBITS( "msec" ); } -#endif // USE_CLIENT - static const char *const svc_strings[svc_num_types] = { "svc_bad", @@ -2738,6 +2730,8 @@ const char *MSG_ServerCommandString( int cmd ) { return s; } +#endif // USE_CLIENT + //=========================================================================== void SZ_TagInit( sizebuf_t *buf, void *data, size_t length, uint32_t tag ) { diff --git a/source/q_msg.h b/source/q_msg.h index 1d0e227..10d8361 100644 --- a/source/q_msg.h +++ b/source/q_msg.h @@ -138,18 +138,16 @@ void MSG_ParseDeltaPlayerstate_Enhanced( const player_state_t *from, player_s #endif void MSG_ParseDeltaPlayerstate_Packet( const player_state_t *from, player_state_t *to, int flags ); -void MSG_ShowDeltaEntityBits( int bits ); #if USE_CLIENT +void MSG_ShowDeltaEntityBits( int bits ); void MSG_ShowDeltaPlayerstateBits_Default( int flags ); void MSG_ShowDeltaPlayerstateBits_Enhanced( int flags ); -#endif void MSG_ShowDeltaPlayerstateBits_Packet( int flags ); -#if USE_CLIENT void MSG_ShowDeltaUsercmdBits_Enhanced( int bits ); -#endif const char *MSG_ServerCommandString( int cmd ); #define MSG_ShowSVC( cmd ) \ Com_Printf( "%3"PRIz":%s\n", msg_read.readcount - 1, \ MSG_ServerCommandString( cmd ) ) +#endif // USE_CLIENT diff --git a/source/q_shared.c b/source/q_shared.c index dce4a17..f32ad5c 100644 --- a/source/q_shared.c +++ b/source/q_shared.c @@ -1407,22 +1407,14 @@ Q_strlcat =============== */ size_t Q_strlcat( char *dst, const char *src, size_t size ) { - size_t srclen = strlen( src ); - size_t dstlen = strlen( dst ); - size_t ret = srclen + dstlen; + size_t ret, len = strlen( dst ); - if( dstlen >= size ) { + if( len >= size ) { Com_Error( ERR_FATAL, "%s: already overflowed", __func__ ); } - size -= dstlen; - dst += dstlen; - - if( size ) { - size_t len = srclen >= size ? size - 1 : srclen; - memcpy( dst, src, len ); - dst[len] = 0; - } + ret = Q_strlcpy( dst + len, src, size - len ); + ret += len; return ret; } @@ -1432,32 +1424,26 @@ size_t Q_strlcat( char *dst, const char *src, size_t size ) { Q_concat =============== */ -size_t Q_concat( char *dest, size_t destsize, ... ) { +size_t Q_concat( char *dest, size_t size, ... ) { va_list argptr; const char *s; size_t len, total = 0; - va_start( argptr, destsize ); - - if( destsize ) { - while( ( s = va_arg( argptr, const char * ) ) != NULL ) { - len = strlen( s ); - if( total + len < destsize ) { - memcpy( dest, s, len ); - dest += len; - } - total += len; - } - *dest = 0; - } else { - while( ( s = va_arg( argptr, const char * ) ) != NULL ) { - len = strlen( s ); - total += len; + va_start( argptr, size ); + while( ( s = va_arg( argptr, const char * ) ) != NULL ) { + len = strlen( s ); + if( total + len < size ) { + memcpy( dest, s, len ); + dest += len; } + total += len; } - va_end( argptr ); + if( size ) { + *dest = 0; + } + return total; } @@ -1465,7 +1451,7 @@ size_t Q_concat( char *dest, size_t destsize, ... ) { =============== Q_vsnprintf -Work around broken M$ CRT semantics. +Work around broken M$ C runtime semantics. =============== */ size_t Q_vsnprintf( char *dest, size_t size, const char *fmt, va_list argptr ) { diff --git a/source/r_images.c b/source/r_images.c index 4c873bf..3f5eb50 100644 --- a/source/r_images.c +++ b/source/r_images.c @@ -610,8 +610,8 @@ JPEG LOADING #if USE_JPG typedef struct my_error_mgr { - struct jpeg_error_mgr pub; - jmp_buf setjmp_buffer; + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; const char *filename; } *my_error_ptr; @@ -768,8 +768,8 @@ JPEG WRITING typedef struct my_destination_mgr { struct jpeg_destination_mgr pub; /* public fields */ - fileHandle_t hFile; /* target stream */ - JOCTET *buffer; /* start of buffer */ + fileHandle_t hFile; /* target stream */ + JOCTET *buffer; /* start of buffer */ } *my_dest_ptr; @@ -1129,6 +1129,7 @@ IMAGE MANAGER #define RIMAGES_HASH 256 + image_t r_images[MAX_RIMAGES]; list_t r_imageHash[RIMAGES_HASH]; int r_numImages; @@ -1584,11 +1585,11 @@ IMG_ForHandle =============== */ image_t *IMG_ForHandle( qhandle_t h ) { - if( h < 0 || h >= r_numImages ) { - Com_Error( ERR_FATAL, "%s: %d out of range", __func__, h ); - } + if( h < 0 || h >= r_numImages ) { + Com_Error( ERR_FATAL, "%s: %d out of range", __func__, h ); + } - return &r_images[h]; + return &r_images[h]; } /* @@ -1597,14 +1598,17 @@ R_RegisterSkin =============== */ qhandle_t R_RegisterSkin( const char *name ) { - image_t *image; + image_t *image; - image = IMG_Find( name, it_skin ); - if( !image ) { - return 0; - } + if( !r_numImages ) { + return 0; + } + image = IMG_Find( name, it_skin ); + if( !image ) { + return 0; + } - return ( image - r_images ); + return ( image - r_images ); } /* @@ -1613,24 +1617,28 @@ R_RegisterPic ================ */ qhandle_t R_RegisterPic( const char *name ) { - image_t *image; - char fullname[MAX_QPATH]; + image_t *image; + char fullname[MAX_QPATH]; + + if( !r_numImages ) { + return 0; + } - if( name[0] == '*' ) { - image = IMG_Find( name + 1, it_tmp ); + if( name[0] == '*' ) { + image = IMG_Find( name + 1, it_tmp ); } else if( name[0] == '/' || name[0] == '\\' ) { - image = IMG_Find( name + 1, it_pic ); + image = IMG_Find( name + 1, it_pic ); } else { - Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); - COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); - image = IMG_Find( fullname, it_pic ); - } + Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); + COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); + image = IMG_Find( fullname, it_pic ); + } - if( !image ) { - return 0; - } + if( !image ) { + return 0; + } - return ( image - r_images ); + return ( image - r_images ); } /* @@ -1639,22 +1647,26 @@ R_RegisterFont ================ */ qhandle_t R_RegisterFont( const char *name ) { - image_t *image; - char fullname[MAX_QPATH]; + image_t *image; + char fullname[MAX_QPATH]; + + if( !r_numImages ) { + return 0; + } - if( name[0] == '/' || name[0] == '\\' ) { - image = IMG_Find( name + 1, it_charset ); + if( name[0] == '/' || name[0] == '\\' ) { + image = IMG_Find( name + 1, it_charset ); } else { - Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); - COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); - image = IMG_Find( fullname, it_charset ); - } + Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); + COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); + image = IMG_Find( fullname, it_charset ); + } - if( !image ) { - return 0; - } + if( !image ) { + return 0; + } - return ( image - r_images ); + return ( image - r_images ); } /* @@ -1672,7 +1684,7 @@ void IMG_FreeUnused( void ) { last = r_images + r_numImages; for( image = r_images; image < last; image++ ) { if( image->registration_sequence == registration_sequence ) { -#if SOFTWARE_RENDERER +#if USE_REF == REF_SOFT Com_PageInMemory( image->pixels[0], image->width * image->height * VID_BYTES ); #endif continue; // used this sequence @@ -1754,9 +1766,9 @@ void IMG_GetPalette( byte **pic ) { void IMG_Init( void ) { int i; - if( r_numImages ) { - Com_Error( ERR_FATAL, "%s: %d images not freed", __func__, r_numImages ); - } + if( r_numImages ) { + Com_Error( ERR_FATAL, "%s: %d images not freed", __func__, r_numImages ); + } #if USE_PNG || USE_JPG || USE_TGA diff --git a/source/sv_local.h b/source/sv_local.h index e39665c..9d7ea9c 100644 --- a/source/sv_local.h +++ b/source/sv_local.h @@ -31,9 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "pmove.h" #include "protocol.h" #include "q_msg.h" -#include "q_fifo.h" #include "net_sock.h" -#include "net_stream.h" #include "net_chan.h" #include "g_public.h" #include "sv_public.h" @@ -75,8 +73,6 @@ typedef struct { int clientNum; } client_frame_t; -#define PAUSED_FRAMES 10 - typedef struct { int solid32; } server_entity_t; @@ -345,8 +341,6 @@ typedef struct server_static_s { //============================================================================= -extern netadr_t net_from; - extern netadr_t master_adr[MAX_MASTERS]; // address of the master server extern list_t sv_banlist; @@ -367,7 +361,6 @@ extern cvar_t *sv_hostname; extern cvar_t *sv_maxclients; extern cvar_t *sv_password; extern cvar_t *sv_reserved_slots; -extern cvar_t *sv_noreload; // don't reload level state when reentering extern cvar_t *sv_airaccelerate; // development tool extern cvar_t *sv_qwmod; // atu QW Physics modificator extern cvar_t *sv_enforcetime; diff --git a/source/sv_main.c b/source/sv_main.c index c81bb4c..f386dbd 100644 --- a/source/sv_main.c +++ b/source/sv_main.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sv_local.h" -netadr_t master_adr[MAX_MASTERS]; // address of group servers +netadr_t master_adr[MAX_MASTERS]; // address of group servers pmoveParams_t sv_pmp; @@ -29,65 +29,64 @@ LIST_DECL( sv_cmdlist_connect ); LIST_DECL( sv_cmdlist_begin ); LIST_DECL( sv_filterlist ); -client_t *sv_client; // current client +client_t *sv_client; // current client -cvar_t *sv_enforcetime; +cvar_t *sv_enforcetime; -cvar_t *sv_timeout; // seconds without any message -cvar_t *sv_zombietime; // seconds to sink messages after disconnect -cvar_t *sv_ghostime; +cvar_t *sv_timeout; // seconds without any message +cvar_t *sv_zombietime; // seconds to sink messages after disconnect +cvar_t *sv_ghostime; -cvar_t *rcon_password; // password for remote server commands +cvar_t *rcon_password; // password for remote server commands cvar_t *sv_password; cvar_t *sv_reserved_password; -cvar_t *sv_force_reconnect; +cvar_t *sv_force_reconnect; cvar_t *sv_show_name_changes; -cvar_t *allow_download; -cvar_t *allow_download_players; -cvar_t *allow_download_models; -cvar_t *allow_download_sounds; -cvar_t *allow_download_maps; -cvar_t *allow_download_demos; -cvar_t *allow_download_other; - -cvar_t *sv_airaccelerate; -cvar_t *sv_qwmod; // atu QW Physics modificator -cvar_t *sv_noreload; // don't reload level state when reentering +cvar_t *allow_download; +cvar_t *allow_download_players; +cvar_t *allow_download_models; +cvar_t *allow_download_sounds; +cvar_t *allow_download_maps; +cvar_t *allow_download_demos; +cvar_t *allow_download_other; + +cvar_t *sv_airaccelerate; +cvar_t *sv_qwmod; // atu QW Physics modificator cvar_t *sv_novis; -cvar_t *sv_maxclients; -cvar_t *sv_reserved_slots; -cvar_t *sv_showclamp; +cvar_t *sv_maxclients; +cvar_t *sv_reserved_slots; +cvar_t *sv_showclamp; cvar_t *sv_locked; cvar_t *sv_downloadserver; -cvar_t *sv_hostname; -cvar_t *sv_public; // should heartbeats be sent +cvar_t *sv_hostname; +cvar_t *sv_public; // should heartbeats be sent #if USE_CLIENT -cvar_t *sv_debug_send; -cvar_t *sv_pad_packets; +cvar_t *sv_debug_send; +cvar_t *sv_pad_packets; #endif -cvar_t *sv_lan_force_rate; +cvar_t *sv_lan_force_rate; cvar_t *sv_calcpings_method; cvar_t *sv_changemapcmd; -cvar_t *sv_strafejump_hack; -cvar_t *sv_bodyque_hack; +cvar_t *sv_strafejump_hack; +cvar_t *sv_bodyque_hack; #ifndef _WIN32 -cvar_t *sv_oldgame_hack; +cvar_t *sv_oldgame_hack; #endif #if USE_PACKETDUP cvar_t *sv_packetdup_hack; #endif -cvar_t *sv_iplimit; -cvar_t *sv_status_limit; -cvar_t *sv_status_show; -cvar_t *sv_uptime; -cvar_t *sv_badauth_time; +cvar_t *sv_iplimit; +cvar_t *sv_status_limit; +cvar_t *sv_status_show; +cvar_t *sv_uptime; +cvar_t *sv_badauth_time; cvar_t *g_features; @@ -101,28 +100,28 @@ void SV_RemoveClient( client_t *client ) { } if( client->netchan ) { - Netchan_Close( client->netchan ); - client->netchan = NULL; + Netchan_Close( client->netchan ); + client->netchan = NULL; } // unlink them from active client list List_Remove( &client->entry ); #if USE_MVD_CLIENT - // unlink them from MVD client list - if( sv.state == ss_broadcast ) { - MVD_RemoveClient( client ); - } + // unlink them from MVD client list + if( sv.state == ss_broadcast ) { + MVD_RemoveClient( client ); + } #endif - Com_DPrintf( "Going from cs_zombie to cs_free for %s\n", client->name ); + Com_DPrintf( "Going from cs_zombie to cs_free for %s\n", client->name ); - client->state = cs_free; // can now be reused - client->name[0] = 0; + client->state = cs_free; // can now be reused + client->name[0] = 0; } void SV_CleanClient( client_t *client ) { - int i; + int i; #if USE_ANTICHEAT & 2 string_entry_t *bad, *next; @@ -133,15 +132,15 @@ void SV_CleanClient( client_t *client ) { client->ac_bad_files = NULL; #endif - if( client->download ) { - Z_Free( client->download ); - client->download = NULL; - } + if( client->download ) { + Z_Free( client->download ); + client->download = NULL; + } - if( client->versionString ) { - Z_Free( client->versionString ); - client->versionString = NULL; - } + if( client->versionString ) { + Z_Free( client->versionString ); + client->versionString = NULL; + } // free baselines allocated for this client for( i = 0; i < SV_BASELINES_CHUNKS; i++ ) { @@ -168,10 +167,10 @@ void SV_DropClient( client_t *client, const char *reason ) { return; // called recursively? } - client->state = cs_zombie; // become free in a few seconds + client->state = cs_zombie; // become free in a few seconds client->lastmessage = svs.realtime; - if( reason ) { + if( reason ) { if( oldstate == cs_spawned ) { // announce to others #if USE_MVD_CLIENT @@ -194,25 +193,25 @@ void SV_DropClient( client_t *client, const char *reason ) { Com_Printf( "%s[%s] was dropped: %s\n", client->name, NET_AdrToString( &client->netchan->remote_address ), reason ); } - } + } - // add the disconnect - MSG_WriteByte( svc_disconnect ); - SV_ClientAddMessage( client, MSG_RELIABLE|MSG_CLEAR ); + // add the disconnect + MSG_WriteByte( svc_disconnect ); + SV_ClientAddMessage( client, MSG_RELIABLE|MSG_CLEAR ); - if( oldstate == cs_spawned || ( g_features->integer & GMF_WANT_ALL_DISCONNECTS ) ) { - // call the prog function for removing a client - // this will remove the body, among other things - ge->ClientDisconnect( client->edict ); - } + if( oldstate == cs_spawned || ( g_features->integer & GMF_WANT_ALL_DISCONNECTS ) ) { + // call the prog function for removing a client + // this will remove the body, among other things + ge->ClientDisconnect( client->edict ); + } #if USE_ANTICHEAT & 2 AC_ClientDisconnect( client ); #endif - SV_CleanClient( client ); + SV_CleanClient( client ); - Com_DPrintf( "Going to cs_zombie for %s\n", client->name ); + Com_DPrintf( "Going to cs_zombie for %s\n", client->name ); #if USE_MVD_SERVER // give MVD server a chance to detect if it's dummy client was dropped @@ -230,33 +229,33 @@ CONNECTIONLESS COMMANDS */ qboolean SV_RateLimited( ratelimit_t *r ) { - if( !r->limit ) { - return qfalse; - } - if( svs.realtime - r->time > r->period ) { - r->count = 0; - r->time = svs.realtime; - return qfalse; - } - - if( r->count < r->limit ) { - return qfalse; - } - - return qtrue; + if( !r->limit ) { + return qfalse; + } + if( svs.realtime - r->time > r->period ) { + r->count = 0; + r->time = svs.realtime; + return qfalse; + } + + if( r->count < r->limit ) { + return qfalse; + } + + return qtrue; } void SV_RateInit( ratelimit_t *r, int limit, int period ) { - if( limit < 0 ) { - limit = 0; - } - if( period < 100 ) { - period = 100; - } - r->count = 0; - r->time = svs.realtime; - r->limit = limit; - r->period = period; + if( limit < 0 ) { + limit = 0; + } + if( period < 100 ) { + period = 100; + } + r->count = 0; + r->time = svs.realtime; + r->limit = limit; + r->period = period; } addrmatch_t *SV_MatchAddress( list_t *list, netadr_t *address ) { @@ -280,10 +279,10 @@ It is assumed that size of status buffer is at least SV_OUTPUTBUF_LENGTH! =============== */ static size_t SV_StatusString( char *status ) { - char entry[MAX_STRING_CHARS]; - client_t *cl; - size_t total, len; - char *tmp = sv_maxclients->string; + char entry[MAX_STRING_CHARS]; + client_t *cl; + size_t total, len; + char *tmp = sv_maxclients->string; // XXX: ugly hack to hide reserved slots if( sv_reserved_slots->integer ) { @@ -293,7 +292,7 @@ static size_t SV_StatusString( char *status ) { } // add server info - total = Cvar_BitInfo( status, CVAR_SERVERINFO ); + total = Cvar_BitInfo( status, CVAR_SERVERINFO ); sv_maxclients->string = tmp; @@ -310,7 +309,7 @@ static size_t SV_StatusString( char *status ) { status[total++] = '\n'; // add player list - if( sv_status_show->integer > 1 ) { + if( sv_status_show->integer > 1 ) { FOR_EACH_CLIENT( cl ) { if( cl->state == cs_zombie ) { continue; @@ -323,7 +322,7 @@ static size_t SV_StatusString( char *status ) { continue; } if( total + len >= SV_OUTPUTBUF_LENGTH ) { - break; // can't hold any more + break; // can't hold any more } memcpy( status + total, entry, len ); total += len; @@ -332,20 +331,20 @@ static size_t SV_StatusString( char *status ) { status[total] = 0; - return total; + return total; } static void q_printf( 1, 2 ) SV_OobPrintf( const char *format, ... ) { - va_list argptr; - char buffer[MAX_PACKETLEN_DEFAULT]; - size_t len; + va_list argptr; + char buffer[MAX_PACKETLEN_DEFAULT]; + size_t len; // write the packet header - memcpy( buffer, "\xff\xff\xff\xffprint\n", 10 ); - - va_start( argptr, format ); - len = Q_vsnprintf( buffer + 10, sizeof( buffer ) - 10, format, argptr ); - va_end( argptr ); + memcpy( buffer, "\xff\xff\xff\xffprint\n", 10 ); + + va_start( argptr, format ); + len = Q_vsnprintf( buffer + 10, sizeof( buffer ) - 10, format, argptr ); + va_end( argptr ); if( len >= sizeof( buffer ) - 10 ) { Com_WPrintf( "%s: overflow\n", __func__ ); @@ -353,7 +352,7 @@ static void q_printf( 1, 2 ) SV_OobPrintf( const char *format, ... ) { } // send the datagram - NET_SendPacket( NS_SERVER, &net_from, len + 10, buffer ); + NET_SendPacket( NS_SERVER, &net_from, len + 10, buffer ); } @@ -365,28 +364,28 @@ Responds with all the info that qplug or qspy can see ================ */ static void SVC_Status( void ) { - char buffer[MAX_PACKETLEN_DEFAULT]; + char buffer[MAX_PACKETLEN_DEFAULT]; size_t len; - if( !sv_status_show->integer ) { - return; - } + if( !sv_status_show->integer ) { + return; + } - if( SV_RateLimited( &svs.ratelimit_status ) ) { - Com_DPrintf( "Dropping status request from %s\n", + if( SV_RateLimited( &svs.ratelimit_status ) ) { + Com_DPrintf( "Dropping status request from %s\n", NET_AdrToString( &net_from ) ); - return; - } + return; + } - svs.ratelimit_status.count++; + svs.ratelimit_status.count++; // write the packet header - memcpy( buffer, "\xff\xff\xff\xffprint\n", 10 ); + memcpy( buffer, "\xff\xff\xff\xffprint\n", 10 ); len = SV_StatusString( buffer + 10 ); // send the datagram - NET_SendPacket( NS_SERVER, &net_from, len + 10, buffer ); + NET_SendPacket( NS_SERVER, &net_from, len + 10, buffer ); } /* @@ -396,18 +395,18 @@ SVC_Ack ================ */ static void SVC_Ack( void ) { - int i; - - for( i = 0; i < MAX_MASTERS; i++ ) { - if( !master_adr[i].port ) { - continue; - } - if( NET_IsEqualBaseAdr( &master_adr[i], &net_from ) ) { - Com_Printf( "Ping acknowledge from %s\n", + int i; + + for( i = 0; i < MAX_MASTERS; i++ ) { + if( !master_adr[i].port ) { + continue; + } + if( NET_IsEqualBaseAdr( &master_adr[i], &net_from ) ) { + Com_Printf( "Ping acknowledge from %s\n", NET_AdrToString( &net_from ) ); - break; - } - } + break; + } + } } /* @@ -419,36 +418,36 @@ The second parameter should be the current protocol version number. ================ */ static void SVC_Info( void ) { - char string[MAX_QPATH]; + char string[MAX_QPATH]; size_t len; - int count; - int version; + int count; + int version; client_t *client; - if (sv_maxclients->integer == 1) - return; // ignore in single player + if (sv_maxclients->integer == 1) + return; // ignore in single player - version = atoi (Cmd_Argv(1)); + version = atoi (Cmd_Argv(1)); - if (version != PROTOCOL_VERSION_DEFAULT) { - return; - } - - count = 0; + if (version != PROTOCOL_VERSION_DEFAULT) { + return; + } + + count = 0; FOR_EACH_CLIENT( client ) { - if (client->state != cs_zombie) - count++; + if (client->state != cs_zombie) + count++; } - len = Q_snprintf (string, sizeof(string), + len = Q_snprintf (string, sizeof(string), "\xff\xff\xff\xffinfo\n%16s %8s %2i/%2i\n", - sv_hostname->string, sv.name, count, sv_maxclients->integer - + sv_hostname->string, sv.name, count, sv_maxclients->integer - sv_reserved_slots->integer ); if( len >= sizeof( string ) ) { return; } - - NET_SendPacket( NS_SERVER, &net_from, len, string ); + + NET_SendPacket( NS_SERVER, &net_from, len, string ); } /* @@ -459,7 +458,7 @@ Just responds with an acknowledgement ================ */ static void SVC_Ping( void ) { - OOB_PRINT( NS_SERVER, &net_from, "ack" ); + OOB_PRINT( NS_SERVER, &net_from, "ack" ); } /* @@ -474,39 +473,39 @@ challenge, they must give a valid IP address. ================= */ static void SVC_GetChallenge( void ) { - int i, oldest; + int i, oldest; unsigned challenge; - unsigned oldestTime; + unsigned oldestTime; - oldest = 0; - oldestTime = 0xffffffff; + oldest = 0; + oldestTime = 0xffffffff; - // see if we already have a challenge for this ip - for( i = 0; i < MAX_CHALLENGES; i++ ) { - if( NET_IsEqualBaseAdr( &net_from, &svs.challenges[i].adr ) ) - break; - if( svs.challenges[i].time > com_eventTime ) { - svs.challenges[i].time = com_eventTime; + // see if we already have a challenge for this ip + for( i = 0; i < MAX_CHALLENGES; i++ ) { + if( NET_IsEqualBaseAdr( &net_from, &svs.challenges[i].adr ) ) + break; + if( svs.challenges[i].time > com_eventTime ) { + svs.challenges[i].time = com_eventTime; + } + if( svs.challenges[i].time < oldestTime ) { + oldestTime = svs.challenges[i].time; + oldest = i; } - if( svs.challenges[i].time < oldestTime ) { - oldestTime = svs.challenges[i].time; - oldest = i; - } - } + } challenge = ( ( rand() << 16 ) | rand() ) & 0x7fffffff; - if( i == MAX_CHALLENGES ) { - // overwrite the oldest - svs.challenges[oldest].challenge = challenge; - svs.challenges[oldest].adr = net_from; - svs.challenges[oldest].time = com_eventTime; - } else { - svs.challenges[i].challenge = challenge; - svs.challenges[i].time = com_eventTime; - } - - // send it back - Netchan_OutOfBandPrint( NS_SERVER, &net_from, + if( i == MAX_CHALLENGES ) { + // overwrite the oldest + svs.challenges[oldest].challenge = challenge; + svs.challenges[oldest].adr = net_from; + svs.challenges[oldest].time = com_eventTime; + } else { + svs.challenges[i].challenge = challenge; + svs.challenges[i].time = com_eventTime; + } + + // send it back + Netchan_OutOfBandPrint( NS_SERVER, &net_from, "challenge %u p=34,35,36", challenge ); } @@ -518,17 +517,17 @@ A connection request that did not come from the master ================== */ static void SVC_DirectConnect( void ) { - char userinfo[MAX_INFO_STRING]; + char userinfo[MAX_INFO_STRING]; char reconnect_var[16]; char reconnect_val[16]; - int i, number, count; - size_t length; - client_t *cl, *newcl, *lastcl; - int protocol, version; - int qport; - int challenge; - qboolean allow; - char *info, *s; + int i, number, count; + size_t length; + client_t *cl, *newcl, *lastcl; + int protocol, version; + int qport; + int challenge; + qboolean allow; + char *info, *s; int maxlength; netchan_type_t nctype; char *ncstring, *acstring; @@ -536,11 +535,11 @@ static void SVC_DirectConnect( void ) { int reserved; int zlib; - protocol = atoi( Cmd_Argv( 1 ) ); - qport = atoi( Cmd_Argv( 2 ) ) ; - challenge = atoi( Cmd_Argv( 3 ) ); + protocol = atoi( Cmd_Argv( 1 ) ); + qport = atoi( Cmd_Argv( 2 ) ) ; + challenge = atoi( Cmd_Argv( 3 ) ); - Com_DPrintf( "SVC_DirectConnect: protocol=%i, qport=%i, challenge=%i\n", + Com_DPrintf( "SVC_DirectConnect: protocol=%i, qport=%i, challenge=%i\n", protocol, qport, challenge ); if( protocol < PROTOCOL_VERSION_DEFAULT || @@ -551,28 +550,28 @@ static void SVC_DirectConnect( void ) { return; } - if( !NET_IsLocalAddress( &net_from ) ) { + if( !NET_IsLocalAddress( &net_from ) ) { addrmatch_t *match; - // see if the challenge is valid - for( i = 0; i < MAX_CHALLENGES; i++ ) { - if( !svs.challenges[i].challenge ) { - continue; - } - if( NET_IsEqualBaseAdr( &net_from, &svs.challenges[i].adr ) ) { - if( svs.challenges[i].challenge == challenge ) - break; // good - SV_OobPrintf( "Bad challenge.\n" ); - Com_DPrintf( " rejected - bad challenge.\n" ); - return; - } - } - if( i == MAX_CHALLENGES ) { - SV_OobPrintf( "No challenge for address.\n" ); - Com_DPrintf( " rejected - no challenge.\n" ); - return; - } - svs.challenges[i].challenge = 0; + // see if the challenge is valid + for( i = 0; i < MAX_CHALLENGES; i++ ) { + if( !svs.challenges[i].challenge ) { + continue; + } + if( NET_IsEqualBaseAdr( &net_from, &svs.challenges[i].adr ) ) { + if( svs.challenges[i].challenge == challenge ) + break; // good + SV_OobPrintf( "Bad challenge.\n" ); + Com_DPrintf( " rejected - bad challenge.\n" ); + return; + } + } + if( i == MAX_CHALLENGES ) { + SV_OobPrintf( "No challenge for address.\n" ); + Com_DPrintf( " rejected - no challenge.\n" ); + return; + } + svs.challenges[i].challenge = 0; // check for banned address if( ( match = SV_MatchAddress( &sv_banlist, &net_from ) ) != NULL ) { @@ -586,8 +585,8 @@ static void SVC_DirectConnect( void ) { } if( sv_locked->integer ) { - SV_OobPrintf( "Server is locked.\n" ); - Com_DPrintf( " rejected - server is locked.\n" ); + SV_OobPrintf( "Server is locked.\n" ); + Com_DPrintf( " rejected - server is locked.\n" ); return; } @@ -691,48 +690,48 @@ static void SVC_DirectConnect( void ) { } // validate userinfo - info = Cmd_Argv( 4 ); - if( !info[0] ) { + info = Cmd_Argv( 4 ); + if( !info[0] ) { SV_OobPrintf( "Empty userinfo string.\n" ); - Com_DPrintf( " rejected - empty userinfo.\n" ); - return; - } + Com_DPrintf( " rejected - empty userinfo.\n" ); + return; + } - if( !Info_Validate( info ) ) { + if( !Info_Validate( info ) ) { SV_OobPrintf( "Malformed userinfo string.\n" ); - Com_DPrintf( " rejected - malformed userinfo.\n" ); + Com_DPrintf( " rejected - malformed userinfo.\n" ); return; - } + } - s = Info_ValueForKey( info, "name" ); - if( !s[0] || Q_IsWhiteSpace( s ) ) { + s = Info_ValueForKey( info, "name" ); + if( !s[0] || Q_IsWhiteSpace( s ) ) { SV_OobPrintf( "Please set your name before connecting.\n" ); - Com_DPrintf( " rejected - empty name.\n" ); + Com_DPrintf( " rejected - empty name.\n" ); return; - } + } - length = strlen( s ); - if( length > MAX_CLIENT_NAME - 1 ) { + length = strlen( s ); + if( length > MAX_CLIENT_NAME - 1 ) { SV_OobPrintf( "Names longer than %d characters are not allowed.\n" "Your name is %"PRIz" characters long.\n", MAX_CLIENT_NAME - 1, length ); - Com_DPrintf( " rejected - oversize name (%"PRIz" chars).\n", length ); - return; - } - - s = Info_ValueForKey( info, "skin" ); - if( !s[0] ) { + Com_DPrintf( " rejected - oversize name (%"PRIz" chars).\n", length ); + return; + } + + s = Info_ValueForKey( info, "skin" ); + if( !s[0] ) { SV_OobPrintf( "Please set your skin before connecting.\n" ); - Com_DPrintf( " rejected - empty skin.\n" ); + Com_DPrintf( " rejected - empty skin.\n" ); return; - } - - length = strlen( s ); - if( !Q_ispath( s[0] ) || !Q_ispath( s[ length - 1 ] ) || strchr( s, '.' ) ) + } + + length = strlen( s ); + if( !Q_ispath( s[0] ) || !Q_ispath( s[ length - 1 ] ) || strchr( s, '.' ) ) { SV_OobPrintf( "Malformed skin.\n" ); - Com_DPrintf( " rejected - malformed skin.\n" ); - return; - } + Com_DPrintf( " rejected - malformed skin.\n" ); + return; + } // check password s = Info_ValueForKey( info, "password" ); @@ -762,7 +761,7 @@ static void SVC_DirectConnect( void ) { reserved = sv_reserved_slots->integer; } - Q_strlcpy( userinfo, info, sizeof( userinfo ) ); + Q_strlcpy( userinfo, info, sizeof( userinfo ) ); // make sure mvdspec key is not set Info_RemoveKey( userinfo, "mvdspec" ); @@ -772,68 +771,68 @@ static void SVC_DirectConnect( void ) { Info_RemoveKey( userinfo, "password" ); } - // force the IP key/value pair so the game can filter based on ip - s = NET_AdrToString( &net_from ); - if( !Info_SetValueForKey( userinfo, "ip", s ) ) { - SV_OobPrintf( "Oversize userinfo string.\n" ); - Com_DPrintf( " rejected - oversize userinfo.\n" ); - return; - } + // force the IP key/value pair so the game can filter based on ip + s = NET_AdrToString( &net_from ); + if( !Info_SetValueForKey( userinfo, "ip", s ) ) { + SV_OobPrintf( "Oversize userinfo string.\n" ); + Com_DPrintf( " rejected - oversize userinfo.\n" ); + return; + } - newcl = NULL; + newcl = NULL; reconnect_var[0] = 0; reconnect_val[0] = 0; - // if there is already a slot for this ip, reuse it + // if there is already a slot for this ip, reuse it FOR_EACH_CLIENT( cl ) { - if( NET_IsEqualAdr( &net_from, &cl->netchan->remote_address ) ) { - if( cl->state == cs_zombie ) { + if( NET_IsEqualAdr( &net_from, &cl->netchan->remote_address ) ) { + if( cl->state == cs_zombie ) { strcpy( reconnect_var, cl->reconnect_var ); strcpy( reconnect_val, cl->reconnect_val ); } else { - SV_DropClient( cl, "reconnected" ); - } + SV_DropClient( cl, "reconnected" ); + } - Com_DPrintf( "%s: reconnect\n", NET_AdrToString( &net_from ) ); - newcl = cl; + Com_DPrintf( "%s: reconnect\n", NET_AdrToString( &net_from ) ); + newcl = cl; - // NOTE: it's safe to call SV_Remove since we exit the loop - SV_RemoveClient( cl ); - break; - } - } + // NOTE: it's safe to call SV_Remove since we exit the loop + SV_RemoveClient( cl ); + break; + } + } - // find a client slot - if( !newcl ) { + // find a client slot + if( !newcl ) { lastcl = svs.udp_client_pool + sv_maxclients->integer - reserved; for( newcl = svs.udp_client_pool; newcl < lastcl; newcl++ ) { if( !newcl->state ) { break; } } - if( newcl == lastcl ) { + if( newcl == lastcl ) { if( sv_reserved_slots->integer && !reserved ) { - SV_OobPrintf( "Server and reserved slots are full.\n" ); - Com_DPrintf( " rejected - reserved slots are full.\n" ); + SV_OobPrintf( "Server and reserved slots are full.\n" ); + Com_DPrintf( " rejected - reserved slots are full.\n" ); } else { - SV_OobPrintf( "Server is full.\n" ); - Com_DPrintf( " rejected - server is full.\n" ); + SV_OobPrintf( "Server is full.\n" ); + Com_DPrintf( " rejected - server is full.\n" ); } - return; - } - } - - // build a new connection - // accept the new client - // this is the only place a client_t is ever initialized - memset( newcl, 0, sizeof( *newcl ) ); - number = newcl - svs.udp_client_pool; + return; + } + } + + // build a new connection + // accept the new client + // this is the only place a client_t is ever initialized + memset( newcl, 0, sizeof( *newcl ) ); + number = newcl - svs.udp_client_pool; newcl->number = newcl->slot = number; - newcl->challenge = challenge; // save challenge for checksumming - newcl->protocol = protocol; + newcl->challenge = challenge; // save challenge for checksumming + newcl->protocol = protocol; newcl->version = version; newcl->flags = zlib; - newcl->edict = EDICT_NUM( number + 1 ); + newcl->edict = EDICT_NUM( number + 1 ); newcl->gamedir = fs_game->string; newcl->mapname = sv.name; newcl->configstrings = ( char * )sv.configstrings; @@ -852,17 +851,17 @@ static void SVC_DirectConnect( void ) { #endif // r1q2 extensions - if( protocol == PROTOCOL_VERSION_R1Q2 || - protocol == PROTOCOL_VERSION_Q2PRO ) - { - newcl->pmp.speedMultiplier = 2; - newcl->pmp.strafeHack = sv_strafejump_hack->integer > 0 ? qtrue : qfalse; - } else { - newcl->pmp.strafeHack = sv_strafejump_hack->integer > 1 ? qtrue : qfalse; + if( protocol == PROTOCOL_VERSION_R1Q2 || + protocol == PROTOCOL_VERSION_Q2PRO ) + { + newcl->pmp.speedMultiplier = 2; + newcl->pmp.strafeHack = sv_strafejump_hack->integer > 0 ? qtrue : qfalse; + } else { + newcl->pmp.strafeHack = sv_strafejump_hack->integer > 1 ? qtrue : qfalse; } // q2pro extensions - if( protocol == PROTOCOL_VERSION_Q2PRO ) { + if( protocol == PROTOCOL_VERSION_Q2PRO ) { if( sv_qwmod->integer ) { newcl->pmp.qwmod = sv_qwmod->integer; newcl->pmp.maxspeed = 320; @@ -873,35 +872,35 @@ static void SVC_DirectConnect( void ) { } newcl->pmp.flyfix = qtrue; newcl->pmp.flyfriction = 4; - } - - // get the game a chance to reject this connection or modify the userinfo - sv_client = newcl; - sv_player = newcl->edict; - allow = ge->ClientConnect( newcl->edict, userinfo ); - sv_client = NULL; - sv_player = NULL; - if ( !allow ) { - char *reason; - - reason = Info_ValueForKey( userinfo, "rejmsg" ); - if( *reason ) { - SV_OobPrintf( "%s\nConnection refused.\n", reason ); - } else { - SV_OobPrintf( "Connection refused.\n" ); - } - Com_DPrintf( " game rejected a connection.\n" ); - return; - } + } + + // get the game a chance to reject this connection or modify the userinfo + sv_client = newcl; + sv_player = newcl->edict; + allow = ge->ClientConnect( newcl->edict, userinfo ); + sv_client = NULL; + sv_player = NULL; + if ( !allow ) { + char *reason; + + reason = Info_ValueForKey( userinfo, "rejmsg" ); + if( *reason ) { + SV_OobPrintf( "%s\nConnection refused.\n", reason ); + } else { + SV_OobPrintf( "Connection refused.\n" ); + } + Com_DPrintf( " game rejected a connection.\n" ); + return; + } // setup netchan newcl->netchan = Netchan_Setup( NS_SERVER, nctype, &net_from, qport, maxlength, protocol ); newcl->numpackets = 1; - // parse some info from the info strings - Q_strlcpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ) ); - SV_UserinfoChanged( newcl ); + // parse some info from the info strings + Q_strlcpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ) ); + SV_UserinfoChanged( newcl ); #if USE_ANTICHEAT & 2 if( !sv_force_reconnect->string[0] || reconnect_var[0] ) { @@ -919,8 +918,8 @@ static void SVC_DirectConnect( void ) { dlstring[0] = 0; } - // send the connect packet to the client - Netchan_OutOfBandPrint( NS_SERVER, &net_from, "client_connect%s%s%s map=%s", + // send the connect packet to the client + Netchan_OutOfBandPrint( NS_SERVER, &net_from, "client_connect%s%s%s map=%s", ncstring, acstring, dlstring, newcl->mapname ); List_Init( &newcl->msg_free ); @@ -954,21 +953,21 @@ static void SVC_DirectConnect( void ) { // add them to the linked list of connected clients List_SeqAdd( &svs.udp_client_list, &newcl->entry ); - Com_DPrintf( "Going from cs_free to cs_assigned for %s\n", newcl->name ); - newcl->state = cs_assigned; - newcl->lastframe = -1; - newcl->lastmessage = svs.realtime; // don't timeout + Com_DPrintf( "Going from cs_free to cs_assigned for %s\n", newcl->name ); + newcl->state = cs_assigned; + newcl->lastframe = -1; + newcl->lastmessage = svs.realtime; // don't timeout } static int Rcon_Validate (void) { - if (!rcon_password->string[0]) - return 0; + if (!rcon_password->string[0]) + return 0; - if (strcmp (Cmd_Argv(1), rcon_password->string) ) - return 0; + if (strcmp (Cmd_Argv(1), rcon_password->string) ) + return 0; - return 1; + return 1; } /* @@ -980,33 +979,33 @@ Redirect all printfs. =============== */ static void SVC_RemoteCommand( void ) { - int i; - char *string; + int i; + char *string; - if( SV_RateLimited( &svs.ratelimit_badrcon ) ) { - Com_DPrintf( "Dropping rcon from %s\n", - NET_AdrToString( &net_from ) ); - return; - } + if( SV_RateLimited( &svs.ratelimit_badrcon ) ) { + Com_DPrintf( "Dropping rcon from %s\n", + NET_AdrToString( &net_from ) ); + return; + } - i = Rcon_Validate(); - string = Cmd_RawArgsFrom( 2 ); - if( i == 0 ) { - Com_Printf( "Invalid rcon from %s:\n%s\n", - NET_AdrToString( &net_from ), string ); - SV_OobPrintf( "Bad rcon_password.\n" ); - svs.ratelimit_badrcon.count++; - return; + i = Rcon_Validate(); + string = Cmd_RawArgsFrom( 2 ); + if( i == 0 ) { + Com_Printf( "Invalid rcon from %s:\n%s\n", + NET_AdrToString( &net_from ), string ); + SV_OobPrintf( "Bad rcon_password.\n" ); + svs.ratelimit_badrcon.count++; + return; } - Com_Printf( "Rcon from %s:\n%s\n", - NET_AdrToString( &net_from ), string ); + Com_Printf( "Rcon from %s:\n%s\n", + NET_AdrToString( &net_from ), string ); - SV_BeginRedirect( RD_PACKET ); + SV_BeginRedirect( RD_PACKET ); - Cmd_ExecuteString( string ); + Cmd_ExecuteString( string ); - Com_EndRedirect(); + Com_EndRedirect(); } static const ucmd_t svcmds[] = { @@ -1031,30 +1030,30 @@ connectionless packets. */ static void SV_ConnectionlessPacket( void ) { char string[MAX_STRING_CHARS]; - char *c; + char *c; int i; size_t len; - MSG_BeginReading(); - MSG_ReadLong(); // skip the -1 marker + MSG_BeginReading(); + MSG_ReadLong(); // skip the -1 marker - len = MSG_ReadStringLine( string, sizeof( string ) ); + len = MSG_ReadStringLine( string, sizeof( string ) ); if( len >= sizeof( string ) ) { Com_DPrintf( "ignored oversize connectionless packet\n" ); return; } - Cmd_TokenizeString( string, qfalse ); + Cmd_TokenizeString( string, qfalse ); - c = Cmd_Argv( 0 ); - Com_DPrintf( "ServerPacket[%s]: %s\n", NET_AdrToString( &net_from ), c ); + c = Cmd_Argv( 0 ); + Com_DPrintf( "ServerPacket[%s]: %s\n", NET_AdrToString( &net_from ), c ); - if( !NET_IsLocalAddress( &net_from ) && net_from.ip[0] == 127 && - net_from.port == Cvar_VariableInteger( "net_port" ) ) - { - Com_DPrintf( "dropped connectionless packet from self\n" ); - return; - } + if( !NET_IsLocalAddress( &net_from ) && net_from.ip[0] == 127 && + net_from.port == Cvar_VariableInteger( "net_port" ) ) + { + Com_DPrintf( "dropped connectionless packet from self\n" ); + return; + } if( !strcmp( c, "rcon" ) ) { SVC_RemoteCommand(); @@ -1073,7 +1072,7 @@ static void SV_ConnectionlessPacket( void ) { } } - Com_DPrintf( "bad connectionless packet\n" ); + Com_DPrintf( "bad connectionless packet\n" ); } @@ -1084,7 +1083,7 @@ int SV_CountClients( void ) { int count = 0; FOR_EACH_CLIENT( cl ) { - if( cl->state > cs_zombie ) { + if( cl->state > cs_zombie ) { count++; } } @@ -1099,17 +1098,17 @@ Updates the cl->ping variables =================== */ static void SV_CalcPings( void ) { - int j; - client_t *cl; - int total, count; + int j; + client_t *cl; + int total, count; switch( sv_calcpings_method->integer ) { case 0: FOR_EACH_CLIENT( cl ) { - if( cl->state != cs_spawned ) - continue; + if( cl->state != cs_spawned ) + continue; cl->ping = 0; - cl->edict->client->ping = 0; + cl->edict->client->ping = 0; } break; case 2: @@ -1150,7 +1149,7 @@ static void SV_CalcPings( void ) { cl->edict->client->ping = cl->ping; } break; - } + } } @@ -1163,14 +1162,14 @@ for their command moves. If they exceed it, assume cheating. =================== */ static void SV_GiveMsec( void ) { - client_t *cl; + client_t *cl; - if( sv.framenum & 15 ) - return; + if( sv.framenum & 15 ) + return; FOR_EACH_CLIENT( cl ) { - cl->commandMsec = 1800; // 1600 + some slop - } + cl->commandMsec = 1800; // 1600 + some slop + } } @@ -1180,94 +1179,94 @@ SV_PacketEvent ================= */ static void SV_PacketEvent( neterr_t ret ) { - client_t *client; + client_t *client; netchan_t *netchan; - int qport; + int qport; - // check for connectionless packet (0xffffffff) first + // check for connectionless packet (0xffffffff) first // connectionless packets are processed even if the server is down - if( ret == NET_OK && *( int * )msg_read.data == -1 ) { - SV_ConnectionlessPacket(); - return; - } + if( ret == NET_OK && *( int * )msg_read.data == -1 ) { + SV_ConnectionlessPacket(); + return; + } - if( !svs.initialized ) { - return; - } + if( !svs.initialized ) { + return; + } - if( ret == NET_ERROR ) { - // check for errors from connected clients + if( ret == NET_ERROR ) { + // check for errors from connected clients FOR_EACH_CLIENT( client ) { - if( client->state == cs_zombie ) { - continue; // already a zombie - } + if( client->state == cs_zombie ) { + continue; // already a zombie + } netchan = client->netchan; - if( !NET_IsEqualBaseAdr( &net_from, &netchan->remote_address ) ) { - continue; - } - if( net_from.port && netchan->remote_address.port != net_from.port ) { + if( !NET_IsEqualBaseAdr( &net_from, &netchan->remote_address ) ) { + continue; + } + if( net_from.port && netchan->remote_address.port != net_from.port ) { continue; } client->flags |= CF_ERROR; // drop them soon - break; - } - return; - } + break; + } + return; + } - // check for packets from connected clients + // check for packets from connected clients FOR_EACH_CLIENT( client ) { netchan = client->netchan; - if( !NET_IsEqualBaseAdr( &net_from, &netchan->remote_address ) ) { - continue; - } - - // read the qport out of the message so we can fix up - // stupid address translating routers - if( client->protocol == PROTOCOL_VERSION_DEFAULT ) { - qport = msg_read.data[8] | ( msg_read.data[9] << 8 ); - if( netchan->qport != qport ) { - continue; - } - } else if( netchan->qport ) { - qport = msg_read.data[8]; - if( netchan->qport != qport ) { - continue; - } - } else { - if( netchan->remote_address.port != net_from.port ) { + if( !NET_IsEqualBaseAdr( &net_from, &netchan->remote_address ) ) { + continue; + } + + // read the qport out of the message so we can fix up + // stupid address translating routers + if( client->protocol == PROTOCOL_VERSION_DEFAULT ) { + qport = msg_read.data[8] | ( msg_read.data[9] << 8 ); + if( netchan->qport != qport ) { + continue; + } + } else if( netchan->qport ) { + qport = msg_read.data[8]; + if( netchan->qport != qport ) { + continue; + } + } else { + if( netchan->remote_address.port != net_from.port ) { continue; } } - if( netchan->remote_address.port != net_from.port ) { - Com_DPrintf( "Fixing up a translated port for %s: %d --> %d\n", + if( netchan->remote_address.port != net_from.port ) { + Com_DPrintf( "Fixing up a translated port for %s: %d --> %d\n", client->name, netchan->remote_address.port, net_from.port ); - netchan->remote_address.port = net_from.port; - } + netchan->remote_address.port = net_from.port; + } - if( netchan->Process( netchan ) ) { - // this is a valid, sequenced packet, so process it - if( client->state != cs_zombie ) { + if( netchan->Process( netchan ) ) { + // this is a valid, sequenced packet, so process it + if( client->state != cs_zombie ) { //if( client->state != cs_assigned ) { - client->lastmessage = svs.realtime; // don't timeout + client->lastmessage = svs.realtime; // don't timeout //} client->flags &= ~CF_ERROR; // don't drop - SV_ExecuteClientMessage( client ); - } - } + SV_ExecuteClientMessage( client ); + } + } - break; - } + break; + } } void SV_ProcessEvents( void ) { - neterr_t ret; + neterr_t ret; #if USE_CLIENT - memset( &net_from, 0, sizeof( net_from ) ); - net_from.type = NA_LOOPBACK; + memset( &net_from, 0, sizeof( net_from ) ); + net_from.type = NA_LOOPBACK; - // process loopback packets + // process loopback packets while( NET_GetLoopPacket( NS_SERVER ) ) { SV_PacketEvent( NET_OK ); } @@ -1275,7 +1274,7 @@ void SV_ProcessEvents( void ) { // process network packets while( ( ret = NET_GetPacket( NS_SERVER ) ) != NET_AGAIN ) { - SV_PacketEvent( ret ); + SV_PacketEvent( ret ); } } @@ -1293,16 +1292,16 @@ packets synchronously with game DLL ticks. ================== */ void SV_SendAsyncPackets( void ) { - qboolean retransmit; - client_t *client; + qboolean retransmit; + client_t *client; netchan_t *netchan; - size_t cursize; - + size_t cursize; + FOR_EACH_CLIENT( client ) { - // don't overrun bandwidth - if( svs.realtime - client->send_time < client->send_delta ) { - continue; - } + // don't overrun bandwidth + if( svs.realtime - client->send_time < client->send_delta ) { + continue; + } netchan = client->netchan; @@ -1310,18 +1309,18 @@ void SV_SendAsyncPackets( void ) { if( netchan->fragment_pending ) { cursize = netchan->TransmitNextFragment( netchan ); #if USE_CLIENT - if( sv_debug_send->integer ) { - Com_Printf( S_COLOR_BLUE"%s: frag: %"PRIz"\n", + if( sv_debug_send->integer ) { + Com_Printf( S_COLOR_BLUE"%s: frag: %"PRIz"\n", client->name, cursize ); } #endif goto calctime; } - // spawned clients are handled elsewhere - if( client->state == cs_spawned && !client->download && !( client->flags & CF_NODATA ) ) { - continue; - } + // spawned clients are handled elsewhere + if( client->state == cs_spawned && !client->download && !( client->flags & CF_NODATA ) ) { + continue; + } // see if it's time to resend a (possibly dropped) packet retransmit = com_localTime - netchan->last_sent > 1000 ? qtrue : qfalse; @@ -1331,24 +1330,24 @@ void SV_SendAsyncPackets( void ) { continue; } - // just update reliable if needed - if( netchan->type == NETCHAN_OLD ) { - SV_ClientWriteReliableMessages_Old( client, netchan->maxpacketlen ); - } - if( netchan->message.cursize || netchan->reliable_ack_pending || + // just update reliable if needed + if( netchan->type == NETCHAN_OLD ) { + SV_ClientWriteReliableMessages_Old( client, netchan->maxpacketlen ); + } + if( netchan->message.cursize || netchan->reliable_ack_pending || netchan->reliable_length || retransmit ) { - cursize = netchan->Transmit( netchan, 0, NULL, 1 ); + cursize = netchan->Transmit( netchan, 0, NULL, 1 ); #if USE_CLIENT - if( sv_debug_send->integer ) { - Com_Printf( S_COLOR_BLUE"%s: send: %"PRIz"\n", + if( sv_debug_send->integer ) { + Com_Printf( S_COLOR_BLUE"%s: send: %"PRIz"\n", client->name, cursize ); } #endif calctime: - SV_CalcSendTime( client, cursize ); - } - } + SV_CalcSendTime( client, cursize ); + } + } } /* @@ -1365,41 +1364,41 @@ if necessary ================== */ static void SV_CheckTimeouts( void ) { - client_t *client; - unsigned zombie_time = 1000 * sv_zombietime->value; - unsigned drop_time = 1000 * sv_timeout->value; + client_t *client; + unsigned zombie_time = 1000 * sv_zombietime->value; + unsigned drop_time = 1000 * sv_timeout->value; unsigned ghost_time = 1000 * sv_ghostime->value; unsigned delta; FOR_EACH_CLIENT( client ) { - // never timeout local clients - if( NET_IsLocalAddress( &client->netchan->remote_address ) ) { - continue; - } + // never timeout local clients + if( NET_IsLocalAddress( &client->netchan->remote_address ) ) { + continue; + } // NOTE: delta calculated this way is not sensitive to overflow delta = svs.realtime - client->lastmessage; - if( client->state == cs_zombie ) { + if( client->state == cs_zombie ) { if( delta > zombie_time ) { - SV_RemoveClient( client ); - } - continue; + SV_RemoveClient( client ); + } + continue; } if( client->flags & CF_DROP ) { - SV_DropClient( client, NULL ); + SV_DropClient( client, NULL ); continue; } if( client->flags & CF_ERROR ) { if( delta > ghost_time ) { - SV_DropClient( client, "connection reset by peer" ); - SV_RemoveClient( client ); // don't bother with zombie state + SV_DropClient( client, "connection reset by peer" ); + SV_RemoveClient( client ); // don't bother with zombie state continue; } } if( delta > drop_time || ( client->state == cs_assigned && delta > ghost_time ) ) { - SV_DropClient( client, "timed out" ); - SV_RemoveClient( client ); // don't bother with zombie state + SV_DropClient( client, "timed out" ); + SV_RemoveClient( client ); // don't bother with zombie state } - } + } } /* @@ -1411,16 +1410,16 @@ player processing happens outside RunWorldFrame ================ */ static void SV_PrepWorldFrame( void ) { - edict_t *ent; - int i; + edict_t *ent; + int i; - for( i = 1; i < ge->num_edicts; i++, ent++ ) { - ent = EDICT_NUM( i ); - // events only last for a single message - ent->s.event = 0; - } + for( i = 1; i < ge->num_edicts; i++, ent++ ) { + ent = EDICT_NUM( i ); + // events only last for a single message + ent->s.event = 0; + } - sv.tracecount = 0; + sv.tracecount = 0; } /* @@ -1430,39 +1429,39 @@ SV_RunGameFrame */ static void SV_RunGameFrame( void ) { #if USE_CLIENT - if( host_speeds->integer ) - time_before_game = Sys_Milliseconds(); + if( host_speeds->integer ) + time_before_game = Sys_Milliseconds(); #endif - // we always need to bump framenum, even if we - // don't run the world, otherwise the delta - // compression can get confused when a client - // has the "current" frame - sv.framenum++; - sv.frametime -= 100; + // we always need to bump framenum, even if we + // don't run the world, otherwise the delta + // compression can get confused when a client + // has the "current" frame + sv.framenum++; + sv.frametime -= 100; #if USE_MVD_SERVER - // save the entire world state if recording a serverdemo - SV_MvdBeginFrame(); + // save the entire world state if recording a serverdemo + SV_MvdBeginFrame(); #endif - ge->RunFrame(); + ge->RunFrame(); - if( msg_write.cursize ) { - Com_WPrintf( "Game DLL left %"PRIz" bytes " + if( msg_write.cursize ) { + Com_WPrintf( "Game DLL left %"PRIz" bytes " "in multicast buffer, cleared.\n", msg_write.cursize ); - SZ_Clear( &msg_write ); - } + SZ_Clear( &msg_write ); + } #if USE_MVD_SERVER - // save the entire world state if recording a serverdemo - SV_MvdEndFrame(); + // save the entire world state if recording a serverdemo + SV_MvdEndFrame(); #endif #if USE_CLIENT - if( host_speeds->integer ) - time_after_game = Sys_Milliseconds(); + if( host_speeds->integer ) + time_after_game = Sys_Milliseconds(); #endif } @@ -1475,34 +1474,34 @@ let it know we are alive, and log information ================ */ static void SV_MasterHeartbeat( void ) { - char buffer[MAX_PACKETLEN_DEFAULT]; + char buffer[MAX_PACKETLEN_DEFAULT]; size_t len; - int i; + int i; - if( !Com_IsDedicated() ) - return; // only dedicated servers send heartbeats + if( !Com_IsDedicated() ) + return; // only dedicated servers send heartbeats - if( !sv_public->integer ) - return; // a private dedicated game + if( !sv_public->integer ) + return; // a private dedicated game - if( svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000 ) - return; // not time to send yet + if( svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000 ) + return; // not time to send yet - svs.last_heartbeat = svs.realtime; + svs.last_heartbeat = svs.realtime; // write the packet header - memcpy( buffer, "\xff\xff\xff\xffheartbeat\n", 14 ); + memcpy( buffer, "\xff\xff\xff\xffheartbeat\n", 14 ); - // send the same string that we would give for a status OOB command + // send the same string that we would give for a status OOB command len = SV_StatusString( buffer + 14 ); - // send to group master - for( i = 0; i < MAX_MASTERS; i++ ) { - if( master_adr[i].port ) { - Com_DPrintf( "Sending heartbeat to %s\n", + // send to group master + for( i = 0; i < MAX_MASTERS; i++ ) { + if( master_adr[i].port ) { + Com_DPrintf( "Sending heartbeat to %s\n", NET_AdrToString( &master_adr[i] ) ); - NET_SendPacket( NS_SERVER, &master_adr[i], len + 14, buffer ); - } + NET_SendPacket( NS_SERVER, &master_adr[i], len + 14, buffer ); + } } } @@ -1514,21 +1513,21 @@ Informs all masters that this server is going down ================= */ static void SV_MasterShutdown( void ) { - int i; + int i; - if( !Com_IsDedicated() ) - return; // only dedicated servers send heartbeats + if( !Com_IsDedicated() ) + return; // only dedicated servers send heartbeats - if( !sv_public->integer ) - return; // a private dedicated game + if( !sv_public->integer ) + return; // a private dedicated game - // send to group master - for( i = 0; i < MAX_MASTERS; i++ ) { - if( master_adr[i].port ) { - Com_DPrintf( "Sending shutdown to %s\n", + // send to group master + for( i = 0; i < MAX_MASTERS; i++ ) { + if( master_adr[i].port ) { + Com_DPrintf( "Sending shutdown to %s\n", NET_AdrToString( &master_adr[i] ) ); - OOB_PRINT( NS_SERVER, &master_adr[i], "shutdown" ); - } + OOB_PRINT( NS_SERVER, &master_adr[i], "shutdown" ); + } } } @@ -1542,25 +1541,25 @@ void SV_Frame( unsigned msec ) { int mvdconns; #if USE_CLIENT - time_before_game = time_after_game = 0; + time_before_game = time_after_game = 0; #endif - svs.realtime += msec; + svs.realtime += msec; #if USE_MVD_CLIENT - mvdconns = MVD_Frame(); + mvdconns = MVD_Frame(); #else mvdconns = 0; #endif - // if server is not active, do nothing - if( !svs.initialized ) { - if( Com_IsDedicated() ) { - Sys_Sleep( 1 ); + // if server is not active, do nothing + if( !svs.initialized ) { + if( Com_IsDedicated() ) { + Sys_Sleep( 1 ); goto runbuf; - } - return; - } + } + return; + } #if USE_CLIENT // pause if there is only local client on the server @@ -1572,8 +1571,8 @@ void SV_Frame( unsigned msec ) { Cvar_Set( "sv_paused", "1" ); IN_Activate(); } - return; // don't run if paused - } + return; // don't run if paused + } if( sv_paused->integer ) { Cvar_Set( "sv_paused", "0" ); @@ -1585,52 +1584,52 @@ void SV_Frame( unsigned msec ) { AC_Run(); #endif - // check timeouts - SV_CheckTimeouts (); + // check timeouts + SV_CheckTimeouts (); // deliver fragments and reliable messages for connecting clients - SV_SendAsyncPackets(); + SV_SendAsyncPackets(); - // move autonomous things around if enough time has passed + // move autonomous things around if enough time has passed sv.frametime += msec; - if( !com_timedemo->integer && sv.frametime < 100 ) { - if( Com_IsDedicated() ) { - NET_Sleep( 100 - sv.frametime ); + if( !com_timedemo->integer && sv.frametime < 100 ) { + if( Com_IsDedicated() ) { + NET_Sleep( 100 - sv.frametime ); } - return; - } + return; + } - // update ping based on the last known frame from all clients - SV_CalcPings(); + // update ping based on the last known frame from all clients + SV_CalcPings(); - // give the clients some timeslices - SV_GiveMsec(); + // give the clients some timeslices + SV_GiveMsec(); - // let everything in the world think and move + // let everything in the world think and move SV_RunGameFrame(); - // send messages back to the UDP clients - SV_SendClientMessages(); + // send messages back to the UDP clients + SV_SendClientMessages(); #if USE_MVD_SERVER // run TCP client connections SV_MvdRunClients(); #endif - // send a heartbeat to the master if needed - SV_MasterHeartbeat(); + // send a heartbeat to the master if needed + SV_MasterHeartbeat(); - // clear teleport flags, etc for next frame + // clear teleport flags, etc for next frame #if USE_MVD_CLIENT - if( sv.state == ss_broadcast ) { - MVD_PrepWorldFrame(); + if( sv.state == ss_broadcast ) { + MVD_PrepWorldFrame(); } else #endif { - SV_PrepWorldFrame(); - } + SV_PrepWorldFrame(); + } - if( Com_IsDedicated() ) { + if( Com_IsDedicated() ) { runbuf: // run cmd buffer in dedicated mode if( cmd_buffer.waitCount > 0 ) { @@ -1650,29 +1649,29 @@ WARNING: may modify userinfo in place! ================= */ void SV_UpdateUserinfo( char *userinfo ) { - char *s; - size_t len; - - if( !userinfo[0] ) { - SV_DropClient( sv_client, "empty userinfo" ); - return; - } - - if( !Info_Validate( userinfo ) ) { - SV_DropClient( sv_client, "malformed userinfo" ); - return; - } - - s = Info_ValueForKey( userinfo, "name" ); - len = strlen( s ); - if( len >= MAX_CLIENT_NAME || Q_IsWhiteSpace( s ) ) { + char *s; + size_t len; + + if( !userinfo[0] ) { + SV_DropClient( sv_client, "empty userinfo" ); + return; + } + + if( !Info_Validate( userinfo ) ) { + SV_DropClient( sv_client, "malformed userinfo" ); + return; + } + + s = Info_ValueForKey( userinfo, "name" ); + len = strlen( s ); + if( len >= MAX_CLIENT_NAME || Q_IsWhiteSpace( s ) ) { if( sv_client->name[0] ) { SV_ClientCommand( sv_client, "set name \"%s\"\n", sv_client->name ); } else { - SV_DropClient( sv_client, "malformed name" ); + SV_DropClient( sv_client, "malformed name" ); } - return; - } + return; + } s = Info_ValueForKey( userinfo, "skin" ); len = strlen( s ); @@ -1681,16 +1680,16 @@ void SV_UpdateUserinfo( char *userinfo ) { return; } - // force the IP key/value pair so the game can filter based on ip - s = NET_AdrToString( &sv_client->netchan->remote_address ); - if( !Info_SetValueForKey( userinfo, "ip", s ) ) { - SV_DropClient( sv_client, "oversize userinfo" ); - return; - } + // force the IP key/value pair so the game can filter based on ip + s = NET_AdrToString( &sv_client->netchan->remote_address ); + if( !Info_SetValueForKey( userinfo, "ip", s ) ) { + SV_DropClient( sv_client, "oversize userinfo" ); + return; + } - strcpy( sv_client->userinfo, userinfo ); + strcpy( sv_client->userinfo, userinfo ); - SV_UserinfoChanged( sv_client ); + SV_UserinfoChanged( sv_client ); } @@ -1704,22 +1703,22 @@ into a more C freindly form. */ void SV_UserinfoChanged( client_t *cl ) { char name[MAX_CLIENT_NAME]; - char *val; - size_t len; - int i; + char *val; + size_t len; + int i; - // call prog code to allow overrides - ge->ClientUserinfoChanged( cl->edict, cl->userinfo ); + // call prog code to allow overrides + ge->ClientUserinfoChanged( cl->edict, cl->userinfo ); - // name for C code - val = Info_ValueForKey( cl->userinfo, "name" ); - len = Q_strlcpy( name, val, sizeof( name ) ); + // name for C code + val = Info_ValueForKey( cl->userinfo, "name" ); + len = Q_strlcpy( name, val, sizeof( name ) ); if( len >= sizeof( name ) ) { len = sizeof( name ) - 1; } - // mask off high bit - for( i = 0; i < len; i++ ) - name[i] &= 127; + // mask off high bit + for( i = 0; i < len; i++ ) + name[i] &= 127; if( cl->name[0] && strcmp( cl->name, name ) ) { if( Com_IsDedicated() ) { Com_Printf( "%s[%s] changed name to %s\n", cl->name, @@ -1737,16 +1736,16 @@ void SV_UserinfoChanged( client_t *cl ) { } memcpy( cl->name, name, len + 1 ); - // rate command - val = Info_ValueForKey( cl->userinfo, "rate" ); - if( *val ) { - cl->rate = atoi( val ); - clamp( cl->rate, 100, 15000 ); - } else { - cl->rate = 5000; - } + // rate command + val = Info_ValueForKey( cl->userinfo, "rate" ); + if( *val ) { + cl->rate = atoi( val ); + clamp( cl->rate, 100, 15000 ); + } else { + cl->rate = 5000; + } - // never drop over the loopback + // never drop over the loopback if( NET_IsLocalAddress( &cl->netchan->remote_address ) ) { cl->rate = 0; } @@ -1758,12 +1757,12 @@ void SV_UserinfoChanged( client_t *cl ) { cl->rate = 0; } - // msg command - val = Info_ValueForKey( cl->userinfo, "msg" ); - if( *val ) { - cl->messagelevel = atoi( val ); + // msg command + val = Info_ValueForKey( cl->userinfo, "msg" ); + if( *val ) { + cl->messagelevel = atoi( val ); clamp( cl->messagelevel, PRINT_LOW, PRINT_CHAT + 1 ); - } + } } @@ -1780,12 +1779,12 @@ void SV_SetConsoleTitle( void ) { } static void sv_status_limit_changed( cvar_t *self ) { - SV_RateInit( &svs.ratelimit_status, self->integer, 1000 ); + SV_RateInit( &svs.ratelimit_status, self->integer, 1000 ); } static void sv_badauth_time_changed( cvar_t *self ) { - SV_RateInit( &svs.ratelimit_badpass, 1, self->value * 1000 ); - SV_RateInit( &svs.ratelimit_badrcon, 1, self->value * 1000 ); + SV_RateInit( &svs.ratelimit_badpass, 1, self->value * 1000 ); + SV_RateInit( &svs.ratelimit_badrcon, 1, self->value * 1000 ); } static void sv_hostname_changed( cvar_t *self ) { @@ -1810,90 +1809,89 @@ Only called at quake2.exe startup, not for each game =============== */ void SV_Init( void ) { - SV_InitOperatorCommands (); + SV_InitOperatorCommands(); #if USE_MVD_SERVER SV_MvdRegister(); #endif #if USE_MVD_CLIENT - MVD_Register(); + MVD_Register(); #endif #if USE_ANTICHEAT & 2 AC_Register(); #endif - Cvar_Get( "protocol", va( "%i", PROTOCOL_VERSION_DEFAULT ), CVAR_SERVERINFO|CVAR_ROM ); - - Cvar_Get( "skill", "1", CVAR_LATCH ); - Cvar_Get( "deathmatch", "1", CVAR_SERVERINFO|CVAR_LATCH ); - Cvar_Get( "coop", "0", /*CVAR_SERVERINFO|*/CVAR_LATCH ); - Cvar_Get( "cheats", "0", CVAR_SERVERINFO|CVAR_LATCH ); - Cvar_Get( "dmflags", va( "%i", DF_INSTANT_ITEMS ), CVAR_SERVERINFO ); - Cvar_Get( "fraglimit", "0", CVAR_SERVERINFO ); - Cvar_Get( "timelimit", "0", CVAR_SERVERINFO ); - - sv_maxclients = Cvar_Get( "maxclients", "8", CVAR_SERVERINFO|CVAR_LATCH ); - sv_reserved_slots = Cvar_Get( "sv_reserved_slots", "0", CVAR_LATCH ); - sv_hostname = Cvar_Get( "hostname", "noname", CVAR_SERVERINFO|CVAR_ARCHIVE ); + Cvar_Get( "protocol", va( "%i", PROTOCOL_VERSION_DEFAULT ), CVAR_SERVERINFO|CVAR_ROM ); + + Cvar_Get( "skill", "1", CVAR_LATCH ); + Cvar_Get( "deathmatch", "1", CVAR_SERVERINFO|CVAR_LATCH ); + Cvar_Get( "coop", "0", /*CVAR_SERVERINFO|*/CVAR_LATCH ); + Cvar_Get( "cheats", "0", CVAR_SERVERINFO|CVAR_LATCH ); + Cvar_Get( "dmflags", va( "%i", DF_INSTANT_ITEMS ), CVAR_SERVERINFO ); + Cvar_Get( "fraglimit", "0", CVAR_SERVERINFO ); + Cvar_Get( "timelimit", "0", CVAR_SERVERINFO ); + + sv_maxclients = Cvar_Get( "maxclients", "8", CVAR_SERVERINFO|CVAR_LATCH ); + sv_reserved_slots = Cvar_Get( "sv_reserved_slots", "0", CVAR_LATCH ); + sv_hostname = Cvar_Get( "hostname", "noname", CVAR_SERVERINFO|CVAR_ARCHIVE ); sv_hostname->changed = sv_hostname_changed; - sv_timeout = Cvar_Get( "timeout", "90", 0 ); - sv_zombietime = Cvar_Get( "zombietime", "2", 0 ); - sv_ghostime = Cvar_Get( "sv_ghostime", "6", 0 ); - sv_showclamp = Cvar_Get( "showclamp", "0", 0 ); - sv_enforcetime = Cvar_Get ( "sv_enforcetime", "1", 0 ); - sv_force_reconnect = Cvar_Get ( "sv_force_reconnect", "", CVAR_LATCH ); - sv_show_name_changes = Cvar_Get( "sv_show_name_changes", "0", 0 ); - - allow_download = Cvar_Get( "allow_download", "1", CVAR_ARCHIVE ); - allow_download_players = Cvar_Get( "allow_download_players", "0", CVAR_ARCHIVE ); - allow_download_models = Cvar_Get( "allow_download_models", "1", CVAR_ARCHIVE ); - allow_download_sounds = Cvar_Get( "allow_download_sounds", "1", CVAR_ARCHIVE ); - allow_download_maps = Cvar_Get( "allow_download_maps", "1", CVAR_ARCHIVE ); - allow_download_demos = Cvar_Get( "allow_download_demos", "0", 0 ); - allow_download_other = Cvar_Get( "allow_download_other", "0", 0 ); - - sv_noreload = Cvar_Get ("sv_noreload", "0", 0); - sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH); - sv_qwmod = Cvar_Get( "sv_qwmod", "0", CVAR_LATCH ); //atu QWMod - sv_public = Cvar_Get( "public", "0", CVAR_LATCH ); - rcon_password = Cvar_Get( "rcon_password", "", CVAR_PRIVATE ); - sv_password = Cvar_Get( "sv_password", "", CVAR_PRIVATE ); - sv_reserved_password = Cvar_Get( "sv_reserved_password", "", CVAR_PRIVATE ); - sv_locked = Cvar_Get( "sv_locked", "0", 0 ); - sv_novis = Cvar_Get ("sv_novis", "0", 0); - sv_downloadserver = Cvar_Get( "sv_downloadserver", "", 0 ); + sv_timeout = Cvar_Get( "timeout", "90", 0 ); + sv_zombietime = Cvar_Get( "zombietime", "2", 0 ); + sv_ghostime = Cvar_Get( "sv_ghostime", "6", 0 ); + sv_showclamp = Cvar_Get( "showclamp", "0", 0 ); + sv_enforcetime = Cvar_Get ( "sv_enforcetime", "1", 0 ); + sv_force_reconnect = Cvar_Get ( "sv_force_reconnect", "", CVAR_LATCH ); + sv_show_name_changes = Cvar_Get( "sv_show_name_changes", "0", 0 ); + + allow_download = Cvar_Get( "allow_download", "1", CVAR_ARCHIVE ); + allow_download_players = Cvar_Get( "allow_download_players", "0", CVAR_ARCHIVE ); + allow_download_models = Cvar_Get( "allow_download_models", "1", CVAR_ARCHIVE ); + allow_download_sounds = Cvar_Get( "allow_download_sounds", "1", CVAR_ARCHIVE ); + allow_download_maps = Cvar_Get( "allow_download_maps", "1", CVAR_ARCHIVE ); + allow_download_demos = Cvar_Get( "allow_download_demos", "0", 0 ); + allow_download_other = Cvar_Get( "allow_download_other", "0", 0 ); + + sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH); + sv_qwmod = Cvar_Get( "sv_qwmod", "0", CVAR_LATCH ); //atu QWMod + sv_public = Cvar_Get( "public", "0", CVAR_LATCH ); + rcon_password = Cvar_Get( "rcon_password", "", CVAR_PRIVATE ); + sv_password = Cvar_Get( "sv_password", "", CVAR_PRIVATE ); + sv_reserved_password = Cvar_Get( "sv_reserved_password", "", CVAR_PRIVATE ); + sv_locked = Cvar_Get( "sv_locked", "0", 0 ); + sv_novis = Cvar_Get ("sv_novis", "0", 0); + sv_downloadserver = Cvar_Get( "sv_downloadserver", "", 0 ); #if USE_CLIENT - sv_debug_send = Cvar_Get( "sv_debug_send", "0", 0 ); - sv_pad_packets = Cvar_Get( "sv_pad_packets", "0", 0 ); + sv_debug_send = Cvar_Get( "sv_debug_send", "0", 0 ); + sv_pad_packets = Cvar_Get( "sv_pad_packets", "0", 0 ); #endif - sv_lan_force_rate = Cvar_Get( "sv_lan_force_rate", "0", CVAR_LATCH ); - sv_calcpings_method = Cvar_Get( "sv_calcpings_method", "1", 0 ); - sv_changemapcmd = Cvar_Get( "sv_changemapcmd", "", 0 ); + sv_lan_force_rate = Cvar_Get( "sv_lan_force_rate", "0", CVAR_LATCH ); + sv_calcpings_method = Cvar_Get( "sv_calcpings_method", "1", 0 ); + sv_changemapcmd = Cvar_Get( "sv_changemapcmd", "", 0 ); - sv_strafejump_hack = Cvar_Get( "sv_strafejump_hack", "1", CVAR_LATCH ); + sv_strafejump_hack = Cvar_Get( "sv_strafejump_hack", "1", CVAR_LATCH ); - sv_bodyque_hack = Cvar_Get( "sv_bodyque_hack", "0", 0 ); + sv_bodyque_hack = Cvar_Get( "sv_bodyque_hack", "0", 0 ); #ifndef _WIN32 - sv_oldgame_hack = Cvar_Get( "sv_oldgame_hack", "0", CVAR_LATCH ); + sv_oldgame_hack = Cvar_Get( "sv_oldgame_hack", "0", CVAR_LATCH ); #endif #if USE_PACKETDUP - sv_packetdup_hack = Cvar_Get( "sv_packetdup_hack", "0", 0 ); + sv_packetdup_hack = Cvar_Get( "sv_packetdup_hack", "0", 0 ); #endif - sv_iplimit = Cvar_Get( "sv_iplimit", "3", 0 ); + sv_iplimit = Cvar_Get( "sv_iplimit", "3", 0 ); - sv_status_show = Cvar_Get( "sv_status_show", "2", 0 ); + sv_status_show = Cvar_Get( "sv_status_show", "2", 0 ); - sv_status_limit = Cvar_Get( "sv_status_limit", "15", 0 ); - sv_status_limit->changed = sv_status_limit_changed; + sv_status_limit = Cvar_Get( "sv_status_limit", "15", 0 ); + sv_status_limit->changed = sv_status_limit_changed; - sv_uptime = Cvar_Get( "sv_uptime", "0", 0 ); + sv_uptime = Cvar_Get( "sv_uptime", "0", 0 ); - sv_badauth_time = Cvar_Get( "sv_badauth_time", "1", 0 ); - sv_badauth_time->changed = sv_badauth_time_changed; + sv_badauth_time = Cvar_Get( "sv_badauth_time", "1", 0 ); + sv_badauth_time->changed = sv_badauth_time_changed; Cvar_Get( "sv_features", va( "%d", SV_FEATURES ), CVAR_ROM ); g_features = Cvar_Get( "g_features", "0", CVAR_ROM ); @@ -1904,7 +1902,7 @@ void SV_Init( void ) { sv_pmp.friction = 6; sv_pmp.flyfriction = 9; sv_pmp.waterfriction = 1; - sv_pmp.speedMultiplier = 1; + sv_pmp.speedMultiplier = 1; SV_SetConsoleTitle(); } @@ -1920,17 +1918,17 @@ server is going to totally exit after returning from this function. ================== */ static void SV_FinalMessage( const char *message, int cmd ) { - client_t *client, *next; + client_t *client; netchan_t *netchan; - int i; + int i; - MSG_WriteByte( svc_print ); - MSG_WriteByte( PRINT_HIGH ); - MSG_WriteString( message ); - MSG_WriteByte( cmd ); + MSG_WriteByte( svc_print ); + MSG_WriteByte( PRINT_HIGH ); + MSG_WriteString( message ); + MSG_WriteByte( cmd ); - // send it twice - // stagger the packets to crutch operating system limited buffers + // send it twice + // stagger the packets to crutch operating system limited buffers for( i = 0; i < 2; i++ ) { FOR_EACH_CLIENT( client ) { if( client->state == cs_zombie ) { @@ -1946,13 +1944,13 @@ static void SV_FinalMessage( const char *message, int cmd ) { SZ_Clear( &msg_write ); - // free any data dynamically allocated - LIST_FOR_EACH_SAFE( client_t, client, next, &svs.udp_client_list, entry ) { - if( client->state != cs_zombie ) { - SV_CleanClient( client ); - } - SV_RemoveClient( client ); - } + // free any data dynamically allocated + FOR_EACH_CLIENT( client ) { + if( client->state != cs_zombie ) { + SV_CleanClient( client ); + } + SV_RemoveClient( client ); + } } @@ -1965,15 +1963,15 @@ before Sys_Quit or Sys_Error ================ */ void SV_Shutdown( const char *finalmsg, killtype_t type ) { - Cvar_Set( "sv_running", "0" ); - Cvar_Set( "sv_paused", "0" ); + Cvar_Set( "sv_running", "0" ); + Cvar_Set( "sv_paused", "0" ); - if( !svs.initialized ) { + if( !svs.initialized ) { #if USE_MVD_CLIENT MVD_Shutdown(); // make sure MVD client is down #endif - return; - } + return; + } #if USE_ANTICHEAT & 2 AC_Disconnect(); @@ -1990,26 +1988,26 @@ void SV_Shutdown( const char *finalmsg, killtype_t type ) { SV_FinalMessage( finalmsg, svc_disconnect ); } - SV_MasterShutdown(); - SV_ShutdownGameProgs(); + SV_MasterShutdown(); + SV_ShutdownGameProgs(); - // free current level - CM_FreeMap( &sv.cm ); - memset( &sv, 0, sizeof( sv ) ); + // free current level + CM_FreeMap( &sv.cm ); + memset( &sv, 0, sizeof( sv ) ); - // free server static data - Z_Free( svs.udp_client_pool ); - Z_Free( svs.entityStates ); + // free server static data + Z_Free( svs.udp_client_pool ); + Z_Free( svs.entityStates ); #if USE_ZLIB deflateEnd( &svs.z ); #endif - memset( &svs, 0, sizeof( svs ) ); + memset( &svs, 0, sizeof( svs ) ); - sv_client = NULL; - sv_player = NULL; + sv_client = NULL; + sv_player = NULL; SV_SetConsoleTitle(); - Z_LeakTest( TAG_SERVER ); + Z_LeakTest( TAG_SERVER ); } diff --git a/source/sv_mvd.c b/source/sv_mvd.c index 35f88c5..01bd7a9 100644 --- a/source/sv_mvd.c +++ b/source/sv_mvd.c @@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "sv_local.h" +#include "q_fifo.h" +#include "net_stream.h" #include "mvd_gtv.h" #define FOR_EACH_GTV( client ) \ @@ -948,7 +950,7 @@ void SV_MvdEndFrame( void ) { FS_Write( mvd.datagram.data, mvd.datagram.cursize, mvd.recording ); if( sv_mvd_maxsize->value > 0 ) { - int numbytes = FS_RawTell( mvd.recording ); + int numbytes = FS_Tell( mvd.recording ); if( numbytes > sv_mvd_maxsize->value * 1000 ) { Com_Printf( "Stopping MVD recording, maximum size reached.\n" ); diff --git a/source/sv_null.c b/source/sv_null.c index 19bdc6d..bcea168 100644 --- a/source/sv_null.c +++ b/source/sv_null.c @@ -31,11 +31,3 @@ void SV_Frame( int msec ) { void SV_ProcessEvents( void ) { } -#if 0 -qboolean MVD_GetDemoPercent( int *percent, int *bufferPercent ) { - *percent = 0; - *bufferPercent = 0; - - return qfalse; -} -#endif diff --git a/source/sv_public.h b/source/sv_public.h index c12e2d2..48f577b 100644 --- a/source/sv_public.h +++ b/source/sv_public.h @@ -39,5 +39,8 @@ void SV_Shutdown( const char *finalmsg, killtype_t type ); void SV_Frame (unsigned msec); void SV_SetConsoleTitle( void ); void SV_ConsoleOutput( const char *msg ); -//qboolean MVD_GetDemoPercent( int *percent, int *bufferPercent ); + +#if USE_MVD_CLIENT && USE_CLIENT +int MVD_GetDemoPercent( void ); +#endif diff --git a/source/sv_user.c b/source/sv_user.c index cf4358a..29f36d2 100644 --- a/source/sv_user.c +++ b/source/sv_user.c @@ -917,18 +917,18 @@ USER CMD EXECUTION SV_ClientThink ================== */ -static inline void SV_ClientThink( client_t *cl, usercmd_t *cmd ) { - cl->commandMsec -= cmd->msec; +static inline void SV_ClientThink( usercmd_t *cmd ) { + sv_client->commandMsec -= cmd->msec; - if( cl->commandMsec < 0 && sv_enforcetime->integer ) { + if( sv_client->commandMsec < 0 && sv_enforcetime->integer ) { #ifdef _DEBUG Com_DPrintf( "commandMsec underflow from %s: %d\n", - cl->name, cl->commandMsec ); + sv_client->name, sv_client->commandMsec ); #endif return; } - ge->ClientThink( cl->edict, cmd ); + ge->ClientThink( sv_player, cmd ); } static inline void SV_SetLastFrame( int lastframe ) { @@ -983,22 +983,21 @@ static void SV_OldClientExecuteMove( int net_drop ) { if( net_drop > 2 ) { sv_client->frameflags |= FF_CLIENTPRED; -// Com_DPrintf( "%s: net_drop %i\n", sv_client->name, net_drop ); } if( net_drop < 20 ) { while( net_drop > 2 ) { - SV_ClientThink( sv_client, &sv_client->lastcmd ); + SV_ClientThink( &sv_client->lastcmd ); net_drop--; } if( net_drop > 1 ) - SV_ClientThink( sv_client, &oldest ); + SV_ClientThink( &oldest ); if( net_drop > 0 ) - SV_ClientThink( sv_client, &oldcmd ); + SV_ClientThink( &oldcmd ); } - SV_ClientThink( sv_client, &newcmd ); + SV_ClientThink( &newcmd ); sv_client->lastcmd = newcmd; } @@ -1069,13 +1068,12 @@ static void SV_NewClientExecuteMove( int c, int net_drop ) { if( net_drop > numDups ) { sv_client->frameflags |= FF_CLIENTPRED; -// Com_DPrintf( "%s: net_drop %i\n", sv_client->name, net_drop ); } if( net_drop < 20 ) { // run lastcmd multiple times if no backups available while( net_drop > numDups ) { - SV_ClientThink( sv_client, &sv_client->lastcmd ); + SV_ClientThink( &sv_client->lastcmd ); net_drop--; } @@ -1083,7 +1081,7 @@ static void SV_NewClientExecuteMove( int c, int net_drop ) { while( net_drop > 0 ) { i = numDups - net_drop; for( j = 0; j < numCmds[i]; j++ ) { - SV_ClientThink( sv_client, &cmds[i][j] ); + SV_ClientThink( &cmds[i][j] ); } net_drop--; } @@ -1092,7 +1090,7 @@ static void SV_NewClientExecuteMove( int c, int net_drop ) { // run new cmds for( j = 0; j < numCmds[numDups]; j++ ) { - SV_ClientThink( sv_client, &cmds[numDups][j] ); + SV_ClientThink( &cmds[numDups][j] ); } sv_client->lastcmd = *lastcmd; diff --git a/source/sv_world.c b/source/sv_world.c index 2d35b94..432cce4 100644 --- a/source/sv_world.c +++ b/source/sv_world.c @@ -31,23 +31,23 @@ FIXME: this use of "area" is different from the bsp file use */ typedef struct areanode_s { - int axis; // -1 = leaf node - float dist; - struct areanode_s *children[2]; - list_t trigger_edicts; - list_t solid_edicts; + int axis; // -1 = leaf node + float dist; + struct areanode_s *children[2]; + list_t trigger_edicts; + list_t solid_edicts; } areanode_t; -#define AREA_DEPTH 4 -#define AREA_NODES 32 +#define AREA_DEPTH 4 +#define AREA_NODES 32 -static areanode_t sv_areanodes[AREA_NODES]; -static int sv_numareanodes; +static areanode_t sv_areanodes[AREA_NODES]; +static int sv_numareanodes; -static float *area_mins, *area_maxs; -static edict_t **area_list; -static int area_count, area_maxcount; -static int area_type; +static float *area_mins, *area_maxs; +static edict_t **area_list; +static int area_count, area_maxcount; +static int area_type; /* =============== @@ -57,41 +57,41 @@ Builds a uniformly subdivided tree for the given world size =============== */ static areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) { - areanode_t *anode; - vec3_t size; - vec3_t mins1, maxs1, mins2, maxs2; - - anode = &sv_areanodes[sv_numareanodes]; - sv_numareanodes++; - - List_Init (&anode->trigger_edicts); - List_Init (&anode->solid_edicts); - - if (depth == AREA_DEPTH) - { - anode->axis = -1; - anode->children[0] = anode->children[1] = NULL; - return anode; - } - - VectorSubtract (maxs, mins, size); - if (size[0] > size[1]) - anode->axis = 0; - else - anode->axis = 1; - - anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]); - VectorCopy (mins, mins1); - VectorCopy (mins, mins2); - VectorCopy (maxs, maxs1); - VectorCopy (maxs, maxs2); - - maxs1[anode->axis] = mins2[anode->axis] = anode->dist; - - anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2); - anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1); - - return anode; + areanode_t *anode; + vec3_t size; + vec3_t mins1, maxs1, mins2, maxs2; + + anode = &sv_areanodes[sv_numareanodes]; + sv_numareanodes++; + + List_Init (&anode->trigger_edicts); + List_Init (&anode->solid_edicts); + + if (depth == AREA_DEPTH) + { + anode->axis = -1; + anode->children[0] = anode->children[1] = NULL; + return anode; + } + + VectorSubtract (maxs, mins, size); + if (size[0] > size[1]) + anode->axis = 0; + else + anode->axis = 1; + + anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]); + VectorCopy (mins, mins1); + VectorCopy (mins, mins2); + VectorCopy (maxs, maxs1); + VectorCopy (maxs, maxs2); + + maxs1[anode->axis] = mins2[anode->axis] = anode->dist; + + anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2); + anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1); + + return anode; } /* @@ -101,23 +101,23 @@ SV_ClearWorld =============== */ void SV_ClearWorld( void ) { - mmodel_t *cm; - edict_t *ent; - int i; - - memset( sv_areanodes, 0, sizeof( sv_areanodes ) ); - sv_numareanodes = 0; - - if( sv.cm.cache ) { - cm = &sv.cm.cache->models[0]; - SV_CreateAreaNode( 0, cm->mins, cm->maxs ); - } - - // make sure all entities are unlinked - for( i = 0; i < MAX_EDICTS; i++ ) { - ent = EDICT_NUM( i ); - ent->area.prev = ent->area.next = NULL; - } + mmodel_t *cm; + edict_t *ent; + int i; + + memset( sv_areanodes, 0, sizeof( sv_areanodes ) ); + sv_numareanodes = 0; + + if( sv.cm.cache ) { + cm = &sv.cm.cache->models[0]; + SV_CreateAreaNode( 0, cm->mins, cm->maxs ); + } + + // make sure all entities are unlinked + for( i = 0; i < MAX_EDICTS; i++ ) { + ent = EDICT_NUM( i ); + ent->area.prev = ent->area.next = NULL; + } } @@ -130,121 +130,121 @@ Links entity to PVS leafs. =============== */ void SV_LinkEdict( cm_t *cm, edict_t *ent ) { - mleaf_t *leafs[MAX_TOTAL_ENT_LEAFS]; - int clusters[MAX_TOTAL_ENT_LEAFS]; - int num_leafs; - int i, j; - int area; - mnode_t *topnode; - - // set the size - VectorSubtract (ent->maxs, ent->mins, ent->size); - - // set the abs box - if (ent->solid == SOLID_BSP && + mleaf_t *leafs[MAX_TOTAL_ENT_LEAFS]; + int clusters[MAX_TOTAL_ENT_LEAFS]; + int num_leafs; + int i, j; + int area; + mnode_t *topnode; + + // set the size + VectorSubtract (ent->maxs, ent->mins, ent->size); + + // set the abs box + if (ent->solid == SOLID_BSP && (ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) ) - { // expand for rotation - float max, v; - int i; - - max = 0; - for (i=0 ; i<3 ; i++) { - v = Q_fabs( ent->mins[i]); - if (v > max) - max = v; - v = Q_fabs( ent->maxs[i]); - if (v > max) - max = v; - } - for (i=0 ; i<3 ; i++) - { - ent->absmin[i] = ent->s.origin[i] - max; - ent->absmax[i] = ent->s.origin[i] + max; - } - } - else - { // normal - VectorAdd (ent->s.origin, ent->mins, ent->absmin); - VectorAdd (ent->s.origin, ent->maxs, ent->absmax); - } - - // because movement is clipped an epsilon away from an actual edge, - // we must fully check even when bounding boxes don't quite touch - ent->absmin[0] -= 1; - ent->absmin[1] -= 1; - ent->absmin[2] -= 1; - ent->absmax[0] += 1; - ent->absmax[1] += 1; - ent->absmax[2] += 1; + { // expand for rotation + float max, v; + int i; + + max = 0; + for (i=0 ; i<3 ; i++) { + v = Q_fabs( ent->mins[i]); + if (v > max) + max = v; + v = Q_fabs( ent->maxs[i]); + if (v > max) + max = v; + } + for (i=0 ; i<3 ; i++) + { + ent->absmin[i] = ent->s.origin[i] - max; + ent->absmax[i] = ent->s.origin[i] + max; + } + } + else + { // normal + VectorAdd (ent->s.origin, ent->mins, ent->absmin); + VectorAdd (ent->s.origin, ent->maxs, ent->absmax); + } + + // because movement is clipped an epsilon away from an actual edge, + // we must fully check even when bounding boxes don't quite touch + ent->absmin[0] -= 1; + ent->absmin[1] -= 1; + ent->absmin[2] -= 1; + ent->absmax[0] += 1; + ent->absmax[1] += 1; + ent->absmax[2] += 1; // link to PVS leafs - ent->num_clusters = 0; - ent->areanum = 0; - ent->areanum2 = 0; - - //get all leafs, including solids - num_leafs = CM_BoxLeafs( cm, ent->absmin, ent->absmax, - leafs, MAX_TOTAL_ENT_LEAFS, &topnode); - - // set areas - for (i=0 ; i<num_leafs ; i++) - { - clusters[i] = CM_LeafCluster (leafs[i]); - area = CM_LeafArea (leafs[i]); - if (area) - { // doors may legally straggle two areas, - // but nothing should evern need more than that - if (ent->areanum && ent->areanum != area) - { - if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading) - Com_DPrintf ("Object touching 3 areas at %f %f %f\n", - ent->absmin[0], ent->absmin[1], ent->absmin[2]); - ent->areanum2 = area; - } - else - ent->areanum = area; - } - } - - if (num_leafs >= MAX_TOTAL_ENT_LEAFS) - { // assume we missed some leafs, and mark by headnode - ent->num_clusters = -1; - ent->headnode = CM_NumNode( cm, topnode ); - } - else - { - ent->num_clusters = 0; - for (i=0 ; i<num_leafs ; i++) - { - if (clusters[i] == -1) - continue; // not a visible leaf - for (j=0 ; j<i ; j++) - if (clusters[j] == clusters[i]) - break; - if (j == i) - { - if (ent->num_clusters == MAX_ENT_CLUSTERS) - { // assume we missed some leafs, and mark by headnode - ent->num_clusters = -1; - ent->headnode = CM_NumNode( cm, topnode ); - break; - } - - ent->clusternums[ent->num_clusters++] = clusters[i]; - } - } - } + ent->num_clusters = 0; + ent->areanum = 0; + ent->areanum2 = 0; + + //get all leafs, including solids + num_leafs = CM_BoxLeafs( cm, ent->absmin, ent->absmax, + leafs, MAX_TOTAL_ENT_LEAFS, &topnode); + + // set areas + for (i=0 ; i<num_leafs ; i++) + { + clusters[i] = CM_LeafCluster (leafs[i]); + area = CM_LeafArea (leafs[i]); + if (area) + { // doors may legally straggle two areas, + // but nothing should evern need more than that + if (ent->areanum && ent->areanum != area) + { + if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading) + Com_DPrintf ("Object touching 3 areas at %f %f %f\n", + ent->absmin[0], ent->absmin[1], ent->absmin[2]); + ent->areanum2 = area; + } + else + ent->areanum = area; + } + } + + if (num_leafs >= MAX_TOTAL_ENT_LEAFS) + { // assume we missed some leafs, and mark by headnode + ent->num_clusters = -1; + ent->headnode = CM_NumNode( cm, topnode ); + } + else + { + ent->num_clusters = 0; + for (i=0 ; i<num_leafs ; i++) + { + if (clusters[i] == -1) + continue; // not a visible leaf + for (j=0 ; j<i ; j++) + if (clusters[j] == clusters[i]) + break; + if (j == i) + { + if (ent->num_clusters == MAX_ENT_CLUSTERS) + { // assume we missed some leafs, and mark by headnode + ent->num_clusters = -1; + ent->headnode = CM_NumNode( cm, topnode ); + break; + } + + ent->clusternums[ent->num_clusters++] = clusters[i]; + } + } + } } void PF_UnlinkEdict (edict_t *ent) { - if (!ent->area.prev) - return; // not linked in anywhere - List_Remove (&ent->area); - ent->area.prev = ent->area.next = NULL; + if (!ent->area.prev) + return; // not linked in anywhere + List_Remove (&ent->area); + ent->area.prev = ent->area.next = NULL; } static int SV_CalcSolid( vec3_t mins, vec3_t maxs ) { - int i, j, k; + int i, j, k; // assume that x/y are equal and symetric i = maxs[0] / 8; @@ -262,7 +262,7 @@ static int SV_CalcSolid( vec3_t mins, vec3_t maxs ) { } static int SV_CalcSolid32( vec3_t mins, vec3_t maxs ) { - int i, j, k; + int i, j, k; // assume that x/y are equal and symetric i = maxs[0]; @@ -280,28 +280,28 @@ static int SV_CalcSolid32( vec3_t mins, vec3_t maxs ) { } void PF_LinkEdict (edict_t *ent) { - areanode_t *node; + areanode_t *node; server_entity_t *sent; int entnum; - if (ent->area.prev) - PF_UnlinkEdict (ent); // unlink from old position - - if (ent == ge->edicts) - return; // don't add the world + if (ent->area.prev) + PF_UnlinkEdict (ent); // unlink from old position + + if (ent == ge->edicts) + return; // don't add the world - if (!ent->inuse) - return; + if (!ent->inuse) + return; - if( !sv.cm.cache ) { - return; - } + if( !sv.cm.cache ) { + return; + } entnum = NUM_FOR_EDICT( ent ); sent = &sv.entities[entnum]; - // encode the size into the entity_state for client prediction - switch( ent->solid ) { + // encode the size into the entity_state for client prediction + switch( ent->solid ) { case SOLID_BBOX: if( ( ent->svflags & SVF_DEADMONSTER ) || VectorCompare( ent->mins, ent->maxs ) ) { ent->s.solid = 0; @@ -312,44 +312,44 @@ void PF_LinkEdict (edict_t *ent) { } break; case SOLID_BSP: - ent->s.solid = 31; // a solid_bbox will never create this value + ent->s.solid = 31; // a solid_bbox will never create this value sent->solid32 = 31; // FIXME: use 255? break; default: - ent->s.solid = 0; + ent->s.solid = 0; sent->solid32 = 0; break; } SV_LinkEdict( &sv.cm, ent ); - // if first time, make sure old_origin is valid - if (!ent->linkcount) { - VectorCopy (ent->s.origin, ent->s.old_origin); - } - ent->linkcount++; + // if first time, make sure old_origin is valid + if (!ent->linkcount) { + VectorCopy (ent->s.origin, ent->s.old_origin); + } + ent->linkcount++; - if (ent->solid == SOLID_NOT) - return; + if (ent->solid == SOLID_NOT) + return; // find the first node that the ent's box crosses - node = sv_areanodes; - while (1) - { - if (node->axis == -1) - break; - if (ent->absmin[node->axis] > node->dist) - node = node->children[0]; - else if (ent->absmax[node->axis] < node->dist) - node = node->children[1]; - else - break; // crosses the node - } - - // link it in - if (ent->solid == SOLID_TRIGGER) + node = sv_areanodes; + while (1) + { + if (node->axis == -1) + break; + if (ent->absmin[node->axis] > node->dist) + node = node->children[0]; + else if (ent->absmax[node->axis] < node->dist) + node = node->children[1]; + else + break; // crosses the node + } + + // link it in + if (ent->solid == SOLID_TRIGGER) List_Append( &node->trigger_edicts, &ent->area ); - else + else List_Append( &node->solid_edicts, &ent->area ); } @@ -361,43 +361,43 @@ SV_AreaEdicts_r ==================== */ static void SV_AreaEdicts_r (areanode_t *node) { - list_t *start; - edict_t *check; + list_t *start; + edict_t *check; - // touch linked edicts - if (area_type == AREA_SOLID) - start = &node->solid_edicts; - else - start = &node->trigger_edicts; + // touch linked edicts + if (area_type == AREA_SOLID) + start = &node->solid_edicts; + else + start = &node->trigger_edicts; LIST_FOR_EACH( edict_t, check, start, area ) { - if (check->solid == SOLID_NOT) - continue; // deactivated - if (check->absmin[0] > area_maxs[0] - || check->absmin[1] > area_maxs[1] - || check->absmin[2] > area_maxs[2] - || check->absmax[0] < area_mins[0] - || check->absmax[1] < area_mins[1] - || check->absmax[2] < area_mins[2]) - continue; // not touching - - if (area_count == area_maxcount) { - Com_WPrintf ("SV_AreaEdicts: MAXCOUNT\n"); - return; - } - - area_list[area_count] = check; - area_count++; - } - - if (node->axis == -1) - return; // terminal node - - // recurse down both sides - if ( area_maxs[node->axis] > node->dist ) - SV_AreaEdicts_r ( node->children[0] ); - if ( area_mins[node->axis] < node->dist ) - SV_AreaEdicts_r ( node->children[1] ); + if (check->solid == SOLID_NOT) + continue; // deactivated + if (check->absmin[0] > area_maxs[0] + || check->absmin[1] > area_maxs[1] + || check->absmin[2] > area_maxs[2] + || check->absmax[0] < area_mins[0] + || check->absmax[1] < area_mins[1] + || check->absmax[2] < area_mins[2]) + continue; // not touching + + if (area_count == area_maxcount) { + Com_WPrintf ("SV_AreaEdicts: MAXCOUNT\n"); + return; + } + + area_list[area_count] = check; + area_count++; + } + + if (node->axis == -1) + return; // terminal node + + // recurse down both sides + if ( area_maxs[node->axis] > node->dist ) + SV_AreaEdicts_r ( node->children[0] ); + if ( area_mins[node->axis] < node->dist ) + SV_AreaEdicts_r ( node->children[1] ); } /* @@ -406,18 +406,18 @@ SV_AreaEdicts ================ */ int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, - int maxcount, int areatype) + int maxcount, int areatype) { - area_mins = mins; - area_maxs = maxs; - area_list = list; - area_count = 0; - area_maxcount = maxcount; - area_type = areatype; + area_mins = mins; + area_maxs = maxs; + area_list = list; + area_count = 0; + area_maxcount = maxcount; + area_type = areatype; - SV_AreaEdicts_r (sv_areanodes); + SV_AreaEdicts_r (sv_areanodes); - return area_count; + return area_count; } @@ -432,23 +432,23 @@ object of mins/maxs size. ================ */ static mnode_t *SV_HullForEntity( edict_t *ent ) { - mmodel_t *model; + mmodel_t *model; - if( ent->solid == SOLID_BSP ) { + if( ent->solid == SOLID_BSP ) { int index = ent->s.modelindex - 1; - // explicit hulls in the BSP model - if( index <= 0 || index >= sv.cm.cache->nummodels ) { - Com_Error( ERR_DROP, "%s: inline model %d out of range", + // explicit hulls in the BSP model + if( index <= 0 || index >= sv.cm.cache->nummodels ) { + Com_Error( ERR_DROP, "%s: inline model %d out of range", __func__, index ); - } + } - model = &sv.cm.cache->models[index]; - return model->headnode; - } + model = &sv.cm.cache->models[index]; + return model->headnode; + } - // create a temp hull from bounding box sizes - return CM_HeadnodeForBox( ent->mins, ent->maxs ); + // create a temp hull from bounding box sizes + return CM_HeadnodeForBox( ent->mins, ent->maxs ); } /* @@ -458,46 +458,46 @@ SV_PointContents */ int SV_PointContents (vec3_t p) { - edict_t *touch[MAX_EDICTS], *hit; - int i, num; - int contents, c2; - mnode_t *headnode; + edict_t *touch[MAX_EDICTS], *hit; + int i, num; + int contents, c2; + mnode_t *headnode; - if( !sv.cm.cache ) { - Com_Error( ERR_DROP, "%s: no map loaded", __func__ ); - } + if( !sv.cm.cache ) { + Com_Error( ERR_DROP, "%s: no map loaded", __func__ ); + } - // get base contents from world - contents = CM_PointContents (p, sv.cm.cache->nodes); + // get base contents from world + contents = CM_PointContents (p, sv.cm.cache->nodes); - // or in contents from all the other entities - num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID); + // or in contents from all the other entities + num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID); - for (i=0 ; i<num ; i++) - { - hit = touch[i]; + for (i=0 ; i<num ; i++) + { + hit = touch[i]; - // might intersect, so do an exact clip - headnode = SV_HullForEntity (hit); + // might intersect, so do an exact clip + headnode = SV_HullForEntity (hit); - c2 = CM_TransformedPointContents (p, headnode, + c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles); - contents |= c2; - } + contents |= c2; + } - return contents; + return contents; } typedef struct { - vec3_t boxmins, boxmaxs;// enclose the test object along entire move - vec_t *mins, *maxs; // size of the moving object - vec_t *start, *end; - trace_t *trace; - edict_t *passedict; - int contentmask; + vec3_t boxmins, boxmaxs;// enclose the test object along entire move + vec_t *mins, *maxs; // size of the moving object + vec_t *start, *end; + trace_t *trace; + edict_t *passedict; + int contentmask; } moveclip_t; /* @@ -507,46 +507,46 @@ SV_ClipMoveToEntities ==================== */ static void SV_ClipMoveToEntities( moveclip_t *clip ) { - int i, num; - edict_t *touchlist[MAX_EDICTS], *touch; - trace_t trace; - mnode_t *headnode; - - num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist - , MAX_EDICTS, AREA_SOLID); - - // be careful, it is possible to have an entity in this - // list removed before we get to it (killtriggered) - for (i=0 ; i<num ; i++) - { - touch = touchlist[i]; - if (touch->solid == SOLID_NOT) - continue; - if (touch == clip->passedict) - continue; - if (clip->trace->allsolid) - return; - if (clip->passedict) - { - if (touch->owner == clip->passedict) - continue; // don't clip against own missiles - if (clip->passedict->owner == touch) - continue; // don't clip against owner - } - - if ( !(clip->contentmask & CONTENTS_DEADMONSTER) - && (touch->svflags & SVF_DEADMONSTER) ) - continue; - - // might intersect, so do an exact clip - headnode = SV_HullForEntity (touch); - - CM_TransformedBoxTrace (&trace, clip->start, clip->end, - clip->mins, clip->maxs, headnode, clip->contentmask, - touch->s.origin, touch->s.angles); - - CM_ClipEntity( clip->trace, &trace, touch ); - } + int i, num; + edict_t *touchlist[MAX_EDICTS], *touch; + trace_t trace; + mnode_t *headnode; + + num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist + , MAX_EDICTS, AREA_SOLID); + + // be careful, it is possible to have an entity in this + // list removed before we get to it (killtriggered) + for (i=0 ; i<num ; i++) + { + touch = touchlist[i]; + if (touch->solid == SOLID_NOT) + continue; + if (touch == clip->passedict) + continue; + if (clip->trace->allsolid) + return; + if (clip->passedict) + { + if (touch->owner == clip->passedict) + continue; // don't clip against own missiles + if (clip->passedict->owner == touch) + continue; // don't clip against owner + } + + if ( !(clip->contentmask & CONTENTS_DEADMONSTER) + && (touch->svflags & SVF_DEADMONSTER) ) + continue; + + // might intersect, so do an exact clip + headnode = SV_HullForEntity (touch); + + CM_TransformedBoxTrace (&trace, clip->start, clip->end, + clip->mins, clip->maxs, headnode, clip->contentmask, + touch->s.origin, touch->s.angles); + + CM_ClipEntity( clip->trace, &trace, touch ); + } } @@ -556,17 +556,17 @@ SV_TraceBounds ================== */ static void SV_TraceBounds (moveclip_t *clip) { - int i; - - for (i=0 ; i<3 ; i++) { - if (clip->end[i] > clip->start[i]) { - clip->boxmins[i] = clip->start[i] + clip->mins[i] - 1; - clip->boxmaxs[i] = clip->end[i] + clip->maxs[i] + 1; - } else { - clip->boxmins[i] = clip->end[i] + clip->mins[i] - 1; - clip->boxmaxs[i] = clip->start[i] + clip->maxs[i] + 1; - } - } + int i; + + for (i=0 ; i<3 ; i++) { + if (clip->end[i] > clip->start[i]) { + clip->boxmins[i] = clip->start[i] + clip->mins[i] - 1; + clip->boxmaxs[i] = clip->end[i] + clip->maxs[i] + 1; + } else { + clip->boxmins[i] = clip->end[i] + clip->mins[i] - 1; + clip->boxmaxs[i] = clip->start[i] + clip->maxs[i] + 1; + } + } } /* @@ -578,53 +578,59 @@ Moves the given mins/maxs volume through the world from start to end. Passedict and edicts owned by passedict are explicitly not checked. ================== */ -trace_t *SV_Trace(trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, - edict_t *passedict, int contentmask) +trace_t *SV_Trace( trace_t *trace, + vec3_t start, + vec3_t mins, + vec3_t maxs, + vec3_t end, + edict_t *passedict, + int contentmask ) { - moveclip_t clip; - - if( !sv.cm.cache ) { - Com_Error( ERR_DROP, "%s: no map loaded", __func__ ); - } - - if( ++sv.tracecount > 10000 ) { - Com_EPrintf( "SV_Trace: game DLL caught in infinite loop!\n" ); - memset( trace, 0, sizeof( *trace ) ); - trace->fraction = 1; - trace->ent = ge->edicts; - VectorCopy( end, trace->endpos ); - sv.tracecount = 0; - return trace; - } - - if (!mins) - mins = vec3_origin; - if (!maxs) - maxs = vec3_origin; - - // clip to world - CM_BoxTrace( trace, start, end, mins, maxs, sv.cm.cache->nodes, contentmask ); - trace->ent = ge->edicts; - if (trace->fraction == 0) { - return trace; // blocked by the world - } - - memset( &clip, 0, sizeof( clip ) ); - clip.trace = trace; - clip.contentmask = contentmask; - clip.start = start; - clip.end = end; - clip.mins = mins; - clip.maxs = maxs; - clip.passedict = passedict; - - // create the bounding box of the entire move - SV_TraceBounds( &clip ); - - // clip to other solid entities - SV_ClipMoveToEntities( &clip ); - - return trace; + moveclip_t clip; + + if( !sv.cm.cache ) { + Com_Error( ERR_DROP, "%s: no map loaded", __func__ ); + } + + if( ++sv.tracecount > 10000 ) { + Com_EPrintf( "SV_Trace: game DLL caught in infinite loop!\n" ); + memset( trace, 0, sizeof( *trace ) ); + trace->fraction = 1; + trace->ent = ge->edicts; + VectorCopy( end, trace->endpos ); + sv.tracecount = 0; + return trace; + } + + if (!mins) + mins = vec3_origin; + if (!maxs) + maxs = vec3_origin; + + // clip to world + CM_BoxTrace( trace, start, end, mins, maxs, + sv.cm.cache->nodes, contentmask ); + trace->ent = ge->edicts; + if (trace->fraction == 0) { + return trace; // blocked by the world + } + + memset( &clip, 0, sizeof( clip ) ); + clip.trace = trace; + clip.contentmask = contentmask; + clip.start = start; + clip.end = end; + clip.mins = mins; + clip.maxs = maxs; + clip.passedict = passedict; + + // create the bounding box of the entire move + SV_TraceBounds( &clip ); + + // clip to other solid entities + SV_ClipMoveToEntities( &clip ); + + return trace; } /* @@ -635,10 +641,10 @@ Variant of SV_Trace for native game ABI ================== */ trace_t SV_Trace_Native (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) { - trace_t trace; + trace_t trace; SV_Trace( &trace, start, mins, maxs, end, passedict, contentmask ); - return trace; + return trace; } diff --git a/source/ui_atoms.c b/source/ui_atoms.c index 89a3b64..591f127 100644 --- a/source/ui_atoms.c +++ b/source/ui_atoms.c @@ -671,6 +671,9 @@ UI_Shutdown ================= */ void UI_Shutdown( void ) { + if( !uis.initialized ) { + return; + } UI_ForceMenuOff(); ui_scale->changed = NULL; diff --git a/source/vid_sdl.c b/source/vid_sdl.c index f828e68..51a4d73 100644 --- a/source/vid_sdl.c +++ b/source/vid_sdl.c @@ -526,7 +526,7 @@ void VID_EndFrame( void ) { SDL_Flip( sdl.surface ); } -#else // SOFTWARE_RENDERER +#else // USE_REF == REF_SOFT /* static cvar_t *gl_swapinterval; @@ -609,7 +609,7 @@ void *VID_GetProcAddr( const char *sym ) { return SDL_GL_GetProcAddress( sym ); } -#endif // !SOFTWARE_RENDERER +#endif // USE_REF == REF_GL /* |